diff options
author | nsandonato | 2011-03-02 20:53:29 +0000 |
---|---|---|
committer | nsandonato | 2011-03-02 20:53:29 +0000 |
commit | ee046e964ec9dc0eba3a2df4c35b0366b95af58e (patch) | |
tree | eb83502a1ad349c19ae165538e32dfd9907cbd3d | |
parent | 9039eeb528e8460702d9820f089c077f10c70ea5 (diff) | |
download | webtools.sourceediting-ee046e964ec9dc0eba3a2df4c35b0366b95af58e.tar.gz webtools.sourceediting-ee046e964ec9dc0eba3a2df4c35b0366b95af58e.tar.xz webtools.sourceediting-ee046e964ec9dc0eba3a2df4c35b0366b95af58e.zip |
[109045] [outline] Hide comments in XML outline
33 files changed, 2151 insertions, 459 deletions
diff --git a/bundles/org.eclipse.jst.jsp.ui/plugin.properties b/bundles/org.eclipse.jst.jsp.ui/plugin.properties index 3b5a19fd10..26b2626fe6 100644 --- a/bundles/org.eclipse.jst.jsp.ui/plugin.properties +++ b/bundles/org.eclipse.jst.jsp.ui/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2004, 2010 IBM Corporation and others. +# Copyright (c) 2004, 2011 IBM Corporation 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 @@ -113,4 +113,10 @@ proposalCategory.jspTemplates=JSP Template Proposals proposalCategory.jsp=JSP Proposals proposalCategory.jspJava=JSP Java Proposals +## +HideImportDeclaration.label=Import Directives +HideImportDeclaration.description=Hides Import Directives +HideComments.label=Comments +HideComments.description=Hides Comments + classPatternProvider.name = Class Pattern Provider
\ No newline at end of file diff --git a/bundles/org.eclipse.jst.jsp.ui/plugin.xml b/bundles/org.eclipse.jst.jsp.ui/plugin.xml index b9cc94328e..42bae5e954 100644 --- a/bundles/org.eclipse.jst.jsp.ui/plugin.xml +++ b/bundles/org.eclipse.jst.jsp.ui/plugin.xml @@ -1421,4 +1421,23 @@ contentTypeID="org.eclipse.jst.jsp.core.jspsource"> </categoriesConfiguration> </extension> +<extension + point="org.eclipse.wst.sse.ui.outlineFilters"> + <filter + targetId="org.eclipse.jst.jsp.ui.OutlinePage" + name="%HideImportDeclaration.label" + enabled="false" + description="%HideImportDeclaration.description" + class="org.eclipse.jst.jsp.ui.views.contentoutline.JSPImportDirectiveFilter" + id="org.eclipse.jst.jsp.ui.views.contentoutline.JSPImportDirectiveFilter"> + </filter> + <filter + targetId="org.eclipse.jst.jsp.ui.OutlinePage" + name="%HideComments.label" + enabled="false" + description="%HideComments.description" + class="org.eclipse.wst.xml.ui.views.contentoutline.XMLCommentFilter" + id="org.eclipse.jst.jsp.ui.views.contentoutline.XMLCommentFilter"> + </filter> +</extension> </plugin> diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/views/contentoutline/JSPContentOutlineConfiguration.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/views/contentoutline/JSPContentOutlineConfiguration.java index aaee92bd24..2318b727e1 100644 --- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/views/contentoutline/JSPContentOutlineConfiguration.java +++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/views/contentoutline/JSPContentOutlineConfiguration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 IBM Corporation and others. + * Copyright (c) 2004, 2011 IBM Corporation 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 @@ -35,7 +35,7 @@ public class JSPContentOutlineConfiguration extends HTMLContentOutlineConfigurat // be used // private StructuredContentOutlineConfiguration fEmbeddedConfiguration = // null; - + private static final String OUTLINE_FILTER_PREF = "org.eclipse.jst.jsp.ui.OutlinePage"; //$NON-NLS-1$ /** * Create new instance of JSPContentOutlineConfiguration */ @@ -56,4 +56,8 @@ public class JSPContentOutlineConfiguration extends HTMLContentOutlineConfigurat protected XMLNodeActionManager createNodeActionManager(TreeViewer treeViewer) { return new JSPNodeActionManager((IStructuredModel) treeViewer.getInput(), treeViewer); } + + public String getOutlineFilterTarget(){ + return OUTLINE_FILTER_PREF ; + } } diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/views/contentoutline/JSPImportDirectiveFilter.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/views/contentoutline/JSPImportDirectiveFilter.java new file mode 100644 index 0000000000..e4d11f311f --- /dev/null +++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/views/contentoutline/JSPImportDirectiveFilter.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jst.jsp.ui.views.contentoutline; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.JSP20TLDNames; +import org.eclipse.jst.jsp.core.internal.provisional.JSP11Namespace; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + +public class JSPImportDirectiveFilter extends ViewerFilter { + + + /* + * @see ViewerFilter + */ + public boolean select(Viewer viewer, Object parent, Object element) { + if (element instanceof Node){ + Node node = (Node)element; + if (node.getNodeName().equalsIgnoreCase(JSP11Namespace.ElementName.DIRECTIVE_PAGE)){ + final NamedNodeMap nodeMap = node.getAttributes(); + for (int i=0;i <nodeMap.getLength();i++){ + final Node attr = nodeMap.item(i); + if (attr != null && JSP20TLDNames.IMPORT.equalsIgnoreCase(attr.getNodeName())) + return false; + } + } + } + return true; + } +} diff --git a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/views/contentoutline/CSSContentOutlineConfiguration.java b/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/views/contentoutline/CSSContentOutlineConfiguration.java index fbc9d85e43..ee802ed53f 100644 --- a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/views/contentoutline/CSSContentOutlineConfiguration.java +++ b/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/views/contentoutline/CSSContentOutlineConfiguration.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2004, 2005 IBM Corporation and others. All rights reserved. This + * Copyright (c) 2004, 2011 IBM Corporation 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 @@ -33,6 +33,8 @@ public class CSSContentOutlineConfiguration extends ContentOutlineConfiguration private IContentProvider fContentProvider = null; private ILabelProvider fLabelProvider = null; private final String OUTLINE_SORT_PREF = "outline-sort"; //$NON-NLS-1$ + private static final String OUTLINE_FILTER_PREF = "org.eclipse.wst.css.ui.OutlinePage"; //$NON-NLS-1$ + /** * Create new instance of CSSContentOutlineConfiguration @@ -118,4 +120,8 @@ public class CSSContentOutlineConfiguration extends ContentOutlineConfiguration } return filteredSelection; } + + protected String getOutlineFilterTarget(){ + return OUTLINE_FILTER_PREF ; + } }
\ No newline at end of file diff --git a/bundles/org.eclipse.wst.dtd.ui/src/org/eclipse/wst/dtd/ui/views/contentoutline/DTDContentOutlineConfiguration.java b/bundles/org.eclipse.wst.dtd.ui/src/org/eclipse/wst/dtd/ui/views/contentoutline/DTDContentOutlineConfiguration.java index e42869c7cf..a09b4d5688 100644 --- a/bundles/org.eclipse.wst.dtd.ui/src/org/eclipse/wst/dtd/ui/views/contentoutline/DTDContentOutlineConfiguration.java +++ b/bundles/org.eclipse.wst.dtd.ui/src/org/eclipse/wst/dtd/ui/views/contentoutline/DTDContentOutlineConfiguration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2001, 2007 IBM Corporation and others. + * Copyright (c) 2001, 2011 IBM Corporation 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 @@ -59,7 +59,8 @@ public class DTDContentOutlineConfiguration extends ContentOutlineConfiguration private Map fViewerContributions; private final String OUTLINE_ORDER_PREF = "outline-order"; //$NON-NLS-1$ private final String OUTLINE_SORT_PREF = "outline-sort"; //$NON-NLS-1$ - + private static final String OUTLINE_FILTER_PREF = "org.eclipse.wst.dtd.ui.OutlinePage"; //$NON-NLS-1$ + /** * Default constructor for DTDContentOutlineConfiguration. */ @@ -279,4 +280,8 @@ public class DTDContentOutlineConfiguration extends ContentOutlineConfiguration fMenuHelper = null; } } + + protected String getOutlineFilterTarget(){ + return OUTLINE_FILTER_PREF ; + } } diff --git a/bundles/org.eclipse.wst.html.ui/plugin.properties b/bundles/org.eclipse.wst.html.ui/plugin.properties index 3232def4eb..5d09597f3b 100644 --- a/bundles/org.eclipse.wst.html.ui/plugin.properties +++ b/bundles/org.eclipse.wst.html.ui/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2005, 2010 IBM Corporation and others. +# Copyright (c) 2005, 2011 IBM Corporation 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 @@ -80,3 +80,6 @@ hyperlink.target.eventhandler.name=HTML Event Handlers proposalCategory.htmlTags=HTML Tag Proposals proposalCategory.htmlTemplates=HTML Template Proposals + +HideComments.label=Comments +HideComments.description=Hides Comments
\ No newline at end of file diff --git a/bundles/org.eclipse.wst.html.ui/plugin.xml b/bundles/org.eclipse.wst.html.ui/plugin.xml index 4652ead9c7..fcca90e9ea 100644 --- a/bundles/org.eclipse.wst.html.ui/plugin.xml +++ b/bundles/org.eclipse.wst.html.ui/plugin.xml @@ -734,5 +734,17 @@ contentTypeID="org.eclipse.wst.html.core.htmlsource"> </categoriesConfiguration> </extension> + +<extension + point="org.eclipse.wst.sse.ui.outlineFilters"> + <filter + targetId="org.eclipse.wst.html.ui.OutlinePage" + name="%HideComments.label" + enabled="false" + description="%HideComments.description" + class="org.eclipse.wst.xml.ui.views.contentoutline.XMLCommentFilter" + id="org.eclipse.wst.html.ui.views.contentoutline.XMLCommentFilter"> + </filter> +</extension> </plugin> diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/views/contentoutline/HTMLContentOutlineConfiguration.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/views/contentoutline/HTMLContentOutlineConfiguration.java index 421420430d..dbb3cf3e17 100644 --- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/views/contentoutline/HTMLContentOutlineConfiguration.java +++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/views/contentoutline/HTMLContentOutlineConfiguration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2005 IBM Corporation and others. + * Copyright (c) 2004, 2011 IBM Corporation 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 @@ -25,7 +25,7 @@ import org.eclipse.wst.xml.ui.views.contentoutline.XMLContentOutlineConfiguratio * @since 1.0 */ public class HTMLContentOutlineConfiguration extends XMLContentOutlineConfiguration { - + private static final String OUTLINE_FILTER_PREF = "org.eclipse.wst.html.ui.OutlinePage"; //$NON-NLS-1$ /** * Create new instance of HTMLContentOutlineConfiguration */ @@ -41,4 +41,8 @@ public class HTMLContentOutlineConfiguration extends XMLContentOutlineConfigurat protected IPreferenceStore getPreferenceStore() { return HTMLUIPlugin.getDefault().getPreferenceStore(); } + + protected String getOutlineFilterTarget(){ + return OUTLINE_FILTER_PREF ; + } }
\ No newline at end of file diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/filter_ps.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/filter_ps.gif Binary files differnew file mode 100644 index 0000000000..a4c9e60e25 --- /dev/null +++ b/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/filter_ps.gif diff --git a/bundles/org.eclipse.wst.sse.ui/plugin.properties b/bundles/org.eclipse.wst.sse.ui/plugin.properties index 5ab4691ef9..56f1e2a03e 100644 --- a/bundles/org.eclipse.wst.sse.ui/plugin.properties +++ b/bundles/org.eclipse.wst.sse.ui/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2001, 2010 IBM Corporation and others. +# Copyright (c) 2001, 2011 IBM Corporation 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 @@ -115,3 +115,8 @@ Colors.content_assist_proposals_background=Content Assist Proposals Background Colors.content_assist_proposals_foreground=Content Assist Proposals Foreground Colors.content_assist_parameters_background=Content Assist Parameters Background Colors.content_assist_parameters_foreground=Content Assist Parameters Foreground + +#outline filter +outlineFiltersName=Outline Filters + +command.outline.customFilter=&Filters
\ No newline at end of file diff --git a/bundles/org.eclipse.wst.sse.ui/plugin.xml b/bundles/org.eclipse.wst.sse.ui/plugin.xml index fdacd6680b..e50b9eb176 100644 --- a/bundles/org.eclipse.wst.sse.ui/plugin.xml +++ b/bundles/org.eclipse.wst.sse.ui/plugin.xml @@ -23,8 +23,12 @@ id="characterPairing" name="%Character_Pairing.name" schema="schema/characterPairing.exsd" ></extension-point> - - + <extension-point + id="outlineFilters" + name="%outlineFiltersName" + schema="schema/outlineFilters.exsd"> + </extension-point> + <!-- Make sure default preference values are set at runtime --> <extension point="org.eclipse.core.runtime.preferences"> <initializer @@ -737,10 +741,29 @@ </visibleWhen> </command> </menuContribution> + <!-- content outline --> + <menuContribution locationURI="menu:org.eclipse.ui.views.ContentOutline?after=additions"> + <command + commandId="org.eclipse.wst.sse.ui.outline.customFilter" + id="org.eclipse.wst.sse.ui.outline.customFilter" + label="%command.outline.customFilter" + icon ="icons/full/elcl16/filter_ps.gif" + style="push"> + <visibleWhen checkEnabled="false"> + <with variable="activeEditor"> + <test property="org.eclipse.wst.sse.ui.outline.isConfigurableOutlinePage" /> + </with> + </visibleWhen> + </command> + </menuContribution> </extension> <extension point="org.eclipse.ui.commands"> <command + id="org.eclipse.wst.sse.ui.outline.customFilter" + name="%command.outline.customFilter"> + </command> + <command id="org.eclipse.wst.sse.ui.format" name="%command.format.document.name"> </command> @@ -766,6 +789,12 @@ </iterate> </enabledWhen> </handler> + + <handler + class="org.eclipse.wst.sse.ui.internal.handlers.CustomFilterHandler" + commandId="org.eclipse.wst.sse.ui.outline.customFilter"> + </handler> + </extension> <extension point="org.eclipse.core.expressions.definitions"> @@ -834,5 +863,15 @@ </colorDefinition> </extension> + <extension + point="org.eclipse.core.expressions.propertyTesters"> + <propertyTester + class="org.eclipse.wst.sse.ui.internal.CustomFilterPropertyTester" + id="org.eclipse.wst.sse.ui.internal.handlers.CustomFilterPropertyTester" + namespace="org.eclipse.wst.sse.ui.outline" + properties="isConfigurableOutlinePage" + type="org.eclipse.ui.IEditorPart"> + </propertyTester> + </extension> </plugin> diff --git a/bundles/org.eclipse.wst.sse.ui/schema/outlineFilters.exsd b/bundles/org.eclipse.wst.sse.ui/schema/outlineFilters.exsd new file mode 100644 index 0000000000..8574ae2ea5 --- /dev/null +++ b/bundles/org.eclipse.wst.sse.ui/schema/outlineFilters.exsd @@ -0,0 +1,136 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="org.eclipse.wst.sse.ui" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="org.eclipse.wst.sse.ui" id="outlineFilters" name="%outlineFiltersName"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence> + <element ref="filter" minOccurs="1" maxOccurs="unbounded"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + a fully qualified identifier of the target extension point + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + an optional identifier of the extension instance + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + an optional name of the extension instance + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="filter"> + <annotation> + <appInfo> + <meta.element labelAttribute="name"/> + </appInfo> + </annotation> + <complexType> + <attribute name="id" type="string"> + <annotation> + <documentation> + a unique id that will be used to identify this filter + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + a unique name that allows to identify this filter in the UI. This attribute should be a translated string. Though this attribute is not required for pattern filters (i.e. those using the <samp>pattern</samp> attribute) we suggest to provide a name anyway, otherwise the pattern string itself would be used to represent the filter in the UI. + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + <attribute name="description" type="string"> + <annotation> + <documentation> + a short description for this filter + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + <attribute name="targetId" type="string"> + <annotation> + <documentation> + the id of the target where this filter is contributed. If this attribute is missing, then the filter will +be contributed to all views which use the <code>org.eclipse.wst.sse.ui.actions.CustomFiltersAction</code>. + </documentation> + </annotation> + </attribute> + <attribute name="enabled" type="boolean"> + <annotation> + <documentation> + the filter will be enabled if this attribute is "true" or if this attribute is not present. Most likely the user will be able to override this setting in the UI. + </documentation> + </annotation> + </attribute> + <attribute name="class" type="string"> + <annotation> + <documentation> + the name of the class used to filter the view. The class must extend <code>org.eclipse.jface.viewers.ViewerFilter</code>. If this attribute is here +then the pattern attribute must not provided. + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn="org.eclipse.jface.viewers.ViewerFilter"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + Works similar to javaElementFilter definition with targetId as "org.wst.sse.ui.OutlinePage". + Target id can be changed for different content types to provide their own filters + </documentation> + </annotation> + + + + <annotation> + <appInfo> + <meta.section type="copyright"/> + </appInfo> + <documentation> + Copyright (c) 2010 IBM Corporation and others.<br> +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 <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a> + </documentation> + </annotation> + +</schema> diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/CustomFilterPropertyTester.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/CustomFilterPropertyTester.java new file mode 100644 index 0000000000..d646039df5 --- /dev/null +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/CustomFilterPropertyTester.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.sse.ui.internal; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; +import org.eclipse.wst.sse.ui.internal.contentoutline.ConfigurableContentOutlinePage; + +public class CustomFilterPropertyTester extends PropertyTester { + /* + * (non-Javadoc) + * + * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, + * java.lang.String, java.lang.Object[], java.lang.Object) + */ + public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { + if (receiver instanceof IEditorPart){ + return ((IEditorPart) receiver).getAdapter(IContentOutlinePage.class) instanceof ConfigurableContentOutlinePage; + } + return false; + } + +} diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentoutline/ConfigurableContentOutlinePage.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentoutline/ConfigurableContentOutlinePage.java index ca87d75935..a55306a21a 100644 --- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentoutline/ConfigurableContentOutlinePage.java +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentoutline/ConfigurableContentOutlinePage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2001, 2008 IBM Corporation and others. + * Copyright (c) 2001, 2011 IBM Corporation 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 @@ -67,6 +67,7 @@ import org.eclipse.ui.part.ShowInContext; import org.eclipse.ui.views.contentoutline.ContentOutlinePage; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.eclipse.wst.sse.ui.views.contentoutline.ContentOutlineConfiguration; +import org.eclipse.wst.sse.ui.views.contentoutline.ContentOutlineFilterProcessor; public class ConfigurableContentOutlinePage extends ContentOutlinePage implements IAdaptable { @@ -754,4 +755,8 @@ public class ConfigurableContentOutlinePage extends ContentOutlinePage implement mgr.setMessage(image, text); } } + + public ContentOutlineFilterProcessor getOutlineFilterProcessor() { + return getConfiguration().getOutlineFilterProcessor(getTreeViewer()); + } } diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineCustomFiltersDialog.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineCustomFiltersDialog.java new file mode 100644 index 0000000000..714c68010e --- /dev/null +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineCustomFiltersDialog.java @@ -0,0 +1,417 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.sse.ui.internal.filter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.Stack; +import java.util.StringTokenizer; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +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.ui.PlatformUI; +import org.eclipse.ui.dialogs.SelectionDialog; +import org.eclipse.wst.sse.ui.internal.SSEUIPlugin; +import org.eclipse.wst.sse.ui.internal.util.SWTUtil; + + +public class OutlineCustomFiltersDialog extends SelectionDialog { + + private static final String SEPARATOR= ","; //$NON-NLS-1$ + + private String fViewId; + private boolean fEnablePatterns; + private String[] fPatterns; + private String[] fEnabledFilterIds; + + private OutlineFilterDescriptor[] fBuiltInFilters; + + private CheckboxTableViewer fCheckBoxList; + private Button fEnableUserDefinedPatterns; + private Text fUserDefinedPatterns; + + private Stack fFilterDescriptorChangeHistory; + + + /** + * Creates a dialog to customize Java element filters. + * + * @param shell the parent shell + * @param viewId the id of the view + * @param enablePatterns <code>true</code> if pattern filters are enabled + * @param patterns the filter patterns + * @param enabledFilterIds the Ids of the enabled filters + */ + public OutlineCustomFiltersDialog( + Shell shell, + String viewId, + boolean enablePatterns, + String[] patterns, + String[] enabledFilterIds) { + + super(shell); + Assert.isNotNull(viewId); + Assert.isNotNull(patterns); + Assert.isNotNull(enabledFilterIds); + + fViewId= viewId; + fPatterns= patterns; + fEnablePatterns= enablePatterns; + fEnabledFilterIds= enabledFilterIds; + + fBuiltInFilters= OutlineFilterDescriptor.getFilterDescriptors(fViewId); + fFilterDescriptorChangeHistory= new Stack(); + } + public static final String CUSTOM_FILTERS_DIALOG= SSEUIPlugin.ID + "." + "open_custom_filters_dialog_context"; //$NON-NLS-1$ + protected void configureShell(Shell shell) { + setTitle(OutlineFilterMessages.CustomFiltersDialog_title); + setMessage(OutlineFilterMessages.CustomFiltersDialog_filterList_label); + super.configureShell(shell); + PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, CUSTOM_FILTERS_DIALOG); + } + + /** + * Overrides method in Dialog + * + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite) + */ + protected Control createDialogArea(Composite parent) { + initializeDialogUnits(parent); + // create a composite with standard margins and spacing + Composite composite= new Composite(parent, SWT.NONE); + GridLayout layout= new GridLayout(); + layout.marginHeight= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); + layout.marginWidth= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); + layout.verticalSpacing= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); + layout.horizontalSpacing= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + composite.setFont(parent.getFont()); + Composite group= composite; + + // Checkbox + fEnableUserDefinedPatterns= new Button(group, SWT.CHECK); + fEnableUserDefinedPatterns.setFocus(); + fEnableUserDefinedPatterns.setText(OutlineFilterMessages.CustomFiltersDialog_enableUserDefinedPattern); + + // Pattern field + fUserDefinedPatterns= new Text(group, SWT.SINGLE | SWT.BORDER); + GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); + data.widthHint= convertWidthInCharsToPixels(59); + fUserDefinedPatterns.setLayoutData(data); + String patterns= convertToString(fPatterns, SEPARATOR); + fUserDefinedPatterns.setText(patterns); + SWTUtil.setAccessibilityText(fUserDefinedPatterns, OutlineFilterMessages.CustomFiltersDialog_name_filter_pattern_description); + + // Info text + final Label info= new Label(group, SWT.LEFT); + info.setText(OutlineFilterMessages.CustomFiltersDialog_patternInfo); + + // Enabling / disabling of pattern group + fEnableUserDefinedPatterns.setSelection(fEnablePatterns); + fUserDefinedPatterns.setEnabled(fEnablePatterns); + info.setEnabled(fEnablePatterns); + fEnableUserDefinedPatterns.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + boolean state= fEnableUserDefinedPatterns.getSelection(); + fUserDefinedPatterns.setEnabled(state); + info.setEnabled(fEnableUserDefinedPatterns.getSelection()); + if (state) + fUserDefinedPatterns.setFocus(); + } + }); + + // Filters provided by extension point + if (fBuiltInFilters.length > 0) + createCheckBoxList(group); + + applyDialogFont(parent); + return parent; + } + + private void createCheckBoxList(Composite parent) { + // Filler + new Label(parent, SWT.NONE); + + Label info= new Label(parent, SWT.LEFT); + info.setText(OutlineFilterMessages.CustomFiltersDialog_filterList_label); + + fCheckBoxList= CheckboxTableViewer.newCheckList(parent, SWT.BORDER); + GridData data= new GridData(GridData.FILL_BOTH); + data.heightHint= fCheckBoxList.getTable().getItemHeight() * 10; + fCheckBoxList.getTable().setLayoutData(data); + + fCheckBoxList.setLabelProvider(createLabelPrivder()); + fCheckBoxList.setContentProvider(new ArrayContentProvider()); + Arrays.sort(fBuiltInFilters); + fCheckBoxList.setInput(fBuiltInFilters); + setInitialSelections(getEnabledFilterDescriptors()); + + List initialSelection= getInitialElementSelections(); + if (initialSelection != null && !initialSelection.isEmpty()) + checkInitialSelections(); + + // Description + info= new Label(parent, SWT.LEFT); + info.setText(OutlineFilterMessages.CustomFiltersDialog_description_label); + final Text description= new Text(parent, SWT.LEFT | SWT.WRAP | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.V_SCROLL); + data = new GridData(GridData.FILL_HORIZONTAL); + data.heightHint= convertHeightInCharsToPixels(3); + description.setLayoutData(data); + fCheckBoxList.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection= event.getSelection(); + if (selection instanceof IStructuredSelection) { + Object selectedElement= ((IStructuredSelection)selection).getFirstElement(); + if (selectedElement instanceof OutlineFilterDescriptor) + description.setText(((OutlineFilterDescriptor)selectedElement).getDescription()); + } + } + }); + fCheckBoxList.addCheckStateListener(new ICheckStateListener() { + /* + * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent) + */ + public void checkStateChanged(CheckStateChangedEvent event) { + Object element= event.getElement(); + if (element instanceof OutlineFilterDescriptor) { + // renew if already touched + if (fFilterDescriptorChangeHistory.contains(element)) + fFilterDescriptorChangeHistory.remove(element); + fFilterDescriptorChangeHistory.push(element); + } + }}); + + addSelectionButtons(parent); + } + + private void addSelectionButtons(Composite composite) { + Composite buttonComposite= new Composite(composite, SWT.RIGHT); + GridLayout layout= new GridLayout(); + layout.numColumns= 2; + buttonComposite.setLayout(layout); + GridData data= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL); + data.grabExcessHorizontalSpace= true; + composite.setData(data); + + // Select All button + String label= OutlineFilterMessages.CustomFiltersDialog_SelectAllButton_label; + Button selectButton= createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID, label, false); + SWTUtil.setButtonDimensionHint(selectButton); + SelectionListener listener= new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + fCheckBoxList.setAllChecked(true); + fFilterDescriptorChangeHistory.clear(); + for (int i= 0; i < fBuiltInFilters.length; i++) + fFilterDescriptorChangeHistory.push(fBuiltInFilters[i]); + } + }; + selectButton.addSelectionListener(listener); + + // De-select All button + label= OutlineFilterMessages.CustomFiltersDialog_DeselectAllButton_label; + Button deselectButton= createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID, label, false); + SWTUtil.setButtonDimensionHint(deselectButton); + listener= new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + fCheckBoxList.setAllChecked(false); + fFilterDescriptorChangeHistory.clear(); + for (int i= 0; i < fBuiltInFilters.length; i++) + fFilterDescriptorChangeHistory.push(fBuiltInFilters[i]); + } + }; + deselectButton.addSelectionListener(listener); + } + + private void checkInitialSelections() { + Iterator itemsToCheck= getInitialElementSelections().iterator(); + while (itemsToCheck.hasNext()) + fCheckBoxList.setChecked(itemsToCheck.next(),true); + } + + protected void okPressed() { + if (fBuiltInFilters != null) { + ArrayList result= new ArrayList(); + for (int i= 0; i < fBuiltInFilters.length; ++i) { + if (fCheckBoxList.getChecked(fBuiltInFilters[i])) + result.add(fBuiltInFilters[i]); + } + setResult(result); + } + super.okPressed(); + } + + private ILabelProvider createLabelPrivder() { + return + new LabelProvider() { + public Image getImage(Object element) { + return null; + } + public String getText(Object element) { + if (element instanceof OutlineFilterDescriptor) + return ((OutlineFilterDescriptor)element).getName(); + else + return null; + } + }; + } + + // ---------- result handling ---------- + + protected void setResult(List newResult) { + super.setResult(newResult); + if (fUserDefinedPatterns.getText().length() > 0) { + fEnablePatterns= fEnableUserDefinedPatterns.getSelection(); + fPatterns= convertFromString(fUserDefinedPatterns.getText(), SEPARATOR); + } else { + fEnablePatterns= false; + fPatterns= new String[0]; + } + } + + + /** + * @return the patterns which have been entered by the user + */ + public String[] getUserDefinedPatterns() { + return fPatterns; + } + + /** + * @return the Ids of the enabled built-in filters + */ + public String[] getEnabledFilterIds() { + Object[] result= getResult(); + Set enabledIds= new HashSet(result.length); + for (int i= 0; i < result.length; i++) + enabledIds.add(((OutlineFilterDescriptor)result[i]).getId()); + return (String[]) enabledIds.toArray(new String[enabledIds.size()]); + } + + /** + * @return <code>true</code> if the user-defined patterns are disabled + */ + public boolean areUserDefinedPatternsEnabled() { + return fEnablePatterns; + } + + /** + * @return a stack with the filter descriptor check history + */ + public Stack getFilterDescriptorChangeHistory() { + return fFilterDescriptorChangeHistory; + } + + private OutlineFilterDescriptor[] getEnabledFilterDescriptors() { + OutlineFilterDescriptor[] filterDescs= fBuiltInFilters; + List result= new ArrayList(filterDescs.length); + List enabledFilterIds= Arrays.asList(fEnabledFilterIds); + for (int i= 0; i < filterDescs.length; i++) { + String id= filterDescs[i].getId(); + if (enabledFilterIds.contains(id)) + result.add(filterDescs[i]); + } + return (OutlineFilterDescriptor[])result.toArray(new OutlineFilterDescriptor[result.size()]); + } + + + public static String[] convertFromString(String patterns, String separator) { + StringTokenizer tokenizer= new StringTokenizer(patterns, separator, true); + int tokenCount= tokenizer.countTokens(); + List result= new ArrayList(tokenCount); + boolean escape= false; + boolean append= false; + while (tokenizer.hasMoreTokens()) { + String token= tokenizer.nextToken().trim(); + if (separator.equals(token)) { + if (!escape) + escape= true; + else { + addPattern(result, separator); + append= true; + } + } else { + if (!append) + result.add(token); + else + addPattern(result, token); + append= false; + escape= false; + } + } + return (String[])result.toArray(new String[result.size()]); + } + + private static void addPattern(List list, String pattern) { + if (list.isEmpty()) + list.add(pattern); + else { + int index= list.size() - 1; + list.set(index, ((String)list.get(index)) + pattern); + } + } + + public static String convertToString(String[] patterns, String separator) { + int length= patterns.length; + StringBuffer strBuf= new StringBuffer(); + if (length > 0) + strBuf.append(escapeSeparator(patterns[0], separator)); + else + return ""; //$NON-NLS-1$ + int i= 1; + while (i < length) { + strBuf.append(separator); + strBuf.append(" "); //$NON-NLS-1$ + strBuf.append(escapeSeparator(patterns[i++], separator)); + } + return strBuf.toString(); + } + + private static String escapeSeparator(String pattern, String separator) { + int length= pattern.length(); + StringBuffer buf= new StringBuffer(length); + for (int i= 0; i < length; i++) { + char ch= pattern.charAt(i); + if (separator.equals(String.valueOf(ch))) + buf.append(ch); + buf.append(ch); + } + return buf.toString(); + + } +} diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineFilterDescriptor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineFilterDescriptor.java new file mode 100644 index 0000000000..fd6b24e21e --- /dev/null +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineFilterDescriptor.java @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.sse.ui.internal.filter; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.ibm.icu.text.Collator; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; + +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ViewerFilter; + +import org.eclipse.ui.IPluginContribution; +import org.eclipse.ui.activities.WorkbenchActivityHelper; +import org.eclipse.wst.sse.ui.internal.SSEUIPlugin; + + + +/** + * Represents a custom filter which is provided by the + * "org.eclipse.sse.ui.outlineFilters" extension point. + * + */ +public class OutlineFilterDescriptor implements Comparable, IPluginContribution { + + private static String PATTERN_FILTER_ID_PREFIX= "_patternFilterId_"; //$NON-NLS-1$ + + + private static final String EXTENSION_POINT_NAME= "outlineFilters"; //$NON-NLS-1$ + + private static final String FILTER_TAG= "filter"; //$NON-NLS-1$ + + private static final String PATTERN_ATTRIBUTE= "pattern"; //$NON-NLS-1$ + private static final String ID_ATTRIBUTE= "id"; //$NON-NLS-1$ + private static final String TARGET_ID_ATTRIBUTE= "targetId"; //$NON-NLS-1$ + private static final String CLASS_ATTRIBUTE= "class"; //$NON-NLS-1$ + private static final String NAME_ATTRIBUTE= "name"; //$NON-NLS-1$ + private static final String ENABLED_ATTRIBUTE= "enabled"; //$NON-NLS-1$ + private static final String DESCRIPTION_ATTRIBUTE= "description"; //$NON-NLS-1$ + + private static OutlineFilterDescriptor[] fgFilterDescriptors; + + + private IConfigurationElement fElement; + + /** + * Returns all contributed Java element filters. + * @return all contributed Java element filters + */ + public static OutlineFilterDescriptor[] getFilterDescriptors() { + if (fgFilterDescriptors == null) { + IExtensionRegistry registry= Platform.getExtensionRegistry(); + IConfigurationElement[] elements= registry.getConfigurationElementsFor(SSEUIPlugin.ID, EXTENSION_POINT_NAME); + fgFilterDescriptors= createFilterDescriptors(elements); + } + return fgFilterDescriptors; + } + /** + * Returns all Java element filters which + * are contributed to the given view. + * @param targetId the target id + * @return all contributed Java element filters for the given view + */ + public static OutlineFilterDescriptor[] getFilterDescriptors(String targetId) { + OutlineFilterDescriptor[] filterDescs= OutlineFilterDescriptor.getFilterDescriptors(); + List result= new ArrayList(filterDescs.length); + for (int i= 0; i < filterDescs.length; i++) { + String tid= filterDescs[i].getTargetId(); + if (WorkbenchActivityHelper.filterItem(filterDescs[i])) + continue; + if (tid == null || tid.equals(targetId)) + result.add(filterDescs[i]); + } + return (OutlineFilterDescriptor[])result.toArray(new OutlineFilterDescriptor[result.size()]); + } + + /** + * Creates a new filter descriptor for the given configuration element. + * @param element configuration element + */ + private OutlineFilterDescriptor(IConfigurationElement element) { + fElement= element; + // it is either a pattern filter or a custom filter + Assert.isTrue(isPatternFilter() ^ isCustomFilter(), "An extension for extension-point org.eclipse.sse.ui.outlineFilters does not specify a correct filter"); //$NON-NLS-1$ + Assert.isNotNull(getId(), "An extension for extension-point org.eclipse.sse.ui.outlineFilters does not provide a valid ID"); //$NON-NLS-1$ + Assert.isNotNull(getName(), "An extension for extension-point org.eclipse.sse.ui.outlineFilters does not provide a valid name"); //$NON-NLS-1$ + } + + /** + * Creates a new <code>ViewerFilter</code>. + * This method is only valid for viewer filters. + * @return a new <code>ViewerFilter</code> + */ + public ViewerFilter createViewerFilter() { + if (!isCustomFilter()) + return null; + + final ViewerFilter[] result= new ViewerFilter[1]; + String message = OutlineFilterMessages.FilterDescriptor_filterCreationError_message; + ISafeRunnable code= new SafeRunnable(message) { + /* + * @see org.eclipse.core.runtime.ISafeRunnable#run() + */ + public void run() throws Exception { + result[0]= (ViewerFilter)fElement.createExecutableExtension(CLASS_ATTRIBUTE); + } + + }; + SafeRunner.run(code); + return result[0]; + } + + //---- XML Attribute accessors --------------------------------------------- + + /** + * Returns the filter's id. + * <p> + * This attribute is mandatory for custom filters. + * The ID for pattern filters is + * PATTERN_FILTER_ID_PREFIX plus the pattern itself. + * </p> + * @return the filter id + */ + public String getId() { + if (isPatternFilter()) { + String targetId= getTargetId(); + if (targetId == null) + return PATTERN_FILTER_ID_PREFIX + getPattern(); + else + return targetId + PATTERN_FILTER_ID_PREFIX + getPattern(); + } else + return fElement.getAttribute(ID_ATTRIBUTE); + } + + /** + * Returns the filter's name. + * <p> + * If the name of a pattern filter is missing + * then the pattern is used as its name. + * </p> + * @return the filter's name + */ + public String getName() { + String name= fElement.getAttribute(NAME_ATTRIBUTE); + if (name == null && isPatternFilter()) + name= getPattern(); + return name; + } + + /** + * Returns the filter's pattern. + * + * @return the pattern string or <code>null</code> if it's not a pattern filter + */ + public String getPattern() { + return fElement.getAttribute(PATTERN_ATTRIBUTE); + } + + /** + * Returns the filter's viewId. + * + * @return the view ID or <code>null</code> if the filter is for all views + */ + public String getTargetId() { + String tid= fElement.getAttribute(TARGET_ID_ATTRIBUTE); + + if (tid != null) + return tid; + + // Backwards compatibility code + return null; + + } + + /** + * Returns the filter's description. + * + * @return the description or <code>null</code> if no description is provided + */ + public String getDescription() { + String description= fElement.getAttribute(DESCRIPTION_ATTRIBUTE); + if (description == null) + description= ""; //$NON-NLS-1$ + return description; + } + + /** + * @return <code>true</code> if this filter is a custom filter. + */ + public boolean isPatternFilter() { + return getPattern() != null; + } + + /** + * @return <code>true</code> if this filter is a pattern filter. + */ + public boolean isCustomFilter() { + return fElement.getAttribute(CLASS_ATTRIBUTE) != null; + } + + /** + * Returns <code>true</code> if the filter + * is initially enabled. + * + * This attribute is optional and defaults to <code>true</code>. + * @return returns <code>true</code> if the filter is initially enabled + */ + public boolean isEnabled() { + String strVal= fElement.getAttribute(ENABLED_ATTRIBUTE); + return strVal == null || Boolean.valueOf(strVal).booleanValue(); + } + + /* + * Implements a method from IComparable + */ + public int compareTo(Object o) { + if (o instanceof OutlineFilterDescriptor) + return Collator.getInstance().compare(getName(), ((OutlineFilterDescriptor)o).getName()); + else + return Integer.MIN_VALUE; + } + + //---- initialization --------------------------------------------------- + + /** + * Creates the filter descriptors. + * @param elements the configuration elements + * @return new filter descriptors + */ + private static OutlineFilterDescriptor[] createFilterDescriptors(IConfigurationElement[] elements) { + List result= new ArrayList(5); + Set descIds= new HashSet(5); + for (int i= 0; i < elements.length; i++) { + final IConfigurationElement element= elements[i]; + if (FILTER_TAG.equals(element.getName())) { + + final OutlineFilterDescriptor[] desc= new OutlineFilterDescriptor[1]; + SafeRunner.run(new SafeRunnable(OutlineFilterMessages.FilterDescriptor_filterDescriptionCreationError_message) { + public void run() throws Exception { + desc[0]= new OutlineFilterDescriptor(element); + } + }); + + if (desc[0] != null && !descIds.contains(desc[0].getId())) { + result.add(desc[0]); + descIds.add(desc[0].getId()); + } + } + } + return (OutlineFilterDescriptor[])result.toArray(new OutlineFilterDescriptor[result.size()]); + } + + public String getLocalId() { + return fElement.getAttribute(ID_ATTRIBUTE); + } + + public String getPluginId() { + return fElement.getContributor().getName(); + } +} diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineFilterMessages.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineFilterMessages.java new file mode 100644 index 0000000000..9926e00e12 --- /dev/null +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineFilterMessages.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.sse.ui.internal.filter; + +import org.eclipse.osgi.util.NLS; + +public final class OutlineFilterMessages extends NLS { + + private static final String BUNDLE_NAME= "org.eclipse.wst.sse.ui.internal.filter.OutlineFilterMessages";//$NON-NLS-1$ + + private OutlineFilterMessages() { + // Do not instantiate + } + + public static String CustomFiltersDialog_title; + public static String CustomFiltersDialog_patternInfo; + public static String CustomFiltersDialog_enableUserDefinedPattern; + public static String CustomFiltersDialog_filterList_label; + public static String CustomFiltersDialog_description_label; + public static String CustomFiltersDialog_SelectAllButton_label; + public static String CustomFiltersDialog_DeselectAllButton_label; + public static String CustomFiltersDialog_name_filter_pattern_description; + public static String OpenCustomFiltersDialogAction_text; + public static String FilterDescriptor_filterDescriptionCreationError_message; + public static String FilterDescriptor_filterCreationError_message; + + static { + NLS.initializeMessages(BUNDLE_NAME, OutlineFilterMessages.class); + } +} diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineFilterMessages.properties b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineFilterMessages.properties new file mode 100644 index 0000000000..9ebc024134 --- /dev/null +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineFilterMessages.properties @@ -0,0 +1,24 @@ +############################################################################### +# Copyright (c) 2011 IBM Corporation 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: +# IBM Corporation - initial API and implementation +############################################################################### + +CustomFiltersDialog_title= Outline Element Filters +CustomFiltersDialog_patternInfo= The patterns are separated by a comma, where\n* = any string, ? = any character, ,, = , +CustomFiltersDialog_enableUserDefinedPattern= &Name filter patterns (matching names will be hidden): +CustomFiltersDialog_filterList_label= S&elect the elements to exclude from the view: +CustomFiltersDialog_description_label= Filter description: +CustomFiltersDialog_SelectAllButton_label= &Select All +CustomFiltersDialog_DeselectAllButton_label= &Deselect All +CustomFiltersDialog_name_filter_pattern_description=Name filter patterns. The patterns are separated by a comma, where star is any string + +OpenCustomFiltersDialogAction_text= &Filters... + +FilterDescriptor_filterDescriptionCreationError_message= One of the extensions for extension-point org.eclipse.wst.sse.ui.outlineFilters is incorrect. +FilterDescriptor_filterCreationError_message= The org.eclipse.wst.sse.ui.outlineFilters plug-in extension "{0}" specifies a viewer filter class which does not exist. diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineNamePatternFilter.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineNamePatternFilter.java new file mode 100644 index 0000000000..37ba7d5f48 --- /dev/null +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/OutlineNamePatternFilter.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.sse.ui.internal.filter; + +import org.eclipse.jface.viewers.ContentViewer; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +/** + * The NamePatternFilter selects the elements which + * match the given string patterns. + * <p> + * The following characters have special meaning: + * ? => any character + * * => any string + * </p> + * + */ +public class OutlineNamePatternFilter extends ViewerFilter { + private String[] fPatterns; + private StringMatcher[] fMatchers; + + + /** + * Gets the patterns for the receiver. + * @return returns the patterns to be filtered for + */ + public String[] getPatterns() { + return fPatterns; + } + + + /* (non-Javadoc) + * Method declared on ViewerFilter. + */ + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (getPatterns().length == 0) { + return true; + } + String matchName= null; + if (viewer instanceof ContentViewer){ + final IBaseLabelProvider labelProvider = ((ContentViewer) viewer).getLabelProvider(); + if (labelProvider instanceof ILabelProvider) { + matchName = ((ILabelProvider) labelProvider).getText(element); + } + } + if (matchName != null && matchName.length() > 0) { + String[] fPatterns = getPatterns(); + for (int i = 0; i < fPatterns.length; i++) { + if (new StringMatcher(fPatterns[i], true, false).match(matchName)) + return false; + } + return true; + } + return true; + } + + /** + * Sets the patterns to filter out for the receiver. + * <p> + * The following characters have special meaning: + * ? => any character + * * => any string + * </p> + * @param newPatterns the new patterns + */ + public void setPatterns(String[] newPatterns) { + fPatterns = newPatterns; + fMatchers = new StringMatcher[newPatterns.length]; + for (int i = 0; i < newPatterns.length; i++) { + //Reset the matchers to prevent constructor overhead + fMatchers[i]= new StringMatcher(newPatterns[i], true, false); + } + } +} diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/StringMatcher.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/StringMatcher.java new file mode 100644 index 0000000000..d7dfdd696e --- /dev/null +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/filter/StringMatcher.java @@ -0,0 +1,384 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.sse.ui.internal.filter; + +import java.util.Vector; + +/** + * A string pattern matcher. Supports '*' and '?' wildcards. + */ +public class StringMatcher { + protected String fPattern; + protected int fLength; // pattern length + protected boolean fIgnoreWildCards; + protected boolean fIgnoreCase; + protected boolean fHasLeadingStar; + protected boolean fHasTrailingStar; + protected String fSegments[]; //the given pattern is split into * separated segments + + /* boundary value beyond which we don't need to search in the text */ + protected int fBound= 0; + + + protected static final char fSingleWildCard= '\u0000'; + + public static class Position { + int start; //inclusive + int end; //exclusive + public Position(int start, int end) { + this.start= start; + this.end= end; + } + public int getStart() { + return start; + } + public int getEnd() { + return end; + } + } + /** + * StringMatcher constructor takes in a String object that is a simple + * pattern. The pattern may contain '*' for 0 and many characters and + * '?' for exactly one character. + * + * Literal '*' and '?' characters must be escaped in the pattern + * e.g., "\*" means literal "*", etc. + * + * Escaping any other character (including the escape character itself), + * just results in that character in the pattern. + * e.g., "\a" means "a" and "\\" means "\" + * + * If invoking the StringMatcher with string literals in Java, don't forget + * escape characters are represented by "\\". + * + * @param pattern the pattern to match text against + * @param ignoreCase if true, case is ignored + * @param ignoreWildCards if true, wild cards and their escape sequences are ignored + * (everything is taken literally). + */ + public StringMatcher(String pattern, boolean ignoreCase, boolean ignoreWildCards) { + if (pattern == null) + throw new IllegalArgumentException(); + fIgnoreCase= ignoreCase; + fIgnoreWildCards= ignoreWildCards; + fPattern= pattern; + fLength= pattern.length(); + + if (fIgnoreWildCards) { + parseNoWildCards(); + } else { + parseWildCards(); + } + } + /** + * Find the first occurrence of the pattern between <code>start</code)(inclusive) + * and <code>end</code>(exclusive). + * @param text the String object to search in + * @param start the starting index of the search range, inclusive + * @param end the ending index of the search range, exclusive + * @return an <code>StringMatcher.Position</code> object that keeps the starting + * (inclusive) and ending positions (exclusive) of the first occurrence of the + * pattern in the specified range of the text; return null if not found or subtext + * is empty (start==end). A pair of zeros is returned if pattern is empty string + * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc" + * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned + */ + public StringMatcher.Position find(String text, int start, int end) { + if (text == null) + throw new IllegalArgumentException(); + + int tlen= text.length(); + if (start < 0) + start= 0; + if (end > tlen) + end= tlen; + if (end < 0 ||start >= end ) + return null; + if (fLength == 0) + return new Position(start, start); + if (fIgnoreWildCards) { + int x= posIn(text, start, end); + if (x < 0) + return null; + return new Position(x, x+fLength); + } + + int segCount= fSegments.length; + if (segCount == 0)//pattern contains only '*'(s) + return new Position (start, end); + + int curPos= start; + int matchStart= -1; + int i; + for (i= 0; i < segCount && curPos < end; ++i) { + String current= fSegments[i]; + int nextMatch= regExpPosIn(text, curPos, end, current); + if (nextMatch < 0 ) + return null; + if(i == 0) + matchStart= nextMatch; + curPos= nextMatch + current.length(); + } + if (i < segCount) + return null; + return new Position(matchStart, curPos); + } + /** + * match the given <code>text</code> with the pattern + * @return true if matched eitherwise false + * @param text a String object + */ + public boolean match(String text) { + return match(text, 0, text.length()); + } + /** + * Given the starting (inclusive) and the ending (exclusive) positions in the + * <code>text</code>, determine if the given substring matches with aPattern + * @return true if the specified portion of the text matches the pattern + * @param text a String object that contains the substring to match + * @param start marks the starting position (inclusive) of the substring + * @param end marks the ending index (exclusive) of the substring + */ + public boolean match(String text, int start, int end) { + if (null == text) + throw new IllegalArgumentException(); + + if (start > end) + return false; + + if (fIgnoreWildCards) + return (end - start == fLength) && fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength); + int segCount= fSegments.length; + if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) // pattern contains only '*'(s) + return true; + if (start == end) + return fLength == 0; + if (fLength == 0) + return start == end; + + int tlen= text.length(); + if (start < 0) + start= 0; + if (end > tlen) + end= tlen; + + int tCurPos= start; + int bound= end - fBound; + if ( bound < 0) + return false; + int i=0; + String current= fSegments[i]; + int segLength= current.length(); + + /* process first segment */ + if (!fHasLeadingStar){ + if(!regExpRegionMatches(text, start, current, 0, segLength)) { + return false; + } else { + ++i; + tCurPos= tCurPos + segLength; + } + } + if ((fSegments.length == 1) && (!fHasLeadingStar) && (!fHasTrailingStar)) { + // only one segment to match, no wildcards specified + return tCurPos == end; + } + /* process middle segments */ + while (i < segCount) { + current= fSegments[i]; + int currentMatch; + int k= current.indexOf(fSingleWildCard); + if (k < 0) { + currentMatch= textPosIn(text, tCurPos, end, current); + if (currentMatch < 0) + return false; + } else { + currentMatch= regExpPosIn(text, tCurPos, end, current); + if (currentMatch < 0) + return false; + } + tCurPos= currentMatch + current.length(); + i++; + } + + /* process final segment */ + if (!fHasTrailingStar && tCurPos != end) { + int clen= current.length(); + return regExpRegionMatches(text, end - clen, current, 0, clen); + } + return i == segCount ; + } + + /** + * This method parses the given pattern into segments seperated by wildcard '*' characters. + * Since wildcards are not being used in this case, the pattern consists of a single segment. + */ + private void parseNoWildCards() { + fSegments= new String[1]; + fSegments[0]= fPattern; + fBound= fLength; + } + /** + * Parses the given pattern into segments seperated by wildcard '*' characters. + */ + private void parseWildCards() { + if(fPattern.startsWith("*"))//$NON-NLS-1$ + fHasLeadingStar= true; + if(fPattern.endsWith("*")) {//$NON-NLS-1$ + /* make sure it's not an escaped wildcard */ + if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') { + fHasTrailingStar= true; + } + } + + Vector temp= new Vector(); + + int pos= 0; + StringBuffer buf= new StringBuffer(); + while (pos < fLength) { + char c= fPattern.charAt(pos++); + switch (c) { + case '\\': + if (pos >= fLength) { + buf.append(c); + } else { + char next= fPattern.charAt(pos++); + /* if it's an escape sequence */ + if (next == '*' || next == '?' || next == '\\') { + buf.append(next); + } else { + /* not an escape sequence, just insert literally */ + buf.append(c); + buf.append(next); + } + } + break; + case '*': + if (buf.length() > 0) { + /* new segment */ + temp.addElement(buf.toString()); + fBound += buf.length(); + buf.setLength(0); + } + break; + case '?': + /* append special character representing single match wildcard */ + buf.append(fSingleWildCard); + break; + default: + buf.append(c); + } + } + + /* add last buffer to segment list */ + if (buf.length() > 0) { + temp.addElement(buf.toString()); + fBound += buf.length(); + } + + fSegments= new String[temp.size()]; + temp.copyInto(fSegments); + } + /** + * @param text a string which contains no wildcard + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int posIn(String text, int start, int end) {//no wild card in pattern + int max= end - fLength; + + if (!fIgnoreCase) { + int i= text.indexOf(fPattern, start); + if (i == -1 || i > max) + return -1; + return i; + } + + for (int i= start; i <= max; ++i) { + if (text.regionMatches(true, i, fPattern, 0, fLength)) + return i; + } + + return -1; + } + /** + * @param text a simple regular expression that may only contain '?'(s) + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @param p a simple regular expression that may contains '?' + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int regExpPosIn(String text, int start, int end, String p) { + int plen= p.length(); + + int max= end - plen; + for (int i= start; i <= max; ++i) { + if (regExpRegionMatches(text, i, p, 0, plen)) + return i; + } + return -1; + } + + + protected boolean regExpRegionMatches(String text, int tStart, String p, int pStart, int plen) { + while (plen-- > 0) { + char tchar= text.charAt(tStart++); + char pchar= p.charAt(pStart++); + + /* process wild cards */ + if (!fIgnoreWildCards) { + /* skip single wild cards */ + if (pchar == fSingleWildCard) { + continue; + } + } + if (pchar == tchar) + continue; + if (fIgnoreCase) { + if (Character.toUpperCase(tchar) == Character.toUpperCase(pchar)) + continue; + // comparing after converting to upper case doesn't handle all cases; + // also compare after converting to lower case + if (Character.toLowerCase(tchar) == Character.toLowerCase(pchar)) + continue; + } + return false; + } + return true; + } + /** + * @param text the string to match + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @param p a string that has no wildcard + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int textPosIn(String text, int start, int end, String p) { + + int plen= p.length(); + int max= end - plen; + + if (!fIgnoreCase) { + int i= text.indexOf(p, start); + if (i == -1 || i > max) + return -1; + return i; + } + + for (int i= start; i <= max; ++i) { + if (text.regionMatches(true, i, p, 0, plen)) + return i; + } + + return -1; + } +} diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/handlers/CustomFilterHandler.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/handlers/CustomFilterHandler.java new file mode 100644 index 0000000000..baaa020b0b --- /dev/null +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/handlers/CustomFilterHandler.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.sse.ui.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; +import org.eclipse.wst.sse.ui.internal.contentoutline.ConfigurableContentOutlinePage; + +public class CustomFilterHandler extends AbstractHandler { + public Object execute(ExecutionEvent event) throws ExecutionException { + + IEditorPart editor = HandlerUtil.getActiveEditor(event); + ConfigurableContentOutlinePage page = (ConfigurableContentOutlinePage) editor.getAdapter(IContentOutlinePage.class); + if (page != null) { + page.getOutlineFilterProcessor().openDialog(); + } + return null; + } + +} diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/quickoutline/QuickOutlinePopupDialog.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/quickoutline/QuickOutlinePopupDialog.java index 6a2f62cfbb..f5db0f4da1 100644 --- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/quickoutline/QuickOutlinePopupDialog.java +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/quickoutline/QuickOutlinePopupDialog.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 IBM Corporation and others. + * Copyright (c) 2010, 2011 IBM Corporation 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 @@ -57,7 +57,7 @@ import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; import org.eclipse.wst.sse.ui.IContentSelectionProvider; import org.eclipse.wst.sse.ui.internal.SSEUIPlugin; -import org.eclipse.wst.sse.ui.internal.quickoutline.StringPatternFilter.StringMatcher; +import org.eclipse.wst.sse.ui.internal.filter.StringMatcher; import org.eclipse.wst.sse.ui.quickoutline.AbstractQuickOutlineConfiguration; /** diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/quickoutline/StringPatternFilter.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/quickoutline/StringPatternFilter.java index 86c19f2135..fb191eb4bf 100644 --- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/quickoutline/StringPatternFilter.java +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/quickoutline/StringPatternFilter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 IBM Corporation and others. + * Copyright (c) 2010, 2011 IBM Corporation 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 @@ -10,14 +10,13 @@ *******************************************************************************/ package org.eclipse.wst.sse.ui.internal.quickoutline; -import java.util.Vector; - import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.osgi.util.TextProcessor; +import org.eclipse.wst.sse.ui.internal.filter.StringMatcher; /** * Default Viewer Filter to be used by the {@link QuickOutlinePopupDialog} @@ -68,441 +67,4 @@ public class StringPatternFilter extends ViewerFilter { return fStringMatcher; } - /** - * String matcher based on {@link org.eclipse.ui.internal.misc.StringMatcher} - */ - static class StringMatcher { - protected String fPattern; - - protected int fLength; // pattern length - - protected boolean fIgnoreWildCards; - - protected boolean fIgnoreCase; - - protected boolean fHasLeadingStar; - - protected boolean fHasTrailingStar; - - protected String fSegments[]; //the given pattern is split into * separated segments - - /* boundary value beyond which we don't need to search in the text */ - protected int fBound = 0; - - protected static final char fSingleWildCard = '\u0000'; - - public static class Position { - int start; //inclusive - - int end; //exclusive - - public Position(int start, int end) { - this.start = start; - this.end = end; - } - - public int getStart() { - return start; - } - - public int getEnd() { - return end; - } - } - - /** - * StringMatcher constructor takes in a String object that is a simple - * pattern which may contain '*' for 0 and many characters and - * '?' for exactly one character. - * - * Literal '*' and '?' characters must be escaped in the pattern - * e.g., "\*" means literal "*", etc. - * - * Escaping any other character (including the escape character itself), - * just results in that character in the pattern. - * e.g., "\a" means "a" and "\\" means "\" - * - * If invoking the StringMatcher with string literals in Java, don't forget - * escape characters are represented by "\\". - * - * @param pattern the pattern to match text against - * @param ignoreCase if true, case is ignored - * @param ignoreWildCards if true, wild cards and their escape sequences are ignored - * (everything is taken literally). - */ - public StringMatcher(String pattern, boolean ignoreCase, - boolean ignoreWildCards) { - if (pattern == null) { - throw new IllegalArgumentException(); - } - fIgnoreCase = ignoreCase; - fIgnoreWildCards = ignoreWildCards; - fPattern = pattern; - fLength = pattern.length(); - - if (fIgnoreWildCards) { - parseNoWildCards(); - } else { - parseWildCards(); - } - } - - /** - * Find the first occurrence of the pattern between <code>start</code)(inclusive) - * and <code>end</code>(exclusive). - * @param text the String object to search in - * @param start the starting index of the search range, inclusive - * @param end the ending index of the search range, exclusive - * @return an <code>StringMatcher.Position</code> object that keeps the starting - * (inclusive) and ending positions (exclusive) of the first occurrence of the - * pattern in the specified range of the text; return null if not found or subtext - * is empty (start==end). A pair of zeros is returned if pattern is empty string - * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc" - * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned - */ - public StringMatcher.Position find(String text, int start, int end) { - if (text == null) { - throw new IllegalArgumentException(); - } - - int tlen = text.length(); - if (start < 0) { - start = 0; - } - if (end > tlen) { - end = tlen; - } - if (end < 0 || start >= end) { - return null; - } - if (fLength == 0) { - return new Position(start, start); - } - if (fIgnoreWildCards) { - int x = posIn(text, start, end); - if (x < 0) { - return null; - } - return new Position(x, x + fLength); - } - - int segCount = fSegments.length; - if (segCount == 0) { - return new Position(start, end); - } - - int curPos = start; - int matchStart = -1; - int i; - for (i = 0; i < segCount && curPos < end; ++i) { - String current = fSegments[i]; - int nextMatch = regExpPosIn(text, curPos, end, current); - if (nextMatch < 0) { - return null; - } - if (i == 0) { - matchStart = nextMatch; - } - curPos = nextMatch + current.length(); - } - if (i < segCount) { - return null; - } - return new Position(matchStart, curPos); - } - - /** - * match the given <code>text</code> with the pattern - * @return true if matched otherwise false - * @param text a String object - */ - public boolean match(String text) { - if(text == null) { - return false; - } - return match(text, 0, text.length()); - } - - /** - * Given the starting (inclusive) and the ending (exclusive) positions in the - * <code>text</code>, determine if the given substring matches with aPattern - * @return true if the specified portion of the text matches the pattern - * @param text a String object that contains the substring to match - * @param start marks the starting position (inclusive) of the substring - * @param end marks the ending index (exclusive) of the substring - */ - public boolean match(String text, int start, int end) { - if (null == text) { - throw new IllegalArgumentException(); - } - - if (start > end) { - return false; - } - - if (fIgnoreWildCards) { - return (end - start == fLength) - && fPattern.regionMatches(fIgnoreCase, 0, text, start, - fLength); - } - int segCount = fSegments.length; - if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) { - return true; - } - if (start == end) { - return fLength == 0; - } - if (fLength == 0) { - return start == end; - } - - int tlen = text.length(); - if (start < 0) { - start = 0; - } - if (end > tlen) { - end = tlen; - } - - int tCurPos = start; - int bound = end - fBound; - if (bound < 0) { - return false; - } - int i = 0; - String current = fSegments[i]; - int segLength = current.length(); - - /* process first segment */ - if (!fHasLeadingStar) { - if (!regExpRegionMatches(text, start, current, 0, segLength)) { - return false; - } else { - ++i; - tCurPos = tCurPos + segLength; - } - } - if ((fSegments.length == 1) && (!fHasLeadingStar) - && (!fHasTrailingStar)) { - // only one segment to match, no wildcards specified - return tCurPos == end; - } - /* process middle segments */ - while (i < segCount) { - current = fSegments[i]; - int currentMatch; - int k = current.indexOf(fSingleWildCard); - if (k < 0) { - currentMatch = textPosIn(text, tCurPos, end, current); - if (currentMatch < 0) { - return false; - } - } else { - currentMatch = regExpPosIn(text, tCurPos, end, current); - if (currentMatch < 0) { - return false; - } - } - tCurPos = currentMatch + current.length(); - i++; - } - - /* process final segment */ - if (!fHasTrailingStar && tCurPos != end) { - int clen = current.length(); - return regExpRegionMatches(text, end - clen, current, 0, clen); - } - return i == segCount; - } - - /** - * This method parses the given pattern into segments seperated by wildcard '*' characters. - * Since wildcards are not being used in this case, the pattern consists of a single segment. - */ - private void parseNoWildCards() { - fSegments = new String[1]; - fSegments[0] = fPattern; - fBound = fLength; - } - - /** - * Parses the given pattern into segments seperated by wildcard '*' characters. - * @param p, a String object that is a simple regular expression with '*' and/or '?' - */ - private void parseWildCards() { - if (fPattern.startsWith("*")) { //$NON-NLS-1$ - fHasLeadingStar = true; - } - if (fPattern.endsWith("*")) {//$NON-NLS-1$ - /* make sure it's not an escaped wildcard */ - if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') { - fHasTrailingStar = true; - } - } - - Vector temp = new Vector(); - - int pos = 0; - StringBuffer buf = new StringBuffer(); - while (pos < fLength) { - char c = fPattern.charAt(pos++); - switch (c) { - case '\\': - if (pos >= fLength) { - buf.append(c); - } else { - char next = fPattern.charAt(pos++); - /* if it's an escape sequence */ - if (next == '*' || next == '?' || next == '\\') { - buf.append(next); - } else { - /* not an escape sequence, just insert literally */ - buf.append(c); - buf.append(next); - } - } - break; - case '*': - if (buf.length() > 0) { - /* new segment */ - temp.addElement(buf.toString()); - fBound += buf.length(); - buf.setLength(0); - } - break; - case '?': - /* append special character representing single match wildcard */ - buf.append(fSingleWildCard); - break; - default: - buf.append(c); - } - } - - /* add last buffer to segment list */ - if (buf.length() > 0) { - temp.addElement(buf.toString()); - fBound += buf.length(); - } - - fSegments = new String[temp.size()]; - temp.copyInto(fSegments); - } - - /** - * @param text a string which contains no wildcard - * @param start the starting index in the text for search, inclusive - * @param end the stopping point of search, exclusive - * @return the starting index in the text of the pattern , or -1 if not found - */ - protected int posIn(String text, int start, int end) {//no wild card in pattern - int max = end - fLength; - - if (!fIgnoreCase) { - int i = text.indexOf(fPattern, start); - if (i == -1 || i > max) { - return -1; - } - return i; - } - - for (int i = start; i <= max; ++i) { - if (text.regionMatches(true, i, fPattern, 0, fLength)) { - return i; - } - } - - return -1; - } - - /** - * @param text a simple regular expression that may only contain '?'(s) - * @param start the starting index in the text for search, inclusive - * @param end the stopping point of search, exclusive - * @param p a simple regular expression that may contains '?' - * @return the starting index in the text of the pattern , or -1 if not found - */ - protected int regExpPosIn(String text, int start, int end, String p) { - int plen = p.length(); - - int max = end - plen; - for (int i = start; i <= max; ++i) { - if (regExpRegionMatches(text, i, p, 0, plen)) { - return i; - } - } - return -1; - } - - /** - * - * @return boolean - * @param text a String to match - * @param start int that indicates the starting index of match, inclusive - * @param end</code> int that indicates the ending index of match, exclusive - * @param p String, String, a simple regular expression that may contain '?' - * @param ignoreCase boolean indicating wether code>p</code> is case sensitive - */ - protected boolean regExpRegionMatches(String text, int tStart, String p, - int pStart, int plen) { - while (plen-- > 0) { - char tchar = text.charAt(tStart++); - char pchar = p.charAt(pStart++); - - /* process wild cards */ - if (!fIgnoreWildCards) { - /* skip single wild cards */ - if (pchar == fSingleWildCard) { - continue; - } - } - if (pchar == tchar) { - continue; - } - if (fIgnoreCase) { - if (Character.toUpperCase(tchar) == Character - .toUpperCase(pchar)) { - continue; - } - // comparing after converting to upper case doesn't handle all cases; - // also compare after converting to lower case - if (Character.toLowerCase(tchar) == Character - .toLowerCase(pchar)) { - continue; - } - } - return false; - } - return true; - } - - /** - * @param text the string to match - * @param start the starting index in the text for search, inclusive - * @param end the stopping point of search, exclusive - * @param p a pattern string that has no wildcard - * @return the starting index in the text of the pattern , or -1 if not found - */ - protected int textPosIn(String text, int start, int end, String p) { - - int plen = p.length(); - int max = end - plen; - - if (!fIgnoreCase) { - int i = text.indexOf(p, start); - if (i == -1 || i > max) { - return -1; - } - return i; - } - - for (int i = start; i <= max; ++i) { - if (text.regionMatches(true, i, p, 0, plen)) { - return i; - } - } - - return -1; - } - } } diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/util/SWTUtil.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/util/SWTUtil.java index c58494e480..aeb7dd77c3 100644 --- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/util/SWTUtil.java +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/util/SWTUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 IBM Corporation and others. + * Copyright (c) 2010, 2011 IBM Corporation 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 @@ -15,8 +15,22 @@ import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.layout.PixelConverter; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.swt.SWT; +import org.eclipse.swt.accessibility.AccessibleAdapter; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.dnd.DragSource; +import org.eclipse.swt.dnd.DropTarget; import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Caret; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Widget; /** @@ -26,6 +40,48 @@ import org.eclipse.swt.widgets.Button; */ public class SWTUtil { + + public static final int COMBO_VISIBLE_ITEM_COUNT= 30; + + /** + * Returns the standard display to be used. The method first checks, if + * the thread calling this method has an associated display. If so, this + * display is returned. Otherwise the method returns the default display. + * @return returns the standard display to be used + */ + public static Display getStandardDisplay() { + Display display; + display= Display.getCurrent(); + if (display == null) + display= Display.getDefault(); + return display; + } + + /** + * Returns the shell for the given widget. If the widget doesn't represent + * a SWT object that manage a shell, <code>null</code> is returned. + * @param widget the widget + * + * @return the shell for the given widget + */ + public static Shell getShell(Widget widget) { + if (widget instanceof Control) + return ((Control)widget).getShell(); + if (widget instanceof Caret) + return ((Caret)widget).getParent().getShell(); + if (widget instanceof DragSource) + return ((DragSource)widget).getControl().getShell(); + if (widget instanceof DropTarget) + return ((DropTarget)widget).getControl().getShell(); + if (widget instanceof Menu) + return ((Menu)widget).getParent().getShell(); + if (widget instanceof ScrollBar) + return ((ScrollBar)widget).getParent().getShell(); + + return null; + } + + /** * Returns a width hint for a button control. * @param button the button @@ -53,4 +109,48 @@ public class SWTUtil { ((GridData)gd).horizontalAlignment = GridData.FILL; } } + + public static int getTableHeightHint(Table table, int rows) { + if (table.getFont().equals(JFaceResources.getDefaultFont())) + table.setFont(JFaceResources.getDialogFont()); + int result= table.getItemHeight() * rows + table.getHeaderHeight(); + if (table.getLinesVisible()) + result+= table.getGridLineWidth() * (rows - 1); + return result; + } + + /** + * Adds an accessibility listener returning the given fixed name. + * + * @param control the control to add the accessibility support to + * @param text the name + */ + public static void setAccessibilityText(Control control, final String text) { + control.getAccessible().addAccessibleListener(new AccessibleAdapter() { + public void getName(AccessibleEvent e) { + e.result= text; + } + }); + } + + /** + * + * @param combo the combo + * + * @see Combo#setVisibleItemCount(int) + * @see #COMBO_VISIBLE_ITEM_COUNT + * + */ + public static void setDefaultVisibleItemCount(Combo combo) { + combo.setVisibleItemCount(COMBO_VISIBLE_ITEM_COUNT); + } + + public static GridLayout newLayoutNoMargins(int columns) { + GridLayout layout= new GridLayout(columns, false); + layout.marginWidth= 0; + layout.marginHeight= 0; + return layout; + } + + } diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/contentoutline/ContentOutlineConfiguration.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/contentoutline/ContentOutlineConfiguration.java index 428fd8e099..6b461113a2 100644 --- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/contentoutline/ContentOutlineConfiguration.java +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/contentoutline/ContentOutlineConfiguration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2001, 2010 IBM Corporation and others. + * Copyright (c) 2001, 2011 IBM Corporation 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 @@ -39,6 +39,7 @@ import org.eclipse.wst.sse.ui.internal.editor.EditorPluginImages; * @since 1.0 */ public abstract class ContentOutlineConfiguration { + /** * Add a collapse action to help with navigation. */ @@ -86,6 +87,7 @@ public abstract class ContentOutlineConfiguration { private IContributionItem[] fMenuContributions = null; private IContributionItem[] fToolbarContributions = null; private final String OUTLINE_LINK_PREF = "outline-link-editor"; //$NON-NLS-1$ + private static final String OUTLINE_FILTER_PREF = "org.eclipse.wst.sse.ui.OutlinePage"; //$NON-NLS-1$ ImageDescriptor SYNCED_D = EditorPluginImageHelper.getInstance().getImageDescriptor(EditorPluginImages.IMG_DLCL_SYNCED); ImageDescriptor SYNCED_E = EditorPluginImageHelper.getInstance().getImageDescriptor(EditorPluginImages.IMG_ELCL_SYNCED); @@ -313,4 +315,24 @@ public abstract class ContentOutlineConfiguration { fMenuContributions = null; } } + + /** + * Provides the target used when associating filters to the outline + * + * @return The target id used when associating filters to the outline + */ + protected String getOutlineFilterTarget() { + return OUTLINE_FILTER_PREF ; + } + + /** + * Returns the content outline filter processor for this configuration + * + * @param viewer the {@link TreeViewer} that is associated with the filter + * + * @return A {@link ContentOutlineFilterProcessor} to filter nodes in the outline + */ + public ContentOutlineFilterProcessor getOutlineFilterProcessor(TreeViewer viewer){ + return new ContentOutlineFilterProcessor(getPreferenceStore(), getOutlineFilterTarget(), viewer); + } } diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/contentoutline/ContentOutlineFilterProcessor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/contentoutline/ContentOutlineFilterProcessor.java new file mode 100644 index 0000000000..b1b61e3e33 --- /dev/null +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/views/contentoutline/ContentOutlineFilterProcessor.java @@ -0,0 +1,318 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.sse.ui.views.contentoutline; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.jface.window.Window; +import org.eclipse.wst.sse.ui.internal.filter.OutlineCustomFiltersDialog; +import org.eclipse.wst.sse.ui.internal.filter.OutlineFilterDescriptor; +import org.eclipse.wst.sse.ui.internal.filter.OutlineNamePatternFilter; + +/** + * Action group to add the filter action to a view part's tool bar menu. + * <p> + * This class may be instantiated; it is not intended to be subclassed. + * </p> + * + * @noextend This class is not intended to be subclassed by clients. + */ +public class ContentOutlineFilterProcessor { + + private static final String SEPARATOR = ","; //$NON-NLS-1$ + private final String TAG_USER_DEFINED_PATTERNS_ENABLED = "userDefinedPatternsEnabled"; //$NON-NLS-1$ + private final String TAG_USER_DEFINED_PATTERNS = "userDefinedPatterns"; //$NON-NLS-1$ + + private static class FilterItem { + boolean enabled; + boolean previouslyEnabled; + OutlineFilterDescriptor descriptor; + String id; + + private ViewerFilter filterInstance = null; + + public FilterItem(OutlineFilterDescriptor descriptor) { + this.descriptor = descriptor; + this.id = descriptor.getId(); + this.previouslyEnabled = false; + this.enabled = descriptor.isEnabled(); + } + + public ViewerFilter getFilterInstance() { + if (filterInstance == null) { + filterInstance = descriptor.createViewerFilter(); + } + return filterInstance; + + } + } + + private final StructuredViewer fViewer; + private final OutlineNamePatternFilter fPatternFilter; + + private boolean fUserDefinedPatternsEnabled; + private String[] fUserDefinedPatterns; + + private String[] fPreviousPatterns; + + private final Map fFilterItems; + + private final String fTargetId; + private IPreferenceStore fStore; + + /** + * Creates a new <code>CustomFilterAction</code>. + * + * @param store + * the preference Store + * @param ownerId + * the id of this action group's owner + * @param viewer + * the viewer to be filtered + */ + public ContentOutlineFilterProcessor(IPreferenceStore store, String ownerId, StructuredViewer viewer) { + Assert.isNotNull(ownerId); + Assert.isNotNull(viewer); + fStore = store; + fTargetId = ownerId; + fViewer = viewer; + fPatternFilter = new OutlineNamePatternFilter(); + + fUserDefinedPatterns = new String[0]; + fUserDefinedPatternsEnabled = false; + fPreviousPatterns = new String[0]; + + fFilterItems = new HashMap(); + OutlineFilterDescriptor[] filterDescriptors = OutlineFilterDescriptor.getFilterDescriptors(fTargetId); + for (int i = 0; i < filterDescriptors.length; i++) { + FilterItem item = new FilterItem(filterDescriptors[i]); + fFilterItems.put(item.id, item); + + } + + initializeWithViewDefaults(); + + updateViewerFilters(); + + } + + /* + * @see org.eclipse.jface.action.IContributionItem#isDynamic() + */ + public boolean isDynamic() { + return true; + } + + /** + * Returns a list of currently enabled filters. The filter is identified by + * its id. + * <p> + * This method is for internal use only and should not be called by clients + * outside of JDT/UI. + * </p> + * + * @return a list of currently enabled filters + * + * @noreference This method is not intended to be referenced by clients. + */ + public String[] internalGetEnabledFilterIds() { + ArrayList enabledFilterIds = new ArrayList(); + for (Iterator iterator = fFilterItems.values().iterator(); iterator.hasNext();) { + FilterItem item = (FilterItem) iterator.next(); + if (item.enabled) { + enabledFilterIds.add(item.id); + } + } + return (String[]) enabledFilterIds.toArray(new String[enabledFilterIds.size()]); + } + + private void setEnabledFilterIds(String[] enabledIds) { + // set all to false + fUserDefinedPatternsEnabled = false; + for (Iterator iterator = fFilterItems.values().iterator(); iterator.hasNext();) { + FilterItem item = (FilterItem) iterator.next(); + item.enabled = false; + } + // set enabled to true + for (int i = 0; i < enabledIds.length; i++) { + FilterItem item = (FilterItem) fFilterItems.get(enabledIds[i]); + if (item != null) { + item.enabled = true; + } + if (fPatternFilter.getClass().getName().equals(enabledIds[i])) + fUserDefinedPatternsEnabled = true; + } + } + + private void setUserDefinedPatterns(String[] patterns) { + fUserDefinedPatterns = patterns; + } + + private boolean areUserDefinedPatternsEnabled() { + return fUserDefinedPatternsEnabled; + } + + private void setUserDefinedPatternsEnabled(boolean state) { + fUserDefinedPatternsEnabled = state; + } + + // ---------- viewer filter handling ---------- + + private boolean updateViewerFilters() { + ViewerFilter[] installedFilters = fViewer.getFilters(); + ArrayList viewerFilters = new ArrayList(installedFilters.length); + + HashSet patterns = new HashSet(); + + boolean hasChange = false; + boolean patternChange = false; + + for (Iterator iterator = fFilterItems.values().iterator(); iterator.hasNext();) { + FilterItem item = (FilterItem) iterator.next(); + if (item.descriptor.isCustomFilter()) { + if (item.enabled != item.previouslyEnabled) { + hasChange = true; + } + if (item.enabled) { + ViewerFilter filter = item.getFilterInstance(); // only + // create + // when + // changed + if (filter != null) { + viewerFilters.add(filter); + } + } + } else if (item.descriptor.isPatternFilter()) { + if (item.enabled) { + patterns.add(item.descriptor.getPattern()); + } + patternChange |= (item.enabled != item.previouslyEnabled); + } + item.previouslyEnabled = item.enabled; + } + + if (areUserDefinedPatternsEnabled()) { + for (int i = 0; i < fUserDefinedPatterns.length; i++) { + patterns.add(fUserDefinedPatterns[i]); + } + } + if (!patternChange) { // no pattern change so far, test if the user + // patterns made a difference + patternChange = hasChanges(patterns, fPreviousPatterns); + } + + fPreviousPatterns = (String[]) patterns.toArray(new String[patterns.size()]); + if (patternChange || hasChange) { + fPatternFilter.setPatterns(fPreviousPatterns); + if (patterns.isEmpty()) { + viewerFilters.remove(fPatternFilter); + } else if (!viewerFilters.contains(fPatternFilter)) { + boolean contains = false; + for (int i = 0; i < viewerFilters.size(); i++) { + if (viewerFilters.get(i) instanceof OutlineNamePatternFilter) { + OutlineNamePatternFilter filter = (OutlineNamePatternFilter) viewerFilters.get(i); + String[] a1 = filter.getPatterns(); + String[] a2 = fPatternFilter.getPatterns(); + if (a1[0].equals(a2[0])) + contains = true; + else { + viewerFilters.remove(i); + } + break; + } + } + if (!contains) + viewerFilters.add(fPatternFilter); + } + hasChange = true; + } + if (hasChange) { + fViewer.setFilters((ViewerFilter[]) viewerFilters.toArray(new ViewerFilter[viewerFilters.size()])); // will + // refresh + } + return hasChange; + } + + private boolean hasChanges(HashSet patterns, String[] oldPatterns) { + HashSet copy = (HashSet) patterns.clone(); + for (int i = 0; i < oldPatterns.length; i++) { + boolean found = copy.remove(oldPatterns[i]); + if (!found) + return true; + } + return !copy.isEmpty(); + } + + // ---------- view kind/defaults persistency ---------- + + private void initializeWithViewDefaults() { + // get default values for view + + fUserDefinedPatternsEnabled = fStore.getBoolean(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED)); + setUserDefinedPatterns(OutlineCustomFiltersDialog.convertFromString(fStore.getString(getPreferenceKey(TAG_USER_DEFINED_PATTERNS)), SEPARATOR)); + + for (Iterator iterator = fFilterItems.values().iterator(); iterator.hasNext();) { + FilterItem item = (FilterItem) iterator.next(); + String id = item.id; + // set default to value from plugin contributions (fixes + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=73991 ): + fStore.setDefault(id, item.descriptor.isEnabled()); + item.enabled = fStore.getBoolean(id); + } + + } + + private void storeViewDefaults() { + // get default values for view + + fStore.setValue(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED), fUserDefinedPatternsEnabled); + fStore.setValue(getPreferenceKey(TAG_USER_DEFINED_PATTERNS), OutlineCustomFiltersDialog.convertToString(fUserDefinedPatterns, SEPARATOR)); + + boolean fFilterSelected = false; + for (Iterator iterator = fFilterItems.values().iterator(); iterator.hasNext();) { + FilterItem item = (FilterItem) iterator.next(); + fStore.setValue(item.id, item.enabled); + if (item.enabled) + fFilterSelected = true; + } + + fStore.setValue(fTargetId, fUserDefinedPatternsEnabled || fFilterSelected); + + } + + private String getPreferenceKey(String tag) { + return "CustomFiltersActionGroup." + fTargetId + '.' + tag; //$NON-NLS-1$ + } + + public void openDialog() { + OutlineCustomFiltersDialog dialog = new OutlineCustomFiltersDialog(fViewer.getControl().getShell(), fTargetId, areUserDefinedPatternsEnabled(), fUserDefinedPatterns, internalGetEnabledFilterIds()); + + if (dialog.open() == Window.OK) { + + setEnabledFilterIds(dialog.getEnabledFilterIds()); + setUserDefinedPatternsEnabled(dialog.areUserDefinedPatternsEnabled()); + setUserDefinedPatterns(dialog.getUserDefinedPatterns()); + storeViewDefaults(); + + updateViewerFilters(); + } else { + storeViewDefaults(); + } + } +} diff --git a/bundles/org.eclipse.wst.xml.ui/plugin.properties b/bundles/org.eclipse.wst.xml.ui/plugin.properties index c2484f105b..b8c51a8131 100644 --- a/bundles/org.eclipse.wst.xml.ui/plugin.properties +++ b/bundles/org.eclipse.wst.xml.ui/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2001, 2010 IBM Corporation and others. +# Copyright (c) 2001, 2011 IBM Corporation 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 @@ -148,3 +148,11 @@ contentModel.command.synch.name=Synch # XML Documentation view xmlannotations=Documentation + +# outline filter +HideComments.label=Comments +HideComments.description=Hides Comments +HideProcessingInstruction.label=Processing Instructions +HideProcessingInstruction.description=Hides Processing Instructions +HideCDATASection.label=CDATA +HideCDATASection.description=Hides CDATA Section Tags
\ No newline at end of file diff --git a/bundles/org.eclipse.wst.xml.ui/plugin.xml b/bundles/org.eclipse.wst.xml.ui/plugin.xml index 603800da04..1e6e62d949 100644 --- a/bundles/org.eclipse.wst.xml.ui/plugin.xml +++ b/bundles/org.eclipse.wst.xml.ui/plugin.xml @@ -1719,4 +1719,31 @@ </state> </command> </extension> + <extension + point="org.eclipse.wst.sse.ui.outlineFilters"> + <filter + targetId="org.eclipse.wst.xml.ui.OutlinePage" + name="%HideComments.label" + enabled="false" + description="%HideComments.description" + class="org.eclipse.wst.xml.ui.views.contentoutline.XMLCommentFilter" + id="org.eclipse.wst.xml.ui.views.contentoutline.XMLCommentFilter"> + </filter> + <filter + targetId="org.eclipse.wst.xml.ui.OutlinePage" + name="%HideProcessingInstruction.label" + enabled="false" + description="%HideProcessingInstruction.description" + class="org.eclipse.wst.xml.ui.views.contentoutline.XMLProcessingInstructionFilter" + id="org.eclipse.wst.xml.ui.views.contentoutline.XMLProcessingInstructionFilter"> + </filter> + <filter + targetId="org.eclipse.wst.xml.ui.OutlinePage" + name="%HideCDATASection.label" + enabled="false" + description="%HideCDATASection.description" + class="org.eclipse.wst.xml.ui.views.contentoutline.XMLCDATASectionFilter" + id="org.eclipse.wst.xml.ui.views.contentoutline.XMLCDATASectionFilter"> + </filter> +</extension> </plugin> diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLCDATASectionFilter.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLCDATASectionFilter.java new file mode 100644 index 0000000000..d41706a5bb --- /dev/null +++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLCDATASectionFilter.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + * + *******************************************************************************/ +package org.eclipse.wst.xml.ui.views.contentoutline; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.w3c.dom.CDATASection; + +public class XMLCDATASectionFilter extends ViewerFilter { + + public boolean select(Viewer viewer, Object parent, Object element) { + return !(element instanceof CDATASection); + } + +}
\ No newline at end of file diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLCommentFilter.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLCommentFilter.java new file mode 100644 index 0000000000..a747c90147 --- /dev/null +++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLCommentFilter.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.xml.ui.views.contentoutline; + + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.w3c.dom.Comment; + + +/** + * Filters package declarations + */ +public class XMLCommentFilter extends ViewerFilter { + + /* + * @see ViewerFilter + */ + public boolean select(Viewer viewer, Object parent, Object element) { + return !(element instanceof Comment); + } +} diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLContentOutlineConfiguration.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLContentOutlineConfiguration.java index caecf23ca5..015c8c41c4 100644 --- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLContentOutlineConfiguration.java +++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLContentOutlineConfiguration.java @@ -266,7 +266,8 @@ public class XMLContentOutlineConfiguration extends AbstractXMLContentOutlineCon * Preference key for Show Attributes */ private final String OUTLINE_SHOW_ATTRIBUTE_PREF = "outline-show-attribute"; //$NON-NLS-1$ - + private static final String OUTLINE_FILTER_PREF = "org.eclipse.wst.xml.ui.OutlinePage"; //$NON-NLS-1$ + /** * Create new instance of XMLContentOutlineConfiguration */ @@ -408,4 +409,8 @@ public class XMLContentOutlineConfiguration extends AbstractXMLContentOutlineCon } return filteredSelection; } + + protected String getOutlineFilterTarget(){ + return OUTLINE_FILTER_PREF ; + } } diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLProcessingInstructionFilter.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLProcessingInstructionFilter.java new file mode 100644 index 0000000000..59b74e9b14 --- /dev/null +++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/views/contentoutline/XMLProcessingInstructionFilter.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.xml.ui.views.contentoutline; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.w3c.dom.ProcessingInstruction; + +public class XMLProcessingInstructionFilter extends ViewerFilter { + + public boolean select(Viewer viewer, Object parent, Object element) { + return !(element instanceof ProcessingInstruction); + } + +}
\ No newline at end of file |