blob: e238378d1b5fe21ae3407bd7bc8181c58e63048c [file] [log] [blame]
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
package org.eclipse.compare.internal.patch;
import java.io.*;
import java.util.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.wizard.*;
import org.eclipse.ui.help.*;
import org.eclipse.ui.model.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.compare.internal.Utilities;
/* package */ class InputPatchPage extends WizardPage {
// constants
protected static final int SIZING_TEXT_FIELD_WIDTH= 250;
protected static final int COMBO_HISTORY_LENGTH= 5;
private final static int SIZING_SELECTION_WIDGET_WIDTH= 400;
private final static int SIZING_SELECTION_WIDGET_HEIGHT= 150;
// dialog store id constants
private final static String PAGE_NAME= "PatchWizardPage1"; //$NON-NLS-1$
private final static String STORE_PATCH_FILE_ID= PAGE_NAME + ".PATCH_FILE"; //$NON-NLS-1$
private final static String STORE_PATCH_FILES_ID= PAGE_NAME + ".PATCH_FILES"; //$NON-NLS-1$
private final static String STORE_USE_CLIPBOARD_ID= PAGE_NAME + ".USE_CLIPBOARD"; //$NON-NLS-1$
// help IDs
private final static String PATCH_HELP_CONTEXT_ID= "PatchWizardHelpId"; //$NON-NLS-1$
private boolean fShowError= false;
// SWT widgets
private Button fUseClipboardButton;
private Combo fPatchFileNameField;
private Button fPatchFileBrowseButton;
private Button fUsePatchFileButton;
private Group fPatchFileGroup;
private CheckboxTreeViewer fPatchTargets;
private PatchWizard fPatchWizard;
InputPatchPage(PatchWizard pw) {
super("InputPatchPage", PatchMessages.getString("InputPatchPage.title"), null); //$NON-NLS-1$ //$NON-NLS-2$
fPatchWizard= pw;
setMessage(PatchMessages.getString("InputPatchPage.message")); //$NON-NLS-1$
}
/**
* Get a path from the supplied text widget.
* @return org.eclipse.core.runtime.IPath
*/
protected IPath getPathFromText(Text textField) {
return (new Path(textField.getText())).makeAbsolute();
}
/* package */ String getPatchName() {
if (getUseClipboard())
return PatchMessages.getString("InputPatchPage.Clipboard"); //$NON-NLS-1$
return getPatchFilePath();
}
public void createControl(Composite parent) {
Composite composite= new Composite(parent, SWT.NULL);
composite.setLayout(new GridLayout());
composite.setLayoutData(new GridData(/* GridData.VERTICAL_ALIGN_FILL | */ GridData.HORIZONTAL_ALIGN_FILL));
setControl(composite);
Label l= new Label(composite, SWT.NONE); // a spacer
l.setText(PatchMessages.getString("InputPatchPage.SelectInput")); //$NON-NLS-1$
buildInputGroup(composite);
new Label(composite, SWT.NONE); // a spacer
buildPatchFileGroup(composite);
restoreWidgetValues();
updateWidgetEnablements();
//updatePageCompletion();
WorkbenchHelp.setHelp(composite, PATCH_HELP_CONTEXT_ID);
}
/* (non-JavaDoc)
* Method declared in IWizardPage.
*/
public IWizardPage getNextPage() {
if (true) {
Patcher patcher= ((PatchWizard) getWizard()).getPatcher();
// Create a reader for the input
Reader reader= null;
if (getUseClipboard()) {
Control c= getControl();
if (c != null) {
Clipboard clipboard= new Clipboard(c.getDisplay());
Object o= clipboard.getContents(TextTransfer.getInstance());
clipboard.dispose();
if (o instanceof String)
reader= new StringReader((String)o);
}
} else {
String patchFilePath= getPatchFilePath();
if (patchFilePath != null) {
try {
reader= new FileReader(patchFilePath);
} catch (FileNotFoundException ex) {
MessageDialog.openError(null,
PatchMessages.getString("InputPatchPage.PatchErrorDialog.title"), //$NON-NLS-1$
PatchMessages.getString("InputPatchPage.PatchFileNotFound.message")); //$NON-NLS-1$
}
}
}
// parse the input
if (reader != null) {
try {
patcher.parse(new BufferedReader(reader));
} catch (IOException ex) {
MessageDialog.openError(null,
PatchMessages.getString("InputPatchPage.PatchErrorDialog.title"), //$NON-NLS-1$
PatchMessages.getString("InputPatchPage.ParseError.message")); //$NON-NLS-1$
}
try {
reader.close();
} catch (IOException x) {
}
}
Diff[] diffs= patcher.getDiffs();
if (diffs == null || diffs.length == 0) {
String source= getUseClipboard() ? "Clipboard" //$NON-NLS-1$
: "File"; //$NON-NLS-1$
MessageDialog.openError(null,
PatchMessages.getString("InputPatchPage.PatchErrorDialog.title"), //$NON-NLS-1$
PatchMessages.getString("InputPatchPage.NoDiffsFound_"+source+".message")); //$NON-NLS-1$ //$NON-NLS-2$
return this;
}
// guess prefix count
int guess= guessPrefix(diffs);
patcher.setStripPrefixSegments(guess);
}
return super.getNextPage();
}
private int guessPrefix(Diff[] diffs) {
/*
ArrayList list= new ArrayList();
IResource target= fPatchWizard.getTarget();
if (target instanceof IFile) {
list.add(target.getFullPath());
} else if (target instanceof IContainer) {
addLeaf(list, (IContainer) target);
}
// guess prefix count
for (int i= 0; i < diffs.length; i++) {
IPath p= diffs[i].fOldPath;
if (p != null) {
int matches= match(p, list);
if (matches > 0) {
return p.segmentCount() - matches;
}
}
}
*/
return 0;
}
private int match(IPath path, ArrayList list) {
Iterator iter= list.iterator();
while (iter.hasNext()) {
IPath filePath= (IPath) iter.next();
int matches= matchTrailingSegments(path, filePath);
if (matches > 0)
return matches;
}
return 0;
}
private int matchTrailingSegments(IPath p1, IPath p2) {
int matches= 0;
int i1= p1.segmentCount()-1;
int i2= p2.segmentCount()-1;
for (; i1 >= 0 && i2 >= 0; i1--, i2--) {
String s1= p1.segment(i1);
String s2= p2.segment(i2);
if (!s1.equals(s2))
break;
matches++;
}
return matches;
}
private void addLeaf(ArrayList list, IContainer c) {
IResource[] rs= null;
try {
rs= c.members();
} catch(CoreException ex) {
}
if (rs != null) {
for (int i= 0; i < rs.length; i++) {
IResource r= rs[i];
if (r instanceof IFile)
list.add(r.getFullPath());
else if (r instanceof IContainer)
addLeaf(list, (IContainer) r);
}
}
}
/* (non-JavaDoc)
* Method declared in IWizardPage.
*/
public boolean canFlipToNextPage() {
if (true) {
// we can't call getNextPage to determine if flipping is allowed since computing
// the next page is quite expensive. So we say yes if the page is complete.
return isPageComplete();
} else {
return super.canFlipToNextPage();
}
}
private void setEnablePatchFile(boolean enable) {
fPatchFileNameField.setEnabled(enable);
fPatchFileBrowseButton.setEnabled(enable);
}
/**
* Create the group for selecting the patch file
*/
private void buildPatchFileGroup(Composite parent) {
fPatchFileGroup= new Group(parent, SWT.NONE);
fPatchFileGroup.setText(PatchMessages.getString("InputPatchPage.SelectPatch.title")); //$NON-NLS-1$
GridLayout layout= new GridLayout();
layout.numColumns= 3;
fPatchFileGroup.setLayout(layout);
fPatchFileGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
// 1st row
fUsePatchFileButton= new Button(fPatchFileGroup, SWT.RADIO);
fUsePatchFileButton.setText(PatchMessages.getString("InputPatchPage.FileButton.text")); //$NON-NLS-1$
fPatchFileNameField= new Combo(fPatchFileGroup, SWT.BORDER);
GridData gd= new GridData(GridData.FILL_HORIZONTAL);
//gd.horizontalIndent= 8;
gd.widthHint= SIZING_TEXT_FIELD_WIDTH;
fPatchFileNameField.setLayoutData(gd);
fPatchFileBrowseButton= new Button(fPatchFileGroup, SWT.PUSH);
fPatchFileBrowseButton.setText(PatchMessages.getString("InputPatchPage.ChooseFileButton.text")); //$NON-NLS-1$
fPatchFileBrowseButton.setLayoutData(new GridData());
// 2nd row
fUseClipboardButton= new Button(fPatchFileGroup, SWT.RADIO);
fUseClipboardButton.setText(PatchMessages.getString("InputPatchPage.UseClipboardButton.text")); //$NON-NLS-1$
gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gd.horizontalSpan= 2;
fUseClipboardButton.setLayoutData(gd);
// Add listeners
fUsePatchFileButton.addSelectionListener(
new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
fShowError= true;
setEnablePatchFile(!getUseClipboard());
updateWidgetEnablements();
}
}
);
fPatchFileNameField.addSelectionListener(
new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
setSourceName(fPatchFileNameField.getText());
updateWidgetEnablements();
}
}
);
fPatchFileNameField.addModifyListener(
new ModifyListener() {
public void modifyText(ModifyEvent e) {
fShowError= true;
updateWidgetEnablements();
}
}
);
fPatchFileBrowseButton.addSelectionListener(
new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
handlePatchFileBrowseButtonPressed();
updateWidgetEnablements();
}
}
);
//fPatchFileNameField.setFocus();
}
private void buildInputGroup(Composite parent) {
PatchWizard pw= (PatchWizard) getWizard();
IResource target= pw.getTarget();
IWorkspace workspace= target.getWorkspace();
IWorkspaceRoot root= workspace.getRoot();
Tree tree= new Tree(parent, SWT.BORDER);
GridData gd= new GridData(GridData.FILL_HORIZONTAL);
gd.heightHint= 200;
tree.setLayoutData(gd);
fPatchTargets= new CheckboxTreeViewer(tree);
fPatchTargets.setLabelProvider(new WorkbenchLabelProvider());
fPatchTargets.setContentProvider(new WorkbenchContentProvider());
fPatchTargets.setSorter(new WorkbenchViewerSorter());
fPatchTargets.setInput(root);
if (target != null) {
fPatchTargets.expandToLevel(target, 0);
fPatchTargets.setSelection(new StructuredSelection(target));
}
// register listeners
fPatchTargets.addSelectionChangedListener(
new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
fPatchWizard.setTargets(PatchWizard.getResource(event.getSelection()));
updateWidgetEnablements();
}
}
);
//fPatchFileNameField.setFocus();
}
/**
* Returns a content provider for <code>IResource</code>s that returns
* only children of the given resource type.
*/
private ITreeContentProvider getResourceProvider(final int resourceType) {
return new WorkbenchContentProvider() {
public Object[] getChildren(Object o) {
if (o instanceof IContainer) {
try {
ArrayList results= new ArrayList();
IResource[] members= ((IContainer)o).members();
for (int i= 0; i < members.length; i++)
// filter out the desired resource types
if ((members[i].getType() & resourceType) != 0)
results.add(members[i]);
return results.toArray();
} catch (CoreException e) {
}
}
// just return an empty set of children
return new Object[0];
}
};
}
/**
* Updates the enable state of this page's controls.
*/
private void updateWidgetEnablements() {
String error= null;
ISelection selection= fPatchTargets.getSelection();
boolean anySelected= selection != null && !selection.isEmpty();
if (!anySelected)
error= PatchMessages.getString("InputPatchPage.NothingSelected.message"); //$NON-NLS-1$
boolean gotPatch= false;
if (getUseClipboard()) {
Control c= getControl();
if (c != null) {
Clipboard clipboard= new Clipboard(c.getDisplay());
Object o= clipboard.getContents(TextTransfer.getInstance());
clipboard.dispose();
if (o instanceof String) {
String s= ((String) o).trim();
if (s.length() > 0)
gotPatch= true;
else
error= PatchMessages.getString("InputPatchPage.ClipboardIsEmpty.message"); //$NON-NLS-1$
} else
error= PatchMessages.getString("InputPatchPage.NoTextInClipboard.message"); //$NON-NLS-1$
} else
error= PatchMessages.getString("InputPatchPage.CouldNotReadClipboard.message"); //$NON-NLS-1$
} else {
String path= fPatchFileNameField.getText();
if (path != null && path.length() > 0) {
File file= new File(path);
gotPatch= file.exists() && file.isFile() && file.length() > 0;
if (!gotPatch)
error= PatchMessages.getString("InputPatchPage.CannotLocatePatch.message") + path; //$NON-NLS-1$
} else {
error= PatchMessages.getString("InputPatchPage.NoFileName.message"); //$NON-NLS-1$
}
}
setPageComplete(anySelected && gotPatch);
if (fShowError)
setErrorMessage(error);
}
protected void handlePatchFileBrowseButtonPressed() {
FileDialog dialog= new FileDialog(getShell(), SWT.NONE);
dialog.setText(PatchMessages.getString("InputPatchPage.SelectPatchFileDialog.title")); //$NON-NLS-1$
dialog.setFilterPath(getPatchFilePath());
String res= dialog.open();
if (res == null)
return;
String patchFilePath= dialog.getFileName();
IPath filterPath= new Path(dialog.getFilterPath());
IPath path= filterPath.append(patchFilePath).makeAbsolute();
patchFilePath= path.toOSString();
//fDialogSettings.put(IUIConstants.DIALOGSTORE_LASTEXTJAR, filterPath.toOSString());
fPatchFileNameField.setText(patchFilePath);
//setSourceName(patchFilePath);
}
/**
* Sets the source name of the import to be the supplied path.
* Adds the name of the path to the list of items in the
* source combo and selects it.
*
* @param path the path to be added
*/
protected void setSourceName(String path) {
if (path.length() > 0) {
String[] currentItems= fPatchFileNameField.getItems();
int selectionIndex= -1;
for (int i= 0; i < currentItems.length; i++)
if (currentItems[i].equals(path))
selectionIndex= i;
if (selectionIndex < 0) { // not found in history
int oldLength= currentItems.length;
String[] newItems= new String[oldLength + 1];
System.arraycopy(currentItems, 0, newItems, 0, oldLength);
newItems[oldLength]= path;
fPatchFileNameField.setItems(newItems);
selectionIndex= oldLength;
}
fPatchFileNameField.select(selectionIndex);
//resetSelection();
}
}
/**
* The Finish button was pressed. Try to do the required work now and answer
* a boolean indicating success. If false is returned then the wizard will
* not close.
*
* @return boolean
*/
public boolean finish() {
// if (!ensureSourceIsValid())
// return false;
saveWidgetValues();
// Iterator resourcesEnum = getSelectedResources().iterator();
// List fileSystemObjects = new ArrayList();
// while (resourcesEnum.hasNext()) {
// fileSystemObjects.add(
// ((FileSystemElement) resourcesEnum.next()).getFileSystemObject());
// }
//
// if (fileSystemObjects.size() > 0)
// return importResources(fileSystemObjects);
//
// MessageDialog
// .openInformation(
// getContainer().getShell(),
// DataTransferMessages.getString("DataTransfer.information"), //$NON-NLS-1$
// DataTransferMessages.getString("FileImport.noneSelected")); //$NON-NLS-1$
//
// return false;
return true;
}
/**
* Use the dialog store to restore widget values to the values that they held
* last time this wizard was used to completion
*/
private void restoreWidgetValues() {
boolean useClipboard= false;
IDialogSettings settings= getDialogSettings();
if (settings != null) {
useClipboard= settings.getBoolean(STORE_USE_CLIPBOARD_ID);
// set filenames history
String[] sourceNames= settings.getArray(STORE_PATCH_FILES_ID);
if (sourceNames != null)
for (int i= 0; i < sourceNames.length; i++)
if (sourceNames[i] != null && sourceNames[i].length() > 0)
fPatchFileNameField.add(sourceNames[i]);
// set patch file path
String patchFilePath= settings.get(STORE_PATCH_FILES_ID);
if (patchFilePath != null)
setSourceName(patchFilePath);
}
// set 'Use Clipboard' radio buttons
setUseClipboard(useClipboard);
}
/**
* Since Finish was pressed, write widget values to the dialog store so that they
* will persist into the next invocation of this wizard page
*/
void saveWidgetValues() {
IDialogSettings settings= getDialogSettings();
if (settings != null) {
settings.put(STORE_USE_CLIPBOARD_ID, getUseClipboard());
settings.put(STORE_PATCH_FILES_ID, getPatchFilePath());
// update source names history
String[] sourceNames= settings.getArray(STORE_PATCH_FILES_ID);
if (sourceNames == null)
sourceNames= new String[0];
sourceNames= addToHistory(sourceNames, getPatchFilePath());
settings.put(STORE_PATCH_FILES_ID, sourceNames);
}
}
// static helpers
private void setUseClipboard(boolean useClipboard) {
if (useClipboard)
fUseClipboardButton.setSelection(true);
else
fUsePatchFileButton.setSelection(true);
setEnablePatchFile(!useClipboard);
}
private boolean getUseClipboard() {
if (fUseClipboardButton != null)
return fUseClipboardButton.getSelection();
return false;
}
private String getPatchFilePath() {
if (fPatchFileNameField != null)
return fPatchFileNameField.getText();
return ""; //$NON-NLS-1$
}
/**
* Creates a new label with a bold font.
*
* @param parent the parent control
* @param text the label text
* @return the new label control
*/
private static Label buildPlainLabel(Composite parent, String text) {
Label label= new Label(parent, SWT.NONE);
label.setText(text);
GridData data= new GridData();
data.verticalAlignment= GridData.FILL;
data.horizontalAlignment= GridData.FILL;
label.setLayoutData(data);
return label;
}
/**
* Adds an entry to a history, while taking care of duplicate history items
* and excessively long histories. The assumption is made that all histories
* should be of length <code>COMBO_HISTORY_LENGTH</code>.
*
* @param history the current history
* @param newEntry the entry to add to the history
*/
protected static String[] addToHistory(String[] history, String newEntry) {
java.util.ArrayList l= new java.util.ArrayList(java.util.Arrays.asList(history));
l.remove(newEntry);
l.add(0,newEntry);
// since only one new item was added, we can be over the limit
// by at most one item
if (l.size() > COMBO_HISTORY_LENGTH)
l.remove(COMBO_HISTORY_LENGTH);
return (String[]) l.toArray(new String[l.size()]);
}
}