blob: d610d0c022835d4a04775f6db840d755ca784f2e [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.compare.internal;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.graphics.Image;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.ui.*;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.compare.*;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.IStreamContentAccessor;
public class EditionAction implements IActionDelegate {
/**
* Implements the IStreamContentAccessor and ITypedElement protocols
* for a Document.
*/
class DocumentBufferNode implements ITypedElement, IStreamContentAccessor {
private IDocument fDocument;
private IFile fFile;
DocumentBufferNode(IDocument document, IFile file) {
fDocument= document;
fFile= file;
}
public String getName() {
return fFile.getName();
}
public String getType() {
return fFile.getFileExtension();
}
public Image getImage() {
return null;
}
public InputStream getContents() {
return new ByteArrayInputStream(fDocument.get().getBytes());
}
}
private ISelection fSelection;
private String fBundleName;
private boolean fReplaceMode;
protected boolean fPrevious= false;
protected String fHelpContextId;
EditionAction(boolean replaceMode, String bundleName) {
fReplaceMode= replaceMode;
fBundleName= bundleName;
}
public final void selectionChanged(IAction action, ISelection selection) {
fSelection= selection;
if (action != null) {
IFile[] files= getFiles(selection, fReplaceMode);
action.setEnabled(files.length == 1); // we don't support multiple selection for now
}
}
public void run(IAction action) {
IFile[] files= getFiles(fSelection, fReplaceMode);
for (int i= 0; i < files.length; i++)
doFromHistory(files[i]);
}
private void doFromHistory(final IFile file) {
ResourceBundle bundle= ResourceBundle.getBundle(fBundleName);
String title= Utilities.getString(bundle, "title"); //$NON-NLS-1$
Shell parentShell= CompareUIPlugin.getShell();
IFileState states[]= null;
try {
states= file.getHistory(null);
} catch (CoreException ex) {
MessageDialog.openError(parentShell, title, ex.getMessage());
return;
}
if (states == null || states.length <= 0) {
String msg= Utilities.getString(bundle, "noLocalHistoryError"); //$NON-NLS-1$
MessageDialog.openInformation(parentShell, title, msg);
return;
}
ITypedElement base= new ResourceNode(file);
IDocument document= getDocument(file);
ITypedElement target= base;
if (document != null)
target= new DocumentBufferNode(document, file);
ITypedElement[] editions= new ITypedElement[states.length+1];
editions[0]= base;
for (int i= 0; i < states.length; i++)
editions[i+1]= new HistoryItem(base, states[i]);
EditionSelectionDialog d= new EditionSelectionDialog(parentShell, bundle);
d.setEditionTitleArgument(file.getName());
d.setEditionTitleImage(CompareUIPlugin.getImage(file));
//d.setHideIdenticalEntries(false);
if (fHelpContextId != null)
d.setHelpContextId(fHelpContextId);
if (fReplaceMode) {
ITypedElement ti= null;
if (fPrevious)
ti= d.selectPreviousEdition(target, editions, null);
else
ti= d.selectEdition(target, editions, null);
if (ti instanceof IStreamContentAccessor) {
IStreamContentAccessor sa= (IStreamContentAccessor)ti;
try {
if (document != null)
updateDocument(document, sa);
else
updateWorkspace(bundle, parentShell, sa, file);
} catch (InterruptedException x) {
// Do nothing. Operation has been canceled by user.
} catch (InvocationTargetException x) {
String reason= x.getTargetException().getMessage();
MessageDialog.openError(parentShell, title, Utilities.getFormattedString(bundle, "replaceError", reason)); //$NON-NLS-1$
}
}
} else {
d.setCompareMode(true);
d.selectEdition(target, editions, null);
}
}
private void updateWorkspace(final ResourceBundle bundle, Shell shell,
final IStreamContentAccessor sa, final IFile file)
throws InvocationTargetException, InterruptedException {
WorkspaceModifyOperation operation= new WorkspaceModifyOperation() {
public void execute(IProgressMonitor pm) throws InvocationTargetException {
try {
String taskName= Utilities.getString(bundle, "taskName"); //$NON-NLS-1$
pm.beginTask(taskName, IProgressMonitor.UNKNOWN);
file.setContents(sa.getContents(), false, true, pm);
} catch (CoreException e) {
throw new InvocationTargetException(e);
} finally {
pm.done();
}
}
};
ProgressMonitorDialog pmdialog= new ProgressMonitorDialog(shell);
pmdialog.run(false, true, operation);
}
private void updateDocument(IDocument document, IStreamContentAccessor sa) throws InvocationTargetException {
try {
InputStream is= sa.getContents();
String text= Utilities.readString(is);
document.replace(0, document.getLength(), text);
} catch (CoreException e) {
throw new InvocationTargetException(e);
} catch (BadLocationException e) {
throw new InvocationTargetException(e);
}
}
private IDocument getDocument(IFile file) {
IWorkbench wb= PlatformUI.getWorkbench();
if (wb == null)
return null;
IWorkbenchWindow[] ws= wb.getWorkbenchWindows();
if (ws == null)
return null;
FileEditorInput test= new FileEditorInput(file);
for (int i= 0; i < ws.length; i++) {
IWorkbenchWindow w= ws[i];
IWorkbenchPage[] wps= w.getPages();
if (wps != null) {
for (int j= 0; j < wps.length; j++) {
IWorkbenchPage wp= wps[j];
IEditorPart ep= wp.findEditor(test);
if (ep instanceof ITextEditor) {
ITextEditor te= (ITextEditor) ep;
IDocumentProvider dp= te.getDocumentProvider();
if (dp != null) {
IDocument doc= dp.getDocument(ep);
if (doc != null)
return doc;
}
}
}
}
}
return null;
}
private IFile[] getFiles(ISelection selection, boolean modifiable) {
ArrayList result= new ArrayList();
Object[] s= Utilities.toArray(selection);
for (int i= 0; i < s.length; i++) {
Object o= s[i];
IFile file= null;
if (o instanceof IFile) {
file= (IFile) o;
} else if (o instanceof IAdaptable) {
IAdaptable a= (IAdaptable) o;
Object adapter= a.getAdapter(IResource.class);
if (adapter instanceof IFile)
file= (IFile) adapter;
}
if (file != null) {
if (modifiable) {
if (!file.isReadOnly())
result.add(file);
} else {
result.add(file);
}
}
}
return (IFile[]) result.toArray(new IFile[result.size()]);
}
}