001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package net.refractions.udig.internal.ui.operations;
018:
019: import java.util.ArrayList;
020: import java.util.Collection;
021: import java.util.Collections;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026:
027: import net.refractions.udig.core.internal.ExtensionPointList;
028: import net.refractions.udig.internal.ui.UiPlugin;
029: import net.refractions.udig.ui.internal.Messages;
030: import net.refractions.udig.ui.operations.OpAction;
031:
032: import org.eclipse.core.runtime.IConfigurationElement;
033: import org.eclipse.jface.action.GroupMarker;
034: import org.eclipse.jface.action.IContributionItem;
035: import org.eclipse.jface.action.IMenuManager;
036: import org.eclipse.jface.action.MenuManager;
037: import org.eclipse.jface.action.Separator;
038: import org.eclipse.jface.action.SubContributionItem;
039: import org.eclipse.jface.viewers.ISelection;
040: import org.eclipse.jface.viewers.IStructuredSelection;
041: import org.eclipse.ui.IWorkbenchActionConstants;
042: import org.eclipse.ui.IWorkbenchWindow;
043:
044: /**
045: * Creates an Operation Sub menu containing operations for all operations defined for an object.
046: *
047: * @author jeichar
048: * @since 0.6.0
049: */
050: public class OperationMenuFactory {
051: List<IConfigurationElement> extensionPoints;
052: private MenuManager contextManager;
053: private ArrayList<OpAction> actions = new ArrayList<OpAction>();
054: private Map<String, OperationCategory> categories = new HashMap<String, OperationCategory>();
055: private MenuManager menuManager;
056: private IWorkbenchWindow window;
057:
058: /**
059: * Create instance
060: */
061: public OperationMenuFactory() {
062: extensionPoints = ExtensionPointList
063: .getExtensionPointList("net.refractions.udig.ui.operation"); //$NON-NLS-1$
064: createActionList(extensionPoints);
065: }
066:
067: /**
068: * Gets a context menu containing all the enabled operations
069: *
070: * @param selection the current selection.
071: * @return a context menu containing all the enabled operations
072: */
073: public MenuManager getContextMenu(ISelection selection) {
074: contextManager = createMenuManager();
075: Iterator iter = getCategories().values().iterator();
076: while (iter.hasNext()) {
077: OperationCategory category = (OperationCategory) iter
078: .next();
079:
080: for (OpAction action : category.getActions()) {
081: if (selection instanceof IStructuredSelection)
082: action.updateEnablement(
083: (IStructuredSelection) selection, true);
084: if (action.isEnabled())
085: contextManager.add(action);
086: }
087: if (iter.hasNext())
088: contextManager.add(new Separator());
089: }
090:
091: if (getActions().size() != 0) {
092: contextManager.add(new Separator());
093: }
094: for (OpAction action : getActions()) {
095: if (selection instanceof IStructuredSelection)
096: action.updateEnablement(
097: (IStructuredSelection) selection, true);
098: if (action.isEnabled()) {
099: contextManager.add(action);
100: }
101: }
102: return contextManager;
103: }
104:
105: /**
106: * Creates a menu manager with actions that will enable or disable themselved depending on the
107: * current workbench selection.
108: *
109: * @return a menu manager with all the Operation Actions.
110: */
111: public MenuManager getMenu() {
112: if (menuManager == null) {
113: menuManager = new MenuManager(getMenuText());
114: for (OperationCategory category : categories.values()) {
115: if (category.getItems().length > 0) {
116: menuManager.add(category);
117: }
118: }
119: for (OpAction action : actions) {
120: menuManager.add(action);
121: }
122: menuManager.add(new GroupMarker(
123: IWorkbenchActionConstants.MB_ADDITIONS));
124: }
125: return menuManager;
126: }
127:
128: /**
129: */
130: public void add() {
131: menuManager.update();
132: }
133:
134: private void createActionList(List<IConfigurationElement> list) {
135: for (IConfigurationElement element : list) {
136: try {
137: if (element.getName().equals("category")) //$NON-NLS-1$
138: categories
139: .put(
140: element.getAttribute("id"), new OperationCategory(element)); //$NON-NLS-1$
141: } catch (Exception e) {
142: UiPlugin.log(null, e);
143: }
144: }
145: for (IConfigurationElement element : list) {
146: if (element.getName().equals("category")) //$NON-NLS-1$
147: continue;
148: OpAction action = new OpAction(element);
149:
150: if (window != null)
151: window.getSelectionService().addSelectionListener(
152: action);
153: OperationCategory category = categories.get(element
154: .getAttribute("categoryId")); //$NON-NLS-1$
155: if (category != null) {
156: category.add(action);
157: } else {
158: actions.add(action);
159: if (element.getAttribute("categoryId") != null && element.getAttribute("categoryId").length() != 0) { //$NON-NLS-1$ //$NON-NLS-2$
160: UiPlugin
161: .log(
162: "Action '" + action.getText() + "' references invalid category '" + element.getAttribute("categoryId") + "'.", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
163: }
164: }
165: }
166: }
167:
168: /**
169: * Adds actions defined by extension points to the menu bar.
170: * @param menuBar
171: */
172: public void contributeActions(IMenuManager menuBar) {
173: for (OperationCategory category : categories.values()) {
174: for (OpAction action : category.getActions()) {
175: addActionToMenu(menuBar, action);
176: }
177: }
178: for (OpAction action : actions) {
179: addActionToMenu(menuBar, action);
180: }
181: }
182:
183: /**
184: * TODO summary sentence for addActionToMenu ...
185: *
186: * @param menuBar
187: * @param action
188: */
189: private void addActionToMenu(IMenuManager menuBar, OpAction action) {
190: if (action.getMenuPath() != null)
191: try {
192: String[] paths = action.getMenuPath().split("/"); //$NON-NLS-1$
193: IMenuManager manager = menuBar
194: .findMenuUsingPath(IWorkbenchActionConstants.MB_ADDITIONS);
195: if (manager == null) {
196: manager = menuBar;
197: }
198: String markerID = null;
199: for (String path : paths) {
200: markerID = null;
201: IContributionItem item = manager
202: .findUsingPath(path);
203: if (item == null) {
204: UiPlugin.log(action.getMenuPath()
205: + " is not a valid menuPath", null); //$NON-NLS-1$
206: break;
207: }
208: if (item instanceof IMenuManager) {
209: manager = (IMenuManager) item;
210: } else if (item.isGroupMarker()) {
211: markerID = item.getId();
212: } else if (item instanceof SubContributionItem) {
213: item = ((SubContributionItem) item)
214: .getInnerItem();
215: if (item instanceof IMenuManager) {
216: manager = (IMenuManager) item;
217: } else if (item.isGroupMarker()) {
218: markerID = item.getId();
219: }
220: }
221: }
222: if (manager != null) {
223: if (markerID != null)
224: manager.appendToGroup(markerID, action);
225: else {
226: manager.add(action);
227: }
228: } else {
229: UiPlugin.log(action.getMenuPath()
230: + " is not a valid menuPath", null); //$NON-NLS-1$
231: }
232: } catch (Exception e) {
233: UiPlugin.log("Error adding operation to menu", e); //$NON-NLS-1$
234: }
235: }
236:
237: /**
238: * @return Returns the window.
239: */
240: public IWorkbenchWindow getWindow() {
241: return window;
242: }
243:
244: /**
245: * @param window The window to set.
246: */
247: public void setWindow(IWorkbenchWindow window) {
248: IWorkbenchWindow oldwindow = this .window;
249: this .window = window;
250: Collection<OperationCategory> cat = categories.values();
251: for (OperationCategory category : cat) {
252: List<OpAction> catActions = category.getActions();
253: for (OpAction action : catActions) {
254: if (window != null)
255: window.getSelectionService().addSelectionListener(
256: action);
257: if (oldwindow != null)
258: oldwindow.getSelectionService()
259: .removeSelectionListener(action);
260: }
261: }
262: for (OpAction action : actions) {
263: if (window != null)
264: window.getSelectionService().addSelectionListener(
265: action);
266: if (oldwindow != null)
267: oldwindow.getSelectionService()
268: .removeSelectionListener(action);
269: }
270: }
271:
272: public List<OpAction> getActions() {
273: return Collections.unmodifiableList(actions);
274: }
275:
276: public Map<String, OperationCategory> getCategories() {
277: return Collections.unmodifiableMap(categories);
278: }
279:
280: private String getMenuText() {
281: return Messages.OperationMenuFactory_menu_text;
282: }
283:
284: public MenuManager createMenuManager() {
285: return new MenuManager(getMenuText(), "analysis"); //$NON-NLS-1$
286: }
287:
288: public OperationCategory findCategory(String categoryId) {
289: return getCategories().get(categoryId);
290: }
291:
292: public OpAction find(String actionId) {
293: for (OpAction action : getActions()) {
294: if (action.getId().equals(actionId)) {
295: return action;
296: }
297: }
298:
299: for (OperationCategory category : getCategories().values()) {
300: for (OpAction action : category.actions) {
301: if (action.getId().equals(actionId)) {
302: return action;
303: }
304: }
305: }
306:
307: return null;
308: }
309: }
|