1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.browsing.ui;
14 import java.util.Collection;
17 import java.util.function.BiFunction;
18 import java.util.function.Consumer;
20 import org.eclipse.core.runtime.IAdaptable;
21 import org.simantics.browsing.ui.NodeContext.CacheKey;
22 import org.simantics.browsing.ui.NodeContext.PrimitiveQueryKey;
23 import org.simantics.browsing.ui.NodeContext.QueryKey;
24 import org.simantics.browsing.ui.content.Labeler;
25 import org.simantics.browsing.ui.content.Labeler.Modifier;
26 import org.simantics.utils.threads.IThreadWorkQueue;
31 public interface GraphExplorer extends IAdaptable {
34 * A key that can be used to associate GraphExplorer instances with other
35 * objects in, e.g. SWT widgets using Widget.setData(String, Object).
37 public static final String KEY_GRAPH_EXPLORER = "GraphExplorer";
40 * @see #setAutoExpandLevel(int)
42 public static int ALL_LEVELS = -1;
44 public static final Object EMPTY_INPUT = new Object() {
47 public String toString() { return "GraphExplorer.EMPTY_INPUT"; };
52 * @deprecated not needed anymore, just remove all uses
55 public interface ModificationContext extends IAdaptable {
60 * An IGraphExplorer has a UI which uses some toolkit (AWT/SWT). The
61 * toolkits are assumed to be single-threaded. The return value of this
62 * method indicates the thread used for UI-related accesses.
64 * @return the single access thread used by this GraphExplorer
66 IThreadWorkQueue getThread();
69 * Override this method to customize the maximum amount of child nodes that
70 * are shown for any node. The returned value must be non-negative.
72 * Use {@link Integer#MAX_VALUE} to maximize the limit.
74 * @return max amount of children shown for a node, must not be negative
77 void setMaxChildren(int maxChildren);
80 * Query for context-specific max children to show value using the provided
81 * query manager and node context.
85 * @return node specific child limit or what is returned by
86 * {@link #getMaxChildren()} if node specific limit is not set
88 int getMaxChildren(NodeQueryManager manager, NodeContext context);
96 <T> void setProcessor(NodeQueryProcessor<T> processor);
97 <T> NodeQueryProcessor<T> getProcessor(QueryKey<T> key);
100 * TODO: documentation
105 <T> void setPrimitiveProcessor(PrimitiveQueryProcessor<T> processor);
106 <T> PrimitiveQueryProcessor<T> getPrimitiveProcessor(PrimitiveQueryKey<T> key);
109 * Associates the provided DataSource implementation with class T in this
110 * GraphExplorer. PrimitiveQueryProcessor implementations can access these
111 * data sources through the class provided by
112 * {@link DataSource#getProvidedClass()}. Specifying a new association for
113 * the same T will overwrite the previous data source association.
115 * @param <T> the provided data source type
116 * @param dataSource the data source
118 <T> void setDataSource(DataSource<T> dataSource);
121 * Removes the data source associated with the provided class.
123 * @param forProvidedClass
124 * @return the removed data source association
126 <T> DataSource<T> removeDataSource(Class<T> forProvidedClass);
128 void setUIContexts(Set<String> contexts);
131 * Set the root input object of this explorer.
132 * @param root the input object, may <b>not</b> be <code>null</code>
134 void setRoot(Object root);
137 * Set the root node context of this explorer. Allows the client to provide
138 * the complete NodeContext to be used as the explorer root input while
139 * {@link #setRoot(Object)} only allows the client to provide the
140 * {@link BuiltinKeys#INPUT} data for the root NodeContext.
142 * @param root the root node context, may <b>not</b> be <code>null</code>
144 void setRootContext(NodeContext context);
147 * Get the current UI item context of the root input object.
149 * Return value is undefined for a disposed or uninitialized GraphExplorer.
150 * An explorer is uninitialized when {@link #setRoot(Object)} or
151 * {@link #setRootContext(NodeContext)} has not been invoked yet.
153 * @return input object's UI item context
155 NodeContext getRoot();
158 * Get the parent node context of the specified node context. If there is no
159 * visible parent node in the explorer, <code>null</code> is returned.
161 * Only to be invoked from the UI thread (see {@link #getThread()}.
163 * @param context the context to the possible parent node for
164 * @return <code>null</code> if there is no parent node
166 NodeContext getParentContext(NodeContext context);
169 * Consult the explorer's cache for the specified node and key. The method
170 * will return a result only if the requested query has been previously
171 * performed and has not been cleared (invalidated).
174 * @param context the UI item's context
175 * @param key the cache key to consult for
176 * @return the value in the cache or <code>null</code> if no value was found
178 <T> T query(NodeContext context, CacheKey<T> key);
180 // --- UI related things ---
182 public interface TransientExplorerState {
183 Integer getActiveColumn();
186 Object getWidgetSelection();
187 TransientExplorerState getTransientState();
189 SelectionDataResolver getSelectionDataResolver();
190 void setSelectionDataResolver(SelectionDataResolver r);
193 * @return the current {@link SelectionFilter}
195 SelectionFilter getSelectionFilter();
198 * Set new {@link SelectionFilter} for this explorer to control what will be
199 * put into selections provided by this <code>GraphExplorer</code>.
201 * TODO: specify what should happen to the current provided selection when a
202 * new filter is set. Should it change immediately or be left as is?
204 * @param f the new filter or <code>null</code> to disable filtering
206 void setSelectionFilter(SelectionFilter f);
208 void setSelectionTransformation(BiFunction<GraphExplorer, Object[], Object[]> f);
210 //ISelectionProvider getSelectionProvider();
212 void setColumnsVisible(boolean visible);
213 void setColumns(Column[] columns);
214 void setColumns(Column[] columns, Consumer<Map<Column, Object>> callback);
215 Column[] getColumns();
220 boolean select(NodeContext context);
221 boolean selectPath(Collection<NodeContext> contexts);
222 boolean isVisible(NodeContext context);
225 * Sets the expanded state of the specified node context.
228 * May work asynchronously.
231 * @param context the context to set the expanded state for
232 * @param expanded <code>true</code> to expand, <code>false</code> to
235 void setExpanded(NodeContext context, boolean expanded);
237 <T> void addListener(T listener);
238 <T> void removeListener(T listener);
243 * Attempts to start in-line editing at the specified INodeContext in this
244 * graph explorer. The nature of the in-line editing (i.e. used controls)
245 * depends on the kind of {@link Modifier} returned by the {@link Labeler}
246 * of the specified node context. The labeler is determined by the
247 * {@link BuiltinKeys#SELECTED_LABELER} query.
250 * Only to be invoked from the UI thread (see {@link #getThread()}.
252 * @param context the node, i.e. tree item or tree-table row to start
254 * @param columnKey a key to identify the column to edit. This argument must
255 * match one of the keys of the tree columns set using
256 * {@link #setColumns(Column[])}.
257 * @return <code>true</code> if the editing process was successfully
260 String startEditing(NodeContext context, String columnKey);
261 String startEditing(String columnKey);
264 * @return <code>true</code> if the explorer is disposed.
266 boolean isDisposed();
269 * Return the backing UI control of this GraphExplorer.
277 * @deprecated not needed anymore, just remove calls
280 void setModificationContext(ModificationContext modificationContext);
283 * Sets the auto-expand level to be used when the input of the viewer is set
284 * using {@link #setInput(Object)}. The value 0 means that there is no
285 * auto-expand; 1 means that the invisible root element is expanded (since
286 * most concrete subclasses do not show the root element, there is usually
287 * no practical difference between using the values 0 and 1); 2 means that
288 * top-level elements are expanded, but not their children; 3 means that
289 * top-level elements are expanded, and their children, but not
290 * grandchildren; and so on.
292 * The value {@value #ALL_LEVELS} means that all subtrees should be
296 * @param level non-negative level, or {@value #ALL_LEVELS} to expand all
299 void setAutoExpandLevel(int level);
302 * Sets the implementation that this GraphExplorer shall use to persist its
303 * state when disposed and to load its state when created.
305 * In order to restore a previously persisted state, this method must be
306 * called before invoking {@link #setRoot(Object)} or
307 * {@link #setRootContext(NodeContext)}.
309 * @param persistor the persistor to use
311 void setPersistor(StatePersistor persistor);
314 * @return <code>true</code> if the explorer is in editable state
315 * @see #setEditable(boolean)
317 boolean isEditable();
320 * Makes this explorer editable or non-editable as far as this
321 * implementation is concerned. For a non-editable explorer
322 * {@link #startEditing(String)} and
323 * {@link #startEditing(NodeContext, String)} will do nothing. Externally
324 * added listeners (see {@link #addListener(Object)}) will still get
325 * notified of events so those need to be handled separately.
328 * By default, implementations should be editable.
330 void setEditable(boolean editable);
333 * Returns underlaying data object, which was clicked (with mouse).
334 * @param event Mouse Event (usually org.eclipse.swt.events.MouseEvent)
336 public Object getClicked(Object event);