View Javadoc

1   /*
2    * Copyright 1999-2006 Faculty of Mathematics, Physics and Informatics, Comenius
3    * University, Bratislava. This file is protected by the Mozilla Public License
4    * version 1.1 (the License); you may not use this file except in compliance
5    * with the License. You may obtain a copy of the License at
6    * http://euromath2.sourceforge.net/license.html Unless required by applicable
7    * law or agreed to in writing, software distributed under the License is
8    * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
9    * KIND, either express or implied. See the License for the specific language
10   * governing permissions and limitations under the License.
11   */
12  package sk.uniba.euromath.plugin.views.outline.actions;
13  
14  import java.util.List;
15  
16  import org.eclipse.gef.commands.CommandStack;
17  import org.eclipse.gef.ui.actions.ActionRegistry;
18  import org.eclipse.jface.action.Action;
19  import org.eclipse.jface.action.IAction;
20  import org.eclipse.jface.action.IMenuListener;
21  import org.eclipse.jface.action.IMenuManager;
22  import org.eclipse.jface.action.IToolBarManager;
23  import org.eclipse.jface.action.MenuManager;
24  import org.eclipse.jface.action.Separator;
25  import org.eclipse.swt.widgets.Menu;
26  import org.eclipse.ui.IActionBars;
27  import org.eclipse.ui.IWorkbenchActionConstants;
28  import org.eclipse.ui.IWorkbenchPart;
29  import org.w3c.dom.Node;
30  
31  import sk.uniba.euromath.editor.actions.AbstractActionContributor;
32  import sk.uniba.euromath.editor.textEditor.actions.CopyAsTextAction;
33  import sk.uniba.euromath.editor.textEditor.actions.PasteTextAction;
34  import sk.uniba.euromath.editor.xmlEditor.actions.ActionConsts;
35  import sk.uniba.euromath.editor.xmlEditor.actions.AddAttributeWizardAction;
36  import sk.uniba.euromath.editor.xmlEditor.actions.CopyAction;
37  import sk.uniba.euromath.editor.xmlEditor.actions.CutAction;
38  import sk.uniba.euromath.editor.xmlEditor.actions.DecloseElementAction;
39  import sk.uniba.euromath.editor.xmlEditor.actions.DeleteSelectionAction;
40  import sk.uniba.euromath.editor.xmlEditor.actions.EmptyAction;
41  import sk.uniba.euromath.editor.xmlEditor.actions.EnclosingAction;
42  import sk.uniba.euromath.editor.xmlEditor.actions.InsertElementAction;
43  import sk.uniba.euromath.editor.xmlEditor.actions.InsertEntityReferenceAction;
44  import sk.uniba.euromath.editor.xmlEditor.actions.InsertPosition;
45  import sk.uniba.euromath.editor.xmlEditor.actions.InsertTextualNode;
46  import sk.uniba.euromath.editor.xmlEditor.actions.ModifyNodeAction;
47  import sk.uniba.euromath.editor.xmlEditor.actions.PasteAction;
48  import sk.uniba.euromath.editor.xmlEditor.actions.RedoAction;
49  import sk.uniba.euromath.editor.xmlEditor.actions.UndoAction;
50  import sk.uniba.euromath.plugin.views.outline.XMLAccessContentProvider;
51  import sk.uniba.euromath.plugin.views.outline.XMLOutlinePage;
52  import sk.uniba.euromath.plugin.views.outline.actions.lang.Messages;
53  
54  /***
55   * @author Tomáš Studva 16.10.2005
56   */
57  public class XMLOutlineActionContributor extends AbstractActionContributor {
58  
59          protected IWorkbenchPart workbenchPart;
60  
61          protected XMLOutlinePage xmlOutlinePage;
62  
63          protected ActionRegistry actionRegistry;
64  
65          private final OutlineContentSwitcher attributeSwitcher;
66  
67          private final OutlineContentSwitcher cdataSwitcher;
68  
69          private final OutlineContentSwitcher commentSwitcher;
70  
71          private final OutlineContentSwitcher prociSwitcher;
72  
73          private final OutlineContentSwitcher textNodeSwitcher;
74  
75          // private final OutlineSourceSwitcher sourceSwitcher;
76  
77          /***
78           * Constructor.
79           * 
80           * @param wokbenchPart
81           */
82          public XMLOutlineActionContributor(XMLOutlinePage page) {
83                  super(page, (CommandStack) page.getAdapter(CommandStack.class));
84  
85                  this.xmlOutlinePage = page;
86                  setWorkbechPart(page.getSite().getPage().getActivePart());
87                  setActionRegistry(new ActionRegistry());
88                  createContextMenu();
89                  // add this to listen part activation, to reasign global actions
90  
91                  this.attributeSwitcher = new OutlineContentSwitcher(
92                                  getContentProvider(),
93                                  Messages
94                                                  .getString("XMLOutlineActionContributor.0"), Node.ATTRIBUTE_NODE, true); //$NON-NLS-1$
95                  this.cdataSwitcher = new OutlineContentSwitcher(
96                                  getContentProvider(),
97                                  Messages
98                                                  .getString("XMLOutlineActionContributor.1"), Node.CDATA_SECTION_NODE, true); //$NON-NLS-1$
99                  this.commentSwitcher = new OutlineContentSwitcher(
100                                 getContentProvider(),
101                                 Messages
102                                                 .getString("XMLOutlineActionContributor.2"), Node.COMMENT_NODE, true); //$NON-NLS-1$
103                 this.prociSwitcher = new OutlineContentSwitcher(
104                                 getContentProvider(),
105                                 Messages
106                                                 .getString("XMLOutlineActionContributor.3"), //$NON-NLS-1$
107                                 Node.PROCESSING_INSTRUCTION_NODE, true);
108                 this.textNodeSwitcher = new OutlineContentSwitcher(
109                                 getContentProvider(),
110                                 Messages
111                                                 .getString("XMLOutlineActionContributor.4"), Node.TEXT_NODE, true); //$NON-NLS-1$
112                 // sourceSwitcher = new
113                 // OutlineSourceSwitcher(getXMLOutlinePage());
114                 fillLocalMenu(this.xmlOutlinePage.getSite().getActionBars()
115                                 .getMenuManager());
116                 fillLocalToolBar(this.xmlOutlinePage.getSite().getActionBars()
117                                 .getToolBarManager());
118                 hookGlobalActions();
119         }
120 
121         @Override
122         public void dispose() {
123                 IActionBars bars = this.xmlOutlinePage.getSite()
124                                 .getActionBars();
125                 // undo, redo
126                 bars.setGlobalActionHandler(UndoAction.id, null);
127                 bars.setGlobalActionHandler(RedoAction.id, null);
128                 // cut, copy, paste
129                 bars.setGlobalActionHandler(CutAction.id, null);
130                 bars.setGlobalActionHandler(CopyAction.id, null);
131                 bars.setGlobalActionHandler(PasteAction.id, null);
132                 // delete
133                 bars.setGlobalActionHandler(DeleteSelectionAction.id, null);
134                 bars.updateActionBars();
135 
136         }
137 
138         @Override
139         protected void configureFactory() {
140                 // undo, redo
141                 getActionFactory().registerAction(UndoAction.id,
142                                 UndoAction.class);
143                 getActionFactory().registerAction(RedoAction.id,
144                                 RedoAction.class);
145 
146                 // clipboard actions
147                 getActionFactory()
148                                 .registerAction(CutAction.id, CutAction.class);
149                 getActionFactory().registerAction(CopyAction.id,
150                                 CopyAction.class);
151                 getActionFactory().registerAction(CopyAsTextAction.id,
152                                 CopyAsTextAction.class);
153                 getActionFactory().registerAction(PasteAction.id,
154                                 PasteAction.class);
155 
156                 // deleting actions
157                 getActionFactory().registerAction(DeleteSelectionAction.id,
158                                 DeleteSelectionAction.class);
159 
160                 // attribute actions
161                 getActionFactory().registerAction(AddAttributeWizardAction.id,
162                                 AddAttributeWizardAction.class);
163                 // modify node action
164                 getActionFactory().registerAction(ModifyNodeAction.id,
165                                 ModifyNodeAction.class);
166 
167                 // en(de)close
168                 getActionFactory().registerAction(DecloseElementAction.id,
169                                 DecloseElementAction.class);
170                 getActionFactory().registerAction(EnclosingAction.id,
171                                 EnclosingAction.class);
172 
173         }
174 
175         private void createContextMenu() {
176                 MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
177                 menuMgr.setRemoveAllWhenShown(true);
178                 menuMgr.addMenuListener(new IMenuListener() {
179                         public void menuAboutToShow(IMenuManager manager) {
180                                 populateContextMenu(manager);
181                         }
182                 });
183                 Menu menu = menuMgr.createContextMenu(this.xmlOutlinePage
184                                 .getControl());
185                 this.xmlOutlinePage.getControl().setMenu(menu);
186                 this.xmlOutlinePage.getSite().registerContextMenu(
187                                 "menu1", menuMgr, //$NON-NLS-1$
188                                 null);
189         }
190 
191         protected void populateContextMenu(IMenuManager manager) {
192                 final List<Node> selectedNodes = this.xmlOutlinePage
193                                 .getDOMSelection().getContents();
194                 List<Action> actions;
195 
196                 manager.add(new Separator("Undo actions")); //$NON-NLS-1$
197                 actions = checkOrCreateActions(ActionConsts.UNDO_ACTIONS);
198                 for (IAction action : actions) {
199                         manager.add(action);
200                 }
201 
202                 manager.add(new Separator("Clipboard actions")); //$NON-NLS-1$
203                 manager.add(checkOrCreateAction(CutAction.id));
204                 manager.add(checkOrCreateAction(CopyAction.id));
205                 manager.add(checkOrCreateAction(CopyAsTextAction.id));
206 
207                 manager.add(new Separator("Node actions")); //$NON-NLS-1$
208                 // Insert
209                 // ->insert
210                 MenuManager insertSubMenu = new MenuManager("Insert"); //$NON-NLS-1$
211                 manager.add(insertSubMenu);
212                 // ->insert -> beforeSubMenu
213                 MenuManager insertBeforeSubMenu = new MenuManager("Before"); //$NON-NLS-1$
214                 insertBeforeSubMenu.setRemoveAllWhenShown(true);
215                 insertBeforeSubMenu.add(checkOrCreateAction(EmptyAction.id));
216                 insertBeforeSubMenu.addMenuListener(new IMenuListener() {
217                         public void menuAboutToShow(IMenuManager manager) {
218                                 populateInsertSubMenu(InsertPosition.Before,
219                                                 manager);
220                         }
221                 });
222                 insertSubMenu.add(insertBeforeSubMenu);
223                 // ->insert -> afterSubMenu
224                 MenuManager insertAfterSubMenu = new MenuManager("After"); //$NON-NLS-1$
225                 insertAfterSubMenu.setRemoveAllWhenShown(true);
226                 insertAfterSubMenu.add(checkOrCreateAction(EmptyAction.id));
227                 insertAfterSubMenu.addMenuListener(new IMenuListener() {
228                         public void menuAboutToShow(IMenuManager manager) {
229                                 populateInsertSubMenu(InsertPosition.After,
230                                                 manager);
231                         }
232                 });
233                 insertSubMenu.add(insertAfterSubMenu);
234                 // ->insert -> AsFirstChildSubMenu
235                 if (selectedNodes.size() == 1
236                                 && selectedNodes.get(0).getNodeType() == Node.ELEMENT_NODE) {
237                         MenuManager insertAsFirstChildSubMenu = new MenuManager(
238                                         "As first child"); //$NON-NLS-1$
239                         insertAsFirstChildSubMenu.setRemoveAllWhenShown(true);
240                         insertAsFirstChildSubMenu
241                                         .add(checkOrCreateAction(EmptyAction.id));
242                         insertAsFirstChildSubMenu
243                                         .addMenuListener(new IMenuListener() {
244                                                 public void menuAboutToShow(
245                                                                 IMenuManager manager) {
246                                                         populateInsertSubMenu(
247                                                                         InsertPosition.AsFirstChild,
248                                                                         manager);
249                                                 }
250                                         });
251                         insertSubMenu.add(insertAsFirstChildSubMenu);
252                 }
253                 insertSubMenu.add(new AddAttributeWizardAction(
254                                 getWorkbenchPart()));
255 
256                 // Delete
257                 // ->delete
258                 manager.add(checkOrCreateAction(DeleteSelectionAction.id));
259                 // en(de)close actions
260                 manager.add(checkOrCreateAction(EnclosingAction.id));
261                 manager.add(checkOrCreateAction(DecloseElementAction.id));
262                 // Modify
263                 // ->modify
264                 manager.add(checkOrCreateAction(ModifyNodeAction.id));
265 
266                 manager.add(new Separator(
267                                 IWorkbenchActionConstants.MB_ADDITIONS));
268         }
269 
270         /***
271          * Fills up insert before/child/after menu to right content. Insert menu
272          * must be empty prior.
273          * 
274          * @param manager
275          *                of insert menu
276          * @param position
277          *                one of {@link InsertPosition#Before},
278          *                {@link InsertPosition#AsFirstChild},
279          *                {@link InsertPosition#After}
280          */
281         protected void populateInsertSubMenu(InsertPosition position,
282                         IMenuManager manager) {
283                 if ((position != InsertPosition.Before)
284                                 & (position != InsertPosition.AsFirstChild)
285                                 & (position != InsertPosition.After)) {
286                         throw new IllegalArgumentException("Illegal position."); //$NON-NLS-1$
287                 }
288                 manager.add(new PasteAction(position, getWorkbenchPart()));
289                 manager.add(new PasteTextAction(position, getWorkbenchPart()));
290                 manager.add(new Separator());
291                 manager.add(new InsertElementAction(position, null,
292                                 getWorkbenchPart()));
293                 manager.add(new InsertTextualNode(Node.TEXT_NODE, position,
294                                 getWorkbenchPart()));
295                 manager.add(new InsertTextualNode(Node.CDATA_SECTION_NODE,
296                                 position, getWorkbenchPart()));
297                 manager.add(new InsertTextualNode(Node.COMMENT_NODE, position,
298                                 getWorkbenchPart()));
299                 manager.add(new InsertTextualNode(
300                                 Node.PROCESSING_INSTRUCTION_NODE, position,
301                                 getWorkbenchPart()));
302                 manager.add(new InsertEntityReferenceAction(position, null,
303                                 getWorkbenchPart()));
304         }
305 
306         /***
307          * Fills menu shown after click on arrow in right upper corner.
308          */
309         public void fillLocalMenu(IMenuManager manager) {
310                 manager.add(this.attributeSwitcher);
311                 manager.add(this.cdataSwitcher);
312                 manager.add(this.commentSwitcher);
313                 manager.add(this.prociSwitcher);
314                 manager.add(this.textNodeSwitcher);
315                 // manager.add(sourceSwitcher);
316         }
317 
318         // IMPLEMENT: when images for atomic xml action will be chosen, local
319         // toolbar
320         // should be filled with them...
321         public void fillLocalToolBar(IToolBarManager manager) {
322                 // do nothing
323         }
324 
325         public void hookGlobalActions() {
326                 IActionBars bars = this.xmlOutlinePage.getSite()
327                                 .getActionBars();
328                 // undo, redo
329                 bars.setGlobalActionHandler(UndoAction.id,
330                                 checkOrCreateAction(UndoAction.id));
331                 bars.setGlobalActionHandler(RedoAction.id,
332                                 checkOrCreateAction(RedoAction.id));
333                 // cut, copy, paste
334                 bars.setGlobalActionHandler(CutAction.id,
335                                 checkOrCreateAction(CutAction.id));
336                 bars.setGlobalActionHandler(CopyAction.id,
337                                 checkOrCreateAction(CopyAction.id));
338                 bars.setGlobalActionHandler(PasteAction.id,
339                                 checkOrCreateAction(PasteAction.id));
340                 // delete
341                 bars.setGlobalActionHandler(DeleteSelectionAction.id,
342                                 checkOrCreateAction(DeleteSelectionAction.id));
343                 bars.updateActionBars();
344         }
345 
346         /*
347          * (non-Javadoc)
348          * 
349          * @see sk.uniba.euromath.editor.xmlEditor.actions.AbstractActionContributor#getWorkbenchPart()
350          */
351         @Override
352         public IWorkbenchPart getWorkbenchPart() {
353                 return this.workbenchPart;
354         }
355 
356         /*
357          * (non-Javadoc)
358          * 
359          * @see sk.uniba.euromath.editor.xmlEditor.actions.AbstractActionContributor#getActionRegistry()
360          */
361         @Override
362         public ActionRegistry getActionRegistry() {
363                 return this.actionRegistry;
364         }
365 
366         /***
367          * @param actionRegistry
368          *                The actionRegistry to set.
369          */
370         public void setActionRegistry(ActionRegistry actionRegistry) {
371                 this.actionRegistry = actionRegistry;
372         }
373 
374         public XMLAccessContentProvider getContentProvider() {
375                 return this.xmlOutlinePage.getContentProvider();
376         }
377 
378         /***
379          * @param workbechPart
380          *                The workbechPart to set.
381          */
382         public void setWorkbechPart(IWorkbenchPart workbenchPart) {
383                 this.workbenchPart = workbenchPart;
384         }
385 
386         private class OutlineContentSwitcher extends Action {
387                 private XMLAccessContentProvider provider;
388 
389                 private short nodeType;
390 
391                 public OutlineContentSwitcher(
392                                 XMLAccessContentProvider provider, String text,
393                                 short nodeType, boolean on) {
394                         super(text, IAction.AS_CHECK_BOX);
395                         setChecked(on);
396                         this.provider = provider;
397                         this.nodeType = nodeType;
398                 }
399 
400                 /*
401                  * (non-Javadoc)
402                  * 
403                  * @see org.eclipse.jface.action.IAction#run()
404                  */
405                 @Override
406                 public void run() {
407                         getProvider().setShowType(nodeType, isChecked());
408                         XMLOutlineActionContributor.this.xmlOutlinePage
409                                         .getViewer().refresh();
410                 }
411 
412                 /***
413                  * @return Returns the provider.
414                  */
415                 protected XMLAccessContentProvider getProvider() {
416                         return this.provider;
417                 }
418 
419                 /***
420                  * @param provider
421                  *                The provider to set.
422                  */
423                 protected void setProvider(XMLAccessContentProvider provider) {
424                         this.provider = provider;
425                 }
426         }
427 
428         private class OutlineSourceSwitcher extends Action {
429                 private static final String SHOW_TRN = "Show transformed document"; //$NON-NLS-1$
430 
431                 private static final String SHOW_ORI = "Show original document"; //$NON-NLS-1$
432 
433                 private boolean showsTransformed;
434 
435                 private XMLOutlinePage page;
436 
437                 public OutlineSourceSwitcher(XMLOutlinePage page) {
438                         super(SHOW_TRN);
439                         this.page = page;
440                         this.showsTransformed = false;
441                 }
442 
443                 /*
444                  * (non-Javadoc)
445                  * 
446                  * @see org.eclipse.jface.action.IAction#run()
447                  */
448                 @Override
449                 public void run() {
450                         setShowsTransformed(!isShowsTransformed());
451                         if (isShowsTransformed()) {
452                                 setText(SHOW_ORI);
453                         } else {
454                                 setText(SHOW_TRN);
455                         }
456                         getPage().setShowTransformed(isShowsTransformed());
457                 }
458 
459                 /***
460                  * @return Returns the showsTransformed.
461                  */
462                 protected boolean isShowsTransformed() {
463                         return this.showsTransformed;
464                 }
465 
466                 /***
467                  * @param showsTransformed
468                  *                The showsTransformed to set.
469                  */
470                 protected void setShowsTransformed(boolean showsTransformed) {
471                         this.showsTransformed = showsTransformed;
472                 }
473 
474                 /***
475                  * @return Returns the page.
476                  */
477                 protected XMLOutlinePage getPage() {
478                         return this.page;
479                 }
480 
481                 /***
482                  * @param page
483                  *                The page to set.
484                  */
485                 protected void setPage(XMLOutlinePage page) {
486                         this.page = page;
487                 }
488         }
489 
490         /***
491          * @param workbenchPart
492          *                The workbenchPart to set.
493          */
494         protected void setWorkbenchPart(IWorkbenchPart workbenchPart) {
495                 this.workbenchPart = workbenchPart;
496         }
497 }