View Javadoc

1   /*
2    * Created on Jul 24, 2005.
3    * Copyright 1999-2006 Faculty of Mathematics, Physics and Informatics, Comenius University, Bratislava.
4    * This file is protected by the Mozilla Public License
5    * version 1.1 (the "License"); you may not use this file except in compliance with the License. 
6    * You may obtain a copy of the License at 
7    * 
8    *      http://euromath2.sourceforge.net/license.html
9    * 
10   * Unless required by applicable law or agreed to in writing, software 
11   * distributed under the License is distributed on an "AS IS" BASIS, 
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License. 
15   */
16  package sk.uniba.euromath.editor.xmlEditor.actions;
17  
18  import java.util.List;
19  import javax.xml.namespace.QName;
20  import org.eclipse.gef.GraphicalViewer;
21  import org.eclipse.gef.ui.actions.ActionRegistry;
22  import org.eclipse.jface.action.ICoolBarManager;
23  import org.eclipse.jface.action.IMenuListener;
24  import org.eclipse.jface.action.IMenuManager;
25  import org.eclipse.jface.action.IStatusLineManager;
26  import org.eclipse.jface.action.IToolBarManager;
27  import org.eclipse.jface.action.Separator;
28  import org.eclipse.swt.widgets.Menu;
29  import org.eclipse.ui.IWorkbenchActionConstants;
30  import org.eclipse.ui.IWorkbenchPart;
31  import org.w3c.dom.Attr;
32  import org.w3c.dom.Element;
33  import org.w3c.dom.NamedNodeMap;
34  import org.w3c.dom.Node;
35  import sk.baka.ikslibs.DOMUtils;
36  import sk.baka.ikslibs.levelmapper.NodeListID;
37  import sk.uniba.euromath.Const;
38  import sk.uniba.euromath.editor.EditorSite;
39  import sk.uniba.euromath.editor.actions.AbstractActionContributor;
40  import sk.uniba.euromath.editor.actions.IActionContributor;
41  import sk.uniba.euromath.editor.xmlEditor.actions.lang.Messages;
42  
43  /***
44   * Contributor for XMLEditor. Creates and fills context menu with actions for
45   * selecting and editing.
46   * 
47   * @author Tomáš Studva Sep 19, 2005
48   */
49  
50  public class XMLActionContributor extends AbstractActionContributor implements
51                  IActionContributor {
52  
53          /***
54           * Delete submenu manager.
55           */
56          private EMMenuManager deleteMenu;
57  
58          /***
59           * Insert before submenu manager.
60           */
61          private EMMenuManager insertBeforeMenu;
62  
63          /***
64           * Insert child submenu manager.
65           */
66          private EMMenuManager insertChildMenu;
67  
68          /***
69           * Insert after submenu manager.
70           */
71          private EMMenuManager insertAfterMenu;
72  
73          /***
74           * Insert attribute submenu manager.
75           */
76          private EMMenuManager attributeMenu;
77  
78          /***
79           * Global action registry.
80           */
81          private ActionRegistry globalActionRegistry;
82  
83          /***
84           * EditorSite.
85           */
86          private EditorSite editorSite;
87  
88          /***
89           * GraphicalViewer.
90           */
91          private GraphicalViewer graphicalViewer;
92  
93          /***
94           * Menu mamager for context menu.
95           */
96          private EMMenuManager contextMenuManager;
97  
98          /***
99           * Constructor.
100          * 
101          * @param site
102          *                EditorSite instance
103          * @param viewer
104          *                GraphicalViewer from XMLEditor, to which this
105          *                contributor contributes context menu
106          */
107         public XMLActionContributor(EditorSite site, GraphicalViewer viewer) {
108                 // site is selection provider, actions handles with editorsite
109                 // global
110                 // selection from all IEditors
111                 super(site);
112                 setEditorSite(site);
113                 setXMLAccess(site.getXMLAccess());
114                 setGraphicalViewer(viewer);
115                 createContextMenu();
116         }
117 
118         @Override
119         protected void configureFactory() {
120                 // undo, redo
121                 getActionFactory().registerAction(UndoAction.id,
122                                 UndoAction.class);
123                 getActionFactory().registerAction(RedoAction.id,
124                                 RedoAction.class);
125                 // delete elements only action
126                 getActionFactory().registerAction(DeleteElementsOnlyAction.id,
127                                 DeleteElementsOnlyAction.class);
128                 // selections
129                 getActionFactory().registerAction(SelectParentAction.id,
130                                 SelectParentAction.class);
131                 // attribute actions
132                 getActionFactory().registerAction(AddAttributeWizardAction.id,
133                                 AddAttributeWizardAction.class);
134                 getActionFactory().registerAction(ModifyNodeAction.id,
135                                 ModifyNodeAction.class);
136         }
137 
138         /***
139          * Creates context menu on GraphicalViewer's control.
140          */
141         protected void createContextMenu() {
142                 // create and setup menuManager
143                 this.contextMenuManager = new EMMenuManager(
144                                 Messages
145                                                 .getString("XMLActionContributor.ContextMenuText"), //$NON-NLS-1$
146                                 ActionConsts.CONTEXT_MENU);
147                 getContextMenuManager().setRemoveAllWhenShown(true);
148                 getContextMenuManager().addMenuListener(new IMenuListener() {
149                         public void menuAboutToShow(IMenuManager manager) {
150                                 contributeToContextMenu(manager);
151                         }
152                 });
153                 // create SWT controll
154                 Menu contextMenu = getContextMenuManager().createContextMenu(
155                                 getGraphicalViewer().getControl());
156                 getGraphicalViewer().getControl().setMenu(contextMenu);
157                 // Be sure to register it so that other plug-ins can add
158                 // actions.
159                 getEditorSite().getSite().registerContextMenu(
160                                 getContextMenuManager(), getEditorSite());
161 
162                 // create and setup submenus
163                 this.deleteMenu = new EMMenuManager(
164                                 Messages
165                                                 .getString("XMLActionContributor.DeleteSubmenuText"), //$NON-NLS-1$
166                                 ActionConsts.DELETE_SUBMENU);
167 
168                 this.insertBeforeMenu = new EMMenuManager(
169                                 Messages
170                                                 .getString("XMLActionContributor.InsertBeforeSubmenuText"), //$NON-NLS-1$,
171                                 ActionConsts.INSERT_BEFORE_SUBMENU);
172                 getInsertBeforeMenu().setRemoveAllWhenShown(true);
173                 getInsertBeforeMenu().addMenuListener(new IMenuListener() {
174                         public void menuAboutToShow(IMenuManager manager) {
175                                 populateInsertPositionMenu(manager,
176                                                 InsertNodeAction.BEFORE);
177                         }
178                 });
179                 this.insertChildMenu = new EMMenuManager(
180                                 Messages
181                                                 .getString("XMLActionContributor.InsertChildSubmenuText"), //$NON-NLS-1$,
182                                 ActionConsts.INSERT_CHILD_SUBMENU);
183                 getInsertChildMenu().setRemoveAllWhenShown(true);
184                 getInsertChildMenu().addMenuListener(new IMenuListener() {
185                         public void menuAboutToShow(IMenuManager manager) {
186                                 populateInsertPositionMenu(manager,
187                                                 InsertNodeAction.AS_FIRST_CHILD);
188                         }
189                 });
190                 this.insertAfterMenu = new EMMenuManager(
191                                 Messages
192                                                 .getString("XMLActionContributor.InsertAfterSubmenuText"), //$NON-NLS-1$
193                                 ActionConsts.INSERT_AFTER_SUBMENU);
194                 getInsertAfterMenu().setRemoveAllWhenShown(true);
195                 getInsertAfterMenu().addMenuListener(new IMenuListener() {
196                         public void menuAboutToShow(IMenuManager manager) {
197                                 populateInsertPositionMenu(manager,
198                                                 InsertNodeAction.AFTER);
199                         }
200                 });
201                 this.attributeMenu = new EMMenuManager(
202                                 Messages
203                                                 .getString("XMLActionContributor.AttributeSubmenuText"), //$NON-NLS-1$
204                                 ActionConsts.ATTRIBUTE_SUBMENU);
205                 getAttributeMenu().setRemoveAllWhenShown(true);
206                 getAttributeMenu().addMenuListener(new IMenuListener() {
207                         public void menuAboutToShow(IMenuManager manager) {
208                                 populateAttributeMenu(manager);
209                         }
210                 });
211 
212         }
213 
214         /***
215          * Initialization of this contributor with access to global registry.
216          * 
217          * @param actionRegistry
218          *                global action registry
219          */
220         public void init(ActionRegistry actionRegistry) {
221                 this.globalActionRegistry = actionRegistry;
222                 // fill delete menu, because it has removeAllwhen show set to
223                 // false
224                 populateDeleteMenu(getDeleteMenu());
225         }
226 
227         /***
228          * Fills delete menu with actions. In this case delete menu is filled
229          * only in init.
230          * 
231          * @param manager
232          *                deleteMenu manager
233          */
234         protected void populateDeleteMenu(IMenuManager manager) {
235                 manager.add(checkOrCreateAction(DeleteElementsOnlyAction.id));
236         }
237 
238         /*
239          * (non-Javadoc)
240          * 
241          * @see sk.uniba.euromath.api.editor.IActionContributor#contributeToToolBar(org.eclipse.jface.action.IToolBarManager)
242          */
243         public void contributeToToolBar(IToolBarManager manager) {
244 
245         }
246 
247         /*
248          * (non-Javadoc)
249          * 
250          * @see sk.uniba.euromath.api.editor.IActionContributor#contributeToStatusLine(org.eclipse.jface.action.IStatusLineManager)
251          */
252         public void contributeToStatusLine(IStatusLineManager manager) {
253                 // position of cursor of mouse
254                 // manager.add();
255         }
256 
257         /*
258          * (non-Javadoc)
259          * 
260          * @see sk.uniba.euromath.api.editor.IActionContributor#contributeCoolBar(org.eclipse.jface.action.ICoolBarManager)
261          */
262         public void contributeCoolBar(ICoolBarManager manager) {
263 
264         }
265 
266         /*
267          * (non-Javadoc)
268          * 
269          * @see sk.uniba.euromath.api.editor.IActionContributor#contributeToMenu(org.eclipse.jface.action.IMenuManager)
270          */
271         public void contributeToMenu(IMenuManager manager) {
272 
273         }
274 
275         /***
276          * Fills context menu.
277          * 
278          * @param manager
279          */
280         protected void contributeToContextMenu(IMenuManager manager) {
281                 manager.add(new Separator(
282                                 IWorkbenchActionConstants.MB_ADDITIONS));
283 
284                 // Separator
285                 manager.add(new Separator(ActionConsts.UNDO_GROUP));
286                 // Undo
287                 manager.add(checkOrCreateAction(UndoAction.id));
288                 // Redo
289                 manager.add(checkOrCreateAction(RedoAction.id));
290 
291                 // Separator
292                 manager.add(new Separator(ActionConsts.DELETE_GROUP));
293                 // Delete - submenu
294                 manager.add(getDeleteMenu());
295 
296                 // Separator
297                 manager.add(new Separator(ActionConsts.SELECTED_ELEMENT_GROUP));
298                 // Insert before - submenu
299                 getInsertBeforeMenu().add(checkOrCreateAction(EmptyAction.id));
300                 manager.add(getInsertBeforeMenu());
301                 // Insert as child - submenu
302                 getInsertChildMenu().add(checkOrCreateAction(EmptyAction.id));
303                 manager.add(getInsertChildMenu());
304                 // Insert after - submenu
305                 getInsertAfterMenu().add(checkOrCreateAction(EmptyAction.id));
306                 manager.add(getInsertAfterMenu());
307                 // Attribute - submenu
308                 getAttributeMenu().add(checkOrCreateAction(EmptyAction.id));
309                 manager.add(getAttributeMenu());
310                 // SelectParent action
311                 manager.add(checkOrCreateAction(SelectParentAction.id));
312 
313                 // Separator
314                 manager
315                                 .add(new Separator(
316                                                 ActionConsts.ANCESTORS_ELEMENT_GROUP));
317 
318                 // Element's submenus
319                 // retreive first element on path from selected to root
320                 // using SelectParentAction
321                 SelectParentAction action = (SelectParentAction) checkOrCreateAction(SelectParentAction.id);
322                 Node node = null;
323                 if (action.isEnabled()) {
324                         String nodeId = action.getParentId();
325                         // get element for this id
326                         NodeListID nodeList = getXMLAccess().getIdManager()
327                                         .getNodeNull(nodeId);
328                         if (nodeList != null) {
329                                 node = nodeList.item(0);
330                         }
331                 }
332                 while ((node != null) && (node instanceof Element)) {
333                         EMMenuManager elementMenu = new EMMenuManager(node
334                                         .getNodeName());
335                         elementMenu.setRemoveAllWhenShown(true);
336                         elementMenu.setNode(node);
337 
338                         elementMenu.add(checkOrCreateAction(EmptyAction.id));
339 
340                         elementMenu.addMenuListener(new IMenuListener() {
341                                 public void menuAboutToShow(IMenuManager manager) {
342                                         populateElementMenu(manager);
343                                 }
344                         });
345                         node = node.getParentNode();
346                         manager.add(elementMenu);
347                 }
348                 manager.updateAll(true);
349         }
350 
351         /***
352          * Fills up element menu to right content. Prior element menu must be
353          * empty.
354          * 
355          * @param manager
356          *                of element menu
357          */
358         protected void populateElementMenu(IMenuManager manager) {
359                 EMMenuManager elementMenu = (EMMenuManager) (manager);
360 
361                 // Insert before - submenu
362                 EMMenuManager insertBeforeMenu = new EMMenuManager(
363                                 Messages
364                                                 .getString("XMLActionContributor.InsertBeforeSubmenuText"), //$NON-NLS-1$
365                                 ActionConsts.INSERT_BEFORE_SUBMENU);
366                 insertBeforeMenu.setRemoveAllWhenShown(true);
367                 insertBeforeMenu.setNode(elementMenu.getNode());
368                 insertBeforeMenu.addMenuListener(new IMenuListener() {
369                         public void menuAboutToShow(IMenuManager manager) {
370                                 populateInsertPositionMenu(manager,
371                                                 InsertNodeAction.BEFORE);
372                         }
373                 });
374                 insertBeforeMenu.add(checkOrCreateAction(EmptyAction.id));
375                 elementMenu.add(insertBeforeMenu);
376                 //
377                 // Insert as child - submenu
378                 EMMenuManager insertChildMenu = new EMMenuManager(
379                                 Messages
380                                                 .getString("XMLActionContributor.InsertChildSubmenuText"), //$NON-NLS-1$
381                                 ActionConsts.INSERT_CHILD_SUBMENU);
382                 insertChildMenu.setRemoveAllWhenShown(true);
383                 insertChildMenu.setNode(elementMenu.getNode());
384                 insertChildMenu.addMenuListener(new IMenuListener() {
385                         public void menuAboutToShow(IMenuManager manager) {
386                                 populateInsertPositionMenu(manager,
387                                                 InsertNodeAction.AS_FIRST_CHILD);
388                         }
389                 });
390                 insertChildMenu.add(checkOrCreateAction(EmptyAction.id));
391                 elementMenu.add(insertChildMenu);
392                 //
393                 // Insert after - submenu
394                 EMMenuManager insertAfterMenu = new EMMenuManager(
395                                 Messages
396                                                 .getString("XMLActionContributor.InsertAfterSubmenuText"), //$NON-NLS-1$
397                                 ActionConsts.INSERT_AFTER_SUBMENU);
398                 insertAfterMenu.setRemoveAllWhenShown(true);
399                 insertAfterMenu.setNode(elementMenu.getNode());
400                 insertAfterMenu.addMenuListener(new IMenuListener() {
401                         public void menuAboutToShow(IMenuManager manager) {
402                                 populateInsertPositionMenu(manager,
403                                                 InsertNodeAction.AFTER);
404                         }
405                 });
406                 insertAfterMenu.add(checkOrCreateAction(EmptyAction.id));
407                 elementMenu.add(insertAfterMenu);
408                 //
409                 // Attribute - submenu
410                 EMMenuManager attributeMenu = new EMMenuManager(
411                                 Messages
412                                                 .getString("XMLActionContributor.AttributeSubmenuText"), //$NON-NLS-1$
413                                 ActionConsts.ATTRIBUTE_SUBMENU);
414                 attributeMenu.setRemoveAllWhenShown(true);
415                 attributeMenu.setNode(elementMenu.getNode());
416                 attributeMenu.addMenuListener(new IMenuListener() {
417                         public void menuAboutToShow(IMenuManager manager) {
418                                 populateAttributeMenu(manager);
419                         }
420                 });
421                 attributeMenu.add(checkOrCreateAction(EmptyAction.id));
422                 elementMenu.add(attributeMenu);
423 
424                 // Select action
425                 String nodeId = getXMLAccess().getIdManager().getID(
426                                 elementMenu.getNode());
427                 elementMenu.add(new SelectAction(nodeId, getEditorSite()));
428 
429                 // Delete action
430                 elementMenu.add(new DeleteElementAction((Element) (elementMenu
431                                 .getNode()), getEditorSite()));
432 
433                 elementMenu.updateAll(true);
434         }
435 
436         /***
437          * Fills up insert before/child/after menu to right content. Insert menu
438          * must be empty prior.
439          * 
440          * @param manager
441          *                of insert before menu
442          * @param position
443          *                one of {@link ActionConsts#BEFORE}/{@link ActionConsts#CHILD}/{@link ActionConsts#AFTER}
444          */
445         protected void populateInsertPositionMenu(IMenuManager manager,
446                         short position) {
447                 if ((position != InsertNodeAction.BEFORE)
448                                 & (position != InsertNodeAction.AS_FIRST_CHILD)
449                                 & (position != InsertNodeAction.AFTER))
450                         throw new IllegalArgumentException("Illegal position."); //$NON-NLS-1$
451 
452                 // if menu is not context, is has associated element it works
453                 // with
454                 Element element = (Element) (((EMMenuManager) manager)
455                                 .getNode());
456                 InsertNodeAction action = null;
457 
458                 if (element != null) {
459                         action = new InsertNodeAction(element, position,
460                                         getEditorSite());
461                 } else {
462                         action = new InsertNodeAction(Node.ELEMENT_NODE,
463                                         position, getEditorSite());
464                 }
465 
466                 action.update();
467                 manager.add(action);
468 
469                 // Separator
470                 manager.add(new Separator(
471                                 ActionConsts.INSERT_ELEMENT_WITH_NAME_GROUP));
472                 // Insert actions by element name
473                 if (action.isEnabled()) {
474                         List<QName> qNames = getDocumentModifyHelper()
475                                         .getInsertableElementsQNames(
476                                                         action.getPointer());
477                         for (QName qName : qNames) {
478                                 //TODO STUDVA menu!!!!!!!!
479                                 /*
480                                 if (element == null) {
481                                         XMLAccessModifyAction act = new InsertNodeAction(
482                                                         qName, position,
483                                                         getEditorSite());
484                                         act.update();
485                                         manager.add(act);
486                                 } else {
487                                         XMLAccessModifyAction act = new InsertNodeAction(
488                                                         qName, position,
489                                                         element,
490                                                         getEditorSite());
491                                         act.update();
492                                         manager.add(act);
493                                 }
494                                 */
495                         }
496                 }
497                 manager.updateAll(true);
498         }
499 
500         /***
501          * Fills up attribute menu to right content. Prior attribute menu must
502          * be empty.
503          * 
504          * @param manager
505          *                of attribute menu
506          */
507         protected void populateAttributeMenu(IMenuManager manager) {
508                 Element element = (Element) (((EMMenuManager) manager)
509                                 .getNode());
510                 AddAttributeWizardAction addWizardAction;
511 
512                 if (element != null) {
513                         addWizardAction = new AddAttributeWizardAction(element,
514                                         getEditorSite());
515                 } else {
516                         addWizardAction = (AddAttributeWizardAction) (checkOrCreateAction(AddAttributeWizardAction.id));
517                 }
518                 addWizardAction.update();
519 
520                 if (addWizardAction.isEnabled()) {
521                         //TODO STUDVA menu
522                         /*
523                         NamedNodeMap attributes = addWizardAction.getElement()
524                                         .getAttributes();
525                         for (int i = 0; i < attributes.getLength(); i++) {
526                                 Attr attribute = (Attr) (attributes.item(i));
527                                 // if it is emp:id attribute, ignore it
528                                 if (!(DOMUtils.equalsNodeQName(attribute,
529                                                 Const.EM_ATTRIBUTE_ID_QNAME))) {
530                                         EMMenuManager attrMenu = new EMMenuManager(
531                                                         attribute.getName());
532                                         attrMenu.add(new DeleteAttributeAction(
533                                                         attribute,
534                                                        getEditorSite()));
535                                         attrMenu.add(new ModifyNodeAction(
536                                                         attribute,
537                                                         getEditorSite()));
538                                         manager.add(attrMenu);
539                                 }
540                         }
541                         */
542                 }
543                 manager.add(new Separator(ActionConsts.ADD_ATTRIBUTE_GROUP));
544                 manager.add(addWizardAction);
545                 manager.updateAll(true);
546         }
547 
548         /***
549          * Global registry for all IEditors.
550          * 
551          * @return action registry
552          */
553         public ActionRegistry getGlobalActionRegistry() {
554                 return this.globalActionRegistry;
555         }
556 
557         /***
558          * @return Returns the editorSite.
559          */
560         public EditorSite getEditorSite() {
561                 return this.editorSite;
562         }
563 
564         /***
565          * @param editorSite
566          *                The editorSite to set.
567          */
568         public void setEditorSite(EditorSite editorSite) {
569                 this.editorSite = editorSite;
570         }
571 
572         /***
573          * @return Returns the graphicalViewer.
574          */
575         public GraphicalViewer getGraphicalViewer() {
576                 return this.graphicalViewer;
577         }
578 
579         /***
580          * @param graphicalViewer
581          *                The graphicalViewer to set.
582          */
583         public void setGraphicalViewer(GraphicalViewer graphicalViewer) {
584                 this.graphicalViewer = graphicalViewer;
585         }
586 
587         /***
588          * @param globalActionRegistry
589          *                The globalActionRegistry to set.
590          */
591         public void setGlobalActionRegistry(ActionRegistry globalActionRegistry) {
592                 this.globalActionRegistry = globalActionRegistry;
593         }
594 
595         @Override
596         public IWorkbenchPart getWorkbenchPart() {
597                 return getEditorSite();
598         }
599 
600         @Override
601         public ActionRegistry getActionRegistry() {
602                 return this.globalActionRegistry;
603         }
604 
605         /***
606          * @return Returns the attributeMenu.
607          */
608         protected EMMenuManager getAttributeMenu() {
609                 return this.attributeMenu;
610         }
611 
612         /***
613          * @return Returns the contextMenuManager.
614          */
615         protected EMMenuManager getContextMenuManager() {
616                 return this.contextMenuManager;
617         }
618 
619         /***
620          * @return Returns the deleteMenu.
621          */
622         protected EMMenuManager getDeleteMenu() {
623                 return this.deleteMenu;
624         }
625 
626         /***
627          * @return Returns the insertAfterMenu.
628          */
629         protected EMMenuManager getInsertAfterMenu() {
630                 return this.insertAfterMenu;
631         }
632 
633         /***
634          * @return Returns the insertBeforeMenu.
635          */
636         protected EMMenuManager getInsertBeforeMenu() {
637                 return this.insertBeforeMenu;
638         }
639 
640         /***
641          * @return Returns the insertChildMenu.
642          */
643         protected EMMenuManager getInsertChildMenu() {
644                 return this.insertChildMenu;
645         }
646 
647 }