View | Details | Raw Unified | Return to bug 360894 | Differences between
and this patch

Collapse All | Expand All

(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEPluginImages.java (+7 lines)
Added Link Here
153
	public static final ImageDescriptor DESC_INFO_ST_OBJ = create(PATH_OBJ, "info_st_obj.gif"); //$NON-NLS-1$
153
	public static final ImageDescriptor DESC_INFO_ST_OBJ = create(PATH_OBJ, "info_st_obj.gif"); //$NON-NLS-1$
154
	public static final ImageDescriptor DESC_CATEGORY_OBJ = create(PATH_OBJ, "category_obj.gif"); //$NON-NLS-1$
154
	public static final ImageDescriptor DESC_CATEGORY_OBJ = create(PATH_OBJ, "category_obj.gif"); //$NON-NLS-1$
155
	public static final ImageDescriptor DESC_PSEARCH_OBJ = create(PATH_OBJ, "psearch_obj.gif"); //$NON-NLS-1$
155
	public static final ImageDescriptor DESC_PSEARCH_OBJ = create(PATH_OBJ, "psearch_obj.gif"); //$NON-NLS-1$
156
	public static final ImageDescriptor DESC_ESEARCH_OBJ = create(PATH_OBJ, "esearch_obj.gif"); //$NON-NLS-1$
156
	public static final ImageDescriptor DESC_SITE_OBJ = create(PATH_OBJ, "site_obj.gif"); //$NON-NLS-1$
157
	public static final ImageDescriptor DESC_SITE_OBJ = create(PATH_OBJ, "site_obj.gif"); //$NON-NLS-1$
157
	public static final ImageDescriptor DESC_JUNIT_MAIN_TAB = create(PATH_OBJ, "test.gif"); //$NON-NLS-1$
158
	public static final ImageDescriptor DESC_JUNIT_MAIN_TAB = create(PATH_OBJ, "test.gif"); //$NON-NLS-1$
158
	public static final ImageDescriptor DESC_OUTPUT_FOLDER_OBJ = create(PATH_OBJ, "output_folder_attrib.gif"); //$NON-NLS-1$
159
	public static final ImageDescriptor DESC_OUTPUT_FOLDER_OBJ = create(PATH_OBJ, "output_folder_attrib.gif"); //$NON-NLS-1$
Added Link Here
232
	public static final ImageDescriptor DESC_VERTICAL = create(PATH_LCL, "th_vertical.gif"); //$NON-NLS-1$
233
	public static final ImageDescriptor DESC_VERTICAL = create(PATH_LCL, "th_vertical.gif"); //$NON-NLS-1$
233
	public static final ImageDescriptor DESC_COLLAPSE_ALL = create(PATH_LCL, "collapseall.gif"); //$NON-NLS-1$
234
	public static final ImageDescriptor DESC_COLLAPSE_ALL = create(PATH_LCL, "collapseall.gif"); //$NON-NLS-1$
234
	public static final ImageDescriptor DESC_COLLAPSE_ALL_MINI = create(PATH_LCL, "collapse_all_mini.gif"); //$NON-NLS-1$
235
	public static final ImageDescriptor DESC_COLLAPSE_ALL_MINI = create(PATH_LCL, "collapse_all_mini.gif"); //$NON-NLS-1$
236
	public static final ImageDescriptor DESC_TOGGLE_EXPAND_STATE = create(PATH_LCL, "toggle_expand_state.gif"); //$NON-NLS-1$
235
	public static final ImageDescriptor DESC_HELP = create(PATH_LCL, "help.gif"); //$NON-NLS-1$
237
	public static final ImageDescriptor DESC_HELP = create(PATH_LCL, "help.gif"); //$NON-NLS-1$
236
	public static final ImageDescriptor DESC_LINK_WITH_EDITOR = create(PATH_LCL, "synced.gif"); //$NON-NLS-1$
238
	public static final ImageDescriptor DESC_LINK_WITH_EDITOR = create(PATH_LCL, "synced.gif"); //$NON-NLS-1$
237
	public static final ImageDescriptor DESC_CALLEES = create(PATH_LCL, "ch_callees.gif"); //$NON-NLS-1$
239
	public static final ImageDescriptor DESC_CALLEES = create(PATH_LCL, "ch_callees.gif"); //$NON-NLS-1$
Added Link Here
242
	public static final ImageDescriptor DESC_HISTORY_LIST = create(PATH_LCL, "history_list.gif"); //$NON-NLS-1$
244
	public static final ImageDescriptor DESC_HISTORY_LIST = create(PATH_LCL, "history_list.gif"); //$NON-NLS-1$
243
	public static final ImageDescriptor DESC_CLEAR = create(PATH_LCL, "clear.gif"); //$NON-NLS-1$
245
	public static final ImageDescriptor DESC_CLEAR = create(PATH_LCL, "clear.gif"); //$NON-NLS-1$
244
	public static final ImageDescriptor DESC_FILTER = create(PATH_LCL, "filter_ps.gif"); //$NON-NLS-1$
246
	public static final ImageDescriptor DESC_FILTER = create(PATH_LCL, "filter_ps.gif"); //$NON-NLS-1$
247
	public static final ImageDescriptor DESC_FILTER_RELATED = create(PATH_LCL, "filter_related.gif"); //$NON-NLS-1$
248
	public static final ImageDescriptor DESC_SEARCH_EXTENSIONS = create(PATH_LCL, "search_extensions.gif"); //$NON-NLS-1$
245
249
246
	public static final ImageDescriptor DESC_ADD_ATT_DISABLED = create(PATH_LCL_DISABLED, "add_att.gif"); //$NON-NLS-1$
250
	public static final ImageDescriptor DESC_ADD_ATT_DISABLED = create(PATH_LCL_DISABLED, "add_att.gif"); //$NON-NLS-1$
247
	public static final ImageDescriptor DESC_ALPHAB_SORT_CO_DISABLED = create(PATH_LCL_DISABLED, "alphab_sort_co.gif"); //$NON-NLS-1$
251
	public static final ImageDescriptor DESC_ALPHAB_SORT_CO_DISABLED = create(PATH_LCL_DISABLED, "alphab_sort_co.gif"); //$NON-NLS-1$
Added Link Here
255
	public static final ImageDescriptor DESC_HORIZONTAL_DISABLED = create(PATH_LCL_DISABLED, "th_horizontal.gif"); //$NON-NLS-1$
259
	public static final ImageDescriptor DESC_HORIZONTAL_DISABLED = create(PATH_LCL_DISABLED, "th_horizontal.gif"); //$NON-NLS-1$
256
	public static final ImageDescriptor DESC_VERTICAL_DISABLED = create(PATH_LCL_DISABLED, "th_vertical.gif"); //$NON-NLS-1$
260
	public static final ImageDescriptor DESC_VERTICAL_DISABLED = create(PATH_LCL_DISABLED, "th_vertical.gif"); //$NON-NLS-1$
257
	public static final ImageDescriptor DESC_COLLAPSE_ALL_DISABLED = create(PATH_LCL_DISABLED, "collapseall.gif"); //$NON-NLS-1$
261
	public static final ImageDescriptor DESC_COLLAPSE_ALL_DISABLED = create(PATH_LCL_DISABLED, "collapseall.gif"); //$NON-NLS-1$
262
	public static final ImageDescriptor DESC_TOGGLE_EXPAND_STATE_DISABLED = create(PATH_LCL_DISABLED, "toggle_expand_state.gif"); //$NON-NLS-1$	
258
	public static final ImageDescriptor DESC_LINK_WITH_EDITOR_DISABLED = create(PATH_LCL_DISABLED, "synced.gif"); //$NON-NLS-1$
263
	public static final ImageDescriptor DESC_LINK_WITH_EDITOR_DISABLED = create(PATH_LCL_DISABLED, "synced.gif"); //$NON-NLS-1$
259
	public static final ImageDescriptor DESC_CALLEES_DISABLED = create(PATH_LCL_DISABLED, "ch_callees.gif"); //$NON-NLS-1$
264
	public static final ImageDescriptor DESC_CALLEES_DISABLED = create(PATH_LCL_DISABLED, "ch_callees.gif"); //$NON-NLS-1$
260
	public static final ImageDescriptor DESC_CALLERS_DISABLED = create(PATH_LCL_DISABLED, "ch_callers.gif"); //$NON-NLS-1$
265
	public static final ImageDescriptor DESC_CALLERS_DISABLED = create(PATH_LCL_DISABLED, "ch_callers.gif"); //$NON-NLS-1$
Added Link Here
264
	public static final ImageDescriptor DESC_HISTORY_LIST_DISABLED = create(PATH_LCL_DISABLED, "history_list.gif"); //$NON-NLS-1$
269
	public static final ImageDescriptor DESC_HISTORY_LIST_DISABLED = create(PATH_LCL_DISABLED, "history_list.gif"); //$NON-NLS-1$
265
	public static final ImageDescriptor DESC_DCLEAR = create(PATH_LCL_DISABLED, "clear.gif"); //$NON-NLS-1$
270
	public static final ImageDescriptor DESC_DCLEAR = create(PATH_LCL_DISABLED, "clear.gif"); //$NON-NLS-1$
266
	public static final ImageDescriptor DESC_FILTER_DISABLED = create(PATH_LCL_DISABLED, "filter_ps.gif"); //$NON-NLS-1$
271
	public static final ImageDescriptor DESC_FILTER_DISABLED = create(PATH_LCL_DISABLED, "filter_ps.gif"); //$NON-NLS-1$
272
	public static final ImageDescriptor DESC_FILTER_RELATED_DISABLED = create(PATH_LCL_DISABLED, "filter_related.gif"); //$NON-NLS-1$
273
	public static final ImageDescriptor DESC_SEARCH_EXTENSIONS_DISABLED = create(PATH_LCL_DISABLED, "search_extensions.gif"); //$NON-NLS-1$
267
274
268
	public static final ImageDescriptor DESC_RUN_EXC = create(PATH_OBJ, "run_exc.gif"); //$NON-NLS-1$
275
	public static final ImageDescriptor DESC_RUN_EXC = create(PATH_OBJ, "run_exc.gif"); //$NON-NLS-1$
269
	public static final ImageDescriptor DESC_DEBUG_EXC = create(PATH_OBJ, "debug_exc.gif"); //$NON-NLS-1$
276
	public static final ImageDescriptor DESC_DEBUG_EXC = create(PATH_OBJ, "debug_exc.gif"); //$NON-NLS-1$
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java (+6 lines)
Lines 54-59 Link Here
54
54
55
	public static String DependencyPropertiesDialog_exportGroupText;
55
	public static String DependencyPropertiesDialog_exportGroupText;
56
56
57
	public static String ExtensionsPage_toggleExpandState;
58
59
	public static String ExtensionsPage_searchWithExtensionsFilter;
60
57
	public static String ExternalizeStringsOperation_editNames_addComment;
61
	public static String ExternalizeStringsOperation_editNames_addComment;
58
62
59
	public static String ExternalizeStringsOperation_editNames_insertProperty;
63
	public static String ExternalizeStringsOperation_editNames_insertProperty;
Lines 1425-1430 Link Here
1425
	public static String EditorActions_revert;
1429
	public static String EditorActions_revert;
1426
	public static String Actions_open_label;
1430
	public static String Actions_open_label;
1427
	public static String Actions_delete_label;
1431
	public static String Actions_delete_label;
1432
	public static String Actions_filter_relatedPluginElements;
1433
	public static String Actions_search_relatedPluginElements;
1428
	public static String Actions_synchronizeVersions_label;
1434
	public static String Actions_synchronizeVersions_label;
1429
1435
1430
	public static String Menus_new_label;
1436
	public static String Menus_new_label;
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/actions/FilterRelatedExtensionsAction.java (+135 lines)
Added Link Here
1
/*******************************************************************************
2
 *  Copyright (c) 2011, 2012 IBM Corporation and others.
3
 *  All rights reserved. This program and the accompanying materials
4
 *  are made available under the terms of the Eclipse Public License v1.0
5
 *  which accompanies this distribution, and is available at
6
 *  http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 *  Contributors:
9
 *     Sascha Becher <s.becher@qualitype.de> - bug 360894
10
 *******************************************************************************/
11
package org.eclipse.pde.internal.ui.editor.actions;
12
13
import java.util.*;
14
import org.eclipse.jface.action.Action;
15
import org.eclipse.jface.viewers.IStructuredSelection;
16
import org.eclipse.jface.viewers.TreeViewer;
17
import org.eclipse.pde.core.plugin.IPluginAttribute;
18
import org.eclipse.pde.core.plugin.IPluginElement;
19
import org.eclipse.pde.internal.ui.PDEPluginImages;
20
import org.eclipse.pde.internal.ui.PDEUIMessages;
21
import org.eclipse.pde.internal.ui.editor.plugin.FormFilteredTree;
22
import org.eclipse.pde.internal.ui.search.ExtensionsPatternFilter;
23
import org.eclipse.swt.widgets.Text;
24
import org.eclipse.ui.PlatformUI;
25
import org.eclipse.ui.actions.ActionFactory;
26
import org.eclipse.ui.keys.IBindingService;
27
28
/**
29
 * Serves as Filter Related Action in context menu of the extensions tree and toolbar icon on the same page 
30
 * 
31
 * @author Sascha Becher
32
 */
33
public class FilterRelatedExtensionsAction extends Action {
34
35
	protected TreeViewer fExtensionTree;
36
	protected FormFilteredTree fFilteredTree;
37
38
	public FilterRelatedExtensionsAction(TreeViewer treeViewer, FormFilteredTree filteredTree) {
39
		String filterBinding = ((IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class)).getBestActiveBindingFormattedFor(ActionFactory.FIND.getCommandId());
40
		setImageDescriptor(PDEPluginImages.DESC_FILTER_RELATED);
41
		setDisabledImageDescriptor(PDEPluginImages.DESC_FILTER_RELATED_DISABLED);
42
		setText(PDEUIMessages.Actions_filter_relatedPluginElements + ((filterBinding != null) ? "\t" + filterBinding : "")); //$NON-NLS-1$ //$NON-NLS-2$
43
44
		this.fExtensionTree = treeViewer;
45
		this.fFilteredTree = filteredTree;
46
	}
47
48
	public void run() {
49
		String filterPattern = getFilterRelatedPattern((IStructuredSelection) fExtensionTree.getSelection());
50
		Text filterControl = fFilteredTree.getFilterControl();
51
		if (filterControl != null && filterPattern.length() > 0) {
52
			filterControl.setText(filterPattern);
53
		}
54
	}
55
56
	/**
57
	 * Obtains common attributes from selected plugin element to filter tree for; 
58
	 * attribute values are concatenated with a slash and set as filter text
59
	 * 
60
	 * @param selection selected items to filter for related plugin elements 
61
	 */
62
	public static String getFilterRelatedPattern(IStructuredSelection selection) {
63
		Iterator it = selection.iterator();
64
		Set filterPatterns = new HashSet();
65
		while (it.hasNext()) {
66
			Object treeElement = it.next();
67
			if (treeElement instanceof IPluginElement) {
68
				IPluginElement pluginElement = (IPluginElement) treeElement;
69
				for (int i = 0; i < ExtensionsPatternFilter.RELATED_ATTRIBUTES.length; i++) {
70
					String property = ExtensionsPatternFilter.RELATED_ATTRIBUTES[i];
71
					IPluginAttribute attribute = pluginElement.getAttribute(property);
72
					if (attribute != null && attribute.getValue() != null && attribute.getValue().length() > 0) {
73
						String value = attribute.getValue();
74
						if (!value.startsWith("%")) { //$NON-NLS-1$
75
							int delimiterPosition = value.indexOf('?'); // split before '?' and right after last '='
76
							if (delimiterPosition == -1) {
77
								filterPatterns.add(value);
78
							} else {
79
								filterPatterns.add(value.substring(0, delimiterPosition));
80
								int position = value.lastIndexOf('=');
81
								if (position != -1) {
82
									filterPatterns.add(value.substring(position + 1, value.length()));
83
								}
84
							}
85
						} else {
86
							String resourceValue = pluginElement.getResourceString(value);
87
							if ((resourceValue != null && resourceValue.length() > 0)) {
88
								filterPatterns.add(resourceValue);
89
							}
90
						}
91
					}
92
				}
93
			}
94
		}
95
		StringBuffer patternBuffer = new StringBuffer();
96
		for (Iterator iterator = filterPatterns.iterator(); iterator.hasNext();) {
97
			Object pattern = iterator.next();
98
			if (pattern != null) {
99
				patternBuffer.append(pattern);
100
				patternBuffer.append('/');
101
			}
102
		}
103
		String filterPattern = patternBuffer.toString();
104
		if (filterPattern.endsWith("/")) { //$NON-NLS-1$
105
			filterPattern = filterPattern.substring(0, filterPattern.length() - 1);
106
		}
107
		return filterPattern;
108
	}
109
110
	public static boolean isFilterRelatedEnabled(IStructuredSelection structuredSelection) {
111
		boolean createFilterRelatedAction = false;
112
		if (structuredSelection != null && !structuredSelection.isEmpty()) {
113
			Iterator it = structuredSelection.iterator();
114
			while (it.hasNext()) {
115
				Object treeElement = it.next();
116
				if (treeElement instanceof IPluginElement) {
117
					createFilterRelatedAction |= isFilterRelatedEnabled((IPluginElement) treeElement);
118
				}
119
			}
120
		}
121
		return createFilterRelatedAction;
122
	}
123
124
	private static boolean isFilterRelatedEnabled(IPluginElement pluginElement) {
125
		for (int i = 0; i < ExtensionsPatternFilter.RELATED_ATTRIBUTES.length; i++) {
126
			String property = ExtensionsPatternFilter.RELATED_ATTRIBUTES[i];
127
			IPluginAttribute attribute = pluginElement.getAttribute(property);
128
			if (attribute != null) {
129
				return true;
130
			}
131
		}
132
		return false;
133
	}
134
135
}
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/actions/SearchExtensionsAction.java (+74 lines)
Added Link Here
1
/*******************************************************************************
2
 *  Copyright (c) 2011, 2012 IBM Corporation and others.
3
 *  All rights reserved. This program and the accompanying materials
4
 *  are made available under the terms of the Eclipse Public License v1.0
5
 *  which accompanies this distribution, and is available at
6
 *  http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 *  Contributors:
9
 *     Sascha Becher <s.becher@qualitype.de> - bug 360894
10
 *******************************************************************************/
11
package org.eclipse.pde.internal.ui.editor.actions;
12
13
import org.eclipse.jface.action.Action;
14
import org.eclipse.jface.viewers.IStructuredSelection;
15
import org.eclipse.pde.internal.core.search.PluginSearchInput;
16
import org.eclipse.pde.internal.core.search.PluginSearchScope;
17
import org.eclipse.pde.internal.ui.PDEPluginImages;
18
import org.eclipse.pde.internal.ui.editor.plugin.FormFilteredTree;
19
import org.eclipse.pde.internal.ui.search.FindExtensionsByAttributeQuery;
20
import org.eclipse.search.ui.ISearchQuery;
21
import org.eclipse.search.ui.NewSearchUI;
22
23
/**
24
 * Search in workspace plugins for occurences of either the current filter text or filter related attributes
25
 * using the ExtensionsPatternFilter search behaviour.
26
 * 
27
 * @author Sascha Becher
28
 */
29
public class SearchExtensionsAction extends Action {
30
31
	protected IStructuredSelection selection;
32
	protected FormFilteredTree fFilteredTree;
33
34
	private String fFilterRelatedText;
35
36
	public SearchExtensionsAction(FormFilteredTree filteredTree, String actionText) {
37
		this(null, null, actionText);
38
		this.fFilteredTree = filteredTree;
39
	}
40
41
	public SearchExtensionsAction(IStructuredSelection selection, String filterRelatedText, String actionText) {
42
		setImageDescriptor(PDEPluginImages.DESC_SEARCH_EXTENSIONS);
43
		setDisabledImageDescriptor(PDEPluginImages.DESC_SEARCH_EXTENSIONS_DISABLED);
44
		setText(actionText);
45
		this.selection = selection;
46
		this.fFilterRelatedText = filterRelatedText;
47
	}
48
49
	public void run() {
50
		NewSearchUI.activateSearchResultView();
51
		NewSearchUI.runQueryInBackground(createSearchQuery());
52
	}
53
54
	protected ISearchQuery createSearchQuery() {
55
		PluginSearchInput input = new PluginSearchInput();
56
		input.setSearchElement(PluginSearchInput.ELEMENT_PLUGIN);
57
		input.setSearchLimit(PluginSearchInput.LIMIT_ALL);
58
		input.setSearchString(getFilterText());
59
		input.setSearchScope(new PluginSearchScope(PluginSearchScope.SCOPE_WORKSPACE, PluginSearchScope.EXTERNAL_SCOPE_ALL, null));
60
		input.setCaseSensitive(false);
61
		return new FindExtensionsByAttributeQuery(selection, input);
62
	}
63
64
	private String getFilterText() {
65
		if (fFilterRelatedText != null) {
66
			return fFilterRelatedText;
67
		}
68
		if (fFilteredTree != null) {
69
			return fFilteredTree.getFilterControl().getText();
70
		}
71
		return new String();
72
	}
73
74
}
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/actions/ToggleExpandStateAction.java (+119 lines)
Added Link Here
1
/*******************************************************************************
2
 *  Copyright (c) 2011, 2012 IBM Corporation and others.
3
 *  All rights reserved. This program and the accompanying materials
4
 *  are made available under the terms of the Eclipse Public License v1.0
5
 *  which accompanies this distribution, and is available at
6
 *  http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 *  Contributors:
9
 *     Sascha Becher <s.becher@qualitype.de> - bug 360894
10
 *******************************************************************************/
11
package org.eclipse.pde.internal.ui.editor.actions;
12
13
import java.util.*;
14
import org.eclipse.jface.action.Action;
15
import org.eclipse.jface.viewers.*;
16
import org.eclipse.pde.internal.core.text.plugin.PluginParentNode;
17
import org.eclipse.pde.internal.ui.PDEPluginImages;
18
import org.eclipse.pde.internal.ui.PDEUIMessages;
19
import org.eclipse.pde.internal.ui.editor.plugin.FormFilteredTree;
20
21
/**
22
 * Expands and collapses selected tree nodes in the extension elements tree viewer upon their expand state.
23
 *  
24
 * @author Sascha Becher
25
 */
26
public class ToggleExpandStateAction extends Action {
27
28
	public static int NEEDS_EXPAND = 1;
29
	public static int NEEDS_COLLAPSE = 2;
30
31
	protected TreeViewer fExtensionTree;
32
	protected FormFilteredTree fFilteredTree;
33
34
	/**
35
	 * @param treeViewer
36
	 */
37
	public ToggleExpandStateAction(FormFilteredTree filteredTree, TreeViewer treeViewer) {
38
		setImageDescriptor(PDEPluginImages.DESC_TOGGLE_EXPAND_STATE);
39
		setDisabledImageDescriptor(PDEPluginImages.DESC_TOGGLE_EXPAND_STATE_DISABLED);
40
		setText(PDEUIMessages.ExtensionsPage_toggleExpandState);
41
		fExtensionTree = treeViewer;
42
		fFilteredTree = filteredTree;
43
	}
44
45
	public void run() {
46
		StructuredSelection selection = (StructuredSelection) fExtensionTree.getSelection();
47
		if (!selection.isEmpty()) {
48
			try {
49
				List children = traverseChildren(selection.toList());
50
				fFilteredTree.setRedraw(false);
51
				int state = getStateChangeRequired(selection);
52
				if (state == NEEDS_EXPAND) { // expand sub tree
53
					for (Iterator iterator = children.iterator(); iterator.hasNext();) {
54
						fExtensionTree.expandToLevel(iterator.next(), 0);
55
					}
56
					if (selection != null && !(selection.isEmpty())) {
57
						fExtensionTree.setSelection(selection, false);
58
					}
59
				} else { // collapse sub tree
60
					for (Iterator iterator = selection.iterator(); iterator.hasNext();) {
61
						fExtensionTree.setExpandedState(iterator.next(), false);
62
					}
63
				}
64
			} finally {
65
				fFilteredTree.setRedraw(true);
66
				fExtensionTree.refresh();
67
			}
68
		}
69
		super.run();
70
	}
71
72
	public int getStateChangeRequired(StructuredSelection selection) {
73
		for (Iterator iterator = selection.iterator(); iterator.hasNext();) {
74
			Object node = iterator.next();
75
			if (!fExtensionTree.getExpandedState(node)) {
76
				return NEEDS_EXPAND;
77
			}
78
		}
79
		return NEEDS_COLLAPSE;
80
	}
81
82
	protected List traverseChildren(List children) {
83
		List foundChildren = new ArrayList();
84
		foundChildren.addAll(0, children);
85
		for (Iterator iterator = children.iterator(); iterator.hasNext();) {
86
			Object child = iterator.next();
87
			if (child instanceof PluginParentNode) {
88
				PluginParentNode node = (PluginParentNode) child;
89
				if (node.getChildCount() > 0) {
90
					List asList = Arrays.asList(node.getChildren());
91
					List grandChildren = traverseChildren(asList);
92
					foundChildren.addAll(0, grandChildren);
93
				}
94
			}
95
		}
96
		return foundChildren;
97
	}
98
99
	public static boolean isExpandable(IStructuredSelection selection) {
100
		boolean isExpandable = false;
101
		if (selection != null) {
102
			if (!selection.isEmpty()) {
103
				// enable expand action when selected leafs are expandable  
104
				for (Iterator iterator = selection.iterator(); iterator.hasNext();) {
105
					Object element = iterator.next();
106
					if (element instanceof PluginParentNode) {
107
						PluginParentNode node = (PluginParentNode) element;
108
						if (node.getChildCount() > 0) {
109
							isExpandable = true;
110
							break;
111
						}
112
					}
113
				}
114
			}
115
		}
116
		return isExpandable;
117
	}
118
119
}
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionsSection.java (-21 / +138 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
2
 * Copyright (c) 2000, 2012 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 8-19 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Peter Friese <peter.friese@gentleware.com> - bug 194529, bug 196867
10
 *     Peter Friese <peter.friese@gentleware.com> - bug 194529, bug 196867
11
 *     Sascha Becher <s.becher@qualitype.com> - bug 360894
11
 *******************************************************************************/
12
 *******************************************************************************/
12
package org.eclipse.pde.internal.ui.editor.plugin;
13
package org.eclipse.pde.internal.ui.editor.plugin;
13
14
14
import java.util.*;
15
import java.util.*;
15
import org.eclipse.core.resources.IProject;
16
import org.eclipse.core.resources.IProject;
16
import org.eclipse.core.runtime.*;
17
import org.eclipse.core.runtime.*;
18
import org.eclipse.core.runtime.jobs.*;
17
import org.eclipse.jface.action.*;
19
import org.eclipse.jface.action.*;
18
import org.eclipse.jface.dialogs.IMessageProvider;
20
import org.eclipse.jface.dialogs.IMessageProvider;
19
import org.eclipse.jface.util.IPropertyChangeListener;
21
import org.eclipse.jface.util.IPropertyChangeListener;
Lines 32-42 Link Here
32
import org.eclipse.pde.internal.core.text.plugin.PluginBaseNode;
34
import org.eclipse.pde.internal.core.text.plugin.PluginBaseNode;
33
import org.eclipse.pde.internal.ui.*;
35
import org.eclipse.pde.internal.ui.*;
34
import org.eclipse.pde.internal.ui.editor.*;
36
import org.eclipse.pde.internal.ui.editor.*;
35
import org.eclipse.pde.internal.ui.editor.actions.CollapseAction;
37
import org.eclipse.pde.internal.ui.editor.actions.*;
36
import org.eclipse.pde.internal.ui.editor.actions.SortAction;
37
import org.eclipse.pde.internal.ui.editor.contentassist.XMLElementProposalComputer;
38
import org.eclipse.pde.internal.ui.editor.contentassist.XMLElementProposalComputer;
38
import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
39
import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
39
import org.eclipse.pde.internal.ui.parts.TreePart;
40
import org.eclipse.pde.internal.ui.parts.TreePart;
41
import org.eclipse.pde.internal.ui.search.ExtensionsPatternFilter;
40
import org.eclipse.pde.internal.ui.search.PluginSearchActionGroup;
42
import org.eclipse.pde.internal.ui.search.PluginSearchActionGroup;
41
import org.eclipse.pde.internal.ui.util.SWTUtil;
43
import org.eclipse.pde.internal.ui.util.SWTUtil;
42
import org.eclipse.pde.internal.ui.wizards.extension.ExtensionEditorWizard;
44
import org.eclipse.pde.internal.ui.wizards.extension.ExtensionEditorWizard;
Lines 51-59 Link Here
51
import org.eclipse.swt.widgets.*;
53
import org.eclipse.swt.widgets.*;
52
import org.eclipse.ui.actions.ActionContext;
54
import org.eclipse.ui.actions.ActionContext;
53
import org.eclipse.ui.actions.ActionFactory;
55
import org.eclipse.ui.actions.ActionFactory;
54
import org.eclipse.ui.dialogs.PatternFilter;
55
import org.eclipse.ui.forms.widgets.FormToolkit;
56
import org.eclipse.ui.forms.widgets.FormToolkit;
56
import org.eclipse.ui.forms.widgets.Section;
57
import org.eclipse.ui.forms.widgets.Section;
58
import org.eclipse.ui.progress.WorkbenchJob;
57
59
58
public class ExtensionsSection extends TreeSection implements IModelChangedListener, IPropertyChangeListener {
60
public class ExtensionsSection extends TreeSection implements IModelChangedListener, IPropertyChangeListener {
59
	private static final int BUTTON_MOVE_DOWN = 4;
61
	private static final int BUTTON_MOVE_DOWN = 4;
Lines 68-81 Link Here
68
	private Hashtable fEditorWizards;
70
	private Hashtable fEditorWizards;
69
	private SortAction fSortAction;
71
	private SortAction fSortAction;
70
	private CollapseAction fCollapseAction;
72
	private CollapseAction fCollapseAction;
73
	private ToggleExpandStateAction fExpandAction;
74
	private FilterRelatedExtensionsAction fFilterRelatedAction;
75
	private SearchExtensionsAction fSearchAction;
71
76
72
	private static final int BUTTON_ADD = 0;
77
	private static final int BUTTON_ADD = 0;
73
78
74
	private static final String[] COMMON_LABEL_PROPERTIES = {"label", //$NON-NLS-1$
79
	// TODO common label properties should be configured in preferences
75
			"name", //$NON-NLS-1$
80
	public static final String[] COMMON_LABEL_ATTRIBUTES = {"label", //$NON-NLS-1$
76
			"id", //$NON-NLS-1$
81
			"name", "class", "id", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
77
			"commandId", //$NON-NLS-1$
82
			"commandId", "property", "activityId", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
78
			"activityId"}; //$NON-NLS-1$ 
83
			"attribute", "value"}; //$NON-NLS-1$ //$NON-NLS-2$
79
84
80
	private static final String[] VALID_IMAGE_TYPES = {"png", "bmp", "ico", "gif", "jpg", "tiff"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
85
	private static final String[] VALID_IMAGE_TYPES = {"png", "bmp", "ico", "gif", "jpg", "tiff"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
81
86
Lines 232-237 Link Here
232
					updateButtons(ssel.size() != 1 ? null : ssel);
237
					updateButtons(ssel.size() != 1 ? null : ssel);
233
				}
238
				}
234
			});
239
			});
240
241
			// required for enabling constant typing in the filter control
242
			filterText.addKeyListener(new KeyAdapter() {
243
				public void keyPressed(KeyEvent e) {
244
					if (fFilteredTree.getFilterControl().getText().length() > 0) {
245
						Job jobs[] = Job.getJobManager().find(null);
246
						try {
247
							Job.getJobManager().suspend();
248
							for (int i = 0; i < jobs.length; i++) {
249
								Job job = jobs[i];
250
								if (job != null && "Refresh Filter".equals(job.getName())) { //$NON-NLS-1$
251
									// remove prior filtering refresh jobs in order to avoid blocked filter control
252
									job.cancel();
253
								}
254
							}
255
						} finally {
256
							Job.getJobManager().resume();
257
						}
258
					}
259
				}
260
			});
235
		}
261
		}
236
	}
262
	}
237
263
Lines 252-260 Link Here
252
				}
278
				}
253
			}
279
			}
254
		});
280
		});
281
		// Add action to filter tree with some of the selection's attributes
282
		fFilterRelatedAction = new FilterRelatedExtensionsAction(fExtensionTree, fFilteredTree);
283
		toolBarManager.add(fFilterRelatedAction);
284
		// Add action to search all workspace plugins with current filtering applied to the tree viewer
285
		fSearchAction = new SearchExtensionsAction(fFilteredTree, PDEUIMessages.ExtensionsPage_searchWithExtensionsFilter);
286
		toolBarManager.add(fSearchAction);
287
		// Add separator
288
		Separator separator = new Separator();
289
		toolBarManager.add(separator);
255
		// Add sort action to the tool bar
290
		// Add sort action to the tool bar
256
		fSortAction = new SortAction(fExtensionTree, PDEUIMessages.ExtensionsPage_sortAlpha, null, null, this);
291
		fSortAction = new SortAction(fExtensionTree, PDEUIMessages.ExtensionsPage_sortAlpha, null, null, this);
257
		toolBarManager.add(fSortAction);
292
		toolBarManager.add(fSortAction);
293
		// Add expand selected leafs action to the toolbar
294
		fExpandAction = new ToggleExpandStateAction(fFilteredTree, fExtensionTree);
295
		toolBarManager.add(fExpandAction);
258
		// Add collapse action to the tool bar
296
		// Add collapse action to the tool bar
259
		fCollapseAction = new CollapseAction(fExtensionTree, PDEUIMessages.ExtensionsPage_collapseAll);
297
		fCollapseAction = new CollapseAction(fExtensionTree, PDEUIMessages.ExtensionsPage_collapseAll);
260
		toolBarManager.add(fCollapseAction);
298
		toolBarManager.add(fCollapseAction);
Lines 309-319 Link Here
309
	 * @see org.eclipse.pde.internal.ui.editor.PDESection#doGlobalAction(java.lang.String)
347
	 * @see org.eclipse.pde.internal.ui.editor.PDESection#doGlobalAction(java.lang.String)
310
	 */
348
	 */
311
	public boolean doGlobalAction(String actionId) {
349
	public boolean doGlobalAction(String actionId) {
312
350
		if (actionId.equals(ActionFactory.FIND.getId()) && fFilterRelatedAction != null) {
351
			fFilterRelatedAction.run();
352
			return true;
353
		}
313
		if (!isEditable()) {
354
		if (!isEditable()) {
314
			return false;
355
			return false;
315
		}
356
		}
316
317
		if (actionId.equals(ActionFactory.DELETE.getId())) {
357
		if (actionId.equals(ActionFactory.DELETE.getId())) {
318
			handleDelete();
358
			handleDelete();
319
			return true;
359
			return true;
Lines 348-354 Link Here
348
388
349
	protected void fillContextMenu(IMenuManager manager) {
389
	protected void fillContextMenu(IMenuManager manager) {
350
		ISelection selection = fExtensionTree.getSelection();
390
		ISelection selection = fExtensionTree.getSelection();
351
		IStructuredSelection ssel = (IStructuredSelection) selection;
391
		final IStructuredSelection ssel = (IStructuredSelection) selection;
352
		if (ssel.size() == 1) {
392
		if (ssel.size() == 1) {
353
			Object object = ssel.getFirstElement();
393
			Object object = ssel.getFirstElement();
354
			if (object instanceof IPluginParent) {
394
			if (object instanceof IPluginParent) {
Lines 377-388 Link Here
377
			manager.add(new Separator());
417
			manager.add(new Separator());
378
			delAction.setEnabled(isEditable());
418
			delAction.setEnabled(isEditable());
379
		}
419
		}
420
		if (ssel.size() > 0) {
421
			if (FilterRelatedExtensionsAction.isFilterRelatedEnabled(ssel)) {
422
				FilterRelatedExtensionsAction filterRelatedAction = new FilterRelatedExtensionsAction(fExtensionTree, fFilteredTree);
423
				manager.add(filterRelatedAction);
424
				SearchExtensionsAction searchRelatedAction = new SearchExtensionsAction(ssel, FilterRelatedExtensionsAction.getFilterRelatedPattern(ssel), PDEUIMessages.Actions_search_relatedPluginElements);
425
				manager.add(searchRelatedAction);
426
				manager.add(new Separator());
427
			}
428
		}
380
		manager.add(new Separator());
429
		manager.add(new Separator());
381
		if (ssel.size() < 2) { // only cut things when the selection is one
430
		if (ssel.size() < 2) { // only cut things when the selection is one
382
			getPage().getPDEEditor().getContributor().addClipboardActions(manager);
431
			getPage().getPDEEditor().getContributor().addClipboardActions(manager);
383
		}
432
		}
384
		getPage().getPDEEditor().getContributor().contextMenuAboutToShow(manager, false);
433
		getPage().getPDEEditor().getContributor().contextMenuAboutToShow(manager, false);
385
434
		this.fFilteredTree.update();
386
	}
435
	}
387
436
388
	static IMenuManager fillContextMenu(PDEFormPage page, final IPluginParent parent, IMenuManager manager) {
437
	static IMenuManager fillContextMenu(PDEFormPage page, final IPluginParent parent, IMenuManager manager) {
Lines 491-496 Link Here
491
				PDEPlugin.logException(e);
540
				PDEPlugin.logException(e);
492
			}
541
			}
493
		}
542
		}
543
	}
544
545
	public FormFilteredTree getFormFilteredTree() {
546
		return fFilteredTree;
494
	}
547
	}
495
548
496
	private void handleNew() {
549
	private void handleNew() {
Lines 643-652 Link Here
643
		// The model changed but the editor is still open, we should try to retain expansion, selection will be retained on its own
696
		// The model changed but the editor is still open, we should try to retain expansion, selection will be retained on its own
644
		Object[] expanded = fExtensionTree.getExpandedElements();
697
		Object[] expanded = fExtensionTree.getExpandedElements();
645
		IPluginModelBase model = (IPluginModelBase) getPage().getModel();
698
		IPluginModelBase model = (IPluginModelBase) getPage().getModel();
646
		fExtensionTree.getControl().setRedraw(false);
699
		try {
647
		fExtensionTree.setInput(model.getPluginBase());
700
			fExtensionTree.getControl().setRedraw(false);
648
		fExtensionTree.setExpandedElements(expanded);
701
			fExtensionTree.setInput(model.getPluginBase());
649
		fExtensionTree.getControl().setRedraw(true);
702
			fExtensionTree.setExpandedElements(expanded);
703
		} finally {
704
			fExtensionTree.getControl().setRedraw(true);
705
		}
650
		reportMissingExtensionPointSchemas(model.getPluginBase());
706
		reportMissingExtensionPointSchemas(model.getPluginBase());
651
		getManagedForm().fireSelectionChanged(ExtensionsSection.this, fExtensionTree.getSelection());
707
		getManagedForm().fireSelectionChanged(ExtensionsSection.this, fExtensionTree.getSelection());
652
		super.refresh();
708
		super.refresh();
Lines 809-816 Link Here
809
			if (labelAtt == null) {
865
			if (labelAtt == null) {
810
				// try some hard-coded attributes that
866
				// try some hard-coded attributes that
811
				// are used frequently
867
				// are used frequently
812
				for (int i = 0; i < COMMON_LABEL_PROPERTIES.length; i++) {
868
				for (int i = 0; i < COMMON_LABEL_ATTRIBUTES.length; i++) {
813
					labelAtt = element.getAttribute(COMMON_LABEL_PROPERTIES[i]);
869
					labelAtt = element.getAttribute(COMMON_LABEL_ATTRIBUTES[i]);
814
					if (labelAtt != null)
870
					if (labelAtt != null)
815
						break;
871
						break;
816
				}
872
				}
Lines 821-829 Link Here
821
						labelAtt = element.getAttributes()[0];
877
						labelAtt = element.getAttributes()[0];
822
				}
878
				}
823
			}
879
			}
824
			if (labelAtt != null && labelAtt.getValue() != null)
880
			if (labelAtt != null && labelAtt.getValue() != null) {
825
				fullName = stripShortcuts(labelAtt.getValue());
881
				fullName = stripShortcuts(labelAtt.getValue());
882
				if (labelAtt.getName().equals(COMMON_LABEL_ATTRIBUTES[2])) { // remove package from handler class 
883
					fullName = fullName.substring(fullName.lastIndexOf('.') + 1, fullName.length());
884
				}
885
			}
826
			fullName = element.getResourceString(fullName);
886
			fullName = element.getResourceString(fullName);
887
827
			if (fullNames)
888
			if (fullNames)
828
				return fullName != null ? fullName : baseName;
889
				return fullName != null ? fullName : baseName;
829
			if (fullName == null)
890
			if (fullName == null)
Lines 1081-1086 Link Here
1081
	}
1142
	}
1082
1143
1083
	private void updateButtons(Object item) {
1144
	private void updateButtons(Object item) {
1145
		if (fExpandAction != null) {
1146
			fExpandAction.setEnabled(ToggleExpandStateAction.isExpandable((IStructuredSelection) fExtensionTree.getSelection()));
1147
		}
1148
		if (fFilterRelatedAction != null) {
1149
			fFilterRelatedAction.setEnabled(FilterRelatedExtensionsAction.isFilterRelatedEnabled((IStructuredSelection) fExtensionTree.getSelection()));
1150
		}
1151
		if (fSearchAction != null) {
1152
			Text filterControl = fFilteredTree.getFilterControl();
1153
			// enable action only when filtering occurs
1154
			fSearchAction.setEnabled(filterControl != null && filterControl.getText().length() > 0);
1155
		}
1156
1084
		if (getPage().getModel().isEditable() == false)
1157
		if (getPage().getModel().isEditable() == false)
1085
			return;
1158
			return;
1086
		boolean sorted = fSortAction != null && fSortAction.isChecked();
1159
		boolean sorted = fSortAction != null && fSortAction.isChecked();
Lines 1140-1147 Link Here
1140
	 * @see org.eclipse.pde.internal.ui.editor.TreeSection#createTreeViewer(org.eclipse.swt.widgets.Composite, int)
1213
	 * @see org.eclipse.pde.internal.ui.editor.TreeSection#createTreeViewer(org.eclipse.swt.widgets.Composite, int)
1141
	 */
1214
	 */
1142
	protected TreeViewer createTreeViewer(Composite parent, int style) {
1215
	protected TreeViewer createTreeViewer(Composite parent, int style) {
1143
		fFilteredTree = new FormFilteredTree(parent, style, new PatternFilter());
1216
		fFilteredTree = new FormFilteredTree(parent, style, new ExtensionsPatternFilter()) {
1217
			protected WorkbenchJob doCreateRefreshJob() {
1218
				final WorkbenchJob job = super.doCreateRefreshJob();
1219
				job.addJobChangeListener(new JobChangeAdapter() {
1220
					private ISelection selection;
1221
1222
					public void scheduled(IJobChangeEvent event) {
1223
						((ExtensionsPatternFilter) fFilteredTree.getPatternFilter()).clearMatchingLeafs();
1224
						selection = fExtensionTree.getSelection();
1225
						fFilteredTree.setRedraw(false);
1226
					}
1227
1228
					public void done(IJobChangeEvent event) {
1229
						ExtensionsPatternFilter extensionsPatternFilter = ((ExtensionsPatternFilter) fFilteredTree.getPatternFilter());
1230
						fExtensionTree.collapseAll();
1231
						Object[] leafs = extensionsPatternFilter.getMatchingLeafsAsArray();
1232
						for (int i = 0; i < leafs.length; i++) {
1233
							fExtensionTree.expandToLevel(leafs[i], 0);
1234
						}
1235
						if (selection != null && !(selection.isEmpty())) {
1236
							fExtensionTree.setSelection(selection, false);
1237
						}
1238
						fFilteredTree.setRedraw(true);
1239
					}
1240
1241
				});
1242
				return job;
1243
			}
1244
1245
			protected long getRefreshJobDelay() {
1246
				return 500; // required for continuous typing while performing extensive search operation
1247
			}
1248
		};
1144
		parent.setData("filtered", Boolean.TRUE); //$NON-NLS-1$
1249
		parent.setData("filtered", Boolean.TRUE); //$NON-NLS-1$
1250
		fFilteredTree.addMouseWheelListener(new MouseWheelListener() {
1251
1252
			public void mouseScrolled(MouseEvent e) {
1253
				if ((e.stateMask & SWT.MOD1) == SWT.MOD1) {
1254
					//System.out.println("e.stateMask == SWT.MOD1");
1255
					//fExtensionTree.scrollDown(0, 80);
1256
					//fFilteredTree.redraw();
1257
				}
1258
				//}
1259
1260
			}
1261
		});
1145
		return fFilteredTree.getViewer();
1262
		return fFilteredTree.getViewer();
1146
	}
1263
	}
1147
1264
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties (+4 lines)
Lines 1189-1194 Link Here
1189
EditorActions_revert = Re&vert
1189
EditorActions_revert = Re&vert
1190
Actions_open_label = &Open
1190
Actions_open_label = &Open
1191
Actions_delete_label = &Delete
1191
Actions_delete_label = &Delete
1192
Actions_filter_relatedPluginElements=&Filter Related
1193
Actions_search_relatedPluginElements=Search &Related
1192
Actions_synchronizeVersions_label = S&ynchronize Versions...
1194
Actions_synchronizeVersions_label = S&ynchronize Versions...
1193
1195
1194
Menus_new_label = &New
1196
Menus_new_label = &New
Lines 1536-1541 Link Here
1536
ExtensionsPage_title=Extensions
1538
ExtensionsPage_title=Extensions
1537
ExtensionsPage_tabName=Extensions
1539
ExtensionsPage_tabName=Extensions
1538
ExtensionsPage_sortAlpha=Sort the Extensions alphabetically
1540
ExtensionsPage_sortAlpha=Sort the Extensions alphabetically
1541
ExtensionsPage_toggleExpandState=Toggle Expand State
1542
ExtensionsPage_searchWithExtensionsFilter=Extension Element Search
1539
ExtensionDetails_title=Extension Details
1543
ExtensionDetails_title=Extension Details
1540
ExtensionDetails_desc=Set the properties of the selected extension. Required fields are denoted by "*".
1544
ExtensionDetails_desc=Set the properties of the selected extension. Required fields are denoted by "*".
1541
ExtensionDetails_id=ID
1545
ExtensionDetails_id=ID
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/search/AttributesMatch.java (+45 lines)
Added Link Here
1
/*******************************************************************************
2
 *  Copyright (c) 2011, 2012 IBM Corporation and others.
3
 *  All rights reserved. This program and the accompanying materials
4
 *  are made available under the terms of the Eclipse Public License v1.0
5
 *  which accompanies this distribution, and is available at
6
 *  http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 *  Contributors:
9
 *     Sascha Becher <s.becher@qualitype.de> - bug 360894
10
 *******************************************************************************/
11
package org.eclipse.pde.internal.ui.search;
12
13
import org.eclipse.pde.internal.ui.editor.plugin.ManifestEditor;
14
import org.eclipse.search.ui.text.Match;
15
16
/**
17
 * An extension to {@link Match} in order to present matching plugins which resulted 
18
 * in a search queried from the extensions page of the {@link ManifestEditor} 
19
 * 
20
 * @author Sascha Becher
21
 */
22
public class AttributesMatch extends Match {
23
24
	/**
25
	 * A constant expressing that the {@link Match} resulted in a search queried from 
26
	 * the extensions page of the {@link ManifestEditor} 
27
	 */
28
	public static final int UNIT_ATTRIBUTE_SEARCH_PATTERN = 3;
29
30
	protected String searchPattern;
31
32
	public AttributesMatch(Object element, String searchPattern) {
33
		super(element, UNIT_LINE, 0, 0);
34
		this.searchPattern = searchPattern;
35
	}
36
37
	public String getSearchPattern() {
38
		return searchPattern;
39
	}
40
41
	public int getBaseUnit() {
42
		return UNIT_ATTRIBUTE_SEARCH_PATTERN;
43
	}
44
45
}
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/search/ExtensionElementSearchOperation.java (+88 lines)
Added Link Here
1
/*******************************************************************************
2
 *  Copyright (c) 2011, 2012 IBM Corporation and others.
3
 *  All rights reserved. This program and the accompanying materials
4
 *  are made available under the terms of the Eclipse Public License v1.0
5
 *  which accompanies this distribution, and is available at
6
 *  http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 *  Contributors:
9
 *     Sascha Becher <s.becher@qualitype.de> - bug 360894
10
 *******************************************************************************/
11
package org.eclipse.pde.internal.ui.search;
12
13
import java.util.ArrayList;
14
import org.eclipse.core.runtime.IProgressMonitor;
15
import org.eclipse.pde.core.plugin.*;
16
import org.eclipse.pde.internal.core.search.ISearchResultCollector;
17
import org.eclipse.pde.internal.core.search.PluginSearchInput;
18
19
/**
20
 * Search operation for finding extension elements within a plugin using the {@link ExtensionsPatternFilter}.
21
 * 
22
 * @author Sascha Becher
23
 */
24
public class ExtensionElementSearchOperation {
25
26
	protected PluginSearchInput fInput;
27
	private ISearchResultCollector fCollector;
28
29
	public ExtensionElementSearchOperation(PluginSearchInput input, ISearchResultCollector collector) {
30
		this.fInput = input;
31
		this.fCollector = collector;
32
	}
33
34
	public void execute(IProgressMonitor monitor) {
35
		IPluginModelBase[] entries = fInput.getSearchScope().getMatchingModels();
36
		monitor.beginTask("", entries.length); //$NON-NLS-1$
37
38
		try {
39
			for (int i = 0; i < entries.length; i++) {
40
				IPluginModelBase candidate = entries[i];
41
				visit(candidate);
42
				monitor.worked(1);
43
			}
44
		} finally {
45
			monitor.done();
46
		}
47
	}
48
49
	private void visit(IPluginModelBase model) {
50
		ArrayList matches = findMatch(model);
51
		for (int i = 0; i < matches.size(); i++) {
52
			fCollector.accept(matches.get(i));
53
		}
54
	}
55
56
	private ArrayList findMatch(IPluginModelBase model) {
57
		ArrayList result = new ArrayList();
58
		int searchLimit = fInput.getSearchLimit();
59
		if (fInput.getSearchElement() == PluginSearchInput.ELEMENT_PLUGIN) {
60
			if (searchLimit != PluginSearchInput.LIMIT_REFERENCES)
61
				findPluginDeclaration(model, result);
62
			if (searchLimit != PluginSearchInput.LIMIT_DECLARATIONS)
63
				findPluginReferences(model, result);
64
		}
65
		return result;
66
	}
67
68
	private void findPluginDeclaration(IPluginModelBase model, ArrayList result) {
69
		IPluginBase pluginBase = model.getPluginBase();
70
		ExtensionsPatternFilter filter = new ExtensionsPatternFilter();
71
		filter.setUseCacheForSearch(true);
72
		filter.clearMatchingLeafs();
73
		filter.setPattern(fInput.getSearchString());
74
		filter.filter(null, pluginBase, pluginBase.getExtensions());
75
		if (pluginBase instanceof IPlugin && filter.getMatchingLeafsAsArray().length > 0) {
76
			result.add(pluginBase);
77
		}
78
	}
79
80
	private void findPluginReferences(IPluginModelBase model, ArrayList result) {
81
		IPluginBase pluginBase = model.getPluginBase();
82
		IPluginImport[] imports = pluginBase.getImports();
83
		for (int i = 0; i < imports.length; i++) {
84
			findPluginDeclaration(imports[i].getPluginModel(), result);
85
		}
86
	}
87
88
}
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/search/ExtensionsPatternFilter.java (+217 lines)
Added Link Here
1
/*******************************************************************************
2
 *  Copyright (c) 2011, 2012 IBM Corporation and others.
3
 *  All rights reserved. This program and the accompanying materials
4
 *  are made available under the terms of the Eclipse Public License v1.0
5
 *  which accompanies this distribution, and is available at
6
 *  http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 *  Contributors:
9
 *     Sascha Becher <s.becher@qualitype.de> - bug 360894
10
 *******************************************************************************/
11
package org.eclipse.pde.internal.ui.search;
12
13
import java.util.*;
14
import org.eclipse.jface.viewers.Viewer;
15
import org.eclipse.pde.core.plugin.*;
16
import org.eclipse.pde.internal.core.bundle.BundlePlugin;
17
import org.eclipse.ui.dialogs.PatternFilter;
18
19
/**
20
 * An extended filtering capability for the filtered tree of ExtensionsPage. The
21
 * search criteria is splitted by / first. The resulting values are used to
22
 * perform a search on all node's values. All elements fitting at least one of
23
 * the split values will be displayed. This extensions does not compromise the
24
 * default filtering behaviour of the tree while providing the ability to
25
 * highlight related items such as commands along with their command images,
26
 * handlers, menu entries and activities.
27
 * 
28
 * @see org.eclipse.ui.dialogs.FilteredTree
29
 * @since 3.8
30
 * 
31
 */
32
public class ExtensionsPatternFilter extends PatternFilter {
33
34
	// TODO related attributes should be configured in preferences
35
	public static final String[] RELATED_ATTRIBUTES = {"label", //$NON-NLS-1$
36
			"id", "class", "commandId", "value", "pattern", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
37
			"locationURI", "defaultHandler"}; //$NON-NLS-1$ //$NON-NLS-2$ 
38
39
	protected String[] valuePatterns = null;
40
	protected String searchPattern;
41
42
	protected Set matchingLeafs = new HashSet();
43
44
	/**
45
	 * Check if the current (leaf) element is a match with the filter text. The
46
	 * default behavior checks that the label of the element is a match.
47
	 * 
48
	 * Subclasses should override this method.
49
	 * 
50
	 * @param viewer
51
	 *            the viewer that contains the element
52
	 * @param element
53
	 *            the tree element to check
54
	 * @return true if the given element's label matches the filter text
55
	 */
56
	protected boolean isLeafMatch(Viewer viewer, Object element) {
57
		Boolean foundAny = (Boolean) foundAnyCache.get(element);
58
		if (foundAny != null) {
59
			return foundAny.booleanValue();
60
		}
61
62
		// match label; default behaviour
63
		if (viewer != null && super.isLeafMatch(viewer, element)) {
64
			return true;
65
		}
66
67
		// match all splitted attribute's values of IPluginElement against splitted filter patterns
68
		if (element instanceof IPluginElement) {
69
			if (valuePatterns != null && valuePatterns.length > 0) {
70
				for (int j = 0; j < valuePatterns.length; j++) {
71
					String valuePattern = valuePatterns[j];
72
					if (valuePattern != null && valuePattern.length() > 0) {
73
						IPluginElement pluginElement = (IPluginElement) element;
74
						int attributeCount = pluginElement.getAttributeCount();
75
						IPluginAttribute[] pluginAttributes = pluginElement.getAttributes();
76
						for (int i = 0; i < attributeCount; i++) {
77
							IPluginAttribute attribute = pluginAttributes[i];
78
							if (attribute != null && attribute.getValue() != null) {
79
								String[] attributes = attribute.getValue().replaceAll("/{1,}", "/").split("/"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
80
								if (attributes != null) {
81
									for (int k = 0; k < attributes.length; k++) {
82
										String value = attributes[k];
83
										if (value != null && value.length() > 0) {
84
											if (!value.startsWith("%")) { //$NON-NLS-1$
85
												int delimiterPosition = value.indexOf('?'); // strip right of '?'
86
												if (delimiterPosition != -1) {
87
													value = value.substring(0, delimiterPosition);
88
												}
89
											} else {
90
												String resourceValue = pluginElement.getResourceString(value);
91
												value = (resourceValue != null && resourceValue.length() > 0) ? resourceValue : value;
92
											}
93
											if (value.toLowerCase().equals(valuePattern.toLowerCase())) {
94
												return true;
95
											}
96
										}
97
									}
98
								}
99
							}
100
						}
101
						if (valuePattern.equalsIgnoreCase(pluginElement.getName())) {
102
							return true;
103
						}
104
					}
105
				}
106
			}
107
		}
108
		return false;
109
	}
110
111
	public Object[] filter(Viewer viewer, Object parent, Object[] elements) {
112
		if (!useCache) {
113
			return super.filter(viewer, parent, elements);
114
		}
115
		if (parent != null && parent instanceof BundlePlugin) {
116
			if (foundAnyCache.keySet().size() == 0) {
117
				BundlePlugin pluginPlugin = (BundlePlugin) parent;
118
				doFilter(viewer, pluginPlugin, pluginPlugin.getExtensions());
119
			}
120
		}
121
		return super.filter(viewer, parent, elements);
122
	}
123
124
	protected boolean doFilter(Viewer viewer, Object parent, IPluginObject[] children) {
125
		boolean isParentMatch = false;
126
		Object parentMatch = foundAnyCache.get(parent);
127
		if (parentMatch != null) {
128
			isParentMatch = ((Boolean) parentMatch).booleanValue();
129
		}
130
131
		// find leaf matches
132
		boolean isAnyLeafMatch = false;
133
		for (int j = 0; j < children.length; j++) {
134
			IPluginObject iPluginObject = children[j];
135
			boolean isChildMatch = true;
136
			if (!isParentMatch) {
137
				isChildMatch = this.isLeafMatch(viewer, iPluginObject);
138
				isAnyLeafMatch |= isChildMatch;
139
				if (isChildMatch) {
140
					matchingLeafs.add(iPluginObject);
141
				}
142
			}
143
			foundAnyCache.put(iPluginObject, Boolean.valueOf(isChildMatch));
144
		}
145
146
		// traverse children when available
147
		boolean isAnyChildMatch = false;
148
		for (int i = 0; i < children.length; i++) {
149
			IPluginObject iPluginObject = children[i];
150
			if (iPluginObject instanceof IPluginParent) {
151
				IPluginParent pluginElement = (IPluginParent) iPluginObject;
152
				if (pluginElement.getChildren().length > 0) {
153
					boolean isChildrenMatch = doFilter(viewer, pluginElement, pluginElement.getChildren());
154
					isAnyChildMatch |= isChildrenMatch;
155
					if (isChildrenMatch) {
156
						foundAnyCache.put(iPluginObject, Boolean.TRUE);
157
						isParentMatch = true;
158
					}
159
				}
160
			}
161
		}
162
		return isAnyChildMatch | isAnyLeafMatch;
163
	}
164
165
	/* (non-Javadoc)
166
	 * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
167
	 */
168
	public boolean select(Viewer viewer, Object parentElement, Object element) {
169
		if (useCache) {
170
			Object cachedResult = foundAnyCache.get(element);
171
			if (cachedResult != null) {
172
				return ((Boolean) cachedResult).booleanValue();
173
			}
174
		}
175
		return isLeafMatch(viewer, element);
176
	}
177
178
	/*
179
	 * (non-Javadoc)
180
	 * 
181
	 * @see org.eclipse.ui.dialogs.PatternFilter#setPattern(java.lang.String)
182
	 */
183
	public final void setPattern(String patternString) {
184
		super.setPattern(patternString);
185
		searchPattern = patternString;
186
		valuePatterns = patternString.replaceAll("/{1,}", "/").split("/"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
187
	}
188
189
	public String getPattern() {
190
		return searchPattern;
191
	}
192
193
	public void clearMatchingLeafs() {
194
		matchingLeafs.clear();
195
	}
196
197
	public Object[] getMatchingLeafsAsArray() {
198
		return matchingLeafs.toArray();
199
	}
200
201
	public void addMatchingLeafs(List children) {
202
		System.out.println(matchingLeafs.size());
203
		matchingLeafs.addAll(children);
204
		System.out.println(matchingLeafs.size());
205
	}
206
207
	/**
208
	 * Can be called to turn on caching.
209
	 * 
210
	 * @param useCache
211
	 *            The useCache to set.
212
	 */
213
	public void setUseCacheForSearch(boolean useCache) {
214
		this.useCache = useCache;
215
	}
216
217
}
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/search/FindExtensionsByAttributeQuery.java (+83 lines)
Added Link Here
1
/**
2
 * 
3
 */
4
package org.eclipse.pde.internal.ui.search;
5
6
import org.eclipse.core.runtime.*;
7
import org.eclipse.jface.viewers.IStructuredSelection;
8
import org.eclipse.pde.internal.core.bundle.BundlePlugin;
9
import org.eclipse.pde.internal.core.search.ISearchResultCollector;
10
import org.eclipse.pde.internal.core.search.PluginSearchInput;
11
import org.eclipse.search.ui.ISearchQuery;
12
import org.eclipse.search.ui.ISearchResult;
13
import org.eclipse.search.ui.text.AbstractTextSearchResult;
14
15
/**
16
 * @author zour
17
 *
18
 */
19
public class FindExtensionsByAttributeQuery implements ISearchQuery {
20
21
	private SearchResult fSearchResult;
22
23
	private PluginSearchInput fSearchInput;
24
25
	public FindExtensionsByAttributeQuery(IStructuredSelection selection, PluginSearchInput input) {
26
		fSearchInput = input;
27
	}
28
29
	/* (non-Javadoc)
30
	 * @see org.eclipse.search.ui.ISearchQuery#run(org.eclipse.core.runtime.IProgressMonitor)
31
	 */
32
	public IStatus run(IProgressMonitor monitor) throws OperationCanceledException {
33
		final AbstractTextSearchResult result = (AbstractTextSearchResult) getSearchResult();
34
		result.removeAll();
35
		ISearchResultCollector collector = new ISearchResultCollector() {
36
			public void accept(Object match) {
37
				if (match instanceof BundlePlugin) {
38
					BundlePlugin plugin = (BundlePlugin) match;
39
					result.addMatch(new AttributesMatch(plugin, fSearchInput.getSearchString()));
40
				}
41
			}
42
		};
43
		ExtensionElementSearchOperation op = new ExtensionElementSearchOperation(fSearchInput, collector);
44
		op.execute(monitor);
45
		monitor.done();
46
		return Status.OK_STATUS;
47
	}
48
49
	/* (non-Javadoc)
50
	 * @see org.eclipse.search.ui.ISearchQuery#getLabel()
51
	 */
52
	public String getLabel() {
53
		return fSearchInput.getSearchString();
54
	}
55
56
	/* (non-Javadoc)
57
	 * @see org.eclipse.search.ui.ISearchQuery#canRerun()
58
	 */
59
	public boolean canRerun() {
60
		return true;
61
	}
62
63
	/* (non-Javadoc)
64
	 * @see org.eclipse.search.ui.ISearchQuery#canRunInBackground()
65
	 */
66
	public boolean canRunInBackground() {
67
		return true;
68
	}
69
70
	/* (non-Javadoc)
71
	 * @see org.eclipse.search.ui.ISearchQuery#getSearchResult()
72
	 */
73
	public ISearchResult getSearchResult() {
74
		if (fSearchResult == null)
75
			fSearchResult = new SearchResult(this);
76
		return fSearchResult;
77
	}
78
79
	public PluginSearchInput getPluginSearchInput() {
80
		return fSearchInput;
81
	}
82
83
}
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/search/ManifestEditorOpener.java (-5 / +19 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Sascha Becher <s.becher@qualitype.de> - bug 360894
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.pde.internal.ui.search;
12
package org.eclipse.pde.internal.ui.search;
12
13
Lines 16-25 Link Here
16
import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
17
import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
17
import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
18
import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
18
import org.eclipse.pde.internal.core.text.plugin.PluginObjectNode;
19
import org.eclipse.pde.internal.core.text.plugin.PluginObjectNode;
19
import org.eclipse.pde.internal.ui.editor.plugin.ManifestEditor;
20
import org.eclipse.pde.internal.ui.editor.plugin.*;
20
import org.eclipse.search.ui.text.Match;
21
import org.eclipse.search.ui.text.Match;
21
import org.eclipse.ui.IEditorPart;
22
import org.eclipse.ui.IEditorPart;
22
import org.eclipse.ui.PartInitException;
23
import org.eclipse.ui.PartInitException;
24
import org.eclipse.ui.forms.IFormPart;
25
import org.eclipse.ui.forms.IManagedForm;
26
import org.eclipse.ui.forms.editor.IFormPage;
23
import org.osgi.framework.Constants;
27
import org.osgi.framework.Constants;
24
28
25
// TODO this needs a rewrite
29
// TODO this needs a rewrite
Lines 30-39 Link Here
30
		editorPart = ManifestEditor.open(match.getElement(), true);
34
		editorPart = ManifestEditor.open(match.getElement(), true);
31
		if (editorPart != null && editorPart instanceof ManifestEditor) {
35
		if (editorPart != null && editorPart instanceof ManifestEditor) {
32
			ManifestEditor editor = (ManifestEditor) editorPart;
36
			ManifestEditor editor = (ManifestEditor) editorPart;
33
			IDocument doc = editor.getDocument(match);
37
			if (match.getBaseUnit() != AttributesMatch.UNIT_ATTRIBUTE_SEARCH_PATTERN) {
34
			if (doc != null) {
38
				IDocument doc = editor.getDocument(match);
35
				Match exact = findExactMatch(doc, match, editor);
39
				if (doc != null) {
36
				editor.openToSourcePage(match.getElement(), exact.getOffset(), exact.getLength());
40
					Match exact = findExactMatch(doc, match, editor);
41
					editor.openToSourcePage(match.getElement(), exact.getOffset(), exact.getLength());
42
				}
43
			} else { // open to extensions page and initialize filter with search result's pattern text
44
				IFormPage page = editor.setActivePage(ExtensionsPage.PAGE_ID);
45
				IManagedForm form = page.getManagedForm();
46
				IFormPart parts[] = form.getParts();
47
				if (parts != null && parts.length > 0) {
48
					ExtensionsSection section = (ExtensionsSection) parts[0];
49
					section.getFormFilteredTree().getFilterControl().setText(((AttributesMatch) match).getSearchPattern());
50
				}
37
			}
51
			}
38
		}
52
		}
39
		return editorPart;
53
		return editorPart;
(-)a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/search/SearchResult.java (-1 / +8 lines)
Lines 7-12 Link Here
7
 * 
7
 * 
8
 *  Contributors:
8
 *  Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Sascha Becher <s.becher@qualitype.de> - bug 360894
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.pde.internal.ui.search;
12
package org.eclipse.pde.internal.ui.search;
12
13
Lines 29-37 Link Here
29
30
30
public class SearchResult extends AbstractTextSearchResult implements IEditorMatchAdapter {
31
public class SearchResult extends AbstractTextSearchResult implements IEditorMatchAdapter {
31
	protected ISearchQuery fQuery;
32
	protected ISearchQuery fQuery;
33
	private final ImageDescriptor fImage;
32
34
33
	public SearchResult(ISearchQuery query) {
35
	public SearchResult(ISearchQuery query) {
34
		fQuery = query;
36
		fQuery = query;
37
		if (fQuery instanceof FindExtensionsByAttributeQuery) {
38
			fImage = PDEPluginImages.DESC_ESEARCH_OBJ;
39
		} else {
40
			fImage = PDEPluginImages.DESC_PSEARCH_OBJ;
41
		}
35
	}
42
	}
36
43
37
	/* (non-Javadoc)
44
	/* (non-Javadoc)
Lines 60-66 Link Here
60
	 * @see org.eclipse.search.ui.ISearchResult#getImageDescriptor()
67
	 * @see org.eclipse.search.ui.ISearchResult#getImageDescriptor()
61
	 */
68
	 */
62
	public ImageDescriptor getImageDescriptor() {
69
	public ImageDescriptor getImageDescriptor() {
63
		return PDEPluginImages.DESC_PSEARCH_OBJ;
70
		return fImage;
64
	}
71
	}
65
72
66
	/* (non-Javadoc)
73
	/* (non-Javadoc)

Return to bug 360894