]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/SimanticsDialog.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.browsing.ui.swt / src / org / simantics / browsing / ui / swt / SimanticsDialog.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2012 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.browsing.ui.swt;
13
14 import java.util.Collections;
15 import java.util.Map;
16 import java.util.Set;
17
18 import org.eclipse.jface.action.IMenuManager;
19 import org.eclipse.jface.dialogs.Dialog;
20 import org.eclipse.jface.resource.LocalResourceManager;
21 import org.eclipse.jface.viewers.ISelectionProvider;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.dnd.DND;
24 import org.eclipse.swt.dnd.DragSource;
25 import org.eclipse.swt.dnd.DragSourceListener;
26 import org.eclipse.swt.dnd.Transfer;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Control;
29 import org.eclipse.swt.widgets.Shell;
30 import org.eclipse.ui.IMemento;
31 import org.eclipse.ui.ISelectionListener;
32 import org.simantics.Simantics;
33 import org.simantics.browsing.ui.BuiltinKeys;
34 import org.simantics.browsing.ui.GraphExplorer;
35 import org.simantics.browsing.ui.NodeContext;
36 import org.simantics.browsing.ui.common.ColumnKeys;
37 import org.simantics.browsing.ui.common.node.IDropTargetNode;
38 import org.simantics.browsing.ui.graph.impl.GraphInputSources;
39 import org.simantics.browsing.ui.graph.impl.SessionContextInputSource;
40 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;
41 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;
42 import org.simantics.db.management.ISessionContext;
43 import org.simantics.project.ProjectKeys;
44 import org.simantics.ui.dnd.LocalObjectTransfer;
45 import org.simantics.ui.dnd.LocalSelectionDragSourceListener;
46 import org.simantics.ui.dnd.NoImageDragSourceEffect;
47 import org.simantics.utils.ObjectUtils;
48 import org.simantics.utils.datastructures.Function;
49 import org.simantics.utils.datastructures.disposable.DisposeState;
50 import org.simantics.utils.datastructures.hints.HintContext;
51 import org.simantics.utils.datastructures.hints.HintListenerAdapter;
52 import org.simantics.utils.datastructures.hints.HintTracker;
53 import org.simantics.utils.datastructures.hints.IHintContext;
54 import org.simantics.utils.datastructures.hints.IHintContext.Key;
55 import org.simantics.utils.datastructures.hints.IHintListener;
56 import org.simantics.utils.datastructures.hints.IHintObservable;
57 import org.simantics.utils.datastructures.hints.IHintTracker;
58
59 public abstract class SimanticsDialog extends Dialog {
60
61     private final WidgetSupportImpl          widgetSupport = new WidgetSupportImpl();
62
63     protected IHintContext                   factoryHints = new HintContext();
64
65     protected LocalResourceManager           resourceManager;
66
67     protected ISelectionListener             workbenchSelectionListener;
68
69     protected Composite                      parent;
70
71     private Map<String, String>              args;
72
73 //    private ISessionContextProvider          contextProvider;
74
75     private ISessionContext                  sessionContext;
76
77     protected IMemento                       memento;
78
79     //private IHintTracker                     sessionContextTracker = new SessionContextProjectTracker();
80
81     private SessionContextInputSource        inputSource           = GraphInputSources.projectSource();
82
83     private DisposeState                     disposeState          = DisposeState.Alive;
84     
85     private final String title;
86
87 //    protected ISessionContextChangedListener contextChangeListener = new ISessionContextChangedListener() {
88 //        @Override
89 //        public void sessionContextChanged(SessionContextChangedEvent event) {
90 //            sessionContext = event.getNewValue();
91 //            sessionContextTracker.track(sessionContext);
92 //        }
93 //    };
94
95     abstract protected void createControls(Composite body, ISessionContext context, WidgetSupport support);
96
97     public SimanticsDialog(Shell shell, String title) {
98         super(shell);
99         this.title = title;
100     }
101
102     @Override
103     protected void configureShell(Shell shell) {
104         super.configureShell(shell);
105         if (title != null) {
106                         shell.setText(title);
107                 }
108     }
109     
110     protected Transfer[] getAcceptedDataTypes() {
111         return new Transfer[] {  LocalObjectTransfer.getTransfer() };
112     }
113
114     protected void handleDrop(Object data, NodeContext target) {
115         if (target != null) {
116             Object input = target.getConstant(BuiltinKeys.INPUT);
117             //System.out.println("DROPPED " + data + " ON " + target);
118             if (input instanceof IDropTargetNode)
119                 ((IDropTargetNode) input).drop(data);
120         }
121     }
122
123     protected Object createDragSource(GraphExplorer explorer) {
124         ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class);
125
126         DragSourceListener listener = new LocalSelectionDragSourceListener(selectionProvider);
127
128         Control control = explorer.getControl();
129         DragSource source = new DragSource(control, DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT);
130         source.setTransfer(new Transfer[] {LocalObjectTransfer.getTransfer()});
131         source.addDragListener(listener);
132         source.setDragSourceEffect(new NoImageDragSourceEffect(control));
133
134         return listener;
135     }
136
137     /**
138      * @return the set of <code>org.eclipse.ui.context</code> contexts to
139      *         activate for this view site
140      */
141     protected Set<String> getUiContexts() {
142         return Collections.emptySet();
143     }
144
145     /**
146      * The default hint tracker that will be active if
147      * {@link SimanticsViewBase#setSessionContextTracker(IHintTracker) is
148      * not called.
149      */
150     public class SessionContextProjectTracker extends HintTracker {
151         public SessionContextProjectTracker() {
152             IHintListener activeProjectListener = new HintListenerAdapter() {
153                 @Override
154                 public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
155                     applySessionContext(getSessionContext());
156                 }
157             };
158             addKeyHintListener(ProjectKeys.KEY_PROJECT, activeProjectListener);
159         }
160     }
161
162 //    protected void setSessionContextTracker(IHintTracker tracker) {
163 //        this.sessionContextTracker = tracker;
164 //    }
165
166     protected void setInputSource(SessionContextInputSource source) {
167         this.inputSource = source;
168     }
169
170     protected SessionContextInputSource getInputSource() {
171         return inputSource;
172     }
173
174     protected Map<String, String> getViewArguments() {
175         return args;
176     }
177
178     protected DisposeState getDisposeState() {
179         return disposeState;
180     }
181
182     public ISessionContext getSessionContext() {
183         return Simantics.getSessionContext();
184     }
185
186 //    public ISessionContextProvider getSessionContextProvider() {
187 //        return contextProvider;
188 //    }
189
190     protected final void attachToSession() {
191         // Track active ISessionContext changes
192         //contextProvider = SimanticsUI.getSessionContextProvider(getViewSite().getWorkbenchWindow());
193 //        contextProvider.addContextChangedListener(contextChangeListener);
194
195         // Start tracking the current session context for input changes.
196         // This will/must cause applySessionContext to get called.
197         // Doing the applySessionContext initialization this way
198         // instead of directly calling it will also make sure that
199         // applySessionContext is only called once when first initialized,
200         // and not twice like with the direct invocation.
201         this.sessionContext = getSessionContext();
202         applySessionContext(this.sessionContext);
203 //        sessionContextTracker.track(sessionContext);
204     }
205
206     // /////////////////////////////////////////////////////////////////////////
207     // Override / implement these:
208
209     /**
210      * Override this method and provide a proper context menu initializer if you
211      * want to have this base class initialize one for you.
212      * 
213      * @return the initializer to be used by {@link #createControls(Composite)}
214      */
215     protected IContextMenuInitializer getContextMenuInitializer() {
216         String contextMenuId = getContextMenuId();
217         if(contextMenuId != null) {
218             return new ContextMenuInitializer(contextMenuId);
219         } else {
220             return null;
221         }
222     }
223
224     protected String getContextMenuId() {
225         return null;
226     }
227
228     protected int getStyle() {
229         return SWT.NONE;
230     }
231     
232     /**
233      * @param parent
234      * @return
235      */
236     protected GraphExplorer createExplorerControl(Composite parent) {
237         return GraphExplorerFactory.getInstance()
238         .selectionDataResolver(new DefaultSelectionDataResolver())
239         .create(parent, getStyle());
240     }
241
242     /**
243      * Override to customize the addition of listeners a newly created
244      * GraphExplorer.
245      * 
246      * @param explorer
247      */
248     protected void addListeners(GraphExplorer explorer, IMenuManager menuManager) {
249         addSelectionInputListeners(explorer, menuManager);
250     }
251
252     protected void addSelectionInputListeners(GraphExplorer explorer, IMenuManager menuManager) {
253         // Consider ENTER presses to simulate mouse left button double clicks
254         explorer.addListener(new DefaultKeyListener(Simantics.getSessionContextProvider(), explorer, new Function<String[]>() {
255             @Override
256             public String[] execute(Object... obj) {
257                 return new String[] { getEditingColumn((NodeContext) obj[0]) };
258             }
259         }));
260         // Default double click handling
261         explorer.addListener(new DefaultMouseListener(explorer));
262     }
263
264     protected String getEditingColumn(NodeContext context) {
265         return ColumnKeys.SINGLE;
266     }
267
268     // Needed for preventing unnecessary re-initialization of the explorer with the same input.
269     private Object currentInput;
270
271     protected boolean isImportantInput(Object previousInput, Object input) {
272         return !ObjectUtils.objectEquals(previousInput, input);
273     }
274
275     /**
276      * Invoke this to reinitialize the explorer and reset its input. The input
277      * will be resolved from the specified ISessionContext based on the
278      * {@link SessionContextInputSource} that is currently in use. If the input
279      * is identical to the previous input, nothing will be done.
280      * 
281      * @param context
282      */
283     protected final boolean applySessionContext(ISessionContext context) {
284         
285         // If control is not alive anymore, do nothing.
286 //        System.out.println(this + ": applySessionContext(" + context + "), explorer="  + explorer);
287         if (disposeState != DisposeState.Alive)
288             return false;
289
290         this.sessionContext = context;
291         Object input = getInputSource().get(context);
292 //        System.out.println("SimanticsView applySessionContext: " + input);
293         if (!isImportantInput(currentInput, input))
294             return false;
295
296 //        System.out.println(this + ": initializeExplorer(" + explorer + ", " + context + ")");
297 //        initializeExplorer(explorer, context);
298 //        System.out.println(this + ": setRoot(" + input + ")");
299 //        explorer.setRoot(input);
300
301         currentInput = input;
302 //        System.out.println("SimanticsView new input: " + currentInput);
303
304         widgetSupport.fireInput(context, input);
305
306         // Start tracking the session context.
307         //
308         // If this is not the same session that is currently tracked, it will
309         // cause IHintListeners of the sessionContextTracker to fire.
310         // For this we need the above input equality (identity) checking.
311         // This is here just to make sure that we are tracking the correct
312         // session context.
313         //sessionContextTracker.track(sessionContext);
314         applySessionContext(context);
315
316         return true;
317     }
318
319         protected Control createDialogArea(Composite parent) {
320 //              parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_GREEN));
321             this.parent = parent;
322                 Composite composite = (Composite)super.createDialogArea(parent);
323 //              parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLUE));
324                 createControls(composite, sessionContext, widgetSupport);
325                 attachToSession();
326                 return composite;
327         }
328         
329         @Override
330         protected Control createContents(Composite parent) {
331 //              parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_RED));
332                 return super.createContents(parent);
333         }
334     
335         protected Object getSelection() {
336                 return null;
337         }
338         
339 }