KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > viewers > model > TreeModelContentProvider


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.debug.internal.ui.viewers.model;
12
13 import java.util.HashSet JavaDoc;
14 import java.util.Set JavaDoc;
15
16 import org.eclipse.core.runtime.IProgressMonitor;
17 import org.eclipse.core.runtime.IStatus;
18 import org.eclipse.core.runtime.Status;
19 import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
20 import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
21 import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
22 import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
23 import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
24 import org.eclipse.jface.viewers.IBasicPropertyConstants;
25 import org.eclipse.jface.viewers.ILazyTreePathContentProvider;
26 import org.eclipse.jface.viewers.TreePath;
27 import org.eclipse.jface.viewers.TreeSelection;
28 import org.eclipse.jface.viewers.TreeViewer;
29 import org.eclipse.swt.widgets.Item;
30 import org.eclipse.swt.widgets.Tree;
31 import org.eclipse.swt.widgets.TreeItem;
32 import org.eclipse.swt.widgets.Widget;
33 import org.eclipse.ui.progress.UIJob;
34
35 /**
36  * Content provider for a virtual tree.
37  *
38  * @since 3.3
39  */

40 public class TreeModelContentProvider extends ModelContentProvider implements ILazyTreePathContentProvider {
41     
42     protected static final String JavaDoc[] STATE_PROPERTIES = new String JavaDoc[]{IBasicPropertyConstants.P_TEXT, IBasicPropertyConstants.P_IMAGE};
43     
44     /**
45      * Re-filters any filtered children of the given parent element.
46      *
47      * @param path parent element
48      */

49     protected void refilterChildren(TreePath path) {
50         if (getViewer() != null) {
51             int[] filteredChildren = getFilteredChildren(path);
52             if (filteredChildren != null) {
53                 for (int i = 0; i < filteredChildren.length; i++) {
54                     doUpdateElement(path, filteredChildren[i]);
55                 }
56             }
57         }
58     }
59     
60     protected synchronized void doUpdateChildCount(TreePath path) {
61         Object JavaDoc element = getElement(path);
62         IElementContentProvider contentAdapter = getContentAdapter(element);
63         if (contentAdapter != null) {
64             ChildrenCountUpdate request = new ChildrenCountUpdate(this, path, element, contentAdapter, getPresentationContext());
65             schedule(request);
66         }
67     }
68     
69     protected synchronized void doUpdateElement(TreePath parentPath, int modelIndex) {
70         Object JavaDoc parent = getElement(parentPath);
71         IElementContentProvider contentAdapter = getContentAdapter(parent);
72         if (contentAdapter != null) {
73             ChildrenUpdate request = new ChildrenUpdate(this, parentPath, parent, modelIndex, contentAdapter, getPresentationContext());
74             schedule(request);
75         }
76     }
77     
78     protected synchronized void doUpdateHasChildren(TreePath path) {
79         Object JavaDoc element = getElement(path);
80         IElementContentProvider contentAdapter = getContentAdapter(element);
81         if (contentAdapter != null) {
82             HasChildrenUpdate request = new HasChildrenUpdate(this, path, element, contentAdapter, getPresentationContext());
83             schedule(request);
84         }
85     }
86     
87     /* (non-Javadoc)
88      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#getPresentationContext()
89      */

90     protected IPresentationContext getPresentationContext() {
91         return ((TreeModelViewer)getViewer()).getPresentationContext();
92     }
93     
94     /**
95      * Returns the tree viewer this content provider is working for
96      *
97      * @return tree viewer
98      */

99     protected TreeViewer getTreeViewer() {
100         return (TreeViewer)getViewer();
101     }
102
103     /* (non-Javadoc)
104      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleAdd(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta)
105      */

106     protected void handleAdd(IModelDelta delta) {
107         if (DEBUG_CONTENT_PROVIDER) {
108             System.out.println("handleAdd(" + delta.getElement() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
109
}
110         doUpdateChildCount(getViewerTreePath(delta.getParentDelta()));
111     }
112
113     /* (non-Javadoc)
114      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleContent(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta)
115      */

116     protected void handleContent(IModelDelta delta) {
117         if (delta.getChildCount() == 0) {
118             // if the delta is for the root, ensure the root still matches viewer input
119
if (!delta.getElement().equals(getViewer().getInput())) {
120                 return;
121             }
122         }
123         TreePath treePath = getViewerTreePath(delta);
124         cancelSubtreeUpdates(treePath);
125         getTreeViewer().refresh(getElement(treePath));
126     }
127     
128     /* (non-Javadoc)
129      * @see org.eclipse.debug.internal.ui.viewers.model.ModelContentProvider#handleCollapse(org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta)
130      */

131     protected void handleCollapse(IModelDelta delta) {
132         TreePath elementPath = getViewerTreePath(delta);
133         getTreeViewer().setExpandedState(elementPath, false);
134     }
135
136     /* (non-Javadoc)
137      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleExpand(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta)
138      */

139     protected void handleExpand(IModelDelta delta) {
140         // expand each parent, then this node
141
IModelDelta parentDelta = delta.getParentDelta();
142         if (parentDelta != null) {
143             handleExpand(parentDelta);
144             expand(delta);
145         }
146     }
147     
148     protected void expand(IModelDelta delta) {
149         int childCount = delta.getChildCount();
150         int modelIndex = delta.getIndex();
151         TreeViewer treeViewer = getTreeViewer();
152         TreePath elementPath = getViewerTreePath(delta);
153         if (modelIndex >= 0) {
154             int viewIndex = modelToViewIndex(getViewerTreePath(delta.getParentDelta()), modelIndex);
155             if (viewIndex >= 0) {
156                 if (DEBUG_CONTENT_PROVIDER) {
157                     System.out.println("[expand] replace(" + delta.getParentDelta().getElement() + ", (model) " + modelIndex + " (view) " + viewIndex + ", " + delta.getElement()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
158
}
159                 TreePath parentPath = elementPath.getParentPath();
160                 if (parentPath == null) {
161                     parentPath = TreePath.EMPTY;
162                 }
163                 treeViewer.replace(parentPath, viewIndex, delta.getElement());
164             }
165         }
166         if (childCount > 0) {
167             int viewCount = modelToViewChildCount(elementPath, childCount);
168             if (DEBUG_CONTENT_PROVIDER) {
169                 System.out.println("[expand] setChildCount(" + delta.getElement() + ", (model) " + childCount + " (view) " + viewCount); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
170
}
171             treeViewer.setChildCount(elementPath, viewCount);
172             if (!treeViewer.getExpandedState(elementPath)) {
173                 treeViewer.expandToLevel(elementPath, 1);
174             }
175         }
176     }
177
178     /* (non-Javadoc)
179      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleInsert(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta)
180      */

181     protected void handleInsert(IModelDelta delta) {
182         // TODO: filters
183
getTreeViewer().insert(getViewerTreePath(delta.getParentDelta()), delta.getElement(), delta.getIndex());
184     }
185
186     /* (non-Javadoc)
187      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleRemove(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta)
188      */

189     protected void handleRemove(IModelDelta delta) {
190         if (DEBUG_CONTENT_PROVIDER) {
191             System.out.println("handleRemove(" + delta.getElement() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
192
}
193         IModelDelta parentDelta = delta.getParentDelta();
194         InternalTreeModelViewer treeViewer = (InternalTreeModelViewer)getViewer();
195         TreePath parentPath = getViewerTreePath(parentDelta);
196         Widget parentItem = treeViewer.findItem(parentPath);
197         if (parentItem == null) {
198             // if we can't see the parent, nothing to worry about (but clear the filters, if any)
199
clearFilters(parentPath);
200             return;
201         }
202         Object JavaDoc element = delta.getElement();
203         if (removeElementFromFilters(parentPath, element)) {
204             // element was filtered - done
205
return;
206         }
207         int viewIndex = -1;
208         int modelIndex = delta.getIndex();
209         int unmappedIndex = -1;
210         int itemCount = -1;
211         if (modelIndex < 0) {
212             // index not provided by delta
213
Item[] children = treeViewer.getChildren(parentItem);
214             itemCount = children.length;
215             for (int i = 0; i < children.length; i++) {
216                 Item item = children[i];
217                 Object JavaDoc data = item.getData();
218                 if (element.equals(data)) {
219                     viewIndex = i;
220                     modelIndex = viewToModelIndex(parentPath, i);
221                     break;
222                 } else if (data == null) {
223                     unmappedIndex = i;
224                 }
225             }
226         } else {
227             viewIndex = modelToViewIndex(parentPath, modelIndex);
228         }
229         if (modelIndex >= 0) {
230             // found the element
231
if (DEBUG_CONTENT_PROVIDER) {
232                 System.out.println(" - (found) remove(" + parentPath.getLastSegment() + ", viewIndex: " + viewIndex + " modelIndex: " + modelIndex); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
233
}
234             rescheduleUpdates(parentPath, modelIndex);
235             getTreeViewer().remove(parentPath, viewIndex);
236             removeElementFromFilters(parentPath, modelIndex);
237             return;
238         }
239         if (unmappedIndex >= 0) {
240             // did not find the element, but found an unmapped item.
241
// remove the unmapped item in it's place and update filters
242
if (DEBUG_CONTENT_PROVIDER) {
243                 System.out.println(" - (not found) remove(" + parentPath.getLastSegment() + ", viewIndex: " + viewIndex + " modelIndex: " + modelIndex); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
244
}
245             modelIndex = viewToModelIndex(parentPath, unmappedIndex);
246             rescheduleUpdates(parentPath, modelIndex);
247             getTreeViewer().remove(parentPath, unmappedIndex);
248             removeElementFromFilters(parentPath, modelIndex);
249             return;
250         }
251         int modelCount = parentDelta.getChildCount();
252         if (itemCount >= 0 && modelCount >= 0) {
253             if (modelToViewChildCount(parentPath, modelCount) == itemCount) {
254                 // item count matches the parent's child count, don't do anything
255
return;
256             }
257         }
258         // failing that, refresh the parent to properly update for non-visible/unmapped children
259
// and update filtered indexes
260
if (DEBUG_CONTENT_PROVIDER) {
261             System.out.println(" - (not found) remove/refresh(" + delta.getElement()); //$NON-NLS-1$
262
}
263         getTreeViewer().remove(getViewerTreePath(delta));
264         clearFilters(parentPath);
265         getTreeViewer().refresh(parentDelta.getElement());
266     }
267
268     /* (non-Javadoc)
269      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleReplace(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta)
270      */

271     protected void handleReplace(IModelDelta delta) {
272         TreePath parentPath = getViewerTreePath(delta.getParentDelta());
273         getTreeViewer().replace(parentPath, delta.getIndex(), delta.getElement());
274     }
275
276     /* (non-Javadoc)
277      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleSelect(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta)
278      */

279     protected void handleSelect(IModelDelta delta) {
280         int modelIndex = delta.getIndex();
281         TreeViewer treeViewer = getTreeViewer();
282         if (modelIndex >= 0) {
283             IModelDelta parentDelta = delta.getParentDelta();
284             TreePath parentPath = getViewerTreePath(parentDelta);
285             int viewIndex = modelToViewIndex(parentPath, modelIndex);
286             int modelCount = parentDelta.getChildCount();
287             if (modelCount > 0) {
288                 int viewCount = modelToViewChildCount(parentPath, modelCount);
289                 if (DEBUG_CONTENT_PROVIDER) {
290                     System.out.println("[select] setChildCount(" + parentDelta.getElement() + ", (model) " + parentDelta.getChildCount() + " (view) " + viewCount ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
291
}
292                 treeViewer.setChildCount(parentPath, viewCount);
293             }
294             if (DEBUG_CONTENT_PROVIDER) {
295                 System.out.println("[select] replace(" + parentDelta.getElement() + ", (model) " + modelIndex + " (view) " + viewIndex + ", " + delta.getElement()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
296
}
297             treeViewer.replace(parentPath, viewIndex, delta.getElement());
298         }
299         treeViewer.setSelection(new TreeSelection(getViewerTreePath(delta)));
300     }
301
302     /* (non-Javadoc)
303      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleState(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta)
304      */

305     protected void handleState(IModelDelta delta) {
306         getTreeViewer().update(delta.getElement(), STATE_PROPERTIES);
307     }
308
309     /* (non-Javadoc)
310      * @see org.eclipse.debug.internal.ui.viewers.model.ModelContentProvider#handleReveal(org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta)
311      */

312     protected void handleReveal(IModelDelta delta) {
313         IModelDelta parentDelta = delta.getParentDelta();
314         if (parentDelta != null) {
315             handleExpand(parentDelta);
316             reveal(delta);
317         }
318     }
319     
320     protected void reveal(IModelDelta delta) {
321         int modelIndex = delta.getIndex();
322         InternalTreeModelViewer treeViewer = (InternalTreeModelViewer) getTreeViewer();
323         TreePath elementPath = getViewerTreePath(delta);
324         if (modelIndex >= 0) {
325             int viewIndex = modelToViewIndex(getViewerTreePath(delta.getParentDelta()), modelIndex);
326             if (DEBUG_CONTENT_PROVIDER) {
327                 System.out.println("[reveal] replace(" + delta.getParentDelta().getElement() + ", (model) " + modelIndex + " (view) " + viewIndex + ", " + delta.getElement()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
328
}
329             TreePath parentPath = elementPath.getParentPath();
330             if (parentPath == null) {
331                 parentPath = TreePath.EMPTY;
332             }
333             treeViewer.replace(parentPath, viewIndex, delta.getElement());
334             Widget item = treeViewer.findItem(elementPath);
335             if (item instanceof TreeItem) {
336                 treeViewer.getTree().setTopItem((TreeItem) item);
337             }
338         }
339     }
340
341     /* (non-Javadoc)
342      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#buildViewerState(org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta)
343      */

344     protected void buildViewerState(ModelDelta delta) {
345         Tree tree = (Tree) getViewer().getControl();
346         TreeItem[] selection = tree.getSelection();
347         Set JavaDoc set = new HashSet JavaDoc();
348         for (int i = 0; i < selection.length; i++) {
349             set.add(selection[i]);
350         }
351         TreeItem[] items = tree.getItems();
352         for (int i = 0; i < items.length; i++) {
353             buildViewerState(EMPTY_TREE_PATH, delta, items[i], set, i);
354         }
355         // add memento for top item if it is mapped to an element
356
TreeItem topItem = tree.getTopItem();
357         if (topItem != null && topItem.getData() != null) {
358             TreePath path = ((InternalTreeModelViewer)getTreeViewer()).getTreePathFromItem(topItem);
359             ModelDelta parentDelta = delta;
360             for (int i = 0; i < path.getSegmentCount(); i++) {
361                 Object JavaDoc element = path.getSegment(i);
362                 ModelDelta childDelta = parentDelta.getChildDelta(element);
363                 if (childDelta == null) {
364                     parentDelta = parentDelta.addNode(element, IModelDelta.NO_CHANGE);
365                 } else {
366                     parentDelta = childDelta;
367                 }
368             }
369             parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.REVEAL);
370         }
371     }
372
373     /**
374      * @param delta parent delta to build on
375      * @param item item
376      * @param set set of selected tree items
377      * @param index the item's index relative to it's parent
378      */

379     private void buildViewerState(TreePath parentPath, ModelDelta delta, TreeItem item, Set JavaDoc set, int index) {
380         Object JavaDoc element = item.getData();
381         if (element != null) {
382             boolean expanded = item.getExpanded();
383             boolean selected = set.contains(item);
384             if (expanded || selected) {
385                 int flags = IModelDelta.NO_CHANGE;
386                 if (expanded) {
387                     flags = flags | IModelDelta.EXPAND;
388                 }
389                 if (selected) {
390                     flags = flags | IModelDelta.SELECT;
391                 }
392                 int modelIndex = viewToModelIndex(parentPath, index);
393                 TreePath elementPath = parentPath.createChildPath(element);
394                 int numChildren = viewToModelCount(elementPath, item.getItemCount());
395                 ModelDelta childDelta = delta.addNode(element, modelIndex, flags, numChildren);
396                 if (expanded) {
397                     TreeItem[] items = item.getItems();
398                     for (int i = 0; i < items.length; i++) {
399                         buildViewerState(elementPath, childDelta, items[i], set, i);
400                     }
401                 }
402             }
403         }
404     }
405
406     /* (non-Javadoc)
407      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#doInitialRestore()
408      */

409     protected void doInitialRestore() {
410         Tree tree = (Tree) getViewer().getControl();
411         TreeItem[] items = tree.getItems();
412         for (int i = 0; i < items.length; i++) {
413             TreeItem item = items[i];
414             Object JavaDoc data = item.getData();
415             if (data != null) {
416                 doRestore(new TreePath(new Object JavaDoc[]{data}));
417             }
418         }
419     }
420
421     /* (non-Javadoc)
422      * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#getParents(java.lang.Object)
423      */

424     public TreePath[] getParents(Object JavaDoc element) {
425         return null;
426     }
427
428     /* (non-Javadoc)
429      * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#updateChildCount(org.eclipse.jface.viewers.TreePath, int)
430      */

431     public synchronized void updateChildCount(TreePath treePath, int currentChildCount) {
432         if (DEBUG_CONTENT_PROVIDER) {
433             System.out.println("updateChildCount(" + getElement(treePath) + ", " + currentChildCount + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
434
}
435         refilterChildren(treePath);
436         //re-filter children when asked to update the child count for an element (i.e.
437
// when refreshing, see if filtered children are still filtered)
438
doUpdateChildCount(treePath);
439     }
440
441     /* (non-Javadoc)
442      * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#updateElement(org.eclipse.jface.viewers.TreePath, int)
443      */

444     public synchronized void updateElement(TreePath parentPath, int viewIndex) {
445         int modelIndex = viewToModelIndex(parentPath, viewIndex);
446         if (DEBUG_CONTENT_PROVIDER) {
447             System.out.println("updateElement("+ getElement(parentPath) + ", " + viewIndex + ") > modelIndex = " + modelIndex); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
448
}
449         doUpdateElement(parentPath, modelIndex);
450     }
451
452     /* (non-Javadoc)
453      * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#updateHasChildren(org.eclipse.jface.viewers.TreePath)
454      */

455     public synchronized void updateHasChildren(TreePath path) {
456         if (DEBUG_CONTENT_PROVIDER) {
457             System.out.println("updateHasChildren(" + getElement(path)); //$NON-NLS-1$
458
}
459         doUpdateHasChildren(path);
460     }
461
462     /**
463      * @param delta
464      */

465     void doRestore(final ModelDelta delta) {
466         if (delta.getFlags() != IModelDelta.NO_CHANGE) {
467             UIJob job = new UIJob("restore delta") { //$NON-NLS-1$
468
public IStatus runInUIThread(IProgressMonitor monitor) {
469                     TreePath treePath = getViewerTreePath(delta);
470                     InternalTreeModelViewer viewer = (InternalTreeModelViewer)getViewer();
471                     if ((delta.getFlags() & IModelDelta.EXPAND) != 0) {
472                         viewer.expandToLevel(treePath, 1);
473                     }
474                     if ((delta.getFlags() & IModelDelta.SELECT) != 0) {
475                         viewer.setSelection(new TreeSelection(treePath));
476                     }
477                     int flag = IModelDelta.NO_CHANGE;
478                     if ((delta.getFlags() & IModelDelta.REVEAL) != 0) {
479                         flag = IModelDelta.REVEAL;
480                     }
481                     delta.setFlags(flag);
482                     IModelDelta topItemDelta = checkIfRestoreComplete();
483                     // force child deltas to update, so viewer is populated
484
IModelDelta[] childDeltas = delta.getChildDeltas();
485                     for (int i = 0; i < childDeltas.length; i++) {
486                         IModelDelta childDelta = childDeltas[i];
487                         int modelIndex = childDelta.getIndex();
488                         if (modelIndex >= 0) {
489                             doUpdateElement(treePath, modelIndex);
490                         }
491                     }
492                     if (topItemDelta != null) {
493                         TreePath itemPath = getViewerTreePath(topItemDelta);
494                         Widget topItem = viewer.findItem(itemPath);
495                         if (topItem instanceof TreeItem) {
496                             viewer.getTree().setTopItem((TreeItem) topItem);
497                         }
498                     }
499                     return Status.OK_STATUS;
500                 }
501             };
502             job.setSystem(true);
503             job.schedule();
504         }
505     }
506 }
507
Popular Tags