1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package sk.uniba.euromath.editor;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.EnumMap;
21 import java.util.EnumSet;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.LinkedList;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Queue;
28 import java.util.Set;
29
30 import org.apache.commons.io.FilenameUtils;
31 import org.eclipse.core.runtime.IAdaptable;
32 import org.eclipse.core.runtime.IProgressMonitor;
33 import org.eclipse.core.runtime.IStatus;
34 import org.eclipse.draw2d.ColorConstants;
35 import org.eclipse.draw2d.geometry.Dimension;
36 import org.eclipse.draw2d.geometry.Point;
37 import org.eclipse.jface.dialogs.MessageDialog;
38 import org.eclipse.jface.viewers.ISelection;
39 import org.eclipse.jface.viewers.ISelectionChangedListener;
40 import org.eclipse.jface.viewers.ISelectionProvider;
41 import org.eclipse.jface.window.Window;
42 import org.eclipse.swt.SWT;
43 import org.eclipse.swt.graphics.Rectangle;
44 import org.eclipse.swt.layout.FillLayout;
45 import org.eclipse.swt.widgets.Composite;
46 import org.eclipse.ui.IEditorInput;
47 import org.eclipse.ui.IEditorSite;
48 import org.eclipse.ui.PartInitException;
49 import org.eclipse.ui.part.EditorPart;
50 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
51
52 import sk.baka.ikslibs.ResultEnum;
53 import sk.baka.ikslibs.interval.DOMIntervalSet;
54 import sk.baka.xml.gene.CoordinatorInputKey;
55 import sk.baka.xml.gene.ExportException;
56 import sk.baka.xml.gene.exportgraph.TransformGraph;
57 import sk.uniba.euromath.EuroMath;
58 import sk.uniba.euromath.document.DocumentView;
59 import sk.uniba.euromath.document.XMLAccess;
60 import sk.uniba.euromath.editor.actions.MultiViewActionContributor;
61 import sk.uniba.euromath.editor.dialogs.Dialogs;
62 import sk.uniba.euromath.editor.dialogs.IWidgetFactory;
63 import sk.uniba.euromath.editor.dialogs.WidgetWrapperDialog;
64 import sk.uniba.euromath.editor.lang.Messages;
65 import sk.uniba.euromath.editor.selections.DOMSelectionChangedEvent;
66 import sk.uniba.euromath.editor.selections.IDOMSelectionChangedListener;
67 import sk.uniba.euromath.editor.selections.IDOMSelectionProvider;
68 import sk.uniba.euromath.editor.widgets.FileBrowserEnum;
69 import sk.uniba.euromath.editor.widgets.FileRequirementsEnum;
70 import sk.uniba.euromath.editor.widgets.FileSelector;
71 import sk.uniba.euromath.editor.widgets.GraphSelectorWidget;
72 import sk.uniba.euromath.editor.widgets.IUserInputWidget;
73 import sk.uniba.euromath.editor.widgets.MessageLevelEnum;
74 import sk.uniba.euromath.editor.widgets.MultiWidget;
75 import sk.uniba.euromath.editor.xmlEditor.XMLEditor;
76 import sk.uniba.euromath.editor.xmlEditor.policies.FigureSelectionPolicy;
77 import sk.uniba.euromath.gene.IEditorDataReceiver;
78 import sk.uniba.euromath.gene.GeneDataProvider.RendererSite;
79 import sk.uniba.euromath.gene.gui.widgets.EncodingWidget;
80 import sk.uniba.euromath.gene.gui.widgets.XMLSerializerPropertiesWidget;
81 import sk.uniba.euromath.plugin.views.outline.XMLOutlinePage;
82 import sk.uniba.euromath.tools.StringTools;
83
84 /***
85 * TODO STUDVA recoment
86 * <h6>Is a View, is a true compound editor, composites of IEditors.</h6>
87 * <p>
88 * This class houses instances of IEditors: chooses from available, creates
89 * and/or destroys instances of IEditors when required and creates and positions
90 * Composites for them.
91 * </p>
92 * <p>
93 * Is is also ISelectionProvider and owns XMLSelection. Other
94 * IXMLSelectionProviders refernces this XMLSelection, modifies it and send
95 * changes back to EditorSite through methods setSelection(...) or
96 * selectionChanged(...)<br>
97 * </p>
98 * <p>
99 * Is also responsible for loading, transforming, saving. Main functionality is
100 * driven by GENE.
101 * </p>
102 * <p>
103 * Acts as view in MultiViewXMLEditor.
104 * </p>
105 *
106 * @author Tomáš Studva, Martin Vysny, Martin Kollar
107 * @see sk.uniba.euromath.editor.IEditor
108 */
109 public final class EditorSite extends EditorPart implements
110 IDOMSelectionProvider, IDOMSelectionChangedListener,
111 ISelectionProvider, IEditorDataReceiver, IFocusListener {
112
113 /***
114 * Auxiliary class for structure purpose only. Ties together IEditor info
115 * and stores IEditor hierarchy.
116 *
117 * @author Tomáš Studva 23.1.2006
118 */
119 private class EditorContext {
120 /***
121 * Editor.
122 */
123 public IEditor editor;
124
125 /***
126 * Used renderer site by editor.
127 */
128 public RendererSite rendererSite;
129
130 /***
131 * Associated input.
132 */
133 public CoordinatorInputKey key;
134
135 /***
136 * GENE id - renderer id.
137 */
138 public String id;
139
140 /***
141 * Parent editor context reference.
142 */
143 public EditorContext parentEditorContext;
144
145 /***
146 * Contructor.
147 *
148 * @param editor -
149 * IEditor
150 * @param rendererSite -
151 * used renderer site by editor
152 * @param key
153 * Associated input
154 * @param id -
155 * GENE id - renderer id
156 * @param parentEditorContext -
157 * parent editor context reference
158 */
159 public EditorContext(IEditor editor, RendererSite rendererSite,
160 CoordinatorInputKey key, String id,
161 EditorContext parentEditorContext) {
162 super();
163 this.editor = editor;
164 this.rendererSite = rendererSite;
165 this.key = key;
166 this.parentEditorContext = parentEditorContext;
167 this.id = id;
168 }
169 }
170
171 /***
172 * Contributor instance.
173 */
174 private MultiViewActionContributor actionContributor;
175
176 /***
177 * Topmost composite.
178 */
179 private Composite rootComposite;
180
181 /***
182 * Active editor.
183 */
184 private IEditor activeEditor;
185
186 /***
187 * Root editor, works with rootComposite.
188 */
189 private IEditor rootEditor;
190
191 /***
192 * Editor containing this as view.
193 */
194 private final MultiViewXMLEditor parentMultiEditor;
195
196 private DOMIntervalSet xmlSelection;
197
198 /***
199 * Selection listeners of this editor site. Editor site selectionis
200 * synchronized with selection provider from this list.
201 */
202 private final List<IDOMSelectionChangedListener> selectionListeners = new ArrayList<IDOMSelectionChangedListener>();
203
204 /***
205 * IFocusListeners listening to focus changes between IEditors.
206 */
207 private final List<IFocusListener> focusListeners = new ArrayList<IFocusListener>();
208
209 /***
210 * Outline page for this EditorSite - view.
211 */
212 private XMLOutlinePage outlinePage;
213
214 /***
215 * Holds only those ids of nodes from xml data document, that are
216 * visualized(displayed) by at least one IEditor.
217 */
218 private final Set<String> visualizedIds;
219
220 /***
221 * Holds source of last selectionChangeEvent.
222 */
223
224 /***
225 * For every key map holds associated(created, used) IEditor.
226 */
227 private final Map<CoordinatorInputKey, IEditor> keyEditorMap = new HashMap<CoordinatorInputKey, IEditor>();
228
229 /***
230 * For every key map holds renderer related context(site).
231 */
232 private Map<CoordinatorInputKey, RendererSite> keyRendererSiteMap;
233
234 /***
235 * For every key map holds editor related context. Context also contains
236 * key, so whole tree hierarchy is navigable.
237 */
238 private Map<CoordinatorInputKey, EditorContext> editorContexts = new HashMap<CoordinatorInputKey, EditorContext>();
239
240 /***
241 * Constructor.
242 *
243 * @param parentMultiEditor
244 * host for this EditorSite.
245 */
246 public EditorSite(MultiViewXMLEditor parentMultiEditor) {
247 this.parentMultiEditor = parentMultiEditor;
248
249
250 this.xmlSelection = new DOMIntervalSet();
251 this.visualizedIds = new HashSet<String>();
252 }
253
254 /***
255 * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
256 */
257 @Override
258 public void doSave(IProgressMonitor monitor) {
259 try {
260 getParentMultiEditor().getResourceManipulator().save(null);
261 } catch (Exception ex) {
262 EuroMath.log(IStatus.ERROR, 0, "Error storing document", ex);
263 MessageDialog
264 .openError(getEditorSite().getShell(),
265 Messages.getString("ERROR"),
266 Messages.getString("ERROR_STORING_DOCUMENT") + ex.getLocalizedMessage());
267 }
268 }
269
270 /***
271 * @see org.eclipse.ui.ISaveablePart#doSaveAs()
272 */
273 @Override
274 public void doSaveAs() {
275 final IWidgetFactory<MultiWidget> wfactory = new IWidgetFactory<MultiWidget>() {
276
277
278
279
280
281 public MultiWidget create(Composite parent) {
282 final List<IUserInputWidget> widgets = new ArrayList<IUserInputWidget>(
283 3);
284
285 final String docName = parentMultiEditor.getXMLAccess().getFileName();
286 int extSeparator = docName.lastIndexOf('.');
287 if (extSeparator < 0)
288 extSeparator = docName.length();
289 final String documentExtension = FilenameUtils.getExtension(docName);
290 final Map<FileRequirementsEnum, MessageLevelEnum> flags = new EnumMap<FileRequirementsEnum, MessageLevelEnum>(
291 FileRequirementsEnum.class);
292 flags.put(FileRequirementsEnum.MUST_BE_CREATABLE_FILE,
293 MessageLevelEnum.ERROR);
294 flags.put(FileRequirementsEnum.MUST_BE_FILE,
295 MessageLevelEnum.ERROR);
296 flags.put(FileRequirementsEnum.OBJECT_MUST_NOT_EXIST,
297 MessageLevelEnum.WARNING);
298 flags.put(FileRequirementsEnum.PATH_MUST_EXIST,
299 MessageLevelEnum.ERROR);
300 final FileSelector fs = new FileSelector(parent, documentExtension, MessageLevelEnum.WARNING,
301 flags, FileBrowserEnum.SAVE_FILE);
302 fs.setFileName(getXMLAccess().getDocumentURL().toString());
303 widgets.add(fs);
304
305 final EncodingWidget eq = new EncodingWidget(parent);
306 if (getXMLAccess().getEncoding() != null)
307 eq.select(getXMLAccess().getEncoding());
308 widgets.add(eq);
309
310 final XMLSerializerPropertiesWidget deq = new XMLSerializerPropertiesWidget(
311 parent);
312 widgets.add(deq);
313 return new MultiWidget(parent, widgets);
314 }
315 };
316 final WidgetWrapperDialog<MultiWidget> dlg = new WidgetWrapperDialog<MultiWidget>(
317 getEditorSite().getShell(), Messages.getString("SAVE_AS"),
318 Messages.getString("SAVE_FILE_AS",
319 getXMLAccess().getFileName()), wfactory);
320 if (dlg.open() != Window.OK)
321 return;
322
323 final String fname = ((FileSelector) dlg.getWidget().getWidgets()
324 .get(0)).getFileName();
325 final String encoding = ((EncodingWidget) dlg.getWidget().getWidgets()
326 .get(1)).getSelected();
327 final XMLSerializerPropertiesWidget deq = (XMLSerializerPropertiesWidget) dlg
328 .getWidget().getWidgets().get(2);
329
330 try {
331 getParentMultiEditor().getResourceManipulator().save(fname,
332 encoding, deq);
333 } catch (Exception ex) {
334 EuroMath.log(IStatus.ERROR, 0, "Error storing document", ex);
335 MessageDialog
336 .openError(getEditorSite().getShell(),
337 Messages.getString("ERROR"),
338 Messages.getString("ERROR_STORING_DOCUMENT") + ex.getLocalizedMessage());
339 }
340 }
341
342 /***
343 *
344 * @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite,
345 * org.eclipse.ui.IEditorInput)
346 */
347 @Override
348 public void init(IEditorSite site, IEditorInput input)
349 throws PartInitException {
350 setSite(site);
351 setInput(input);
352 }
353
354 /***
355 *
356 * @see org.eclipse.ui.ISaveablePart#isDirty()
357 */
358 @Override
359 public boolean isDirty() {
360 return !getXMLAccess().getUndoManager().isSavePoint();
361 }
362
363 /***
364 *
365 * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
366 */
367 @Override
368 public boolean isSaveAsAllowed() {
369 return true;
370 }
371
372 /***
373 * Creates and initalizes IEditor for coordinator with "parent
374 * parentEditor". Actually IEditors don't have parents. Also creates
375 * Composite.
376 *
377 * @param coordinator
378 * CoordinatorInputKey for which to create editor
379 * @param id
380 * of root node for newly created editr, it is also same id as
381 * have associated renderer
382 * @param parentEditor
383 * editor with Composite which host Composite for this new editor
384 * @return new IEditor instance
385 *
386 * @throws EditorException
387 * is thrown in all bad cases: no suitable editor found, editor
388 * creation failure, editor init failure
389 */
390 private IEditor buildEditor(CoordinatorInputKey coordinator, String id,
391 IEditor parentEditor) throws EditorException {
392
393 String nameSpace = coordinator.targetNamespace;
394 EnumSet<ResultEnum> resultTypes = EnumSet
395 .of(coordinator.info.resultType);
396
397
398 List<EditorInfo> editorInfo = EditInstanceProvider.getInstance()
399 .getEditorsForNamespace(nameSpace, resultTypes);
400 try {
401 IRenderer parentRenderer = parentEditor.getRenderer();
402 RendererSite rendererSite = this.keyRendererSiteMap
403 .get(coordinator);
404
405 parentEditor.getClientComposite().setLayout(
406 new PreferredByControlLayout());
407 Composite c = new Composite(parentEditor.getClientComposite(),
408 SWT.NO_RADIO_GROUP);
409 c.setBackground(ColorConstants.green);
410 c.setLayout(new FillLayout());
411 Point p = parentRenderer.getPlacement(id);
412 Dimension dim = rendererSite.renderer.getCanvasSize();
413 c.setLayoutData(new Rectangle(p.x, p.y, dim.width + 2
414 * FigureSelectionPolicy.SELECION_BORDER_WIDTH, dim.height
415 + 2 * FigureSelectionPolicy.SELECION_BORDER_WIDTH));
416
417 IEditor editor = createBestEditor(editorInfo);
418
419 editor.init(rendererSite.getSource().getSource(),
420 rendererSite.renderer, c, getXMLAccess(), this);
421 return editor;
422 } catch (ExportException e) {
423 throw new EditorException("Some IEditor fails to create.", e);
424 } catch (EditorException e) {
425 throw new EditorException("Some IEditor fails to initialize.", e);
426 }
427 }
428
429 /***
430 * Creates and initalizes root IEditor. Also creates Composite.
431 *
432 * @param coordinator
433 * Coordinator for this root editor
434 * @return root Editor
435 *
436 * @throws EditorException
437 * is thrown in all bad cases: no suitable editor found, editor
438 * creation failure, editor init failure
439 */
440 private IEditor buildRootEditor(CoordinatorInputKey coordinator)
441 throws EditorException {
442 String nameSpace = coordinator.targetNamespace;
443 EnumSet<ResultEnum> resultTypes = EnumSet.of(coordinator
444 .getResultType());
445
446 List<EditorInfo> editorInfo = EditInstanceProvider.getInstance()
447 .getEditorsForNamespace(nameSpace, resultTypes);
448
449 try {
450 getRootComposite().setLayout(new FillLayout());
451
452 IEditor result = createBestEditor(editorInfo);
453 RendererSite rootRendererSite = this.keyRendererSiteMap
454 .get(coordinator);
455
456
457 result.init(rootRendererSite.getSource().getSource(),
458 rootRendererSite.renderer, getRootComposite(),
459 getXMLAccess(), this);
460 return result;
461 } catch (ExportException e) {
462 throw new EditorException("Root IEditor fails to create.", e);
463 }
464
465 }
466
467 /***
468 * Creates best editor. Created is IEditor implementing most of interfaces
469 * providing editing capability, such as {@link IXMLSelectionProvider},
470 * providing Selections.
471 *
472 * @param editorInfo
473 * @return new instance
474 * @throws EditorException
475 * @throws ExportException
476 */
477 private IEditor createBestEditor(List<EditorInfo> editorInfo)
478 throws ExportException {
479
480 if ((editorInfo == null) || editorInfo.isEmpty()) {
481 return new XMLEditor();
482 }
483 return editorInfo.get(0).newEditor();
484 }
485
486
487
488
489 public void initReceiver() {
490
491 }
492
493 /***
494 * @see IEditorDataReceiver#dataChanged(java.util.Map,
495 * CoordinatorInputKey, java.util.Map,
496 * java.util.Map, java.util.Set, java.util.Set)
497 */
498 public void dataChanged(
499 Map<CoordinatorInputKey, RendererSite> rendererKeys,
500 CoordinatorInputKey rootKey,
501 Map<CoordinatorInputKey, Set<CoordinatorInputKey>> nametreeHierarchy,
502 Map<String, CoordinatorInputKey> geneIdMapping,
503 Set<CoordinatorInputKey> newKeys,
504 Set<CoordinatorInputKey> deletedKeys) throws EditorException {
505
506 this.editorContexts.clear();
507
508
509 final HashMap<CoordinatorInputKey, String> keyIdMapping = new HashMap<CoordinatorInputKey, String>(
510 geneIdMapping.size());
511 for (final String id : geneIdMapping.keySet()) {
512 keyIdMapping.put(geneIdMapping.get(id), id);
513 }
514
515 this.keyRendererSiteMap = rendererKeys;
516
517 for (CoordinatorInputKey deletedKey : deletedKeys) {
518 if (this.keyEditorMap.containsKey(deletedKey)) {
519
520
521 IEditor editor = this.keyEditorMap.get(deletedKey);
522
523 if (editor instanceof IDOMSelectionProvider)
524 removeSelectionChangedListener(editor);
525
526
527
528 editor.addFocusListener(this);
529
530
531 if (editor instanceof IDOMSelectionProvider) {
532 ((IDOMSelectionProvider) editor)
533 .removeSelectionChangedListener(this);
534 }
535 editor.dispose();
536 this.keyEditorMap.remove(deletedKey);
537 }
538 }
539
540
541 if (newKeys.contains(rootKey)) {
542 setRootEditor(buildRootEditor(rootKey));
543 this.keyEditorMap.put(rootKey, getRootEditor());
544
545 this.editorContexts.put(rootKey, new EditorContext(getRootEditor(),
546 this.keyRendererSiteMap.get(rootKey), rootKey, keyIdMapping
547 .get(rootKey), null));
548
549 getRootEditor().addFocusListener(this);
550
551
552 if (getRootEditor() instanceof IDOMSelectionProvider) {
553 ((IDOMSelectionProvider) getRootEditor())
554 .addSelectionChangedListener(this);
555 addSelectionChangedListener(getRootEditor());
556
557
558
559
560
561
562
563
564 }
565 } else {
566
567 getRootEditor().reinit(
568 rendererKeys.get(rootKey).getSource().getSource(),
569 rendererKeys.get(rootKey).getSource());
570
571 this.editorContexts.put(rootKey, new EditorContext(getRootEditor(),
572 this.keyRendererSiteMap.get(rootKey), rootKey, keyIdMapping
573 .get(rootKey), null));
574
575 }
576
577
578 IEditor parentEditor;
579 IEditor newEditor;
580 CoordinatorInputKey parentKey;
581
582
583 Queue<CoordinatorInputKey> parentKeys = new LinkedList<CoordinatorInputKey>();
584 parentKeys.add(rootKey);
585
586 while (!parentKeys.isEmpty()) {
587
588 parentKey = parentKeys.poll();
589 parentEditor = this.keyEditorMap.get(parentKey);
590
591 for (CoordinatorInputKey sonKey : nametreeHierarchy.get(parentKey)) {
592 if (newKeys.contains(sonKey)) {
593 final String sonKeyId = keyIdMapping.get(sonKey);
594 assert sonKeyId != null;
595 newEditor = buildEditor(sonKey, sonKeyId, parentEditor);
596 this.keyEditorMap.put(sonKey, newEditor);
597
598 this.editorContexts.put(sonKey, new EditorContext(
599 newEditor, this.keyRendererSiteMap.get(sonKey),
600 sonKey, keyIdMapping.get(sonKey),
601 this.editorContexts.get(parentKey)));
602
603 parentKeys.add(sonKey);
604
605 newEditor.addFocusListener(this);
606
607
608 if (newEditor instanceof IDOMSelectionProvider) {
609 ((IDOMSelectionProvider) newEditor)
610 .addSelectionChangedListener(this);
611 addSelectionChangedListener(newEditor);
612
613
614
615
616
617
618
619
620 }
621 } else {
622
623 this.keyEditorMap.get(sonKey).reinit(
624 rendererKeys.get(sonKey).getSource().getSource(),
625 rendererKeys.get(sonKey).getSource());
626
627 this.editorContexts.put(sonKey, new EditorContext(
628 this.keyEditorMap.get(sonKey),
629 this.keyRendererSiteMap.get(sonKey), sonKey,
630 keyIdMapping.get(sonKey), this.editorContexts
631 .get(parentKey)));
632 }
633 }
634
635 }
636 layout();
637 computeVisualizedIds();
638 fireSelectionChangeEvent();
639 }
640
641 @Override
642 public void createPartControl(Composite parent) {
643 createOutlinePage();
644 hookOutlinePage(getOutlinePage());
645 this.rootComposite = parent;
646
647
648 try {
649 final DocumentView view = new DocumentView(getParentMultiEditor()
650 .getXMLAccess(), null, this);
651 final WidgetWrapperDialog<GraphSelectorWidget> dlg = Dialogs
652 .createGraphSelector(this.getEditorSite().getShell(),
653 GraphSelectorWidget.getEditableChoices(view
654 .getEditGraph()), view.getEditGraph());
655 if (dlg.open() != Window.OK) {
656
657 return;
658 }
659 final TransformGraph graph = dlg.getWidget().getTransformationInfo(
660 view.getCoordinatorInfo());
661 view.initialize(graph);
662
663
664
665 getParentMultiEditor().getXMLAccess().openView(view);
666 } catch (Exception ex) {
667 EuroMath.log(IStatus.ERROR, 0, "Error opening document view", ex);
668 MessageDialog.openError(getEditorSite().getShell(), Messages
669 .getString("ERROR"),
670 Messages.getString("ERROR_INITIALIZING_EDITOR")
671 + ex.getLocalizedMessage());
672 }
673 }
674
675 /***
676 * Responsible for registring EditorSite as lisener in XMLOutlinePage.
677 *
678 * @param page
679 * XMLOutlinePage
680 */
681 private void hookOutlinePage(XMLOutlinePage page) {
682
683 page.addSelectionChangedListener(this);
684
685 }
686
687 /***
688 * Creates outline page.
689 */
690 private void createOutlinePage() {
691 this.outlinePage = new XMLOutlinePage(this);
692 }
693
694 /***
695 * Returns outline page instance.
696 *
697 * @return outline page instance
698 */
699 public XMLOutlinePage getOutlinePage() {
700 return this.outlinePage;
701 }
702
703 /***
704 * Sets focus to activete this EditorSite. As active editor is choosed last
705 * active or root editor.
706 */
707 @Override
708 public void setFocus() {
709 if (getActiveEditor() != null)
710 getActiveEditor().setFocus();
711 if (getRootEditor() != null)
712 setActiveEditor(getRootEditor());
713 }
714
715 /***
716 * Sets editor as IEditor with focus.
717 *
718 * @param editor
719 * to set as active = with focus
720 */
721 private void setActiveEditor(IEditor editor) {
722 this.activeEditor = editor;
723 editor.setFocus();
724 }
725
726 /***
727 * Returns active editor.
728 *
729 * @return IEditor with focus
730 */
731 public IEditor getActiveEditor() {
732 return this.activeEditor;
733 }
734
735 /***
736 * Returns root editor.
737 *
738 * @return root IEditor
739 */
740 public IEditor getRootEditor() {
741 return this.rootEditor;
742 }
743
744 /***
745 * Returns multi editor containing this EditorSite instance as child view.
746 *
747 * @return parent multi editor
748 */
749 public MultiViewXMLEditor getParentMultiEditor() {
750 return this.parentMultiEditor;
751 }
752
753 /***
754 * Returns document instance.
755 *
756 * @return xmlaccess instance
757 */
758 public XMLAccess getXMLAccess() {
759 return getParentMultiEditor().getXMLAccess();
760 }
761
762 public void addSelectionChangedListener(IDOMSelectionChangedListener listener) {
763 if (!this.selectionListeners.contains(listener)) {
764 this.selectionListeners.add(listener);
765 }
766 }
767 /***
768 * @param listener
769 */
770 public void removeSelectionChangedListener(
771 IDOMSelectionChangedListener listener) {
772 this.selectionListeners.remove(listener);
773
774 }
775
776 /***
777 * @return return current XMLSelection
778 */
779 public DOMIntervalSet getDOMSelection() {
780 return xmlSelection;
781 }
782
783 /***
784 * Routes this new IXMLSelection to all listeners
785 *
786 * @param selection
787 * DOM selection to set
788 */
789 public void setSelection(DOMIntervalSet selection) {
790 setSelection(selection, true);
791 }
792
793 /***
794 * Fires SelectionEvent to all listeners, if toAll is <code>true</code>.
795 * Otherwise fires SelectionEvent only to active editor, if it provides
796 * selections (is IXMLSelectionProvider)
797 *
798 * @param selection
799 * IXMLSelection
800 * @param toAll
801 * <code>true</code> means route in all IEditors, that provides
802 * selections <code>false</code> route only in active editor,
803 * if it provides selections
804 */
805 public void setSelection(DOMIntervalSet selection, Boolean toAll) {
806 this.xmlSelection = selection;
807
808 if (toAll)
809 fireSelectionChangeEvent();
810 else {
811 if ((getActiveEditor() != null)
812 && (getActiveEditor() instanceof IDOMSelectionProvider)) {
813
814
815 ((IDOMSelectionProvider) getActiveEditor())
816 .removeSelectionChangedListener(this);
817
818 getActiveEditor().selectionChanged(
819 new DOMSelectionChangedEvent(this, getDOMSelection()));
820
821
822 ((IDOMSelectionProvider) getActiveEditor())
823 .addSelectionChangedListener(this);
824 }
825 }
826
827 }
828
829 /***
830 * FireSelectionChangeEvent containing current selection to listeners
831 */
832 private void fireSelectionChangeEvent() {
833 stopSelectionListening();
834
835 for (IDOMSelectionChangedListener listener : this.selectionListeners)
836 listener.selectionChanged(new DOMSelectionChangedEvent(this,
837 getDOMSelection()));
838
839 startSelectionListening();
840 }
841
842 /***
843 * EditorSite starts selection listening. It adds itself to EditorSites's
844 * listeners listeners. It is a "two way listening" Call in pair with
845 * stopSelectionListening().
846 */
847 private void startSelectionListening() {
848 for (IDOMSelectionChangedListener listener : this.selectionListeners)
849 if (listener instanceof IDOMSelectionProvider)
850 ((IDOMSelectionProvider) listener)
851 .addSelectionChangedListener(this);
852 }
853
854 /***
855 * EditorSite does not realy stops selection listening because setSelection
856 * and selectionChange are public methods, but it EditorSite removes itself
857 * from EditorSite's listeners listeners. This prevents from loops.
858 */
859 private void stopSelectionListening() {
860 for (IDOMSelectionChangedListener listener : this.selectionListeners)
861 if (listener instanceof IDOMSelectionProvider)
862 ((IDOMSelectionProvider) listener)
863 .removeSelectionChangedListener(this);
864 }
865
866 /***
867 * Source of event can be
868 * <ul>
869 * <li>IEditor</li>
870 * <li>ContentOutline</li>
871 * <li>something else for future </li>
872 * </ul>
873 * All this sources should be IXMLSelectionProviders, but more imporatant is
874 * that their IXMLSelection have to be "synchronized" with other
875 * IXMLSelectionProviders
876 *
877 * @param event
878 * SelectionChangedEvent <b>If event.getSelection() is not
879 * instance of XMLSelection, does nothing.<b>
880 */
881 public void selectionChanged(DOMSelectionChangedEvent event) {
882
883 this.xmlSelection = event.getDOMSelection();
884 fireSelectionChangeEvent();
885 }
886
887 /***
888 * @return selection providers IEditors or XMLOutline
889 */
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906 /***
907 * TODO STUDVA nejasne co to ma robit a ci to je spravne implementovane
908 *
909 * @param actionContributor
910 */
911 public void setActionContributor(
912 MultiViewActionContributor actionContributor) {
913 if (getActionContributor() == null) {
914 this.actionContributor = actionContributor;
915 for (IEditor editor : getAllIEditors()) {
916 editor.getActionContributor().init(
917 this.actionContributor.getActionRegistry());
918 }
919 }
920 }
921
922 /***
923 * Returns the adapter for the specified class.
924 */
925 @Override
926 public Object getAdapter(Class adapter) {
927 if (adapter.equals(IContentOutlinePage.class))
928 return getOutlinePage();
929
930 if (adapter.equals(IDOMSelectionProvider.class))
931 return this;
932
933 if (adapter.equals(IDOMSelectionProvider.class))
934 return this;
935
936 if (adapter.equals(XMLAccess.class))
937 return getXMLAccess();
938
939 if (adapter.equals(IEditor.class))
940 return getActiveEditor();
941
942 if (getActiveEditor() instanceof IAdaptable)
943 return ((IAdaptable) getActiveEditor()).getAdapter(adapter);
944
945 return null;
946 }
947
948 /***
949 * Test if IEditor is root editor. If root editor doesn't exists, every time
950 * returns true.
951 *
952 * @param editor
953 * to test
954 * @return <code>true</code> if editor is a rootEditor
955 */
956 public boolean isRootEditor(IEditor editor) {
957 return (getRootEditor() == editor) || (getRootEditor() == null);
958 }
959
960 /***
961 * Lays out editors composites.
962 */
963 private void layout() {
964
965 for (EditorContext editorContext : this.editorContexts.values()) {
966
967
968 if (editorContext.editor != getRootEditor()) {
969 IRenderer parentRenderer = editorContext.parentEditorContext.rendererSite.renderer;
970 Point location = parentRenderer.getPlacement(editorContext.id);
971 try {
972 Dimension dim = editorContext.rendererSite.renderer
973 .getCanvasSize();
974
975 editorContext.editor.getHostingComposite().setLayoutData(
976 new Rectangle(location.x, location.y, dim.width,
977 dim.height));
978 } catch (EditorException e) {
979 EuroMath.log(IStatus.ERROR, 0,
980 "Renderer dimension retreiving error.", e);
981 }
982 }
983 }
984 getRootComposite().layout(true, true);
985 }
986
987 /***
988 * @return Returns the actionContributor.
989 */
990 public MultiViewActionContributor getActionContributor() {
991 return this.actionContributor;
992 }
993
994 /***
995 * Adds listener as focus listener. Listener is added if is not yet
996 * listening.
997 *
998 * @param listener
999 * to add
1000 */
1001 public void addFocusListener(IFocusListener listener) {
1002 if (!getFocusListeners().contains(listener))
1003 getFocusListeners().add(listener);
1004 }
1005
1006 /***
1007 * Removes listener. If not listener is not listening, nothing is done.
1008 *
1009 * @param listener
1010 * to remove
1011 */
1012 public void removeFocusListener(IFocusListener listener) {
1013 getFocusListeners().remove(listener);
1014 }
1015
1016 /***
1017 * @return Returns the focusListeners.
1018 */
1019 private List<IFocusListener> getFocusListeners() {
1020 return this.focusListeners;
1021 }
1022
1023 /***
1024 * @param rootEditor
1025 * The rootEditor to set.
1026 */
1027 private void setRootEditor(IEditor rootEditor) {
1028 this.rootEditor = rootEditor;
1029 }
1030
1031 /***
1032 * IEditor has gained focus. Send message to focus listeners.
1033 */
1034 public void focusGained(IEditor editor) {
1035 for (IFocusListener listener : getFocusListeners()) {
1036 listener.focusGained(editor);
1037 }
1038 }
1039
1040 /***
1041 * IEditor has lost focus. Send message to focus listeners.
1042 */
1043 public void focusLost(IEditor editor) {
1044 for (IFocusListener listener : getFocusListeners()) {
1045 listener.focusLost(editor);
1046 }
1047 }
1048
1049 /***
1050 * Returns all IEditors in this site.
1051 *
1052 * @return collection of all IEditors in this site
1053 */
1054 public Collection<IEditor> getAllIEditors() {
1055 return this.keyEditorMap.values();
1056 }
1057
1058 /***
1059 * Computes or recomputes visualized ids.
1060 *
1061 * @see #getVisualizedIds()
1062 */
1063 private void computeVisualizedIds() {
1064 this.visualizedIds.clear();
1065 for (IEditor editor : getAllIEditors())
1066 this.visualizedIds.addAll(editor.getVisualizedIds());
1067 }
1068
1069 /***
1070 * Returns ids of nodes which are graphically rendered(represented) by at
1071 * least one IEditor. Id's are without :N.
1072 *
1073 * @return list of ids which are visualized by at least one IEditor
1074 */
1075 public Set<String> getVisualizedIds() {
1076 return this.visualizedIds;
1077 }
1078
1079 /***
1080 * @return Returns the rootComposite.
1081 */
1082 public Composite getRootComposite() {
1083 return this.rootComposite;
1084 }
1085
1086 public void addSelectionChangedListener(ISelectionChangedListener listener) {
1087
1088
1089 }
1090
1091 public ISelection getSelection() {
1092
1093 return null;
1094 }
1095
1096 public void removeSelectionChangedListener(ISelectionChangedListener listener) {
1097
1098
1099 }
1100
1101 public void setSelection(ISelection selection) {
1102
1103
1104 }
1105 }