diff options
author | William Chen | 2012-06-13 02:26:22 +0000 |
---|---|---|
committer | William Chen | 2012-06-13 02:26:22 +0000 |
commit | 1aa983b9ed20856a11580ed8cedb7b534b1fef18 (patch) | |
tree | 6ace2edd6297308eab5cd52d414afa43f4ff2c00 /target_explorer | |
parent | 56e2b3c549a80476f533eec717144ce3f36f5dc4 (diff) | |
download | org.eclipse.tcf-1aa983b9ed20856a11580ed8cedb7b534b1fef18.tar.gz org.eclipse.tcf-1aa983b9ed20856a11580ed8cedb7b534b1fef18.tar.xz org.eclipse.tcf-1aa983b9ed20856a11580ed8cedb7b534b1fef18.zip |
Target Explorer: An re-implementation of "Find" feature based on new
thoughts.
Diffstat (limited to 'target_explorer')
21 files changed, 659 insertions, 333 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/QueryDoneOpen.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/QueryDoneOpen.java index 54cef4b2f..be859e69e 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/QueryDoneOpen.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/QueryDoneOpen.java @@ -14,6 +14,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.tcf.protocol.IChannel;
import org.eclipse.tcf.protocol.IToken;
import org.eclipse.tcf.services.IFileSystem;
+import org.eclipse.tcf.services.IFileSystem.DoneClose;
import org.eclipse.tcf.services.IFileSystem.DoneOpen;
import org.eclipse.tcf.services.IFileSystem.FileSystemException;
import org.eclipse.tcf.services.IFileSystem.IFileHandle;
@@ -60,6 +61,13 @@ public class QueryDoneOpen extends CallbackBase implements DoneOpen { service.readdir(handle, new QueryDoneReadDir(callback, channel, service, handle, parentNode));
}
else if (callback != null) {
+ // Close the handle and channel if EOF is signaled or an error occurred.
+ if (handle != null) {
+ service.close(handle, new DoneClose() {
+ @Override
+ public void doneClose(IToken token, FileSystemException error) {}
+ });
+ }
IStatus status = new Status(IStatus.ERROR, CorePlugin.getUniqueIdentifier(), getErrorMessage(error), error);
callback.done(this, status);
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/QueryDoneReadDir.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/QueryDoneReadDir.java index 0da226302..2f23f4258 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/QueryDoneReadDir.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/QueryDoneReadDir.java @@ -83,6 +83,11 @@ public class QueryDoneReadDir extends CallbackBase implements DoneReadDir { service.readdir(handle, new QueryDoneReadDir(callback, channel, service, handle, parentNode));
}
} else if(callback != null) {
+ // Close the handle and channel if EOF is signaled or an error occurred.
+ service.close(handle, new DoneClose() {
+ @Override
+ public void doneClose(IToken token, FileSystemException error) {}
+ });
Status status = new Status(IStatus.ERROR, CorePlugin.getUniqueIdentifier(), getErrorMessage(error), error);
callback.done(this, status);
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/RefreshStateDoneOpenChannel.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/RefreshStateDoneOpenChannel.java index 03a512a7f..9b4f1623b 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/RefreshStateDoneOpenChannel.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/callbacks/RefreshStateDoneOpenChannel.java @@ -49,6 +49,9 @@ public class RefreshStateDoneOpenChannel extends CallbackBase implements IChanne public void doneOpenChannel(Throwable error, IChannel channel) {
IPeer peer = node.peerNode.getPeer();
if (error != null) {
+ if(channel != null) {
+ Tcf.getChannelManager().closeChannel(channel);
+ }
String message = getErrorMessage(error);
IStatus status = new Status(IStatus.ERROR, CorePlugin.getUniqueIdentifier(), message, error);
invokeCallback(status);
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/plugin.xml index 242a51852..287471abb 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/plugin.xml +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/plugin.xml @@ -1913,6 +1913,9 @@ <adapter type="org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel"> </adapter> + <adapter + type="org.eclipse.tcf.te.ui.interfaces.ISearchable"> + </adapter> </factory> <factory adaptableType="org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel" diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeAdapterFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeAdapterFactory.java index 686d89aee..49018aa55 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeAdapterFactory.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeAdapterFactory.java @@ -21,6 +21,7 @@ import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin; import org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.FSTreeElementLabelProvider;
import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
import org.eclipse.tcf.te.ui.interfaces.ILazyLoader;
+import org.eclipse.tcf.te.ui.interfaces.ISearchable;
import org.eclipse.ui.IActionFilter;
import org.eclipse.ui.IPersistableElement;
@@ -66,6 +67,9 @@ public class FSTreeNodeAdapterFactory implements IAdapterFactory { else if(adapterType == IPeerModel.class) {
return node.getPeerModel();
}
+ else if(adapterType == ISearchable.class) {
+ return new FSTreeNodeSearchable();
+ }
}
return null;
}
@@ -75,6 +79,6 @@ public class FSTreeNodeAdapterFactory implements IAdapterFactory { */
@Override
public Class[] getAdapterList() {
- return new Class[] { IActionFilter.class, ILabelProvider.class, IPersistableElement.class, ILazyLoader.class };
+ return new Class[] { IActionFilter.class, ILabelProvider.class, IPersistableElement.class, ILazyLoader.class, ISearchable.class };
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeSearchable.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeSearchable.java new file mode 100644 index 000000000..27118f87d --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeSearchable.java @@ -0,0 +1,231 @@ +/*******************************************************************************
+ * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.adapters;
+
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.interfaces.AbstractSearchable;
+import org.eclipse.tcf.te.ui.interfaces.ISearchMatcher;
+
+/**
+ * The ISearchable adapter for a FSTreeNode which creates a UI for the user to
+ * input the matching condition and returns a matcher to do the matching.
+ */
+public class FSTreeNodeSearchable extends AbstractSearchable implements ISearchMatcher {
+ // The case sensitive check box.
+ Button fBtnCase;
+ // The matching rule check box.
+ Button fBtnMatch;
+ // The types of target files.
+ Combo fBtnFileOnly;
+ // The input field for searching conditions.
+ Text fSearchField;
+ // Whether it is case sensitive
+ boolean fCaseSensitive;
+ // Whether it is precise matching.
+ boolean fMatchPrecise;
+ // The current selected target type index.
+ int fTargetType;
+ // The current target names.
+ String fTargetName;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#createPart(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createPart(Composite container) {
+ Composite comp = new Composite(container, SWT.NONE);
+ GridLayout glayout = new GridLayout(2, false);
+ glayout.marginHeight = 0;
+ glayout.marginWidth = 0;
+ comp.setLayout(glayout);
+ comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Searching field.
+ Label label = new Label(comp, SWT.NONE);
+ label.setText(Messages.TreeViewerSearchDialog_LblCancelText);
+ fSearchField = new Text(comp, SWT.SINGLE | SWT.BORDER);
+ fSearchField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ fSearchField.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ searchTextModified();
+ }
+ });
+
+ SelectionListener l = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ optionChecked(e);
+ }
+ };
+
+ // Search Options Group
+ Group group = new Group(container, SWT.SHADOW_ETCHED_IN);
+ group.setText(Messages.TreeViewerSearchDialog_GrpOptionsText);
+ GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
+ group.setLayoutData(data);
+ group.setLayout(new GridLayout(2, false));
+
+ label = new Label(group, SWT.NONE);
+ label.setText(Messages.FSTreeNodeSearchable_SearchingTargets);
+
+ // Search files only
+ fBtnFileOnly = new Combo(group, SWT.BORDER | SWT.READ_ONLY);
+ fBtnFileOnly.setItems(new String[]{Messages.FSTreeNodeSearchable_FilesAndFolders, Messages.FSTreeNodeSearchable_FilesOnly, Messages.FSTreeNodeSearchable_FoldersOnly});
+ fBtnFileOnly.setLayoutData(new GridData());
+ fBtnFileOnly.select(0);
+ fBtnFileOnly.addSelectionListener(l);
+
+ // Case sensitive
+ fBtnCase = new Button(group, SWT.CHECK);
+ fBtnCase.setText(Messages.TreeViewerSearchDialog_BtnCaseText);
+ fBtnCase.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ fBtnCase.addSelectionListener(l);
+
+ // Matching precisely
+ fBtnMatch = new Button(group, SWT.CHECK);
+ fBtnMatch.setText(Messages.TreeViewerSearchDialog_BtnPreciseText);
+ fBtnMatch.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ fBtnMatch.addSelectionListener(l);
+ }
+
+ /**
+ * The text for searching is modified.
+ */
+ protected void searchTextModified() {
+ fireOptionChanged();
+ fTargetName = fSearchField.getText().trim();
+ }
+
+ /**
+ * An option has been selected.
+ *
+ * @param e The selection event.
+ */
+ protected void optionChecked(SelectionEvent e) {
+ Object src = e.getSource();
+ if (src == fBtnCase) {
+ fCaseSensitive = fBtnCase.getSelection();
+ }
+ else if (src == fBtnMatch) {
+ fMatchPrecise = fBtnMatch.getSelection();
+ }
+ else if (src == fBtnFileOnly) {
+ fTargetType = fBtnFileOnly.getSelectionIndex();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#getMatcher()
+ */
+ @Override
+ public ISearchMatcher getMatcher() {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#isInputValid()
+ */
+ @Override
+ public boolean isInputValid() {
+ String txt = fSearchField.getText();
+ boolean valid = txt != null && txt.trim().length() > 0;
+ return valid;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchMatcher#match(java.lang.Object)
+ */
+ @Override
+ public boolean match(Object context) {
+ if (context == null) return false;
+ if (context instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) context;
+ if(fTargetType == 1 && !node.isFile() || fTargetType == 2 && !node.isDirectory()) return false;
+ String text = node.name;
+ if (text == null) return false;
+ String target = fTargetName;
+ if (!fCaseSensitive) {
+ text = text.toLowerCase();
+ target = target != null ? target.toLowerCase() : null;
+ }
+ if (fMatchPrecise) return text.equals(target);
+ return text.indexOf(target) != -1;
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#getSearchTitle()
+ */
+ @Override
+ public String getSearchTitle() {
+ return Messages.FSTreeNodeSearchable_FindFilesAndFolders;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#getSearchMessage(java.lang.Object)
+ */
+ @Override
+ public String getSearchMessage(Object rootElement) {
+ String message = Messages.FSTreeNodeSearchable_FindMessage;
+ String rootName = getElementName(rootElement);
+ message = NLS.bind(message, rootName);
+ return message;
+ }
+
+ /**
+ * Get a name representation for each file node.
+ *
+ * @param rootElement The root element whose name is being retrieved.
+ * @return The node's name or an expression for the file system.
+ */
+ private String getElementName(Object rootElement) {
+ if(rootElement == null) {
+ return Messages.FSTreeNodeSearchable_SelectedFileSystem;
+ }
+ FSTreeNode rootNode = (FSTreeNode) rootElement;
+ if(rootNode.isSystemRoot()) {
+ return Messages.FSTreeNodeSearchable_SelectedFileSystem;
+ }
+ return rootNode.name;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#getElementText(java.lang.Object)
+ */
+ @Override
+ public String getElementText(Object element) {
+ return getElementName(element);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java index 860f620e3..1d253d716 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java @@ -117,6 +117,13 @@ public class Messages extends NLS { public static String OpenWithMenu_NoEditorFound; public static String OpenWithMenu_OpenWith; public static String FSRename_RenameFileFolderTitle; + public static String FSTreeNodeSearchable_FilesAndFolders; + public static String FSTreeNodeSearchable_FilesOnly; + public static String FSTreeNodeSearchable_FindFilesAndFolders; + public static String FSTreeNodeSearchable_FindMessage; + public static String FSTreeNodeSearchable_FoldersOnly; + public static String FSTreeNodeSearchable_SearchingTargets; + public static String FSTreeNodeSearchable_SelectedFileSystem; public static String RenameFilesHandler_TitleRename; public static String RenameFilesHandler_TitleRenameFile; public static String RenameFilesHandler_TitleRenameFolder; @@ -176,4 +183,8 @@ public class Messages extends NLS { public static String TargetSelectionPage_Description; public static String TargetSelectionPage_Targets; public static String TargetSelectionPage_Title; + public static String TreeViewerSearchDialog_LblCancelText; + public static String TreeViewerSearchDialog_GrpOptionsText; + public static String TreeViewerSearchDialog_BtnCaseText; + public static String TreeViewerSearchDialog_BtnPreciseText; } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties index 49b97550a..1ef54ccbe 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties @@ -57,6 +57,13 @@ OpenWithMenu_DefaultEditor=&Default Editor OpenWithMenu_NoEditorFound=No editor found to edit the file resource.
OpenWithMenu_OpenWith=Open With
FSRename_RenameFileFolderTitle=Error Renaming File or Folder
+FSTreeNodeSearchable_FilesAndFolders=Files/Folders
+FSTreeNodeSearchable_FilesOnly=Files Only
+FSTreeNodeSearchable_FindFilesAndFolders=Find Files/Folders
+FSTreeNodeSearchable_FindMessage=Find files/folders under {0}\nNote that the subsidary nodes will be loaded and searched too.
+FSTreeNodeSearchable_FoldersOnly=Folders Only
+FSTreeNodeSearchable_SearchingTargets=Search targets:
+FSTreeNodeSearchable_SelectedFileSystem=selected File System
RenameFilesHandler_TitleRename=Rename
RenameFilesHandler_TitleRenameFile=Rename File
RenameFilesHandler_TitleRenameFolder=Rename Folder
@@ -116,3 +123,7 @@ NewNodeWizardPage_PromptFolderLabel=Enter or select the parent folder: TargetSelectionPage_Description=Please select the target where the new file/folder is created.
TargetSelectionPage_Targets=Targets:
TargetSelectionPage_Title=Select the target.
+TreeViewerSearchDialog_LblCancelText=Find:
+TreeViewerSearchDialog_GrpOptionsText=Options
+TreeViewerSearchDialog_BtnCaseText=Case sensitive
+TreeViewerSearchDialog_BtnPreciseText=Precise matching
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml index e61a851c1..c106e2ee8 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml @@ -545,6 +545,24 @@ </equals>
</with>
</activeWhen>
+ <enabledWhen>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <or>
+ <instanceof
+ value="org.eclipse.tcf.te.ui.interfaces.ISearchable">
+ </instanceof>
+ <adapt
+ type="org.eclipse.tcf.te.ui.interfaces.ISearchable">
+ </adapt>
+ </or>
+ </iterate>
+ </with>
+ </enabledWhen>
</handler>
<handler
class="org.eclipse.tcf.te.ui.views.handler.EditorSearchHandler"
@@ -557,6 +575,24 @@ </equals>
</with>
</activeWhen>
+ <enabledWhen>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <or>
+ <instanceof
+ value="org.eclipse.tcf.te.ui.interfaces.ISearchable">
+ </instanceof>
+ <adapt
+ type="org.eclipse.tcf.te.ui.interfaces.ISearchable">
+ </adapt>
+ </or>
+ </iterate>
+ </with>
+ </enabledWhen>
</handler>
</extension>
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/AbstractSearchable.java b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/AbstractSearchable.java new file mode 100644 index 000000000..a8baba6fb --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/AbstractSearchable.java @@ -0,0 +1,48 @@ +/*******************************************************************************
+ * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.interfaces;
+
+import org.eclipse.core.commands.common.EventManager;
+
+/**
+ * The base class that implements ISearchable and provide basic implementation method
+ * for adding and removing listeners.
+ */
+public abstract class AbstractSearchable extends EventManager implements ISearchable {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#addOptionListener(org.eclipse.tcf.te.ui.interfaces.IOptionListener)
+ */
+ @Override
+ public void addOptionListener(IOptionListener listener) {
+ super.addListenerObject(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#removeOptionListener(org.eclipse.tcf.te.ui.interfaces.IOptionListener)
+ */
+ @Override
+ public void removeOptionListener(IOptionListener listener) {
+ super.removeListenerObject(listener);
+ }
+
+ /**
+ * Fire an option changed event to the listeners to notify
+ * the current option input has changed.
+ */
+ protected void fireOptionChanged() {
+ Object[] listeners = super.getListeners();
+ for(Object listener : listeners) {
+ ((IOptionListener)listener).optionChanged(null);
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/IOptionListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/IOptionListener.java new file mode 100644 index 000000000..6f7ae57fb --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/IOptionListener.java @@ -0,0 +1,26 @@ +/*******************************************************************************
+ * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.interfaces;
+
+import java.util.EventListener;
+import java.util.EventObject;
+
+/**
+ * The interface that listens and processes the event that
+ * the searching options have been changed.
+ */
+public interface IOptionListener extends EventListener {
+ /**
+ * Invoked when one of the searching options has changed.
+ *
+ * @param event An option changed event.
+ */
+ public void optionChanged(EventObject event);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/ISearchCallback.java b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/ISearchCallback.java index 66a6868fd..e6029bbac 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/ISearchCallback.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/ISearchCallback.java @@ -12,6 +12,10 @@ package org.eclipse.tcf.te.ui.interfaces; import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.viewers.TreePath;
+/**
+ * This callback is invoked when a searching target is hit to report
+ * the result.
+ */
public interface ISearchCallback {
/**
* The callback invoked when the searching job is done, to process
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/ISearchable.java b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/ISearchable.java new file mode 100644 index 000000000..13f8ca90b --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/interfaces/ISearchable.java @@ -0,0 +1,84 @@ +/*******************************************************************************
+ * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.interfaces;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This interface should be implemented or adapted by the tree nodes which
+ * should provide find function. Subclass is encouraged to inherit AbstractSearchable
+ * which provides basic implementation methods.
+ *
+ * @see AbstractSearchable
+ */
+public interface ISearchable {
+ /**
+ * Get the title text of the searching dialog for
+ * this element.
+ *
+ * @return A title of the search dialog
+ */
+ public String getSearchTitle();
+
+ /**
+ * Get the description message that will be displayed
+ * in the title area of the searching dialog with
+ * the given root element.
+ *
+ * @param rootElement The root element where the search is started.
+ * @return The message to describe the searching.
+ */
+ public String getSearchMessage(Object rootElement);
+
+ /**
+ * Get a text to be used during searching process.
+ *
+ * @param element The element to searched.
+ * @return A description text used in searching.
+ */
+ public String getElementText(Object element);
+
+ /**
+ * Create the option part in the searching dialog where the user
+ * enters the matching rule used in searching.
+ *
+ * @param parent The parent composite of this option part.
+ */
+ public void createPart(Composite parent);
+
+ /**
+ * Get a searching matcher object to test if a tree node matches
+ * the current conditions entered by the user.
+ *
+ * @return The matcher object which implements ISearchMatcher for matching.
+ */
+ public ISearchMatcher getMatcher();
+
+ /**
+ * If the current input from the user is valid for a searching process.
+ *
+ * @return true if the input is valid or else false.
+ */
+ public boolean isInputValid();
+
+ /**
+ * Add an option listener that handles the option changed event.
+ *
+ * @param listener The listener to be added.
+ */
+ public void addOptionListener(IOptionListener listener);
+
+ /**
+ * Remove an option listener
+ *
+ * @param listener The listener to be removed.
+ */
+ public void removeOptionListener(IOptionListener listener);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/AbstractSearcher.java b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/AbstractSearcher.java index 78f4cb3b1..ef00c6456 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/AbstractSearcher.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/AbstractSearcher.java @@ -14,9 +14,9 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.swt.widgets.Display;
import org.eclipse.tcf.te.ui.interfaces.ILazyLoader;
import org.eclipse.tcf.te.ui.interfaces.ISearchMatcher;
+import org.eclipse.tcf.te.ui.interfaces.ISearchable;
import org.eclipse.tcf.te.ui.interfaces.ITreeSearcher;
import org.eclipse.tcf.te.ui.trees.Pending;
import org.eclipse.tcf.te.ui.utils.TreeViewerUtil;
@@ -30,45 +30,22 @@ public abstract class AbstractSearcher implements ITreeSearcher { protected TreeViewer fViewer;
// The label provider of the tree viewer.
protected ILabelProvider fLabelProvider;
- // The matcher used to match echo tree nodes.
+
+ protected ISearchable fSearchable;
+
protected ISearchMatcher fMatcher;
/**
* Create a searcher with the specified viewer and matcher.
*
* @param viewer The tree viewer to be searched.
- * @param matcher The matcher used to match tree nodes.
+ * @param searchable The matcher used to match tree nodes.
*/
- protected AbstractSearcher(TreeViewer viewer, ISearchMatcher matcher) {
+ protected AbstractSearcher(TreeViewer viewer, ISearchable searchable) {
fViewer = viewer;
fLabelProvider = (ILabelProvider) fViewer.getLabelProvider();
- fMatcher = matcher;
- }
-
- /**
- * Get the text representation of a element using the label provider
- * of the tree viewer.
- * Note: this method could be called at any thread.
- *
- * @param element The element.
- * @return The text representation.
- */
- protected String getElementText(final Object element) {
- if (Display.getCurrent() != null) {
- if(element == fViewer.getInput()) return "the root"; //$NON-NLS-1$
- if (fLabelProvider != null) {
- return fLabelProvider.getText(element);
- }
- return element == null ? "" : element.toString(); //$NON-NLS-1$
- }
- final String[] result = new String[1];
- fViewer.getTree().getDisplay().syncExec(new Runnable() {
- @Override
- public void run() {
- result[0] = getElementText(element);
- }
- });
- return result[0];
+ this.fSearchable = searchable;
+ this.fMatcher = searchable.getMatcher();
}
/**
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/BreadthFirstSearcher.java b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/BreadthFirstSearcher.java index c540ec99c..4e8009e6e 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/BreadthFirstSearcher.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/BreadthFirstSearcher.java @@ -17,7 +17,7 @@ import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.tcf.te.ui.interfaces.ISearchMatcher; +import org.eclipse.tcf.te.ui.interfaces.ISearchable; /** * The search engine which uses BFS(breadth-first search) algorithm @@ -34,8 +34,8 @@ public class BreadthFirstSearcher extends AbstractSearcher{ * @param viewer The tree viewer. * @param matcher The search matcher used match a single tree node. */ - public BreadthFirstSearcher(TreeViewer viewer, ISearchMatcher matcher){ - super(viewer, matcher); + public BreadthFirstSearcher(TreeViewer viewer, ISearchable searchable){ + super(viewer, searchable); } /* @@ -67,7 +67,7 @@ public class BreadthFirstSearcher extends AbstractSearcher{ Assert.isTrue(queue.offer(childPath)); } } - String elementText = getElementText(element); + String elementText = fSearchable.getElementText(element); monitor.subTask(elementText); if(fMatcher.match(element)) { result = path; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/DepthFirstSearcher.java b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/DepthFirstSearcher.java index 6594adda1..6e35813ac 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/DepthFirstSearcher.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/DepthFirstSearcher.java @@ -16,7 +16,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.tcf.te.ui.interfaces.ISearchMatcher; +import org.eclipse.tcf.te.ui.interfaces.ISearchable; /** * The search engine which uses DFS(depth-first search) algorithm @@ -48,8 +48,8 @@ public class DepthFirstSearcher extends AbstractSearcher { * @param viewer The tree viewer. * @param matcher The search matcher used match a single tree node. */ - public DepthFirstSearcher(TreeViewer viewer, ISearchMatcher matcher) { - super(viewer, matcher); + public DepthFirstSearcher(TreeViewer viewer, ISearchable searchable) { + super(viewer, searchable); } /* @@ -114,7 +114,7 @@ public class DepthFirstSearcher extends AbstractSearcher { while (!fSearchStack.isEmpty() && result == null && !monitor.isCanceled()) { //Search util the stack is empty or the result is found. StackElement top = fSearchStack.getLast(); //Get the top stack element. if(!fForeward && top.index == END_INDEX || fForeward && top.index == START_INDEX){ - String elementText = getElementText(top.node); + String elementText = fSearchable.getElementText(top.node); monitor.subTask(elementText); result = fMatcher.match(top.node) ? this.createContextPath() : null; } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/SearchEngine.java b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/SearchEngine.java index 40e06111c..9a5fc9125 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/SearchEngine.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/SearchEngine.java @@ -23,6 +23,7 @@ import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.tcf.te.ui.activator.UIPlugin;
import org.eclipse.tcf.te.ui.interfaces.ISearchCallback;
+import org.eclipse.tcf.te.ui.interfaces.ISearchable;
import org.eclipse.tcf.te.ui.nls.Messages;
/**
@@ -38,7 +39,7 @@ public class SearchEngine { // If the search algorithm is depth preferable
boolean fDepthFirst;
// The search matcher used to match tree nodes during traversing.
- SearchMatcher fMatcher;
+ ISearchable fSearchable;
// The current starting path of the searcher engine.
TreePath fStartPath;
// Whether it is wrap search.
@@ -50,11 +51,16 @@ public class SearchEngine { * Create an instance for the tree viewer.
*
* @param viewer The tree viewer.
+ * @param depthFirst
*/
- public SearchEngine(TreeViewer viewer) {
+ public SearchEngine(TreeViewer viewer, boolean depthFirst) {
fViewer = viewer;
- fMatcher = new SearchMatcher(viewer);
- fSearcher = new BreadthFirstSearcher(fViewer, fMatcher);
+ fDepthFirst = depthFirst;
+ }
+
+ public void setSearchable(ISearchable matcher) {
+ fSearchable = matcher;
+ fSearcher = fDepthFirst ? new DepthFirstSearcher(fViewer, fSearchable) : new BreadthFirstSearcher(fViewer, fSearchable);
}
/**
@@ -74,20 +80,11 @@ public class SearchEngine { public void setDepthFirst(boolean depthFirst) {
if (fDepthFirst != depthFirst) {
fDepthFirst = depthFirst;
- fSearcher = fDepthFirst ? new DepthFirstSearcher(fViewer, fMatcher) : new BreadthFirstSearcher(fViewer, fMatcher);
+ fSearcher = fDepthFirst ? new DepthFirstSearcher(fViewer, fSearchable) : new BreadthFirstSearcher(fViewer, fSearchable);
}
}
/**
- * Get the current matcher used.
- *
- * @return the current matcher
- */
- public SearchMatcher getMatcher() {
- return fMatcher;
- }
-
- /**
* Set the initial searching path.
*
* @param path The initial searching path.
@@ -99,6 +96,10 @@ public class SearchEngine { }
}
+ public TreePath getStartPath() {
+ return fStartPath;
+ }
+
/**
* If the current searching scope is all.
*/
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/TreeViewerSearchDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/TreeViewerSearchDialog.java index fd53f8f86..5efde2f01 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/TreeViewerSearchDialog.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/internal/utils/TreeViewerSearchDialog.java @@ -9,59 +9,55 @@ *******************************************************************************/ package org.eclipse.tcf.te.ui.internal.utils; +import java.util.EventObject; + +import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TreePath; -import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.wizard.ProgressMonitorPart; -import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; +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.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; +import org.eclipse.tcf.te.ui.forms.FormLayoutFactory; +import org.eclipse.tcf.te.ui.interfaces.IOptionListener; import org.eclipse.tcf.te.ui.interfaces.ISearchCallback; +import org.eclipse.tcf.te.ui.interfaces.ISearchable; import org.eclipse.tcf.te.ui.jface.dialogs.CustomTitleAreaDialog; import org.eclipse.tcf.te.ui.nls.Messages; -import org.eclipse.tcf.te.ui.utils.TreeViewerUtil; +import org.eclipse.ui.forms.events.ExpansionEvent; +import org.eclipse.ui.forms.events.IExpansionListener; +import org.eclipse.ui.forms.widgets.ExpandableComposite; +import org.eclipse.ui.forms.widgets.Section; /** * The searching dialog used to get the searching input. */ -public class TreeViewerSearchDialog extends CustomTitleAreaDialog implements SelectionListener, ISearchCallback { +public class TreeViewerSearchDialog extends CustomTitleAreaDialog implements ISearchCallback, IOptionListener { // The context help id for this dialog. private static final String SEARCH_HELP_ID = "org.eclipse.tcf.te.ui.utils.TreeViewerSearchDialog.help"; //$NON-NLS-1$ // A new search button's ID. private static final int SEARCH_ID = 31; - // The input field for searching conditions. - private Text fSearchField; - // The radio button of depth-first algorithm. - private Button fBtnDepth; - // The radio button of breadth-first algorithm. - private Button fBtnBreadth; - // The case sensitive check box. - private Button fBtnCase; - // The wrap search check box. - private Button fBtnWrap; - // The matching rule check box. - private Button fBtnMatch; + private Combo fCmbAlg; // The searching orientation check box. private Button fBtnBackward; + // The wrap search check box. + private Button fBtnWrap; + // The progress monitor part that controls the searching job. private ProgressMonitorPart fPmPart; @@ -69,11 +65,8 @@ public class TreeViewerSearchDialog extends CustomTitleAreaDialog implements Sel SearchEngine fSearcher; // The tree viewer to be searched. TreeViewer fViewer; - - // The scope all button - private Button fBtnScpAll; - // The scope selected button - private Button fBtnScpSel; + + ISearchable fSearchable; /** * Create a searching dialog using the default algorithm and @@ -99,21 +92,23 @@ public class TreeViewerSearchDialog extends CustomTitleAreaDialog implements Sel setHelpAvailable(true); setContextHelpId(SEARCH_HELP_ID); fViewer = viewer; - fSearcher = TreeViewerUtil.getSearchEngine(fViewer); - fSearcher.setDepthFirst(depthFirst); - fViewer.getTree().addSelectionListener(this); - setTitle(Messages.TreeViewerSearchDialog_DialogTitleMessage); + fSearcher = getSearchEngine(fViewer, depthFirst); } - - /* - * (non-Javadoc) - * @see org.eclipse.tcf.te.ui.jface.dialogs.CustomTitleAreaDialog#close() + /** + * Get a singleton search engine for a tree viewer. If + * it does not exist then create one and store it. + * + * @param viewer The tree viewer. + * @return A search engine. */ - @Override - public boolean close() { - fViewer.getTree().removeSelectionListener(this); - return super.close(); + private SearchEngine getSearchEngine(TreeViewer viewer, boolean depthFirst) { + SearchEngine searcher = (SearchEngine) viewer.getData("search.engine"); //$NON-NLS-1$ + if (searcher == null) { + searcher = new SearchEngine(viewer, depthFirst); + viewer.setData("search.engine", searcher); //$NON-NLS-1$ + } + return searcher; } /* @@ -138,6 +133,9 @@ public class TreeViewerSearchDialog extends CustomTitleAreaDialog implements Sel * Invoked when button "Close" is pressed. */ protected void closePressed() { + if(fSearchable != null) { + fSearchable.removeOptionListener(this); + } fSearcher.endSearch(); setReturnCode(OK); close(); @@ -147,22 +145,10 @@ public class TreeViewerSearchDialog extends CustomTitleAreaDialog implements Sel * Called when search button is pressed to start a new search. */ private void searchButtonPressed() { - fSearcher.getMatcher().setMatchTarget(fSearchField.getText().trim()); getButton(SEARCH_ID).setEnabled(false); fSearcher.startSearch(this, fPmPart); } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) - */ - @Override - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - newShell.setText(Messages.TreeViewerSearchDialog_DialogTitle); - } - /* * (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite) @@ -209,7 +195,7 @@ public class TreeViewerSearchDialog extends CustomTitleAreaDialog implements Sel * (non-Javadoc) * @see org.eclipse.tcf.te.ui.jface.dialogs.CustomTitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite) */ - @Override + @Override protected Control createDialogArea(Composite parent) { // Create the main container Composite composite = (Composite) super.createDialogArea(parent); @@ -222,105 +208,72 @@ public class TreeViewerSearchDialog extends CustomTitleAreaDialog implements Sel container.setLayout(glayout); container.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - Composite comp = new Composite(container, SWT.NONE); - glayout = new GridLayout(2, false); - glayout.marginHeight = 0; - glayout.marginWidth = 0; - comp.setLayout(glayout); - comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - // Searching field. - Label label = new Label(comp, SWT.NONE); - label.setText(Messages.TreeViewerSearchDialog_LblCancelText); - fSearchField = new Text(comp, SWT.SINGLE | SWT.BORDER); - fSearchField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - fSearchField.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - updateSearchButton(); - fSearcher.resetPath(); - } - }); + if(fSearchable != null) { + fSearchable.createPart(container); + } SelectionListener l = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - optionChecked(e); + selectionChanged(e); } }; - // Search Algoritm Selection Group. - Group group = new Group(container, SWT.SHADOW_ETCHED_IN); - group.setText(Messages.TreeViewerSearchDialog_Scope); - GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false); - group.setLayoutData(data); - group.setLayout(new GridLayout(2, true)); - - fBtnScpAll = new Button(group, SWT.RADIO); - fBtnScpAll.setText(Messages.TreeViewerSearchDialog_All); - fBtnScpAll.setSelection(fSearcher.isScopeAll()); - fBtnScpAll.addSelectionListener(l); - fBtnScpAll.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - fBtnScpSel = new Button(group, SWT.RADIO); - fBtnScpSel.setText(Messages.TreeViewerSearchDialog_Selected); - fBtnScpSel.setSelection(!fSearcher.isScopeAll()); - fBtnScpSel.addSelectionListener(l); - fBtnScpSel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - // Search Algoritm Selection Group. - group = new Group(container, SWT.SHADOW_ETCHED_IN); - group.setText(Messages.TreeViewerSearchDialog_SearchAlgorithm); - data = new GridData(SWT.FILL, SWT.CENTER, true, false); - group.setLayoutData(data); - group.setLayout(new GridLayout(2, true)); + Section section = new Section(container, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT); + section.setText(Messages.TreeViewerSearchDialog_AdvancedOptions); + section.setLayout(FormLayoutFactory.createSectionClientGridLayout(false, 2)); + GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); + section.setLayoutData(layoutData); + + final Composite client = new Composite(section, SWT.NONE); + client.setLayout(new GridLayout(3, false)); + client.setBackground(section.getBackground()); + section.setClient(client); - // Breadth-first search - fBtnBreadth = new Button(group, SWT.RADIO); - fBtnBreadth.setText(Messages.TreeViewerSearchDialog_BreadthFirst); - fBtnBreadth.setSelection(!fSearcher.isDepthFirst()); - fBtnBreadth.addSelectionListener(l); - fBtnBreadth.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + section.addExpansionListener(new IExpansionListener(){ + @Override + public void expansionStateChanging(ExpansionEvent e) { + } + + @Override + public void expansionStateChanged(ExpansionEvent e) { + expansionChanged(e.getState(), client.getSize().y); + }}); - // Depth-first search - fBtnDepth = new Button(group, SWT.RADIO); - fBtnDepth.setText(Messages.TreeViewerSearchDialog_DepthFirst); - fBtnDepth.setSelection(fSearcher.isDepthFirst()); - fBtnDepth.addSelectionListener(l); - fBtnDepth.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + Label label = new Label(client, SWT.NONE); + label.setLayoutData(new GridData()); + label.setText(Messages.TreeViewerSearchDialog_SearchNodesUsing); - // Search Options Group - group = new Group(container, SWT.SHADOW_ETCHED_IN); - group.setText(Messages.TreeViewerSearchDialog_GrpOptionsText); - data = new GridData(SWT.FILL, SWT.CENTER, true, false); - group.setLayoutData(data); - group.setLayout(new GridLayout(2, true)); - - // Case sensitive - fBtnCase = new Button(group, SWT.CHECK); - fBtnCase.setText(Messages.TreeViewerSearchDialog_BtnCaseText); - fBtnCase.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - fBtnCase.addSelectionListener(l); + fCmbAlg = new Combo(client, SWT.BORDER | SWT.READ_ONLY); + fCmbAlg.setLayoutData(new GridData()); + fCmbAlg.setItems(new String[]{Messages.TreeViewerSearchDialog_BFS, Messages.TreeViewerSearchDialog_DFS}); + fCmbAlg.select(0); + fCmbAlg.addSelectionListener(l); - // Matching precisely - fBtnMatch = new Button(group, SWT.CHECK); - fBtnMatch.setText(Messages.TreeViewerSearchDialog_BtnPreciseText); - fBtnMatch.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - fBtnMatch.addSelectionListener(l); + label = new Label(client, SWT.NONE); + GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false); + label.setLayoutData(data); + label.setText(Messages.TreeViewerSearchDialog_UseOptions); // Wrap search - fBtnWrap = new Button(group, SWT.CHECK); + fBtnWrap = new Button(client, SWT.CHECK); fBtnWrap.setText(Messages.TreeViewerSearchDialog_BtnWrapText); - fBtnWrap.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + data = new GridData(SWT.FILL, SWT.CENTER, true, false); + data.horizontalSpan = 3; + data.horizontalIndent = 10; + fBtnWrap.setLayoutData(data); fBtnWrap.addSelectionListener(l); // Search backward. - fBtnBackward = new Button(group, SWT.CHECK); + fBtnBackward = new Button(client, SWT.CHECK); fBtnBackward.setText(Messages.TreeViewerSearchDialog_BtnBackText); - fBtnBackward.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + data = new GridData(SWT.FILL, SWT.CENTER, true, false); + data.horizontalSpan = 3; + data.horizontalIndent = 10; + fBtnBackward.setLayoutData(data); fBtnBackward.addSelectionListener(l); // Hidden if it is breadth-first search - fBtnBackward.setVisible(fSearcher.isDepthFirst()); + fBtnBackward.setEnabled(fSearcher.isDepthFirst()); // Progress monitor part to display or cancel searching process. fPmPart = new ProgressMonitorPart(container, null, true); @@ -328,73 +281,70 @@ public class TreeViewerSearchDialog extends CustomTitleAreaDialog implements Sel fPmPart.setLayoutData(data); fPmPart.setVisible(false); + if(fSearchable != null) { + String title = fSearchable.getSearchTitle(); + getShell().setText(title); + this.setTitle(title); + } + return composite; } + protected void expansionChanged(boolean state, int client_height) { + Point p = getShell().getSize(); + p.y = state ? p.y + client_height : p.y - client_height; + getShell().setSize(p.x, p.y); + } + + private ISearchable getSearchable() { + TreePath path = fSearcher.getStartPath(); + if(path != null) { + Object element = path.getLastSegment(); + if(element != null) { + if(element instanceof ISearchable) { + return (ISearchable) element; + } + ISearchable searchable = null; + if(element instanceof IAdaptable) { + searchable = (ISearchable)((IAdaptable)element).getAdapter(ISearchable.class); + } + if(searchable == null) { + searchable = (ISearchable)Platform.getAdapterManager().getAdapter(element, ISearchable.class); + } + if(searchable != null) { + searchable.addOptionListener(this); + fSearcher.setSearchable(searchable); + } + return searchable; + } + } + return null; + } + /** * Event handler to process a button selection event. * * @param e The selection event. */ - void optionChecked(SelectionEvent e) { + void selectionChanged(SelectionEvent e) { Object src = e.getSource(); - if (src == fBtnCase) { - fSearcher.getMatcher().setCaseSensitive(fBtnCase.getSelection()); - } - else if (src == fBtnWrap) { - fSearcher.setWrap(fBtnWrap.getSelection()); - } - else if (src == fBtnMatch) { - fSearcher.getMatcher().setMatchPrecise(fBtnMatch.getSelection()); - } - else if (src == fBtnBackward) { + if (src == fBtnBackward) { fSearcher.endSearch(); fSearcher.setStartPath(fSearcher.getLastResult()); fSearcher.setForeward(!fBtnBackward.getSelection()); } - else if (src == fBtnDepth || src == fBtnBreadth) { - if (src == fBtnDepth) { - fBtnDepth.setSelection(true); - fBtnBreadth.setSelection(false); - } - else if (src == fBtnBreadth) { - fBtnBreadth.setSelection(true); - fBtnDepth.setSelection(false); - } + else if (src == fBtnWrap) { + fSearcher.setWrap(fBtnWrap.getSelection()); + } + else if (src == fCmbAlg) { + int index = fCmbAlg.getSelectionIndex(); fSearcher.endSearch(); - boolean selection = fBtnDepth.getSelection(); + boolean selection = index == 1; fSearcher.setDepthFirst(selection); - fBtnBackward.setVisible(selection); + fBtnBackward.setEnabled(selection); fSearcher.resetPath(); fSearcher.setForeward(!fBtnBackward.getSelection()); } - else if (src == fBtnScpAll || src == fBtnScpSel) { - if(src == fBtnScpAll) { - fBtnScpAll.setSelection(true); - fBtnScpSel.setSelection(false); - } - else { - fBtnScpAll.setSelection(false); - fBtnScpSel.setSelection(true); - } - fSearcher.endSearch(); - boolean scpAll = fBtnScpAll.getSelection(); - if(scpAll) { - setStartPath(new TreePath(new Object[]{fViewer.getInput()})); - } - else { - treeSelected(); - } - } - } - - /** - * Update the enablement of search button. - */ - void updateSearchButton() { - String txt = fSearchField.getText(); - boolean valid = txt != null && txt.trim().length() > 0; - getButton(SEARCH_ID).setEnabled(valid); } /** @@ -404,64 +354,19 @@ public class TreeViewerSearchDialog extends CustomTitleAreaDialog implements Sel */ public void setStartPath(TreePath rootPath) { fSearcher.setStartPath(rootPath); - String text = fSearcher.getMatcher().getElementText(rootPath.getLastSegment()); - if(text != null) { - this.setDefaultMessage(NLS.bind(Messages.TreeViewerSearchDialog_DialogPromptMessage, text), NONE); - } - else { - this.setDefaultMessage(Messages.TreeViewerSearchDialog_RootMsg, NONE); - } - updateScope(); - } - - /** - * Update the state of the scope buttons - */ - private void updateScope() { - if (fBtnScpAll != null && fBtnScpSel != null && fSearcher != null) { - fBtnScpAll.setSelection(fSearcher.isScopeAll()); - fBtnScpSel.setSelection(!fSearcher.isScopeAll()); - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) - */ - @Override - public void widgetSelected(SelectionEvent e) { - treeSelected(); - } - - /** - * Invoked while a tree node is selected. - */ - private void treeSelected() { - fSearcher.endSearch(); - ISelection sel = fViewer.getSelection(); - if (sel == null || sel.isEmpty()) { - fSearcher.resetPath(); - updateScope(); - } - else { - TreeSelection iss = (TreeSelection) sel; - TreePath[] paths = iss.getPaths(); - if (paths == null || paths.length == 0) { - fSearcher.resetPath(); - updateScope(); - } - else { - setStartPath(paths[0]); + fSearchable = getSearchable(); + if (fSearchable != null) { + Object element = rootPath.getLastSegment(); + String text = fSearchable.getSearchMessage(element); + if (text != null) { + setDefaultMessage(text, NONE); } } - fSearcher.setLastResult(null); - } - - /* - * (non-Javadoc) - * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) - */ + } + @Override - public void widgetDefaultSelected(SelectionEvent e) { + public void optionChanged(EventObject event) { + getButton(SEARCH_ID).setEnabled(fSearchable != null && fSearchable.isInputValid()); + fSearcher.resetPath(); } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/nls/Messages.java index 2a6ee09cc..2d1fa24b7 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/nls/Messages.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/nls/Messages.java @@ -69,27 +69,24 @@ public class Messages extends NLS { public static String PreferencePage_label; public static String QuickFilterPopup_PromptMessage; + public static String TreeViewerSearchDialog_AdvancedOptions; public static String TreeViewerSearchDialog_All; + public static String TreeViewerSearchDialog_BFS; public static String TreeViewerSearchDialog_BtnBackText; public static String TreeViewerSearchDialog_BtnCloseText; - public static String TreeViewerSearchDialog_BtnCaseText; - public static String TreeViewerSearchDialog_BtnPreciseText; public static String TreeViewerSearchDialog_BtnSearchText; - public static String TreeViewerSearchDialog_BtnWrapText; public static String TreeViewerSearchDialog_DepthFirst; - public static String TreeViewerSearchDialog_DialogPromptMessage; - public static String TreeViewerSearchDialog_DialogTitle; - public static String TreeViewerSearchDialog_DialogTitleMessage; - public static String TreeViewerSearchDialog_GrpOptionsText; + public static String TreeViewerSearchDialog_DFS; public static String TreeViewerSearchDialog_JobName; - public static String TreeViewerSearchDialog_LblCancelText; public static String TreeViewerSearchDialog_MainTaskName; public static String TreeViewerSearchDialog_NoMoreNodeFound; public static String TreeViewerSearchDialog_NoSuchNode; public static String TreeViewerSearchDialog_Scope; public static String TreeViewerSearchDialog_SearchAlgorithm; + public static String TreeViewerSearchDialog_SearchNodesUsing; public static String TreeViewerSearchDialog_Selected; public static String TreeViewerSearchDialog_BreadthFirst; - public static String TreeViewerSearchDialog_RootMsg; public static String ViewerStateManager_MkdirFailed; + public static String TreeViewerSearchDialog_BtnWrapText; + public static String TreeViewerSearchDialog_UseOptions; } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/nls/Messages.properties index 8f73f3dce..0d96398db 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/nls/Messages.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/nls/Messages.properties @@ -56,26 +56,23 @@ NameValuePairDialog_usedOrIllegalName_error=The name ''{0}'' is reserved or alre PreferencePage_label=General settings for Target Explorer: QuickFilterPopup_PromptMessage=<ENTER> to confirm, <ESC> to reset +TreeViewerSearchDialog_AdvancedOptions=Advanced Options TreeViewerSearchDialog_All=All +TreeViewerSearchDialog_BFS=Breadth-first search TreeViewerSearchDialog_BtnBackText=Find backward TreeViewerSearchDialog_BtnCloseText=Close -TreeViewerSearchDialog_BtnCaseText=Case sensitive -TreeViewerSearchDialog_BtnPreciseText=Precise matching TreeViewerSearchDialog_BtnSearchText=Find -TreeViewerSearchDialog_BtnWrapText=Wrap search TreeViewerSearchDialog_DepthFirst=Depth-First Search -TreeViewerSearchDialog_DialogPromptMessage=Find elements under the node "{0}".\nNote: You can change the starting point by selecting a tree node without disposing this dialog\! -TreeViewerSearchDialog_DialogTitle=Find Elements -TreeViewerSearchDialog_DialogTitleMessage=Find Elements -TreeViewerSearchDialog_GrpOptionsText=Options +TreeViewerSearchDialog_DFS=Depth-first search TreeViewerSearchDialog_JobName=Find Elements -TreeViewerSearchDialog_LblCancelText=Find: TreeViewerSearchDialog_MainTaskName=Finding TreeViewerSearchDialog_NoMoreNodeFound=No more node is found\! TreeViewerSearchDialog_NoSuchNode=No such node\! TreeViewerSearchDialog_Scope=Scope TreeViewerSearchDialog_SearchAlgorithm=Algorithm +TreeViewerSearchDialog_SearchNodesUsing=Search nodes using TreeViewerSearchDialog_Selected=Selected element TreeViewerSearchDialog_BreadthFirst=Breadth-First Search -TreeViewerSearchDialog_RootMsg=Find elements in the whole tree.\nNote: You can change the starting point by selecting a tree node without disposing this dialog\! ViewerStateManager_MkdirFailed=Making the directory for viewerstate.xml failed\! +TreeViewerSearchDialog_BtnWrapText=Wrap search +TreeViewerSearchDialog_UseOptions=with option(s): diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/utils/TreeViewerUtil.java b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/utils/TreeViewerUtil.java index e0d7633dc..7a60b98aa 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/utils/TreeViewerUtil.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui/src/org/eclipse/tcf/te/ui/utils/TreeViewerUtil.java @@ -33,7 +33,6 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.tcf.te.ui.activator.UIPlugin;
import org.eclipse.tcf.te.ui.internal.utils.FilteringImageDescriptor;
import org.eclipse.tcf.te.ui.internal.utils.QuickFilter;
-import org.eclipse.tcf.te.ui.internal.utils.SearchEngine;
import org.eclipse.tcf.te.ui.internal.utils.TreeViewerSearchDialog;
import org.eclipse.tcf.te.ui.jface.images.AbstractImageDescriptor;
import org.eclipse.ui.PlatformUI;
@@ -94,21 +93,6 @@ public class TreeViewerUtil { return text;
}
- /**
- * Get a singleton search engine for a tree viewer. If
- * it does not exist then create one and store it.
- *
- * @param viewer The tree viewer.
- * @return A search engine.
- */
- public static SearchEngine getSearchEngine(TreeViewer viewer) {
- SearchEngine searcher = (SearchEngine) viewer.getData("search.engine"); //$NON-NLS-1$
- if (searcher == null) {
- searcher = new SearchEngine(viewer);
- viewer.setData("search.engine", searcher); //$NON-NLS-1$
- }
- return searcher;
- }
/**
* Reset the viewer to the original view.
@@ -191,15 +175,6 @@ public class TreeViewerUtil { }
/**
- * Search the next element in the tree viewer.
- *
- * @param viewer The tree viewer to be searched.
- */
- public static void doSearchNext(TreeViewer viewer) {
- getSearchEngine(viewer).startSearch(null, null);
- }
-
- /**
* If the specified element is being filtered.
*
* @param path
|