Source Code Cross Referenced for TreeViewer.java in  » IDE-Eclipse » jface » org » eclipse » jface » viewers » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jface » org.eclipse.jface.viewers 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2004, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *     Tom Schindl <tom.schindl@bestsolution.at> - concept of ViewerRow,
0011:         *                                                 refactoring (bug 153993), bug 167323, 191468
0012:         *******************************************************************************/package org.eclipse.jface.viewers;
0013:
0014:        import java.util.Arrays;
0015:        import java.util.Iterator;
0016:        import java.util.LinkedList;
0017:        import java.util.List;
0018:
0019:        import org.eclipse.jface.util.Policy;
0020:        import org.eclipse.swt.SWT;
0021:        import org.eclipse.swt.events.DisposeEvent;
0022:        import org.eclipse.swt.events.DisposeListener;
0023:        import org.eclipse.swt.events.TreeEvent;
0024:        import org.eclipse.swt.events.TreeListener;
0025:        import org.eclipse.swt.graphics.Point;
0026:        import org.eclipse.swt.widgets.Composite;
0027:        import org.eclipse.swt.widgets.Control;
0028:        import org.eclipse.swt.widgets.Event;
0029:        import org.eclipse.swt.widgets.Item;
0030:        import org.eclipse.swt.widgets.Listener;
0031:        import org.eclipse.swt.widgets.Tree;
0032:        import org.eclipse.swt.widgets.TreeItem;
0033:        import org.eclipse.swt.widgets.Widget;
0034:
0035:        /**
0036:         * A concrete viewer based on an SWT <code>Tree</code> control.
0037:         * <p>
0038:         * This class is not intended to be subclassed outside the viewer framework. It
0039:         * is designed to be instantiated with a pre-existing SWT tree control and
0040:         * configured with a domain-specific content provider, label provider, element
0041:         * filter (optional), and element sorter (optional).
0042:         * </p>
0043:         * <p>
0044:         * Content providers for tree viewers must implement either the
0045:         * {@link ITreeContentProvider} interface, (as of 3.2) the
0046:         * {@link ILazyTreeContentProvider} interface, or (as of 3.3) the
0047:         * {@link ILazyTreePathContentProvider}. If the content provider is an
0048:         * <code>ILazyTreeContentProvider</code> or an
0049:         * <code>ILazyTreePathContentProvider</code>, the underlying Tree must be
0050:         * created using the {@link SWT#VIRTUAL} style bit, and the tree viewer will not
0051:         * support sorting or filtering.
0052:         * </p>
0053:         */
0054:        public class TreeViewer extends AbstractTreeViewer {
0055:
0056:            private static final String VIRTUAL_DISPOSE_KEY = Policy.JFACE
0057:                    + ".DISPOSE_LISTENER"; //$NON-NLS-1$
0058:
0059:            /**
0060:             * This viewer's control.
0061:             */
0062:            private Tree tree;
0063:
0064:            /**
0065:             * Flag for whether the tree has been disposed of.
0066:             */
0067:            private boolean treeIsDisposed = false;
0068:
0069:            private boolean contentProviderIsLazy;
0070:
0071:            private boolean contentProviderIsTreeBased;
0072:
0073:            /**
0074:             * The row object reused
0075:             */
0076:            private TreeViewerRow cachedRow;
0077:
0078:            /**
0079:             * true if we are inside a preservingSelection() call
0080:             */
0081:            private boolean preservingSelection;
0082:
0083:            /**
0084:             * Creates a tree viewer on a newly-created tree control under the given
0085:             * parent. The tree control is created using the SWT style bits
0086:             * <code>MULTI, H_SCROLL, V_SCROLL,</code> and <code>BORDER</code>. The
0087:             * viewer has no input, no content provider, a default label provider, no
0088:             * sorter, and no filters.
0089:             *
0090:             * @param parent
0091:             *            the parent control
0092:             */
0093:            public TreeViewer(Composite parent) {
0094:                this (parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
0095:                        | SWT.BORDER);
0096:            }
0097:
0098:            /**
0099:             * Creates a tree viewer on a newly-created tree control under the given
0100:             * parent. The tree control is created using the given SWT style bits. The
0101:             * viewer has no input, no content provider, a default label provider, no
0102:             * sorter, and no filters.
0103:             *
0104:             * @param parent
0105:             *            the parent control
0106:             * @param style
0107:             *            the SWT style bits used to create the tree.
0108:             */
0109:            public TreeViewer(Composite parent, int style) {
0110:                this (new Tree(parent, style));
0111:            }
0112:
0113:            /**
0114:             * Creates a tree viewer on the given tree control. The viewer has no input,
0115:             * no content provider, a default label provider, no sorter, and no filters.
0116:             *
0117:             * @param tree
0118:             *            the tree control
0119:             */
0120:            public TreeViewer(Tree tree) {
0121:                super ();
0122:                this .tree = tree;
0123:                hookControl(tree);
0124:            }
0125:
0126:            /*
0127:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0128:             */
0129:            protected void addTreeListener(Control c, TreeListener listener) {
0130:                ((Tree) c).addTreeListener(listener);
0131:            }
0132:
0133:            /*
0134:             * (non-Javadoc)
0135:             *
0136:             * @see org.eclipse.jface.viewers.ColumnViewer#getColumnViewerOwner(int)
0137:             */
0138:            protected Widget getColumnViewerOwner(int columnIndex) {
0139:                if (columnIndex < 0
0140:                        || (columnIndex > 0 && columnIndex >= getTree()
0141:                                .getColumnCount())) {
0142:                    return null;
0143:                }
0144:
0145:                if (getTree().getColumnCount() == 0)// Hang it off the table if it
0146:                    return getTree();
0147:
0148:                return getTree().getColumn(columnIndex);
0149:            }
0150:
0151:            /*
0152:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0153:             */
0154:            protected Item[] getChildren(Widget o) {
0155:                if (o instanceof  TreeItem) {
0156:                    return ((TreeItem) o).getItems();
0157:                }
0158:                if (o instanceof  Tree) {
0159:                    return ((Tree) o).getItems();
0160:                }
0161:                return null;
0162:            }
0163:
0164:            /*
0165:             * (non-Javadoc) Method declared in Viewer.
0166:             */
0167:            public Control getControl() {
0168:                return tree;
0169:            }
0170:
0171:            /*
0172:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0173:             */
0174:            protected boolean getExpanded(Item item) {
0175:                return ((TreeItem) item).getExpanded();
0176:            }
0177:
0178:            /*
0179:             * (non-Javadoc)
0180:             *
0181:             * @see org.eclipse.jface.viewers.ColumnViewer#getItemAt(org.eclipse.swt.graphics.Point)
0182:             */
0183:            protected Item getItemAt(Point p) {
0184:                TreeItem[] selection = tree.getSelection();
0185:
0186:                if (selection.length == 1) {
0187:                    if (selection[0].getBounds().contains(p)) {
0188:                        return selection[0];
0189:                    }
0190:                }
0191:
0192:                return getTree().getItem(p);
0193:            }
0194:
0195:            /*
0196:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0197:             */
0198:            protected int getItemCount(Control widget) {
0199:                return ((Tree) widget).getItemCount();
0200:            }
0201:
0202:            /*
0203:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0204:             */
0205:            protected int getItemCount(Item item) {
0206:                return ((TreeItem) item).getItemCount();
0207:            }
0208:
0209:            /*
0210:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0211:             */
0212:            protected Item[] getItems(Item item) {
0213:                return ((TreeItem) item).getItems();
0214:            }
0215:
0216:            /**
0217:             * The tree viewer implementation of this <code>Viewer</code> framework
0218:             * method ensures that the given label provider is an instance of either
0219:             * <code>ITableLabelProvider</code> or <code>ILabelProvider</code>. If
0220:             * it is an <code>ITableLabelProvider</code>, then it provides a separate
0221:             * label text and image for each column. If it is an
0222:             * <code>ILabelProvider</code>, then it provides only the label text and
0223:             * image for the first column, and any remaining columns are blank.
0224:             */
0225:            public IBaseLabelProvider getLabelProvider() {
0226:                return super .getLabelProvider();
0227:            }
0228:
0229:            /*
0230:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0231:             */
0232:            protected Item getParentItem(Item item) {
0233:                return ((TreeItem) item).getParentItem();
0234:            }
0235:
0236:            /*
0237:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0238:             */
0239:            protected Item[] getSelection(Control widget) {
0240:                return ((Tree) widget).getSelection();
0241:            }
0242:
0243:            /**
0244:             * Returns this tree viewer's tree control.
0245:             *
0246:             * @return the tree control
0247:             */
0248:            public Tree getTree() {
0249:                return tree;
0250:            }
0251:
0252:            /*
0253:             * (non-Javadoc)
0254:             *
0255:             * @see org.eclipse.jface.viewers.AbstractTreeViewer#hookControl(org.eclipse.swt.widgets.Control)
0256:             */
0257:            protected void hookControl(Control control) {
0258:                super .hookControl(control);
0259:                Tree treeControl = (Tree) control;
0260:
0261:                if ((treeControl.getStyle() & SWT.VIRTUAL) != 0) {
0262:                    treeControl.addDisposeListener(new DisposeListener() {
0263:                        public void widgetDisposed(DisposeEvent e) {
0264:                            treeIsDisposed = true;
0265:                            unmapAllElements();
0266:                        }
0267:                    });
0268:                    treeControl.addListener(SWT.SetData, new Listener() {
0269:
0270:                        public void handleEvent(Event event) {
0271:                            if (contentProviderIsLazy) {
0272:                                TreeItem item = (TreeItem) event.item;
0273:                                TreeItem parentItem = item.getParentItem();
0274:                                int index = event.index;
0275:                                virtualLazyUpdateWidget(
0276:                                        parentItem == null ? (Widget) getTree()
0277:                                                : parentItem, index);
0278:                            }
0279:                        }
0280:
0281:                    });
0282:                }
0283:            }
0284:
0285:            protected ColumnViewerEditor createViewerEditor() {
0286:                return new TreeViewerEditor(this , null,
0287:                        new ColumnViewerEditorActivationStrategy(this ),
0288:                        ColumnViewerEditor.DEFAULT);
0289:            }
0290:
0291:            /*
0292:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0293:             */
0294:            protected Item newItem(Widget parent, int flags, int ix) {
0295:                TreeItem item;
0296:
0297:                if (parent instanceof  TreeItem) {
0298:                    item = (TreeItem) createNewRowPart(
0299:                            getViewerRowFromItem(parent), flags, ix).getItem();
0300:                } else {
0301:                    item = (TreeItem) createNewRowPart(null, flags, ix)
0302:                            .getItem();
0303:                }
0304:
0305:                return item;
0306:            }
0307:
0308:            /*
0309:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0310:             */
0311:            protected void removeAll(Control widget) {
0312:                ((Tree) widget).removeAll();
0313:            }
0314:
0315:            /*
0316:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0317:             */
0318:            protected void setExpanded(Item node, boolean expand) {
0319:                ((TreeItem) node).setExpanded(expand);
0320:                if (contentProviderIsLazy) {
0321:                    // force repaints to happen
0322:                    getControl().update();
0323:                }
0324:            }
0325:
0326:            /*
0327:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0328:             */
0329:            protected void setSelection(List items) {
0330:
0331:                Item[] current = getSelection(getTree());
0332:
0333:                // Don't bother resetting the same selection
0334:                if (isSameSelection(items, current)) {
0335:                    return;
0336:                }
0337:
0338:                TreeItem[] newItems = new TreeItem[items.size()];
0339:                items.toArray(newItems);
0340:                getTree().setSelection(newItems);
0341:            }
0342:
0343:            /*
0344:             * (non-Javadoc) Method declared in AbstractTreeViewer.
0345:             */
0346:            protected void showItem(Item item) {
0347:                getTree().showItem((TreeItem) item);
0348:            }
0349:
0350:            /*
0351:             * (non-Javadoc)
0352:             *
0353:             * @see org.eclipse.jface.viewers.AbstractTreeViewer#getChild(org.eclipse.swt.widgets.Widget,
0354:             *      int)
0355:             */
0356:            protected Item getChild(Widget widget, int index) {
0357:                if (widget instanceof  TreeItem) {
0358:                    return ((TreeItem) widget).getItem(index);
0359:                }
0360:                if (widget instanceof  Tree) {
0361:                    return ((Tree) widget).getItem(index);
0362:                }
0363:                return null;
0364:            }
0365:
0366:            protected void assertContentProviderType(IContentProvider provider) {
0367:                if (provider instanceof  ILazyTreeContentProvider
0368:                        || provider instanceof  ILazyTreePathContentProvider) {
0369:                    return;
0370:                }
0371:                super .assertContentProviderType(provider);
0372:            }
0373:
0374:            protected Object[] getRawChildren(Object parent) {
0375:                if (contentProviderIsLazy) {
0376:                    return new Object[0];
0377:                }
0378:                return super .getRawChildren(parent);
0379:            }
0380:
0381:            void preservingSelection(Runnable updateCode, boolean reveal) {
0382:                if (preservingSelection) {
0383:                    // avoid preserving the selection if called reentrantly,
0384:                    // see bug 172640
0385:                    updateCode.run();
0386:                    return;
0387:                }
0388:                preservingSelection = true;
0389:                try {
0390:                    super .preservingSelection(updateCode, reveal);
0391:                } finally {
0392:                    preservingSelection = false;
0393:                }
0394:            }
0395:
0396:            /**
0397:             * For a TreeViewer with a tree with the VIRTUAL style bit set, set the
0398:             * number of children of the given element or tree path. To set the number
0399:             * of children of the invisible root of the tree, you can pass the input
0400:             * object or an empty tree path.
0401:             *
0402:             * @param elementOrTreePath
0403:             *            the element, or tree path
0404:             * @param count
0405:             *
0406:             * @since 3.2
0407:             */
0408:            public void setChildCount(final Object elementOrTreePath,
0409:                    final int count) {
0410:                if (isBusy())
0411:                    return;
0412:                preservingSelection(new Runnable() {
0413:                    public void run() {
0414:                        if (internalIsInputOrEmptyPath(elementOrTreePath)) {
0415:                            getTree().setItemCount(count);
0416:                            return;
0417:                        }
0418:                        Widget[] items = internalFindItems(elementOrTreePath);
0419:                        for (int i = 0; i < items.length; i++) {
0420:                            TreeItem treeItem = (TreeItem) items[i];
0421:                            treeItem.setItemCount(count);
0422:                        }
0423:                    }
0424:                });
0425:            }
0426:
0427:            /**
0428:             * For a TreeViewer with a tree with the VIRTUAL style bit set, replace the
0429:             * given parent's child at index with the given element. If the given parent
0430:             * is this viewer's input or an empty tree path, this will replace the root
0431:             * element at the given index.
0432:             * <p>
0433:             * This method should be called by implementers of ILazyTreeContentProvider
0434:             * to populate this viewer.
0435:             * </p>
0436:             *
0437:             * @param parentElementOrTreePath
0438:             *            the parent of the element that should be updated, or the tree
0439:             *            path to that parent
0440:             * @param index
0441:             *            the index in the parent's children
0442:             * @param element
0443:             *            the new element
0444:             *
0445:             * @see #setChildCount(Object, int)
0446:             * @see ILazyTreeContentProvider
0447:             * @see ILazyTreePathContentProvider
0448:             *
0449:             * @since 3.2
0450:             */
0451:            public void replace(final Object parentElementOrTreePath,
0452:                    final int index, final Object element) {
0453:                if (isBusy())
0454:                    return;
0455:                Item[] selectedItems = getSelection(getControl());
0456:                TreeSelection selection = (TreeSelection) getSelection();
0457:                Widget[] itemsToDisassociate;
0458:                if (parentElementOrTreePath instanceof  TreePath) {
0459:                    TreePath elementPath = ((TreePath) parentElementOrTreePath)
0460:                            .createChildPath(element);
0461:                    itemsToDisassociate = internalFindItems(elementPath);
0462:                } else {
0463:                    itemsToDisassociate = internalFindItems(element);
0464:                }
0465:                if (internalIsInputOrEmptyPath(parentElementOrTreePath)) {
0466:                    if (index < tree.getItemCount()) {
0467:                        TreeItem item = tree.getItem(index);
0468:                        selection = adjustSelectionForReplace(selectedItems,
0469:                                selection, item, element, getRoot());
0470:                        // disassociate any different item that represents the
0471:                        // same element under the same parent (the tree)
0472:                        for (int i = 0; i < itemsToDisassociate.length; i++) {
0473:                            if (itemsToDisassociate[i] instanceof  TreeItem) {
0474:                                TreeItem itemToDisassociate = (TreeItem) itemsToDisassociate[i];
0475:                                if (itemToDisassociate != item
0476:                                        && itemToDisassociate.getParentItem() == null) {
0477:                                    int indexToDisassociate = getTree()
0478:                                            .indexOf(itemToDisassociate);
0479:                                    disassociate(itemToDisassociate);
0480:                                    getTree().clear(indexToDisassociate, true);
0481:                                }
0482:                            }
0483:                        }
0484:                        Object oldData = item.getData();
0485:                        updateItem(item, element);
0486:                        if (!TreeViewer.this .equals(oldData, element)) {
0487:                            item.clearAll(true);
0488:                        }
0489:                    }
0490:                } else {
0491:                    Widget[] parentItems = internalFindItems(parentElementOrTreePath);
0492:                    for (int i = 0; i < parentItems.length; i++) {
0493:                        TreeItem parentItem = (TreeItem) parentItems[i];
0494:                        if (index < parentItem.getItemCount()) {
0495:                            TreeItem item = parentItem.getItem(index);
0496:                            selection = adjustSelectionForReplace(
0497:                                    selectedItems, selection, item, element,
0498:                                    parentItem.getData());
0499:                            // disassociate any different item that represents the
0500:                            // same element under the same parent (the tree)
0501:                            for (int j = 0; j < itemsToDisassociate.length; j++) {
0502:                                if (itemsToDisassociate[j] instanceof  TreeItem) {
0503:                                    TreeItem itemToDisassociate = (TreeItem) itemsToDisassociate[j];
0504:                                    if (itemToDisassociate != item
0505:                                            && itemToDisassociate
0506:                                                    .getParentItem() == parentItem) {
0507:                                        int indexToDisaccociate = parentItem
0508:                                                .indexOf(itemToDisassociate);
0509:                                        disassociate(itemToDisassociate);
0510:                                        parentItem.clear(indexToDisaccociate,
0511:                                                true);
0512:                                    }
0513:                                }
0514:                            }
0515:                            Object oldData = item.getData();
0516:                            updateItem(item, element);
0517:                            if (!TreeViewer.this .equals(oldData, element)) {
0518:                                item.clearAll(true);
0519:                            }
0520:                        }
0521:                    }
0522:                }
0523:                // Restore the selection if we are not already in a nested preservingSelection:
0524:                if (!preservingSelection) {
0525:                    setSelectionToWidget(selection, false);
0526:                    // send out notification if old and new differ
0527:                    ISelection newSelection = getSelection();
0528:                    if (!newSelection.equals(selection)) {
0529:                        handleInvalidSelection(selection, newSelection);
0530:                    }
0531:                }
0532:            }
0533:
0534:            /**
0535:             * Fix for bug 185673: If the currently replaced item was selected, add it
0536:             * to the selection that is being restored. Only do this if its getData() is
0537:             * currently null
0538:             *
0539:             * @param selectedItems
0540:             * @param selection
0541:             * @param item
0542:             * @param element
0543:             * @return
0544:             */
0545:            private TreeSelection adjustSelectionForReplace(
0546:                    Item[] selectedItems, TreeSelection selection,
0547:                    TreeItem item, Object element, Object parentElement) {
0548:                if (item.getData() != null
0549:                        || selectedItems.length == selection.size()
0550:                        || parentElement == null) {
0551:                    // Don't do anything - we are not seeing an instance of bug 185673
0552:                    return selection;
0553:                }
0554:                for (int i = 0; i < selectedItems.length; i++) {
0555:                    if (item == selectedItems[i]) {
0556:                        // The current item was selected, but its data is null.
0557:                        // The data will be replaced by the given element, so to keep
0558:                        // it selected, we have to add it to the selection.
0559:                        TreePath[] originalPaths = selection.getPaths();
0560:                        int length = originalPaths.length;
0561:                        TreePath[] paths = new TreePath[length + 1];
0562:                        System.arraycopy(originalPaths, 0, paths, 0, length);
0563:                        // set the element temporarily so that we can call getTreePathFromItem
0564:                        item.setData(element);
0565:                        paths[length] = getTreePathFromItem(item);
0566:                        item.setData(null);
0567:                        return new TreeSelection(paths, selection
0568:                                .getElementComparer());
0569:                    }
0570:                }
0571:                // The item was not selected, return the given selection
0572:                return selection;
0573:            }
0574:
0575:            public boolean isExpandable(Object element) {
0576:                if (contentProviderIsLazy) {
0577:                    TreeItem treeItem = (TreeItem) internalExpand(element,
0578:                            false);
0579:                    if (treeItem == null) {
0580:                        return false;
0581:                    }
0582:                    virtualMaterializeItem(treeItem);
0583:                    return treeItem.getItemCount() > 0;
0584:                }
0585:                return super .isExpandable(element);
0586:            }
0587:
0588:            protected Object getParentElement(Object element) {
0589:                boolean oldBusy = busy;
0590:                busy = true;
0591:                try {
0592:                    if (contentProviderIsLazy && !contentProviderIsTreeBased
0593:                            && !(element instanceof  TreePath)) {
0594:                        ILazyTreeContentProvider lazyTreeContentProvider = (ILazyTreeContentProvider) getContentProvider();
0595:                        return lazyTreeContentProvider.getParent(element);
0596:                    }
0597:                    if (contentProviderIsLazy && contentProviderIsTreeBased
0598:                            && !(element instanceof  TreePath)) {
0599:                        ILazyTreePathContentProvider lazyTreePathContentProvider = (ILazyTreePathContentProvider) getContentProvider();
0600:                        TreePath[] parents = lazyTreePathContentProvider
0601:                                .getParents(element);
0602:                        if (parents != null && parents.length > 0) {
0603:                            return parents[0];
0604:                        }
0605:                    }
0606:                    return super .getParentElement(element);
0607:                } finally {
0608:                    busy = oldBusy;
0609:                }
0610:            }
0611:
0612:            protected void createChildren(Widget widget) {
0613:                if (contentProviderIsLazy) {
0614:                    Object element = widget.getData();
0615:                    if (element == null && widget instanceof  TreeItem) {
0616:                        // parent has not been materialized
0617:                        virtualMaterializeItem((TreeItem) widget);
0618:                        // try getting the element now that updateElement was called
0619:                        element = widget.getData();
0620:                    }
0621:                    if (element == null) {
0622:                        // give up because the parent is still not materialized
0623:                        return;
0624:                    }
0625:                    Item[] children = getChildren(widget);
0626:                    if (children.length == 1 && children[0].getData() == null) {
0627:                        // found a dummy node
0628:                        virtualLazyUpdateChildCount(widget, children.length);
0629:                        children = getChildren(widget);
0630:                    }
0631:                    // touch all children to make sure they are materialized
0632:                    for (int i = 0; i < children.length; i++) {
0633:                        if (children[i].getData() == null) {
0634:                            virtualLazyUpdateWidget(widget, i);
0635:                        }
0636:                    }
0637:                    return;
0638:                }
0639:                super .createChildren(widget);
0640:            }
0641:
0642:            protected void internalAdd(Widget widget, Object parentElement,
0643:                    Object[] childElements) {
0644:                if (contentProviderIsLazy) {
0645:                    if (widget instanceof  TreeItem) {
0646:                        TreeItem ti = (TreeItem) widget;
0647:                        int count = ti.getItemCount() + childElements.length;
0648:                        ti.setItemCount(count);
0649:                        ti.clearAll(false);
0650:                    } else {
0651:                        Tree t = (Tree) widget;
0652:                        t.setItemCount(t.getItemCount() + childElements.length);
0653:                        t.clearAll(false);
0654:                    }
0655:                    return;
0656:                }
0657:                super .internalAdd(widget, parentElement, childElements);
0658:            }
0659:
0660:            private void virtualMaterializeItem(TreeItem treeItem) {
0661:                if (treeItem.getData() != null) {
0662:                    // already materialized
0663:                    return;
0664:                }
0665:                if (!contentProviderIsLazy) {
0666:                    return;
0667:                }
0668:                int index;
0669:                Widget parent = treeItem.getParentItem();
0670:                if (parent == null) {
0671:                    parent = treeItem.getParent();
0672:                }
0673:                Object parentElement = parent.getData();
0674:                if (parentElement != null) {
0675:                    if (parent instanceof  Tree) {
0676:                        index = ((Tree) parent).indexOf(treeItem);
0677:                    } else {
0678:                        index = ((TreeItem) parent).indexOf(treeItem);
0679:                    }
0680:                    virtualLazyUpdateWidget(parent, index);
0681:                }
0682:            }
0683:
0684:            /*
0685:             * (non-Javadoc)
0686:             *
0687:             * @see org.eclipse.jface.viewers.AbstractTreeViewer#internalRefreshStruct(org.eclipse.swt.widgets.Widget,
0688:             *      java.lang.Object, boolean)
0689:             */
0690:            protected void internalRefreshStruct(Widget widget, Object element,
0691:                    boolean updateLabels) {
0692:                if (contentProviderIsLazy) {
0693:                    // clear all starting with the given widget
0694:                    if (widget instanceof  Tree) {
0695:                        ((Tree) widget).clearAll(true);
0696:                    } else if (widget instanceof  TreeItem) {
0697:                        ((TreeItem) widget).clearAll(true);
0698:                    }
0699:                    int index = 0;
0700:                    Widget parent = null;
0701:                    if (widget instanceof  TreeItem) {
0702:                        TreeItem treeItem = (TreeItem) widget;
0703:                        parent = treeItem.getParentItem();
0704:                        if (parent == null) {
0705:                            parent = treeItem.getParent();
0706:                        }
0707:                        if (parent instanceof  Tree) {
0708:                            index = ((Tree) parent).indexOf(treeItem);
0709:                        } else {
0710:                            index = ((TreeItem) parent).indexOf(treeItem);
0711:                        }
0712:                    }
0713:                    virtualRefreshExpandedItems(parent, widget, element, index);
0714:                    return;
0715:                }
0716:                super .internalRefreshStruct(widget, element, updateLabels);
0717:            }
0718:
0719:            /**
0720:             * Traverses the visible (expanded) part of the tree and updates child
0721:             * counts.
0722:             *
0723:             * @param parent the parent of the widget, or <code>null</code> if the widget is the tree
0724:             * @param widget
0725:             * @param element
0726:             * @param index the index of the widget in the children array of its parent, or 0 if the widget is the tree
0727:             */
0728:            private void virtualRefreshExpandedItems(Widget parent,
0729:                    Widget widget, Object element, int index) {
0730:                if (widget instanceof  Tree) {
0731:                    if (element == null) {
0732:                        ((Tree) widget).setItemCount(0);
0733:                        return;
0734:                    }
0735:                    virtualLazyUpdateChildCount(widget,
0736:                            getChildren(widget).length);
0737:                } else if (((TreeItem) widget).getExpanded()) {
0738:                    // prevent SetData callback
0739:                    ((TreeItem) widget).setText(" "); //$NON-NLS-1$
0740:                    virtualLazyUpdateWidget(parent, index);
0741:                } else {
0742:                    return;
0743:                }
0744:                Item[] items = getChildren(widget);
0745:                for (int i = 0; i < items.length; i++) {
0746:                    Item item = items[i];
0747:                    Object data = item.getData();
0748:                    virtualRefreshExpandedItems(widget, item, data, i);
0749:                }
0750:            }
0751:
0752:            /*
0753:             * To unmap elements correctly, we need to register a dispose listener with
0754:             * the item if the tree is virtual.
0755:             */
0756:            protected void mapElement(Object element, final Widget item) {
0757:                super .mapElement(element, item);
0758:                // make sure to unmap elements if the tree is virtual
0759:                if ((getTree().getStyle() & SWT.VIRTUAL) != 0) {
0760:                    // only add a dispose listener if item hasn't already on assigned
0761:                    // because it is reused
0762:                    if (item.getData(VIRTUAL_DISPOSE_KEY) == null) {
0763:                        item.setData(VIRTUAL_DISPOSE_KEY, Boolean.TRUE);
0764:                        item.addDisposeListener(new DisposeListener() {
0765:                            public void widgetDisposed(DisposeEvent e) {
0766:                                if (!treeIsDisposed) {
0767:                                    Object data = item.getData();
0768:                                    if (usingElementMap() && data != null) {
0769:                                        unmapElement(data, item);
0770:                                    }
0771:                                }
0772:                            }
0773:                        });
0774:                    }
0775:                }
0776:            }
0777:
0778:            /*
0779:             * (non-Javadoc)
0780:             *
0781:             * @see org.eclipse.jface.viewers.ColumnViewer#getRowPartFromItem(org.eclipse.swt.widgets.Widget)
0782:             */
0783:            protected ViewerRow getViewerRowFromItem(Widget item) {
0784:                if (cachedRow == null) {
0785:                    cachedRow = new TreeViewerRow((TreeItem) item);
0786:                } else {
0787:                    cachedRow.setItem((TreeItem) item);
0788:                }
0789:
0790:                return cachedRow;
0791:            }
0792:
0793:            /**
0794:             * Create a new ViewerRow at rowIndex
0795:             *
0796:             * @param parent
0797:             * @param style
0798:             * @param rowIndex
0799:             * @return ViewerRow
0800:             */
0801:            private ViewerRow createNewRowPart(ViewerRow parent, int style,
0802:                    int rowIndex) {
0803:                if (parent == null) {
0804:                    if (rowIndex >= 0) {
0805:                        return getViewerRowFromItem(new TreeItem(tree, style,
0806:                                rowIndex));
0807:                    }
0808:                    return getViewerRowFromItem(new TreeItem(tree, style));
0809:                }
0810:
0811:                if (rowIndex >= 0) {
0812:                    return getViewerRowFromItem(new TreeItem((TreeItem) parent
0813:                            .getItem(), SWT.NONE, rowIndex));
0814:                }
0815:
0816:                return getViewerRowFromItem(new TreeItem((TreeItem) parent
0817:                        .getItem(), SWT.NONE));
0818:            }
0819:
0820:            /*
0821:             * (non-Javadoc)
0822:             *
0823:             * @see org.eclipse.jface.viewers.AbstractTreeViewer#internalInitializeTree(org.eclipse.swt.widgets.Control)
0824:             */
0825:            protected void internalInitializeTree(Control widget) {
0826:                if (contentProviderIsLazy) {
0827:                    if (widget instanceof  Tree && widget.getData() != null) {
0828:                        virtualLazyUpdateChildCount(widget, 0);
0829:                        return;
0830:                    }
0831:                }
0832:                super .internalInitializeTree(tree);
0833:            }
0834:
0835:            /*
0836:             * (non-Javadoc)
0837:             *
0838:             * @see org.eclipse.jface.viewers.AbstractTreeViewer#updatePlus(org.eclipse.swt.widgets.Item,
0839:             *      java.lang.Object)
0840:             */
0841:            protected void updatePlus(Item item, Object element) {
0842:                if (contentProviderIsLazy) {
0843:                    Object data = item.getData();
0844:                    int itemCount = 0;
0845:                    if (data != null) {
0846:                        // item is already materialized
0847:                        itemCount = ((TreeItem) item).getItemCount();
0848:                    }
0849:                    virtualLazyUpdateHasChildren(item, itemCount);
0850:                } else {
0851:                    super .updatePlus(item, element);
0852:                }
0853:            }
0854:
0855:            /**
0856:             * Removes the element at the specified index of the parent.  The selection is updated if required.
0857:             *
0858:             * @param parentOrTreePath the parent element, the input element, or a tree path to the parent element
0859:             * @param index child index
0860:             * @since 3.3
0861:             */
0862:            public void remove(final Object parentOrTreePath, final int index) {
0863:                if (isBusy())
0864:                    return;
0865:                final List oldSelection = new LinkedList(Arrays
0866:                        .asList(((TreeSelection) getSelection()).getPaths()));
0867:                preservingSelection(new Runnable() {
0868:                    public void run() {
0869:                        TreePath removedPath = null;
0870:                        if (internalIsInputOrEmptyPath(parentOrTreePath)) {
0871:                            Tree tree = (Tree) getControl();
0872:                            if (index < tree.getItemCount()) {
0873:                                TreeItem item = tree.getItem(index);
0874:                                if (item.getData() != null) {
0875:                                    removedPath = getTreePathFromItem(item);
0876:                                    disassociate(item);
0877:                                }
0878:                                item.dispose();
0879:                            }
0880:                        } else {
0881:                            Widget[] parentItems = internalFindItems(parentOrTreePath);
0882:                            for (int i = 0; i < parentItems.length; i++) {
0883:                                TreeItem parentItem = (TreeItem) parentItems[i];
0884:                                if (index < parentItem.getItemCount()) {
0885:                                    TreeItem item = parentItem.getItem(index);
0886:                                    if (item.getData() != null) {
0887:                                        removedPath = getTreePathFromItem(item);
0888:                                        disassociate(item);
0889:                                    }
0890:                                    item.dispose();
0891:                                }
0892:                            }
0893:                        }
0894:                        if (removedPath != null) {
0895:                            boolean removed = false;
0896:                            for (Iterator it = oldSelection.iterator(); it
0897:                                    .hasNext();) {
0898:                                TreePath path = (TreePath) it.next();
0899:                                if (path.startsWith(removedPath, getComparer())) {
0900:                                    it.remove();
0901:                                    removed = true;
0902:                                }
0903:                            }
0904:                            if (removed) {
0905:                                setSelection(
0906:                                        new TreeSelection(
0907:                                                (TreePath[]) oldSelection
0908:                                                        .toArray(new TreePath[oldSelection
0909:                                                                .size()]),
0910:                                                getComparer()), false);
0911:                            }
0912:
0913:                        }
0914:                    }
0915:                });
0916:            }
0917:
0918:            /* (non-Javadoc)
0919:             * @see org.eclipse.jface.viewers.AbstractTreeViewer#handleTreeExpand(org.eclipse.swt.events.TreeEvent)
0920:             */
0921:            protected void handleTreeExpand(TreeEvent event) {
0922:                if (contentProviderIsLazy) {
0923:                    if (event.item.getData() != null) {
0924:                        Item[] children = getChildren(event.item);
0925:                        if (children.length == 1
0926:                                && children[0].getData() == null) {
0927:                            // we have a dummy child node, ask for an updated child
0928:                            // count
0929:                            virtualLazyUpdateChildCount(event.item,
0930:                                    children.length);
0931:                        }
0932:                        fireTreeExpanded(new TreeExpansionEvent(this ,
0933:                                event.item.getData()));
0934:                    }
0935:                    return;
0936:                }
0937:                super .handleTreeExpand(event);
0938:            }
0939:
0940:            /* (non-Javadoc)
0941:             * @see org.eclipse.jface.viewers.AbstractTreeViewer#setContentProvider(org.eclipse.jface.viewers.IContentProvider)
0942:             */
0943:            public void setContentProvider(IContentProvider provider) {
0944:                contentProviderIsLazy = (provider instanceof  ILazyTreeContentProvider)
0945:                        || (provider instanceof  ILazyTreePathContentProvider);
0946:                contentProviderIsTreeBased = provider instanceof  ILazyTreePathContentProvider;
0947:                super .setContentProvider(provider);
0948:            }
0949:
0950:            /**
0951:             * For a TreeViewer with a tree with the VIRTUAL style bit set, inform the
0952:             * viewer about whether the given element or tree path has children. Avoid
0953:             * calling this method if the number of children has already been set.
0954:             *
0955:             * @param elementOrTreePath
0956:             *            the element, or tree path
0957:             * @param hasChildren
0958:             *
0959:             * @since 3.3
0960:             */
0961:            public void setHasChildren(final Object elementOrTreePath,
0962:                    final boolean hasChildren) {
0963:                if (isBusy())
0964:                    return;
0965:                preservingSelection(new Runnable() {
0966:                    public void run() {
0967:                        if (internalIsInputOrEmptyPath(elementOrTreePath)) {
0968:                            if (hasChildren) {
0969:                                virtualLazyUpdateChildCount(getTree(),
0970:                                        getChildren(getTree()).length);
0971:                            } else {
0972:                                setChildCount(elementOrTreePath, 0);
0973:                            }
0974:                            return;
0975:                        }
0976:                        Widget[] items = internalFindItems(elementOrTreePath);
0977:                        for (int i = 0; i < items.length; i++) {
0978:                            TreeItem item = (TreeItem) items[i];
0979:                            if (!hasChildren) {
0980:                                item.setItemCount(0);
0981:                            } else {
0982:                                if (!item.getExpanded()) {
0983:                                    item.setItemCount(1);
0984:                                    TreeItem child = item.getItem(0);
0985:                                    if (child.getData() != null) {
0986:                                        disassociate(child);
0987:                                    }
0988:                                    item.clear(0, true);
0989:                                } else {
0990:                                    virtualLazyUpdateChildCount(item, item
0991:                                            .getItemCount());
0992:                                }
0993:                            }
0994:                        }
0995:                    }
0996:                });
0997:            }
0998:
0999:            /**
1000:             * Update the widget at index.
1001:             * @param widget
1002:             * @param index
1003:             */
1004:            private void virtualLazyUpdateWidget(Widget widget, int index) {
1005:                boolean oldBusy = busy;
1006:                busy = false;
1007:                try {
1008:                    if (contentProviderIsTreeBased) {
1009:                        TreePath treePath;
1010:                        if (widget instanceof  Item) {
1011:                            if (widget.getData() == null) {
1012:                                // we need to materialize the parent first
1013:                                // see bug 167668
1014:                                // however, that would be too risky
1015:                                // see bug 182782 and bug 182598
1016:                                // so we just ignore this call altogether
1017:                                // and don't do this: virtualMaterializeItem((TreeItem) widget);
1018:                                return;
1019:                            }
1020:                            treePath = getTreePathFromItem((Item) widget);
1021:                        } else {
1022:                            treePath = TreePath.EMPTY;
1023:                        }
1024:                        ((ILazyTreePathContentProvider) getContentProvider())
1025:                                .updateElement(treePath, index);
1026:                    } else {
1027:                        ((ILazyTreeContentProvider) getContentProvider())
1028:                                .updateElement(widget.getData(), index);
1029:                    }
1030:                } finally {
1031:                    busy = oldBusy;
1032:                }
1033:            }
1034:
1035:            /**
1036:             * Update the child count
1037:             * @param widget
1038:             * @param currentChildCount
1039:             */
1040:            private void virtualLazyUpdateChildCount(Widget widget,
1041:                    int currentChildCount) {
1042:                boolean oldBusy = busy;
1043:                busy = false;
1044:                try {
1045:                    if (contentProviderIsTreeBased) {
1046:                        TreePath treePath;
1047:                        if (widget instanceof  Item) {
1048:                            treePath = getTreePathFromItem((Item) widget);
1049:                        } else {
1050:                            treePath = TreePath.EMPTY;
1051:                        }
1052:                        ((ILazyTreePathContentProvider) getContentProvider())
1053:                                .updateChildCount(treePath, currentChildCount);
1054:                    } else {
1055:                        ((ILazyTreeContentProvider) getContentProvider())
1056:                                .updateChildCount(widget.getData(),
1057:                                        currentChildCount);
1058:                    }
1059:                } finally {
1060:                    busy = oldBusy;
1061:                }
1062:            }
1063:
1064:            /**
1065:             * Update the item with the current child count.
1066:             * @param item
1067:             * @param currentChildCount
1068:             */
1069:            private void virtualLazyUpdateHasChildren(Item item,
1070:                    int currentChildCount) {
1071:                boolean oldBusy = busy;
1072:                busy = false;
1073:                try {
1074:                    if (contentProviderIsTreeBased) {
1075:                        TreePath treePath;
1076:                        treePath = getTreePathFromItem(item);
1077:                        if (currentChildCount == 0) {
1078:                            // item is not expanded (but may have a plus currently)
1079:                            ((ILazyTreePathContentProvider) getContentProvider())
1080:                                    .updateHasChildren(treePath);
1081:                        } else {
1082:                            ((ILazyTreePathContentProvider) getContentProvider())
1083:                                    .updateChildCount(treePath,
1084:                                            currentChildCount);
1085:                        }
1086:                    } else {
1087:                        ((ILazyTreeContentProvider) getContentProvider())
1088:                                .updateChildCount(item.getData(),
1089:                                        currentChildCount);
1090:                    }
1091:                } finally {
1092:                    busy = oldBusy;
1093:                }
1094:            }
1095:
1096:            protected void disassociate(Item item) {
1097:                if (contentProviderIsLazy) {
1098:                    // avoid causing a callback:
1099:                    item.setText(" "); //$NON-NLS-1$
1100:                }
1101:                super .disassociate(item);
1102:            }
1103:
1104:            protected int doGetColumnCount() {
1105:                return tree.getColumnCount();
1106:            }
1107:
1108:            /**
1109:             * Sets a new selection for this viewer and optionally makes it visible.
1110:             * <p>
1111:             * <b>Currently the <code>reveal</code> parameter is not honored because
1112:             * {@link Tree} does not provide an API to only select an item without
1113:             * scrolling it into view</b>
1114:             * </p>
1115:             *
1116:             * @param selection
1117:             *            the new selection
1118:             * @param reveal
1119:             *            <code>true</code> if the selection is to be made visible,
1120:             *            and <code>false</code> otherwise
1121:             */
1122:            public void setSelection(ISelection selection, boolean reveal) {
1123:                super .setSelection(selection, reveal);
1124:            }
1125:
1126:            public void editElement(Object element, int column) {
1127:                if (element instanceof  TreePath) {
1128:                    setSelection(new TreeSelection((TreePath) element));
1129:                    TreeItem[] items = tree.getSelection();
1130:
1131:                    if (items.length == 1) {
1132:                        ViewerRow row = getViewerRowFromItem(items[0]);
1133:
1134:                        if (row != null) {
1135:                            ViewerCell cell = row.getCell(column);
1136:                            if (cell != null) {
1137:                                getControl().setRedraw(false);
1138:                                triggerEditorActivationEvent(new ColumnViewerEditorActivationEvent(
1139:                                        cell));
1140:                                getControl().setRedraw(true);
1141:                            }
1142:                        }
1143:                    }
1144:                } else {
1145:                    super.editElement(element, column);
1146:                }
1147:            }
1148:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.