1 package org.simantics.document.linking.views;
4 import org.eclipse.jface.action.Action;
5 import org.eclipse.jface.action.IMenuManager;
6 import org.eclipse.jface.action.IToolBarManager;
7 import org.eclipse.jface.layout.GridDataFactory;
8 import org.eclipse.jface.viewers.ISelection;
9 import org.eclipse.jface.viewers.StructuredSelection;
10 import org.eclipse.swt.SWT;
11 import org.eclipse.swt.custom.CCombo;
12 import org.eclipse.swt.events.SelectionAdapter;
13 import org.eclipse.swt.events.SelectionEvent;
14 import org.eclipse.swt.graphics.Rectangle;
15 import org.eclipse.swt.layout.FillLayout;
16 import org.eclipse.swt.layout.FormAttachment;
17 import org.eclipse.swt.layout.FormData;
18 import org.eclipse.swt.layout.FormLayout;
19 import org.eclipse.swt.layout.GridLayout;
20 import org.eclipse.swt.widgets.Button;
21 import org.eclipse.swt.widgets.Composite;
22 import org.eclipse.swt.widgets.Display;
23 import org.eclipse.swt.widgets.Event;
24 import org.eclipse.swt.widgets.Listener;
25 import org.eclipse.swt.widgets.Sash;
26 import org.eclipse.swt.widgets.TabFolder;
27 import org.eclipse.swt.widgets.TabItem;
28 import org.eclipse.swt.widgets.Tree;
29 import org.eclipse.ui.IActionBars;
30 import org.eclipse.ui.IEditorPart;
31 import org.eclipse.ui.IPartListener;
32 import org.eclipse.ui.ISelectionListener;
33 import org.eclipse.ui.IWorkbenchPart;
34 import org.eclipse.ui.part.ViewPart;
35 import org.simantics.Simantics;
36 import org.simantics.browsing.ui.GraphExplorer;
37 import org.simantics.browsing.ui.swt.SingleSelectionInputSource;
38 import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;
39 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;
40 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;
41 import org.simantics.db.ReadGraph;
42 import org.simantics.db.Resource;
43 import org.simantics.db.common.request.ReadRequest;
44 import org.simantics.db.common.request.ResourceRead;
45 import org.simantics.db.common.utils.NameUtils;
46 import org.simantics.db.exception.AdaptionException;
47 import org.simantics.db.exception.DatabaseException;
48 import org.simantics.db.request.Read;
49 import org.simantics.document.DocumentResource;
50 import org.simantics.document.linking.Activator;
51 import org.simantics.document.linking.adapters.SourceObjectAdapter;
52 import org.simantics.document.linking.ge.Constants;
53 import org.simantics.document.linking.ge.MultiSelectionProvider;
54 import org.simantics.document.linking.ge.SourceLinkExplorerComposite;
55 import org.simantics.document.linking.ontology.DocumentLink;
56 import org.simantics.ui.SimanticsUI;
57 import org.simantics.utils.datastructures.ArrayMap;
58 import org.simantics.utils.ui.AdaptionUtils;
61 public class SourceView extends ViewPart implements ISelectionListener, IPartListener{
64 public enum AcceptedObject{ALL,DOCUMENT};
66 * The ID of the view as specified by the extension.
68 public static final String ID = "org.simantics.document.linking.views.SourceView";
70 private Composite composite;
72 private Action pinSelectionAction;
73 private Action linkAllAction;
74 private Action linkDocumentsAction;
76 private WidgetSupport support;
77 private GraphExplorerComposite objectExplorer;
78 private GraphExplorerComposite propertyExplorer;
79 private MultiSelectionProvider selectionProvider;
81 private GraphExplorerComposite browseExplorer;
84 private TabFolder tabFolder;
86 Composite linkComposite;
87 Composite browseComposite;
89 private boolean pinSelection = false;
91 Resource currentModel;
92 private ModelToComboListener modelToComboListener;
93 private CCombo modelCombo;
95 private AcceptedObject acceptedObject = AcceptedObject.DOCUMENT;
100 support = new WidgetSupportImpl();
104 * This is a callback that will allow us
105 * to create the viewer and initialize it.
107 public void createPartControl(Composite parent) {
108 parent.setLayout(new FillLayout());
109 composite = new Composite(parent, SWT.NONE);
110 composite.setLayout(new FillLayout());
111 tabFolder = new TabFolder(composite, SWT.NONE);
112 TabItem link = new TabItem(tabFolder, SWT.NONE);
113 link.setText("Linking");
115 TabItem browse = new TabItem(tabFolder, SWT.NONE);
116 browse.setText("Browsing");
118 linkComposite = new Composite(tabFolder, SWT.NONE);
119 link.setControl(linkComposite);
121 browseComposite = new Composite(tabFolder, SWT.NONE);
122 browse.setControl(browseComposite);
124 selectionProvider = new MultiSelectionProvider();
126 createLinkTab(linkComposite);
127 createBrowseTab(browseComposite);
129 getSite().getPage().addPostSelectionListener(this);
130 getSite().getPage().addPartListener(this);
133 contributeToActionBars();
135 getSite().setSelectionProvider(selectionProvider);
141 public void dispose() {
142 getSite().getPage().removePostSelectionListener(this);
143 getSite().getPage().removePartListener(this);
146 private void createBrowseTab(final Composite browseComposite) {
147 browseComposite.setLayout(new GridLayout(2,false));
148 modelCombo = new CCombo(browseComposite, SWT.BORDER|SWT.READ_ONLY);
149 final WidgetSupport support = new WidgetSupportImpl();
150 SimanticsUI.getSession().asyncRequest(new ReadRequest() {
153 public void run(ReadGraph graph) throws DatabaseException {
154 Resource project = SimanticsUI.getProject().get();
155 modelToComboListener = new ModelToComboListener(modelCombo) {
157 public Resource getCurrentModel() {
161 graph.syncRequest(new ModelRead(project),modelToComboListener);
165 Button checkingButton = new Button(browseComposite, SWT.TOGGLE);
166 checkingButton.setText("All");
167 checkingButton.addSelectionListener(new SelectionAdapter() {
169 public void widgetSelected(SelectionEvent e) {
170 Button button = ((Button)e.widget);
171 boolean checked = button.getSelection();
172 browseExplorer.dispose();
173 createModelExplorer(checked,support,browseComposite);
174 button.setText(checked ? "Old/Removed" : "All");
175 if (currentModel != null)
176 setModel(currentModel, true);
177 browseComposite.getParent().layout(true, true);
181 createModelExplorer(false,support,browseComposite);
184 modelCombo.addSelectionListener(new SelectionAdapter() {
186 public void widgetSelected(SelectionEvent e) {
187 int index = modelCombo.getSelectionIndex();
190 Resource model = (Resource)modelCombo.getData(Integer.toString(index));
196 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).applyTo(modelCombo);
200 private void createModelExplorer(boolean onlyCheckable,WidgetSupport support,Composite browseComposite) {
201 browseExplorer = new SourceLinkExplorerComposite(ArrayMap.keys("displaySelectors", "displayFilter","treeView").values(false, false, true), selectionProvider,getSite(), browseComposite, support,false, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
203 browseExplorer.setBrowseContexts(DocumentLink.URIs.ModelViewpointBrowseContext, DocumentLink.URIs.ModelViewpointActionContext);
205 browseExplorer.setBrowseContexts(DocumentLink.URIs.ModelViewpointBrowseContext2, DocumentLink.URIs.ModelViewpointActionContext);
206 browseExplorer.setColumns(Constants.SOURCE_OBJECT_COLUMNS);
207 browseExplorer.setInputSource(new SingleSelectionInputSource(Resource.class));
208 browseExplorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning
209 browseExplorer.setColumnsVisible(true);
210 browseExplorer.setContextMenuId("#SourceModelViewPopup");
211 browseExplorer.finish();
212 ((Tree)browseExplorer.getExplorer().getControl()).setLinesVisible(true);
214 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).span(2, 1).applyTo(browseExplorer);
217 private void createLinkTab(final Composite linkComposite) {
218 objectExplorer = new SourceLinkExplorerComposite(ArrayMap.keys("displaySelectors", "displayFilter","treeView").values(false, false,true), selectionProvider,getSite(), linkComposite, support, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
219 objectExplorer.setBrowseContexts(DocumentLink.URIs.SourceObjectViewpointBrowseContext, DocumentLink.URIs.SourceObjectViewpointActionContext);
220 objectExplorer.setColumns(Constants.SOURCE_OBJECT_COLUMNS);
221 objectExplorer.setInputSource(new SingleSelectionInputSource(Resource.class));
222 objectExplorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning
223 objectExplorer.setColumnsVisible(true);
224 objectExplorer.setContextMenuId("#SourceObjectViewPopup");
225 objectExplorer.finish();
226 ((Tree)objectExplorer.getExplorer().getControl()).setLinesVisible(true);
228 final Sash sash = new Sash (linkComposite, SWT.HORIZONTAL);
230 propertyExplorer = new SourceLinkExplorerComposite(ArrayMap.keys("displaySelectors", "displayFilter","treeView").values(false, false,true), selectionProvider,getSite(), linkComposite, support, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
231 propertyExplorer.setBrowseContexts(DocumentLink.URIs.SourcePropertyViewpointBrowseContext, DocumentLink.URIs.SourcePropertyViewpointActionContext);
232 propertyExplorer.setColumns(Constants.SOURCE_COLUMNS);
233 propertyExplorer.setInputSource(new SingleSelectionInputSource(Resource.class));
234 propertyExplorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning
235 propertyExplorer.setColumnsVisible(true);
236 propertyExplorer.setContextMenuId("#SourcePropertyViewPopup");
237 propertyExplorer.finish();
238 ((Tree)propertyExplorer.getExplorer().getControl()).setLinesVisible(true);
241 final FormLayout form = new FormLayout ();
242 linkComposite.setLayout (form);
244 FormData button1Data = new FormData ();
245 button1Data.left = new FormAttachment (0, 0);
246 button1Data.right = new FormAttachment (100, 0);
247 button1Data.top = new FormAttachment (0, 0);
248 button1Data.bottom = new FormAttachment (sash, 0);
249 objectExplorer.setLayoutData (button1Data);
251 final int limit = 40, percent = 20;
252 final FormData sashData = new FormData ();
253 sashData.left = new FormAttachment (0, 0);
254 sashData.right = new FormAttachment (100, 0);
255 sashData.top = new FormAttachment (percent, 0);
257 sash.setLayoutData (sashData);
258 sash.addListener (SWT.Selection, new Listener () {
259 public void handleEvent (Event e) {
260 Rectangle sashRect = sash.getBounds ();
261 Rectangle shellRect = linkComposite.getClientArea ();
262 int top = shellRect.height - sashRect.height - limit;
263 e.y = Math.max (Math.min (e.y, top), limit);
264 if (e.y != sashRect.y) {
265 sashData.top = new FormAttachment (0, e.y);
266 linkComposite.layout ();
271 FormData button2Data = new FormData ();
272 button2Data.left = new FormAttachment (0, 0);
273 button2Data.right = new FormAttachment (100, 0);
274 button2Data.top = new FormAttachment (sash, 0);
275 button2Data.bottom = new FormAttachment (100, 0);
276 propertyExplorer.setLayoutData (button2Data);
282 public void partActivated(IWorkbenchPart part) {
283 if (!(part instanceof IEditorPart))
284 selectionEventFilter = part;
288 public void partBroughtToTop(IWorkbenchPart part) {}
291 public void partClosed(IWorkbenchPart part) {}
294 public void partDeactivated(IWorkbenchPart part) {}
297 public void partOpened(IWorkbenchPart part) {}
299 IWorkbenchPart selectionEventFilter = null;
302 public void selectionChanged(IWorkbenchPart part, ISelection selection) {
307 // dnd event may start from different part than the target object is selected.
308 // activating an part sends not only partActivated event, but also selectioChanged event to match the part's selection
309 // since that would interrupt intended dnd operation, we filter selection events send by part activation.
310 if (part == selectionEventFilter) {
311 selectionEventFilter = null;
314 selectionEventFilter = null;
316 final Resource res = AdaptionUtils.adaptToSingle(selection, Resource.class);
320 final Resource selected = SimanticsUI.getSession().syncRequest(new Read<Resource>() {
322 public Resource perform(ReadGraph graph) throws DatabaseException {
324 SourceObjectAdapter adapter = graph.adapt(res, SourceObjectAdapter.class);
325 return adapter.getDocumentableResource(graph, res);
326 } catch (AdaptionException e) {
331 if (selected == null)
333 if (acceptedObject == AcceptedObject.DOCUMENT) {
334 if (Simantics.getSession().syncRequest(new IsDocumentRead(selected)))
337 ISelection realSelection = new StructuredSelection(selected);
338 objectExplorer.setInput(SimanticsUI.getSessionContext(), realSelection);
339 propertyExplorer.setInput(SimanticsUI.getSessionContext(), realSelection);
340 Simantics.getSession().asyncRequest(new ReadRequest() {
343 public void run(ReadGraph graph) throws DatabaseException {
344 String name = NameUtils.getSafeLabel(graph, selected);
345 if (name.length() == 0)
346 name = NameUtils.getSafeName(graph, selected);
347 final String title = name;
348 Display.getDefault().asyncExec(new Runnable() {
357 } catch (Exception e) {
362 private class IsDocumentRead extends ResourceRead<Boolean> {
363 public IsDocumentRead(Resource resource) {
368 public Boolean perform(ReadGraph graph) throws DatabaseException {
369 DocumentResource doc = DocumentResource.getInstance(graph);
370 return graph.isInstanceOf(resource, doc.Document);
375 private void contributeToActionBars() {
376 IActionBars bars = getViewSite().getActionBars();
377 fillLocalPullDown(bars.getMenuManager());
378 fillLocalToolBar(bars.getToolBarManager());
381 private void fillLocalPullDown(IMenuManager manager) {
382 manager.add(linkAllAction);
383 manager.add(linkDocumentsAction);
387 private void fillLocalToolBar(IToolBarManager manager) {
388 manager.add(pinSelectionAction);
392 private void makeActions() {
393 pinSelectionAction = new Action("Pin selection", Action.AS_CHECK_BOX) {
395 pinSelection = isChecked();
398 // action1.setToolTipText("Action 1 tooltip");
399 pinSelectionAction.setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/lock.png"));
402 linkAllAction = new Action("Link All", Action.AS_RADIO_BUTTON) {
405 setAcceptedObject(AcceptedObject.ALL);
410 linkDocumentsAction = new Action("Link Documents", Action.AS_RADIO_BUTTON) {
413 setAcceptedObject(AcceptedObject.DOCUMENT);
417 setAcceptedObject(AcceptedObject.DOCUMENT);
421 public void setAcceptedObject(AcceptedObject acceptedObject) {
422 this.acceptedObject = acceptedObject;
423 if (acceptedObject == AcceptedObject.ALL) {
424 linkAllAction.setChecked(true);
425 linkDocumentsAction.setChecked(false);
427 linkAllAction.setChecked(false);
428 linkDocumentsAction.setChecked(true);
436 * Passing the focus request to the viewer's control.
438 public void setFocus() {
439 composite.setFocus();
442 public void setModel(Resource model) {
443 setModel(model, false);
446 public void setModel(Resource model, boolean force) {
447 if (!force && model.equals(currentModel))
450 currentModel = model;
451 for (int i = 0; i < modelCombo.getItemCount(); i++) {
452 Resource r = (Resource)modelCombo.getData(Integer.toString(i));
453 if (model.equals(r)) {
454 modelCombo.select(i);
455 ISelection realSelection = new StructuredSelection(currentModel);
456 browseExplorer.setInput(SimanticsUI.getSessionContext(), realSelection);
460 modelCombo.select(-1);
461 ISelection realSelection = new StructuredSelection();
462 browseExplorer.setInput(SimanticsUI.getSessionContext(), realSelection);
465 @SuppressWarnings("rawtypes")
467 public Object getAdapter(Class adapter) {
468 if (adapter == GraphExplorer.class) {
469 return browseExplorer.getExplorer();
471 return super.getAdapter(adapter);