blob: 660368864aaa77a28a5e4d150f3a0d19cf248b99 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.search.internal.ui.text;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.util.Assert;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.GlobalBuildAction;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.search.ui.ISearchResultView;
import org.eclipse.search.internal.ui.SearchMessages;
import org.eclipse.search.internal.ui.SearchPlugin;
import org.eclipse.search.internal.ui.SearchResultView;
import org.eclipse.search.internal.ui.SearchResultViewEntry;
import org.eclipse.search.internal.ui.util.ExceptionHandler;
public class ReplaceDialog extends Dialog {
private static final int REPLACE_NEXT= IDialogConstants.CLIENT_ID;
private static final int REPLACE= IDialogConstants.CLIENT_ID + 1;
private static final int NEXT= IDialogConstants.CLIENT_ID + 2;
private String fSearchPattern;
private IWorkbenchWindow fWindow;
private boolean fAutobuild;
private boolean fFatalError;
// UI
private Text fTextField;
private Button fSaveButton;
private Button fReplaceNextButton;
private Button fReplaceButton;
private Button fNextButton;
private boolean fSaved;
private ITextEditor fEditor;
private boolean fCloseEditor;
private IDocument fDocument;
private AbstractMarkerAnnotationModel fAnnotationModel;
private List fElements;
private int fElementIndex;
private SearchResultViewEntry fCurrentEntry;
private List fCurrentMarkers;
private int fMarkerIndex;
private IMarker fCurrentMatch;
private static class MarkerNotPresentableException extends Exception {
private IFile fFile;
MarkerNotPresentableException(IFile file) {
fFile= file;
}
public IFile getFile() {
return fFile;
}
}
protected ReplaceDialog(Shell parentShell, List elements, IWorkbenchWindow window, String searchPattern) {
super(parentShell);
Assert.isNotNull(elements);
Assert.isNotNull(searchPattern);
fElements= new ArrayList(elements);
Assert.isNotNull(window);
fWindow= window;
fSearchPattern= searchPattern;
}
public void create() {
super.create();
Shell shell= getShell();
shell.setText(getDialogTitle());
updateButtons();
}
public int open() {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
fAutobuild= workspace.isAutoBuilding();
if (fAutobuild) {
IWorkspaceDescription description= workspace.getDescription();
description.setAutoBuilding(false);
try {
workspace.setDescription(description);
} catch (CoreException e) {
ExceptionHandler.handle(e, getShell(), getDialogTitle(), SearchMessages.getString("ReplaceDialog.error.auto_building")); //$NON-NLS-1$
fFatalError= true;
}
}
try {
fCurrentMatch= getNextMatch(false);
} catch (CoreException e) {
ExceptionHandler.handle(e, getShell(), getDialogTitle(), SearchMessages.getString("ReplaceDialog.error.no_matches")); //$NON-NLS-1$
fFatalError= true;
} catch (MarkerNotPresentableException e) {
handleMarkerNotPresentableException(e);
fFatalError= true;
}
return super.open();
}
public boolean close() {
boolean result= super.close();
restoreAutoBuildState();
return result;
}
protected Control createDialogArea(Composite parent) {
Composite result= (Composite)super.createDialogArea(parent);
GridLayout layout= (GridLayout)result.getLayout();
layout.numColumns= 2;
initializeDialogUnits(result);
Label label= new Label(result, SWT.NONE);
label.setText(SearchMessages.getString("ReplaceDialog.replace_label")); //$NON-NLS-1$
CLabel clabel= new CLabel(result, SWT.NONE);
clabel.setText(fSearchPattern);
GridData gd= new GridData(GridData.FILL_HORIZONTAL);
gd.widthHint= convertWidthInCharsToPixels(50);
clabel.setLayoutData(gd);
label= new Label(result, SWT.NONE);
label.setText(SearchMessages.getString("ReplaceDialog.with_label")); //$NON-NLS-1$
fTextField= new Text(result, SWT.BORDER);
gd= new GridData(GridData.FILL_HORIZONTAL);
gd.widthHint= convertWidthInCharsToPixels(50);
fTextField.setLayoutData(gd);
fTextField.setFocus();
fSaveButton= new Button(result, SWT.CHECK);
fSaveButton.setText(SearchMessages.getString("ReplaceDialog.save_changes")); //$NON-NLS-1$
fSaveButton.setSelection(true);
gd= new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan= 2;
fSaveButton.setLayoutData(gd);
applyDialogFont(result);
return result;
}
protected void createButtonsForButtonBar(Composite parent) {
fReplaceNextButton= createButton(parent, REPLACE_NEXT, SearchMessages.getString("ReplaceDialog.replace_next"), false); //$NON-NLS-1$
fReplaceButton= createButton(parent, REPLACE, SearchMessages.getString("ReplaceDialog.replace"), false); //$NON-NLS-1$
fNextButton= createButton(parent, NEXT, SearchMessages.getString("ReplaceDialog.next"), false); //$NON-NLS-1$
createButton(parent, IDialogConstants.CANCEL_ID, SearchMessages.getString("ReplaceDialog.close"), false); //$NON-NLS-1$
}
protected Point getInitialLocation(Point initialSize) {
SearchResultView view= (SearchResultView)SearchPlugin.getSearchResultView();
if (view == null)
return super.getInitialLocation(initialSize);
Point result= new Point(0,0);
Control control= view.getViewer().getControl();
Point size= control.getSize();
Point location= control.toDisplay(control.getLocation());
result.x= Math.max(0, location.x + size.x - initialSize.x);
result.y= Math.max(0, location.y + size. y - initialSize.y);
return result;
}
protected void buttonPressed(int buttonId) {
try {
boolean save= fSaveButton.getSelection();
String text= fTextField.getText();
switch(buttonId) {
case REPLACE_NEXT:
replace(fCurrentMatch, text, save);
fCurrentMatch= getNextMatch(save);
break;
case REPLACE:
replace(fCurrentMatch, text, save);
fCurrentMatch= null;
break;
case NEXT:
fCurrentMatch= getNextMatch(save);
break;
case IDialogConstants.CANCEL_ID:
saveEditor(save);
break;
}
} catch (CoreException e) {
ExceptionHandler.handle(e, getShell(), getDialogTitle(), SearchMessages.getString("ReplaceDialog.error.unexpected_exception")); //$NON-NLS-1$
fFatalError= true;
} catch (BadLocationException e) {
MessageDialog.openError(getShell(), getDialogTitle(), SearchMessages.getString("ReplaceDialog.error.different_content")); //$NON-NLS-1$
fFatalError= true;
} catch (MarkerNotPresentableException e) {
handleMarkerNotPresentableException(e);
fFatalError= true;
}
updateButtons();
super.buttonPressed(buttonId);
}
private void replace(IMarker source, String text, boolean save) throws CoreException, BadLocationException {
Position position= fAnnotationModel.getMarkerPosition(source);
fDocument.replace(position.getOffset(), position.getLength(), text);
SearchPlugin.getWorkspace().deleteMarkers(new IMarker[] {source});
}
private boolean hasNextMatch() {
if (fCurrentMarkers != null)
return true;
return fElementIndex < fElements.size();
}
private IMarker getNextMatch(boolean save) throws CoreException, MarkerNotPresentableException {
if (fCurrentMarkers == null) {
if (fElementIndex >= fElements.size())
return null;
saveEditor(save);
fCurrentEntry= (SearchResultViewEntry)fElements.get(fElementIndex++);
fCurrentMarkers= new ArrayList(fCurrentEntry.getMarkers());
fMarkerIndex= 0;
}
IMarker result= (IMarker)fCurrentMarkers.get(fMarkerIndex);
if (fEditor == null) {
IWorkbenchPage activePage = fWindow.getActivePage();
int openEditors= activePage.getEditorReferences().length;
fEditor= openFile(result, activePage);
IDE.gotoMarker(fEditor, result);
IDocumentProvider provider= fEditor.getDocumentProvider();
IEditorInput input = fEditor.getEditorInput();
fDocument= provider.getDocument(input);
fAnnotationModel= (AbstractMarkerAnnotationModel)provider.getAnnotationModel(input);
fCloseEditor= openEditors < activePage.getEditorReferences().length;
} else {
IDE.gotoMarker(fEditor, result);
}
if (fMarkerIndex == fCurrentMarkers.size() - 1) {
fCurrentMarkers= null;
} else {
fMarkerIndex++;
}
return result;
}
private ITextEditor openFile(IMarker marker, IWorkbenchPage activePage) throws MarkerNotPresentableException, PartInitException {
IFile markerFile= marker.getResource() instanceof IFile ? (IFile)marker.getResource() : null;
if (markerFile == null)
throw new MarkerNotPresentableException(null);
String currentEditorId= null;
IEditorDescriptor desc= IDE.getDefaultEditor(markerFile);
if (desc != null)
currentEditorId= desc.getId();
try {
IEditorPart result= activePage.openEditor(new FileEditorInput(markerFile), "org.eclipse.ui.DefaultTextEditor", false); //$NON-NLS-1$
if (!(result instanceof ITextEditor))
throw new MarkerNotPresentableException(markerFile);
return (ITextEditor)result;
} finally {
if (currentEditorId != null)
IDE.setDefaultEditor(markerFile, currentEditorId);
}
}
private void saveEditor(boolean save) throws CoreException {
if (fEditor == null)
return;
save= save && fEditor.isDirty();
if (save) {
IDocumentProvider provider= fEditor.getDocumentProvider();
IEditorInput input = fEditor.getEditorInput();
try {
provider.aboutToChange(input);
provider.saveDocument(new NullProgressMonitor(), input, fDocument, true);
fSaved= true;
} finally {
provider.changed(input);
}
}
if (fCloseEditor && !fEditor.isDirty())
fEditor.close(false);
fEditor= null;
fDocument= null;
fAnnotationModel= null;
fCloseEditor= false;
}
private void updateButtons() {
boolean hasNext= hasNextMatch();
fReplaceNextButton.setEnabled(!fFatalError && fCurrentMatch != null);
fReplaceButton.setEnabled(!fFatalError && fCurrentMatch != null);
fNextButton.setEnabled(!fFatalError && hasNext);
}
private void restoreAutoBuildState() {
if (!fAutobuild)
return;
IWorkspace workspace= ResourcesPlugin.getWorkspace();
IWorkspaceDescription description= workspace.getDescription();
description.setAutoBuilding(true);
try {
workspace.setDescription(description);
} catch (CoreException e) {
ExceptionHandler.handle(e, getShell(), getDialogTitle(), SearchMessages.getString("ReplaceDialog.error.reenable_auto_build_failed")); //$NON-NLS-1$
return;
}
ISearchResultView view= SearchPlugin.getSearchResultView();
if (fSaved && view != null) {
new GlobalBuildAction(
view.getSite().getWorkbenchWindow(),
IncrementalProjectBuilder.INCREMENTAL_BUILD).run();
}
}
private String getDialogTitle() {
return SearchMessages.getString("ReplaceDialog.dialog.title"); //$NON-NLS-1$
}
private void handleMarkerNotPresentableException(MarkerNotPresentableException e) {
IFile file= e.getFile();
String message;
if (file == null) {
message= SearchMessages.getString("ReplaceDialog.error.no_file_for_marker"); //$NON-NLS-1$
} else {
message= SearchMessages.getFormattedString("ReplaceDialog.error.unable_to_open_text_editor", file.getName()); //$NON-NLS-1$
}
MessageDialog.openError(getParentShell(), getDialogTitle(), message);
}
}