Example usage for org.eclipse.jface.viewers TreeViewer setExpandedState

List of usage examples for org.eclipse.jface.viewers TreeViewer setExpandedState

Introduction

In this page you can find the example usage for org.eclipse.jface.viewers TreeViewer setExpandedState.

Prototype

public void setExpandedState(Object elementOrTreePath, boolean expanded) 

Source Link

Document

Sets whether the node corresponding to the given element or tree path is expanded or collapsed.

Usage

From source file:org.eclipse.papyrus.diagram.common.service.palette.StereotypePostAction.java

License:Open Source License

/**
 * Action done when a DoubleClick is received by the tree
 * /*from  w w  w .  java  2  s  .  co m*/
 * @param viewer
 *        the viewer on which the DoubleClick action is applied
 */
protected void performDoubleClickAction(TreeViewer viewer) {

    TreeSelection selection = (TreeSelection) viewer.getSelection();
    if (selection != null && selection.size() == 1) {
        Object selectedObject = selection.getFirstElement();
        if (selectedObject instanceof StereotypeRepresentation) {
            //we expand or collapse the node
            viewer.setExpandedState(selectedObject, !viewer.getExpandedState(selectedObject));
        } else if (selectedObject instanceof PropertyRepresentation) {
            Property prop = ((PropertyRepresentation) selectedObject).getUMLProperty();
            if (prop.isMultivalued()) {
                //we expand or collapse the node
                viewer.setExpandedState(selectedObject, !viewer.getExpandedState(selectedObject));
            } else {
                //we edit a value
                if (((PropertyRepresentation) selectedObject).getValues().isEmpty()) {
                    editMe((PropertyRepresentation) selectedObject, null);
                } else {
                    editMe((PropertyRepresentation) selectedObject,
                            ((PropertyRepresentation) selectedObject).getValues().get(0));
                }

                viewer.update(selectedObject, null);
            }
        } else if (selectedObject instanceof Value) {
            editMe(((Value) selectedObject).getPropertyRepresentation(), (Value) selectedObject);
            viewer.refresh(selectedObject);
        }
    }
}

From source file:org.eclipse.papyrus.uml.diagram.common.service.palette.StereotypePostAction.java

License:Open Source License

/**
 * Action done when a DoubleClick is received by the tree
 * // w  w w.j  a  v a 2 s . c  o  m
 * @param viewer
 *        the viewer on which the DoubleClick action is applied
 */
protected void performDoubleClickAction(TreeViewer viewer) {

    TreeSelection selection = (TreeSelection) viewer.getSelection();
    if (selection != null && selection.size() == 1) {
        Object selectedObject = selection.getFirstElement();
        if (selectedObject instanceof StereotypeRepresentation) {
            // we expand or collapse the node
            viewer.setExpandedState(selectedObject, !viewer.getExpandedState(selectedObject));
        } else if (selectedObject instanceof PropertyRepresentation) {
            Property prop = ((PropertyRepresentation) selectedObject).getUMLProperty();
            if (prop.isMultivalued()) {
                // we expand or collapse the node
                viewer.setExpandedState(selectedObject, !viewer.getExpandedState(selectedObject));
            } else {
                // we edit a value
                if (((PropertyRepresentation) selectedObject).getValues().isEmpty()) {
                    editMe((PropertyRepresentation) selectedObject, null);
                } else {
                    editMe((PropertyRepresentation) selectedObject,
                            ((PropertyRepresentation) selectedObject).getValues().get(0));
                }

                viewer.update(selectedObject, null);
            }
        } else if (selectedObject instanceof Value) {
            editMe(((Value) selectedObject).getPropertyRepresentation(), (Value) selectedObject);
            viewer.refresh(selectedObject);
        }
    }
}

From source file:org.eclipse.php.internal.ui.actions.newprojectwizard.NewWizardNewPage.java

License:Open Source License

/**
 * Create a new FilteredTree in the parent.
 * //w  w  w  . j  a v a2  s .c o  m
 * @param parent
 *            the parent <code>Composite</code>.
 * @since 3.0
 */
protected FilteredTree createFilteredTree(Composite parent) {
    Composite composite = new Composite(parent, SWT.NONE);
    GridLayout layout = new GridLayout();
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    composite.setLayout(layout);

    GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
    data.widthHint = SIZING_VIEWER_WIDTH;
    data.horizontalSpan = 2;
    data.grabExcessHorizontalSpace = true;
    data.grabExcessVerticalSpace = true;

    boolean needsHint = DialogUtil.inRegularFontMode(parent);

    // Only give a height hint if the dialog is going to be too small
    if (needsHint) {
        data.heightHint = SIZING_LISTS_HEIGHT;
    }
    composite.setLayoutData(data);

    filteredTreeFilter = new WizardPatternFilter();
    FilteredTree filterTree = new FilteredTree(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER,
            filteredTreeFilter, true);

    final TreeViewer treeViewer = filterTree.getViewer();
    treeViewer.setContentProvider(new WizardContentProvider());
    treeViewer.setLabelProvider(new WorkbenchLabelProvider());
    treeViewer.addSelectionChangedListener(this);

    ArrayList inputArray = new ArrayList();

    for (int i = 0; i < primaryWizards.length; i++) {
        inputArray.add(primaryWizards[i]);
    }

    if (!projectsOnly) {

        IWizardCategory phpCategory = wizardCategories.findCategory(new Path("org.eclipse.php.project.ui")); //$NON-NLS-1$
        // IWizardCategory[] children = wizardCategories.getCategories();
        // for (int i = 0; i < children.length; i++) {
        // if ("org.eclipse.php.project.ui".equals(children[i].getId())) {
        // phpCategory = children[i];
        // }
        // }
        if (phpCategory != null) {
            IWizardDescriptor[] wizards = phpCategory.getWizards();
            for (int i = 0; i < wizards.length; i++) {
                inputArray.add(wizards[i]);
            }
            inputArray = sortWizard(inputArray);
            IWizardCategory[] categories = phpCategory.getCategories();
            for (int i = 0; i < categories.length; i++) {
                inputArray.add(categories[i]);
            }
            IWizardDescriptor folder = wizardCategories.findWizard("org.eclipse.ui.wizards.new.folder"); //$NON-NLS-1$
            if (folder != null) {
                inputArray.add(folder);
            }
        }
        NewWizardCollectionComparator comparator = NewWizardCollectionComparator.INSTANCE;
        Set set = new HashSet();
        set.addAll(inputArray);
        comparator.setPrimaryWizards(set);
        treeViewer.setComparator(comparator);
    } else {
        NewWizardCollectionComparator comparator = NewWizardCollectionComparator.INSTANCE;
        comparator.setPrimaryWizards(null);
        treeViewer.setComparator(comparator);
    }

    boolean expandTop = false;

    if (wizardCategories != null) {
        if (wizardCategories.getParent() == null) {
            IWizardCategory[] children = wizardCategories.getCategories();
            for (int i = 0; i < children.length; i++) {
                if (!"org.eclipse.php.project.ui".equals(children[i] //$NON-NLS-1$
                        .getId())) {
                    inputArray.add(children[i]);
                }
            }
        } else {
            expandTop = true;
            inputArray.add(wizardCategories);
        }
    }

    // ensure the category is expanded. If there is a remembered expansion
    // it will be set later.
    if (expandTop) {
        treeViewer.setAutoExpandLevel(2);
    }

    AdaptableList input = new AdaptableList(inputArray);

    treeViewer.setInput(input);

    filterTree.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));

    treeViewer.getTree().setFont(parent.getFont());

    treeViewer.addDoubleClickListener(new IDoubleClickListener() {
        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org
         * .eclipse.jface.viewers.DoubleClickEvent)
         */
        public void doubleClick(DoubleClickEvent event) {
            IStructuredSelection s = (IStructuredSelection) event.getSelection();
            selectionChanged(new SelectionChangedEvent(event.getViewer(), s));

            Object element = s.getFirstElement();
            if (treeViewer.isExpandable(element)) {
                treeViewer.setExpandedState(element, !treeViewer.getExpandedState(element));
            } else if (element instanceof WorkbenchWizardElement) {
                page.advanceToNextPageOrFinish();
            }
        }
    });

    treeViewer.addFilter(filter);

    if (projectsOnly) {
        treeViewer.addFilter(projectFilter);
    }

    Dialog.applyDialogFont(filterTree);
    return filterTree;
}

From source file:org.eclipse.php.internal.ui.actions.PHPExplorerActionGroup.java

License:Open Source License

/**
 * this method call ScriptExplorerActionGroup.handleDoubleClick(event) at
 * most cases, except fNavigateActionGroup relative operation
 *///  ww w  .  j av a  2s  . c  o  m
protected void handleDoubleClick(DoubleClickEvent event) {
    TreeViewer viewer = getPart().getTreeViewer();
    IStructuredSelection selection = (IStructuredSelection) event.getSelection();
    Object element = selection.getFirstElement();
    if (viewer.isExpandable(element)) {
        if (doubleClickGoesInto()) {
            super.handleDoubleClick(event);
        } else {
            IAction openAction = fNavigateActionGroup.getOpenAction();
            if (openAction != null && openAction.isEnabled()
                    && OpenStrategy.getOpenMethod() == OpenStrategy.DOUBLE_CLICK)
                return;
            if (selection instanceof ITreeSelection) {
                TreePath[] paths = ((ITreeSelection) selection).getPathsFor(element);
                for (int i = 0; i < paths.length; i++) {
                    viewer.setExpandedState(paths[i], !viewer.getExpandedState(paths[i]));
                }
            } else {
                viewer.setExpandedState(element, !viewer.getExpandedState(element));
            }
        }
    } else {
        super.handleDoubleClick(event);
    }
}

From source file:org.eclipse.rcptt.ctx.filesystem.ui.FilesystemContextEditor.java

License:Open Source License

private void createTree(FormToolkit toolkit, Composite client) {
    final Tree tree = new Tree(client, SWT.BORDER | SWT.MULTI);
    GridDataFactory.fillDefaults().grab(true, true).span(1, 1).hint(100, 50).applyTo(tree);

    viewer = new TreeViewer(tree);
    viewer.setLabelProvider(new FilesystemContextLabelProvider());
    viewer.setContentProvider(new FilesystemContextContentProvider());
    viewer.setInput(getContextElement());
    viewer.addSelectionChangedListener(new ISelectionChangedListener() {
        public void selectionChanged(SelectionChangedEvent event) {
            IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
            Object[] res = sel.toArray();
            FSResource[] resources = new FSResource[res.length];
            for (int i = 0; i < res.length; i++)
                resources[i] = (FSResource) res[i];
            setSelection(resources);/*from   w  w  w .  j  a va2s  .co  m*/
        }
    });
    viewer.addDoubleClickListener(new IDoubleClickListener() {

        /**
         * Opens file or expands/collapses folder.
         */
        public void doubleClick(DoubleClickEvent event) {
            if (openFileAction.isEnabled()) {
                openFileAction.run();
            } else {
                TreeViewer viewer = (TreeViewer) event.getViewer();
                IStructuredSelection selection = (IStructuredSelection) event.getSelection();
                Object selectedNode = selection.getFirstElement();
                viewer.setExpandedState(selectedNode, !viewer.getExpandedState(selectedNode));
            }
        }
    });

    // Setups renaming
    TreeViewerEditor.create(viewer, new DefaultTreeViewerEditStrategy(viewer), ColumnViewerEditor.DEFAULT);
    viewer.setCellEditors(new CellEditor[] { new TextCellEditor(tree) });
    viewer.setCellModifier(new ICellModifier() {
        public void modify(Object element, String property, Object value) {
            TreeItem item = (TreeItem) element;
            FSResource res = (FSResource) item.getData();
            EObject parent = res.eContainer();
            Set<String> allNames = getAllNames(parent);
            allNames.remove(res.getName());

            String newValue = (String) value;
            if (allNames.contains(newValue)) {
                return;
            }

            if (newValue != null && !newValue.isEmpty() && !newValue.equals(res.getName())) {
                res.setName(newValue);
            }
        }

        public Object getValue(Object element, String property) {
            return ((FSResource) element).getName();
        }

        public boolean canModify(Object element, String property) {
            return true;
        }
    });
    viewer.setColumnProperties(new String[] { "" });

    viewer.getControl().addKeyListener(new KeyListener() {

        public void keyReleased(KeyEvent e) {
        }

        public void keyPressed(KeyEvent e) {
            if ((SWT.DEL == e.character) && (0 == e.stateMask)) {
                if (removeAction.isEnabled()) {
                    removeAction.run();
                    e.doit = false;
                }
            }
        }
    });

    UIContentAdapter adapter = new UIContentAdapter() {
        @Override
        protected void changed(Notification notification) {
            if (viewer.getControl().isDisposed()) {
                return;
            }
            viewer.refresh();
        }
    };
    getContextElement().eAdapters().add(adapter);
}

From source file:org.eclipse.rcptt.ui.resources.viewers.WorkspaceContextEditor.java

License:Open Source License

private Tree createTree(Composite parent, FormToolkit toolkit) {
    Tree tree = new Tree(parent, SWT.BORDER | SWT.MULTI);
    GridDataFactory.fillDefaults().grab(true, true).hint(100, 50).applyTo(tree);

    viewer = new TreeViewer(tree);
    TreeViewerEditor.create(viewer, new DefaultTreeViewerEditStrategy(viewer), ColumnViewerEditor.DEFAULT);
    viewer.setCellEditors(new CellEditor[] { new TextCellEditor(tree) });
    viewer.setCellModifier(new ICellModifier() {
        public void modify(Object element, String property, Object value) {
            TreeItem item = (TreeItem) element;
            WSResource res = (WSResource) item.getData();
            WSContainer parent = (WSContainer) res.eContainer();
            Set<String> allNames = getAllNames(parent);
            allNames.remove(res.getName());

            String newValue = (String) value;
            if (allNames.contains(newValue)) {
                return;
            }/*from ww w . jav  a  2 s  . c o m*/
            if (newValue != null && !newValue.equals(res.getName())) {
                try {
                    IPersistenceModel model = getElement().getPersistenceModel();

                    if (res instanceof WSFile) {
                        String oldName = ImportUtils.getName((WSFile) res);
                        res.setName(newValue);
                        String newName = ImportUtils.getName((WSFile) res);
                        model.rename(oldName, newName);
                    } else if (res instanceof WSContainer) {
                        // Rename all stored files.
                        List<String> oldNames = new ArrayList<String>();
                        List<WSFile> allFiles = findChildFiles((WSContainer) res);
                        for (WSFile wsFile : allFiles) {
                            oldNames.add(ImportUtils.getName(wsFile));
                        }
                        res.setName(newValue);
                        for (int i = 0; i < oldNames.size(); i++) {
                            String oldName = oldNames.get(i);
                            WSFile file = allFiles.get(i);
                            String newName = ImportUtils.getName(file);
                            model.rename(oldName, newName);
                        }
                    }
                    // viewer.update(res, null);
                } catch (Exception e) {
                    Q7UIPlugin.log(e);
                }
            }
        }

        public Object getValue(Object element, String property) {
            return ((WSResource) element).getName();
        }

        public boolean canModify(Object element, String property) {
            return true;
        }
    });
    viewer.setColumnProperties(new String[] { "o" });
    viewer.setContentProvider(new WorkspaceContentProvider());
    ILabelDecorator decorator = PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator();
    viewer.setLabelProvider(
            new DecoratingStyledCellLabelProvider(new WorkspaceLabelProvider(), decorator, null));
    viewer.setInput(getContextElement());
    viewer.addSelectionChangedListener(new ISelectionChangedListener() {

        public void selectionChanged(SelectionChangedEvent event) {
            IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
            Object[] res = sel.toArray();
            WSResource[] resources = new WSResource[res.length];
            for (int i = 0; i < res.length; i++)
                resources[i] = (WSResource) res[i];
            setSelection(resources);
        }
    });
    viewer.addDoubleClickListener(new IDoubleClickListener() {

        /**
         * Opens file or expands/collapses folder.
         */
        public void doubleClick(DoubleClickEvent event) {
            if (openFileAction.isEnabled()) {
                openFileAction.run();
            } else {
                TreeViewer viewer = (TreeViewer) event.getViewer();
                IStructuredSelection selection = (IStructuredSelection) event.getSelection();
                Object selectedNode = selection.getFirstElement();
                viewer.setExpandedState(selectedNode, !viewer.getExpandedState(selectedNode));
            }
        }
    });
    viewer.getControl().addKeyListener(new KeyListener() {

        public void keyReleased(KeyEvent e) {
        }

        public void keyPressed(KeyEvent e) {
            if ((SWT.DEL == e.character) && (0 == e.stateMask)) {
                if (removeAction.isEnabled()) {
                    removeAction.run();
                    e.doit = false;
                }
            }
        }
    });

    adapter = new UIContentAdapter() {

        protected void changed(Notification notification) {
            if (viewer.getControl().isDisposed()) {
                return;
            }
            viewer.refresh();
        }
    };
    getContextElement().eAdapters().add(adapter);

    toolkit.adapt(tree);

    return tree;
}

From source file:org.eclipse.sapphire.ui.form.editors.masterdetails.MasterDetailsEditorPage.java

License:Open Source License

private FilteredTree createContentOutline(final Composite parent, final MasterDetailsContentOutline outline,
        final boolean addBorders) {
    final int treeStyle = (addBorders ? SWT.BORDER : SWT.NONE) | SWT.MULTI;

    final ContentOutlineFilteredTree filteredTree = new ContentOutlineFilteredTree(parent, treeStyle, outline);
    final TreeViewer treeViewer = filteredTree.getViewer();
    final Tree tree = treeViewer.getTree();

    final ITreeContentProvider contentProvider = new ITreeContentProvider() {
        private final Listener listener = new Listener() {
            @Override// ww w .j  av a 2  s  . c om
            public void handle(final org.eclipse.sapphire.Event event) {
                if (event instanceof PartEvent) {
                    final SapphirePart part = ((PartEvent) event).part();

                    if (part instanceof MasterDetailsContentNode) {
                        final MasterDetailsContentNode node = (MasterDetailsContentNode) part;

                        if (event instanceof PartVisibilityEvent) {
                            final MasterDetailsContentNode parent = node.getParentNode();

                            if (parent == outline.getRoot()) {
                                treeViewer.refresh();
                            } else {
                                treeViewer.refresh(parent);
                            }
                        } else {
                            if (node.visible()) {
                                if (event instanceof LabelChangedEvent || event instanceof ImageChangedEvent) {
                                    Display.getCurrent().asyncExec(new TreeViewerUpdateJob(treeViewer, node));
                                } else if (event instanceof NodeListEvent) {
                                    treeViewer.refresh(node);
                                }
                            }
                        }
                    }
                }
            }
        };

        private void attach(final List<MasterDetailsContentNode> nodes) {
            for (MasterDetailsContentNode node : nodes) {
                node.attach(this.listener);
            }
        }

        private void detach(final List<MasterDetailsContentNode> nodes) {
            for (MasterDetailsContentNode node : nodes) {
                node.detach(this.listener);
                detach(node.nodes());
            }
        }

        public Object[] getElements(final Object inputElement) {
            final MasterDetailsContentNodeList nodes = outline.getRoot().nodes();
            attach(nodes);
            return nodes.visible().toArray();
        }

        public Object[] getChildren(final Object parentElement) {
            final MasterDetailsContentNodeList nodes = ((MasterDetailsContentNode) parentElement).nodes();
            attach(nodes);
            return nodes.visible().toArray();
        }

        public Object getParent(final Object element) {
            return ((MasterDetailsContentNode) element).getParentNode();
        }

        public boolean hasChildren(final Object parentElement) {
            final MasterDetailsContentNodeList nodes = ((MasterDetailsContentNode) parentElement).nodes();
            attach(nodes);
            return !nodes.visible().isEmpty();
        }

        public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
        }

        public void dispose() {
            detach(outline.getRoot().nodes());
        }
    };

    final LabelProvider labelProvider = new LabelProvider() {
        private final Map<ImageDescriptor, Image> images = new HashMap<ImageDescriptor, Image>();

        @Override
        public String getText(final Object element) {
            return ((MasterDetailsContentNode) element).getLabel();
        }

        @Override
        public Image getImage(final Object element) {
            return getImage((MasterDetailsContentNode) element);
        }

        private Image getImage(final MasterDetailsContentNode node) {
            final ImageDescriptor imageDescriptor = node.getImage();
            Image image = this.images.get(imageDescriptor);

            if (image == null) {
                image = imageDescriptor.createImage();
                this.images.put(imageDescriptor, image);
            }

            return image;
        }

        @Override
        public void dispose() {
            for (Image image : this.images.values()) {
                image.dispose();
            }
        }
    };

    new SapphireToolTip(tree) {
        protected Object getToolTipArea(final Event event) {
            return treeViewer.getCell(new Point(event.x, event.y));
        }

        protected boolean shouldCreateToolTip(Event event) {
            if (!super.shouldCreateToolTip(event)) {
                return false;
            }

            setShift(new Point(0, 20));
            tree.setToolTipText("");

            boolean res = false;

            final MasterDetailsContentNode node = getNode(event);

            if (node != null) {
                res = !node.validation().ok();
            }

            return res;
        }

        private MasterDetailsContentNode getNode(final Event event) {
            final TreeItem item = tree.getItem(new Point(event.x, event.y));

            if (item == null) {
                return null;
            } else {
                return (MasterDetailsContentNode) item.getData();
            }
        }

        protected void afterHideToolTip(Event event) {
            super.afterHideToolTip(event);
            // Clear the restored value else this could be a source of a leak
            if (event != null && event.widget != treeViewer.getControl()) {
                treeViewer.getControl().setFocus();
            }
        }

        @Override
        protected void createContent(final Event event, final Composite parent) {
            final MasterDetailsContentNode node = getNode(event);

            parent.setLayout(glayout(1));

            SapphireFormText text = new SapphireFormText(parent, SWT.NO_FOCUS);
            text.setLayoutData(gdfill());

            final org.eclipse.sapphire.modeling.Status validation = node.validation();
            final List<org.eclipse.sapphire.modeling.Status> items = gather(validation);

            final StringBuffer buffer = new StringBuffer();
            buffer.append("<form>");

            final int count = items.size();
            int i = 0;

            for (org.eclipse.sapphire.modeling.Status item : items) {
                final String imageKey = (item.severity() == org.eclipse.sapphire.modeling.Status.Severity.ERROR
                        ? "error"
                        : "warning");
                buffer.append("<li style=\"image\" value=\"" + imageKey + "\">" + escapeForXml(item.message())
                        + "</li>");

                i++;

                if (count > 10 && i == 9) {
                    break;
                }
            }

            if (count > 10) {
                final String msg = NLS.bind(Resources.problemsOverflowMessage, numberToString(count - 9));
                final String imageKey = (validation
                        .severity() == org.eclipse.sapphire.modeling.Status.Severity.ERROR ? "error"
                                : "warning");
                buffer.append("<br/><li style=\"image\" value=\"" + imageKey + "\">" + msg + "</li>");
            }

            buffer.append("</form>");

            text.setText(buffer.toString(), true, false);
            text.setImage("error", ImageData.createFromClassLoader(SwtResourceCache.class, "Error.png"));
            text.setImage("warning", ImageData.createFromClassLoader(SwtResourceCache.class, "Warning.png"));
        }

        private String numberToString(final int number) {
            switch (number) {
            case 2:
                return Resources.two;
            case 3:
                return Resources.three;
            case 4:
                return Resources.four;
            case 5:
                return Resources.five;
            case 6:
                return Resources.six;
            case 7:
                return Resources.seven;
            case 8:
                return Resources.eight;
            case 9:
                return Resources.nine;
            default:
                return String.valueOf(number);
            }
        }

        private List<org.eclipse.sapphire.modeling.Status> gather(
                final org.eclipse.sapphire.modeling.Status status) {
            final List<org.eclipse.sapphire.modeling.Status> items = new ArrayList<org.eclipse.sapphire.modeling.Status>();
            gather(status, items);
            return items;
        }

        private void gather(final org.eclipse.sapphire.modeling.Status status,
                final List<org.eclipse.sapphire.modeling.Status> items) {
            if (status.children().isEmpty()) {
                items.add(status);
            } else {
                for (org.eclipse.sapphire.modeling.Status child : status.children()) {
                    gather(child, items);
                }
            }
        }
    };

    treeViewer.setContentProvider(contentProvider);
    treeViewer.setLabelProvider(labelProvider);
    treeViewer.setInput(new Object());

    final MutableReference<Boolean> ignoreSelectionChange = new MutableReference<Boolean>(false);
    final MutableReference<Boolean> ignoreExpandedStateChange = new MutableReference<Boolean>(false);

    final Listener contentTreeListener = new Listener() {
        @Override
        public void handle(final org.eclipse.sapphire.Event event) {
            if (event instanceof MasterDetailsContentOutline.SelectionChangedEvent) {
                if (ignoreSelectionChange.get() == true) {
                    return;
                }

                final MasterDetailsContentOutline.SelectionChangedEvent evt = (MasterDetailsContentOutline.SelectionChangedEvent) event;
                final List<MasterDetailsContentNode> selection = evt.selection();

                final IStructuredSelection sel;

                if (selection.isEmpty()) {
                    sel = StructuredSelection.EMPTY;
                } else {
                    sel = new StructuredSelection(selection);
                }

                if (!treeViewer.getSelection().equals(sel)) {
                    for (MasterDetailsContentNode node : selection) {
                        treeViewer.reveal(node);
                    }

                    treeViewer.setSelection(sel);
                }
            } else if (event instanceof MasterDetailsContentOutline.NodeExpandedStateChangedEvent) {
                if (ignoreExpandedStateChange.get() == true) {
                    return;
                }

                final MasterDetailsContentOutline.NodeExpandedStateChangedEvent evt = (MasterDetailsContentOutline.NodeExpandedStateChangedEvent) event;
                final MasterDetailsContentNode node = evt.node();

                final boolean expandedState = node.isExpanded();

                if (treeViewer.getExpandedState(node) != expandedState) {
                    treeViewer.setExpandedState(node, expandedState);
                }
            } else if (event instanceof MasterDetailsContentOutline.FilterChangedEvent) {
                final MasterDetailsContentOutline.FilterChangedEvent evt = (MasterDetailsContentOutline.FilterChangedEvent) event;
                filteredTree.changeFilterText(evt.filter());
            }
        }
    };

    outline.attach(contentTreeListener);

    treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
        public void selectionChanged(final SelectionChangedEvent event) {
            ignoreSelectionChange.set(true);

            try {
                final IStructuredSelection selection = (IStructuredSelection) event.getSelection();
                final List<MasterDetailsContentNode> nodes = new ArrayList<MasterDetailsContentNode>();

                for (Iterator<?> itr = selection.iterator(); itr.hasNext();) {
                    nodes.add((MasterDetailsContentNode) itr.next());
                }

                outline.setSelectedNodes(nodes);
            } finally {
                ignoreSelectionChange.set(false);
            }
        }
    });

    treeViewer.addTreeListener(new ITreeViewerListener() {
        public void treeExpanded(final TreeExpansionEvent event) {
            ignoreExpandedStateChange.set(true);

            try {
                final MasterDetailsContentNode node = (MasterDetailsContentNode) event.getElement();
                node.setExpanded(true);
            } finally {
                ignoreExpandedStateChange.set(false);
            }
        }

        public void treeCollapsed(final TreeExpansionEvent event) {
            ignoreExpandedStateChange.set(true);

            try {
                final MasterDetailsContentNode node = (MasterDetailsContentNode) event.getElement();
                node.setExpanded(false);
            } finally {
                ignoreExpandedStateChange.set(false);
            }
        }
    });

    final ContentOutlineActionSupport actionSupport = new ContentOutlineActionSupport(outline, tree);

    treeViewer.setExpandedElements(outline.getExpandedNodes().toArray());
    contentTreeListener
            .handle(new MasterDetailsContentOutline.SelectionChangedEvent(outline.getSelectedNodes()));

    filteredTree.changeFilterText(outline.getFilterText());

    final ModelElementsTransfer transfer = new ModelElementsTransfer(
            getModelElement().type().getModelElementClass().getClassLoader());
    final Transfer[] transfers = new Transfer[] { transfer };

    final DragSource dragSource = new DragSource(tree, DND.DROP_MOVE);
    dragSource.setTransfer(transfers);

    final List<Element> dragElements = new ArrayList<Element>();

    dragSource.addDragListener(new DragSourceListener() {
        public void dragStart(final DragSourceEvent event) {
            final TreeItem[] selection = tree.getSelection();
            final String filter = outline().getFilterText();

            if ((filter == null || filter.length() == 0) && draggable(selection)) {
                event.doit = true;

                for (TreeItem item : selection) {
                    final MasterDetailsContentNode node = (MasterDetailsContentNode) item.getData();
                    dragElements.add(node.getModelElement());
                }
            } else {
                event.doit = false;
            }
        }

        protected boolean draggable(final TreeItem[] selection) {
            if (selection.length > 0) {
                for (TreeItem item : selection) {
                    final MasterDetailsContentNode node = (MasterDetailsContentNode) item.getData();

                    if (!draggable(node)) {
                        return false;
                    }
                }

                return true;
            }

            return false;
        }

        protected boolean draggable(final MasterDetailsContentNode node) {
            final Element element = node.getModelElement();

            if (element.parent().definition() instanceof ListProperty && node.controls(element)) {
                return true;
            }

            return false;
        }

        public void dragSetData(final DragSourceEvent event) {
            event.data = dragElements;
        }

        public void dragFinished(final DragSourceEvent event) {
            if (event.detail == DND.DROP_MOVE) {
                // When drop target is the same editor as drag source, the drop handler takes care of removing
                // elements from their original location. The following block of code accounts for the case when 
                // dropping into another editor.

                boolean droppedIntoAnotherEditor = false;

                for (Element dragElement : dragElements) {
                    if (!dragElement.disposed()) {
                        droppedIntoAnotherEditor = true;
                        break;
                    }
                }

                if (droppedIntoAnotherEditor) {
                    final TreeItem[] selection = tree.getSelection();
                    final List<MasterDetailsContentNode> dragNodes = new ArrayList<MasterDetailsContentNode>();

                    for (TreeItem item : selection) {
                        dragNodes.add((MasterDetailsContentNode) item.getData());
                    }

                    final MasterDetailsContentNode parentNode = dragNodes.get(0).getParentNode();

                    MasterDetailsContentNode selectionPostDelete = findSelectionPostDelete(
                            parentNode.nodes().visible(), dragNodes);

                    if (selectionPostDelete == null) {
                        selectionPostDelete = parentNode;
                    }

                    try {
                        outline.listeners().suspend(MasterDetailsContentOutline.SelectionChangedEvent.class);

                        for (Element dragElement : dragElements) {
                            final ElementList<?> dragElementContainer = (ElementList<?>) dragElement.parent();
                            dragElementContainer.remove(dragElement);
                        }
                    } catch (Exception e) {
                        // Log this exception unless the cause is EditFailedException. These exception
                        // are the result of the user declining a particular action that is necessary
                        // before the edit can happen (such as making a file writable).

                        final EditFailedException editFailedException = EditFailedException.findAsCause(e);

                        if (editFailedException == null) {
                            SapphireUiFrameworkPlugin.log(e);
                        }
                    } finally {
                        outline.listeners().resume(MasterDetailsContentOutline.SelectionChangedEvent.class);
                    }

                    parentNode.getContentTree().setSelectedNode(selectionPostDelete);
                }
            }

            dragElements.clear();
        }
    });

    final DropTarget target = new DropTarget(tree, DND.DROP_MOVE);
    target.setTransfer(transfers);

    target.addDropListener(new DropTargetAdapter() {
        public void dragOver(final DropTargetEvent event) {
            if (event.item != null) {
                final TreeItem dragOverItem = (TreeItem) event.item;
                final MasterDetailsContentNode dragOverNode = (MasterDetailsContentNode) dragOverItem.getData();
                final MasterDetailsContentNode parentNode = dragOverNode.getParentNode();
                final List<MasterDetailsContentNode> siblingNodes = parentNode.nodes().visible();

                final Point pt = dragOverItem.getDisplay().map(null, tree, event.x, event.y);
                final Rectangle bounds = dragOverItem.getBounds();

                MasterDetailsContentNode precedingNode = null;
                MasterDetailsContentNode trailingNode = null;

                if (pt.y < bounds.y + bounds.height / 2) {
                    precedingNode = findPrecedingItem(siblingNodes, dragOverNode);
                    trailingNode = dragOverNode;

                    event.feedback = DND.FEEDBACK_INSERT_BEFORE;
                } else {
                    precedingNode = dragOverNode;
                    trailingNode = findTrailingItem(siblingNodes, dragOverNode);

                    event.feedback = DND.FEEDBACK_INSERT_AFTER;
                }

                boolean ok = false;

                if (precedingNode != null) {
                    final Element precedingElement = precedingNode.getModelElement();

                    if (precedingElement.parent().definition() instanceof ListProperty
                            && precedingNode.controls(precedingElement)) {
                        ok = true;
                    }
                }

                if (!ok && trailingNode != null) {
                    final Element trailingElement = trailingNode.getModelElement();

                    if (trailingElement.parent().definition() instanceof ListProperty
                            && trailingNode.controls(trailingElement)) {
                        ok = true;
                    }
                }

                if (!ok) {
                    event.feedback = DND.FEEDBACK_NONE;
                }
            }

            event.feedback |= DND.FEEDBACK_SCROLL;
        }

        @SuppressWarnings("unchecked")

        public void drop(final DropTargetEvent event) {
            if (event.data == null || event.item == null) {
                event.detail = DND.DROP_NONE;
                return;
            }

            // Determine where something was dropped.

            final List<Element> droppedElements = (List<Element>) event.data;
            final TreeItem dropTargetItem = (TreeItem) event.item;
            final MasterDetailsContentNode dropTargetNode = (MasterDetailsContentNode) dropTargetItem.getData();
            final MasterDetailsContentNode parentNode = dropTargetNode.getParentNode();
            final List<MasterDetailsContentNode> siblingNodes = parentNode.nodes().visible();

            final Point pt = tree.getDisplay().map(null, tree, event.x, event.y);
            final Rectangle bounds = dropTargetItem.getBounds();

            MasterDetailsContentNode precedingNode = null;
            MasterDetailsContentNode trailingNode = null;

            if (pt.y < bounds.y + bounds.height / 2) {
                precedingNode = findPrecedingItem(siblingNodes, dropTargetNode);
                trailingNode = dropTargetNode;
            } else {
                precedingNode = dropTargetNode;
                trailingNode = findTrailingItem(siblingNodes, dropTargetNode);
            }

            // Determine whether the drop was valid from model standpoint and figure out
            // where in the model the dropped elements are to be inserted.

            ElementList<?> list = null;
            int position = -1;

            if (precedingNode != null) {
                final Element precedingElement = precedingNode.getModelElement();

                if (precedingElement.parent().definition() instanceof ListProperty
                        && !precedingElement.parent().definition().isReadOnly()
                        && precedingNode.controls(precedingElement)) {
                    list = (ElementList<?>) precedingElement.parent();

                    final Set<ElementType> possibleListElementTypes = list.definition()
                            .service(PossibleTypesService.class).types();

                    for (Element droppedElement : droppedElements) {
                        if (!possibleListElementTypes.contains(droppedElement.type())) {
                            list = null;
                            break;
                        }
                    }

                    if (list != null) {
                        position = list.indexOf(precedingElement) + 1;
                    }
                }
            }

            if (list == null && trailingNode != null) {
                final Element trailingElement = trailingNode.getModelElement();

                if (trailingElement.parent().definition() instanceof ListProperty
                        && !trailingElement.parent().definition().isReadOnly()
                        && trailingNode.controls(trailingElement)) {
                    list = (ElementList<?>) trailingElement.parent();

                    final Set<ElementType> possibleListElementTypes = list.definition()
                            .service(PossibleTypesService.class).types();

                    for (Element droppedElement : droppedElements) {
                        if (!possibleListElementTypes.contains(droppedElement.type())) {
                            list = null;
                            break;
                        }
                    }

                    if (list != null) {
                        position = list.indexOf(trailingElement);
                    }
                }
            }

            if (list == null) {
                for (PropertyDef dropTargetChildProperty : dropTargetNode.getChildNodeFactoryProperties()) {
                    if (dropTargetChildProperty instanceof ListProperty
                            && !dropTargetChildProperty.isReadOnly()) {
                        final ListProperty dropTargetChildListProperty = (ListProperty) dropTargetChildProperty;

                        boolean compatible = true;

                        final Set<ElementType> possibleListElementTypes = dropTargetChildListProperty
                                .service(PossibleTypesService.class).types();

                        for (Element droppedElement : droppedElements) {
                            if (!possibleListElementTypes.contains(droppedElement.type())) {
                                compatible = false;
                                break;
                            }
                        }

                        if (compatible) {
                            list = dropTargetNode.getLocalModelElement().property(dropTargetChildListProperty);
                            position = list.size();
                        }
                    }
                }
            }

            if (list == null) {
                event.detail = DND.DROP_NONE;
                return;
            }

            // Perform the removal and insertion into the new location.

            try {
                outline.listeners().suspend(MasterDetailsContentOutline.SelectionChangedEvent.class);

                for (Element dragElement : dragElements) {
                    final ElementList<?> dragElementContainer = (ElementList<?>) dragElement.parent();

                    if (dragElementContainer == list && dragElementContainer.indexOf(dragElement) < position) {
                        position--;
                    }

                    dragElementContainer.remove(dragElement);
                }

                final List<MasterDetailsContentNode> newSelection = new ArrayList<MasterDetailsContentNode>();

                for (Element droppedElement : droppedElements) {
                    final Element insertedElement = list.insert(droppedElement.type(), position);
                    insertedElement.copy(droppedElement);

                    newSelection.add(parentNode.findNode(insertedElement));

                    position++;
                }

                parentNode.getContentTree().setSelectedNodes(newSelection);
            } catch (Exception e) {
                // Log this exception unless the cause is EditFailedException. These exception
                // are the result of the user declining a particular action that is necessary
                // before the edit can happen (such as making a file writable).

                final EditFailedException editFailedException = EditFailedException.findAsCause(e);

                if (editFailedException == null) {
                    SapphireUiFrameworkPlugin.log(e);
                }

                event.detail = DND.DROP_NONE;
            } finally {
                outline.listeners().resume(MasterDetailsContentOutline.SelectionChangedEvent.class);
            }
        }
    });

    tree.addDisposeListener(new DisposeListener() {
        public void widgetDisposed(final DisposeEvent event) {
            outline.detach(contentTreeListener);
            actionSupport.dispose();
        }
    });

    return filteredTree;
}

From source file:org.eclipse.sapphire.ui.forms.swt.MasterDetailsEditorPage.java

License:Open Source License

private FilteredTree createContentOutline(final Composite parent, final MasterDetailsContentOutline outline,
        final boolean addBorders) {
    final int treeStyle = (addBorders ? SWT.BORDER : SWT.NONE) | SWT.MULTI;

    final ContentOutlineFilteredTree filteredTree = new ContentOutlineFilteredTree(parent, treeStyle, outline);
    final TreeViewer treeViewer = filteredTree.getViewer();
    final Tree tree = treeViewer.getTree();

    final ITreeContentProvider contentProvider = new ITreeContentProvider() {
        private final Listener listener = new Listener() {
            @Override//  w  w w .jav a  2s .com
            public void handle(final org.eclipse.sapphire.Event event) {
                if (event instanceof PartEvent) {
                    final SapphirePart part = ((PartEvent) event).part();

                    if (part instanceof MasterDetailsContentNodePart) {
                        final MasterDetailsContentNodePart node = (MasterDetailsContentNodePart) part;

                        if (event instanceof PartVisibilityEvent) {
                            final MasterDetailsContentNodePart parent = node.getParentNode();

                            if (parent == outline.getRoot()) {
                                treeViewer.refresh();
                            } else {
                                treeViewer.refresh(parent);
                            }
                        } else {
                            if (node.visible()) {
                                if (event instanceof LabelChangedEvent || event instanceof ImageChangedEvent
                                        || event instanceof DecorationEvent) {
                                    Display.getCurrent().asyncExec(new TreeViewerUpdateJob(treeViewer, node));
                                } else if (event instanceof NodeListEvent) {
                                    treeViewer.refresh(node);
                                }
                            }
                        }
                    }
                }
            }
        };

        private void attach(final List<MasterDetailsContentNodePart> nodes) {
            for (MasterDetailsContentNodePart node : nodes) {
                node.attach(this.listener);
            }
        }

        private void detach(final List<MasterDetailsContentNodePart> nodes) {
            for (MasterDetailsContentNodePart node : nodes) {
                node.detach(this.listener);
                detach(node.nodes());
            }
        }

        public Object[] getElements(final Object inputElement) {
            final MasterDetailsContentNodeList nodes = outline.getRoot().nodes();
            attach(nodes);
            return nodes.visible().toArray();
        }

        public Object[] getChildren(final Object parentElement) {
            final MasterDetailsContentNodeList nodes = ((MasterDetailsContentNodePart) parentElement).nodes();
            attach(nodes);
            return nodes.visible().toArray();
        }

        public Object getParent(final Object element) {
            return ((MasterDetailsContentNodePart) element).getParentNode();
        }

        public boolean hasChildren(final Object parentElement) {
            final MasterDetailsContentNodeList nodes = ((MasterDetailsContentNodePart) parentElement).nodes();
            attach(nodes);
            return !nodes.visible().isEmpty();
        }

        public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
        }

        public void dispose() {
            detach(outline.getRoot().nodes());
        }
    };

    final StyledCellLabelProvider labelProvider = new StyledCellLabelProvider() {
        private final Map<ImageDescriptor, Image> images = new HashMap<ImageDescriptor, Image>();
        private final Map<org.eclipse.sapphire.Color, Color> colors = new HashMap<org.eclipse.sapphire.Color, Color>();

        public void update(final ViewerCell cell) {
            final MasterDetailsContentNodePart node = (MasterDetailsContentNodePart) cell.getElement();

            final StyledString styledString = new StyledString(node.getLabel());

            for (final TextDecoration decoration : node.decorations()) {
                String text = decoration.text();

                if (text != null) {
                    text = text.trim();

                    if (text.length() > 0) {
                        final Color color = color(decoration.color());

                        styledString.append(" " + text, new Styler() {
                            @Override
                            public void applyStyles(final TextStyle style) {
                                style.foreground = color;
                            }
                        });
                    }
                }
            }

            cell.setText(styledString.toString());
            cell.setStyleRanges(styledString.getStyleRanges());
            cell.setImage(image(node.getImage()));

            super.update(cell);
        }

        private Color color(final org.eclipse.sapphire.Color c) {
            Color color = this.colors.get(c);

            if (color == null) {
                color = new Color(tree.getDisplay(), c.red(), c.green(), c.blue());
                this.colors.put(c, color);
            }

            return color;
        }

        private Image image(final ImageDescriptor imageDescriptor) {
            Image image = this.images.get(imageDescriptor);

            if (image == null) {
                image = imageDescriptor.createImage();
                this.images.put(imageDescriptor, image);
            }

            return image;
        }

        @Override
        public void dispose() {
            for (final Image image : this.images.values()) {
                image.dispose();
            }
        }
    };

    new SapphireToolTip(tree) {
        protected Object getToolTipArea(final Event event) {
            return treeViewer.getCell(new Point(event.x, event.y));
        }

        protected boolean shouldCreateToolTip(Event event) {
            if (!super.shouldCreateToolTip(event)) {
                return false;
            }

            setShift(new Point(0, 20));
            tree.setToolTipText("");

            boolean res = false;

            final MasterDetailsContentNodePart node = getNode(event);

            if (node != null) {
                res = !node.validation().ok();
            }

            return res;
        }

        private MasterDetailsContentNodePart getNode(final Event event) {
            final TreeItem item = tree.getItem(new Point(event.x, event.y));

            if (item == null) {
                return null;
            } else {
                return (MasterDetailsContentNodePart) item.getData();
            }
        }

        protected void afterHideToolTip(Event event) {
            super.afterHideToolTip(event);
            // Clear the restored value else this could be a source of a leak
            if (event != null && event.widget != treeViewer.getControl()) {
                treeViewer.getControl().setFocus();
            }
        }

        @Override
        protected void createContent(final Event event, final Composite parent) {
            final MasterDetailsContentNodePart node = getNode(event);

            parent.setLayout(glayout(1));

            SapphireFormText text = new SapphireFormText(parent, SWT.NO_FOCUS);
            text.setLayoutData(gdfill());

            final org.eclipse.sapphire.modeling.Status validation = node.validation();
            final List<org.eclipse.sapphire.modeling.Status> items = gather(validation);

            final StringBuffer buffer = new StringBuffer();
            buffer.append("<form>");

            final int count = items.size();
            int i = 0;

            for (org.eclipse.sapphire.modeling.Status item : items) {
                final String imageKey = (item.severity() == org.eclipse.sapphire.modeling.Status.Severity.ERROR
                        ? "error"
                        : "warning");
                buffer.append("<li style=\"image\" value=\"" + imageKey + "\">" + escapeForXml(item.message())
                        + "</li>");

                i++;

                if (count > 10 && i == 9) {
                    break;
                }
            }

            if (count > 10) {
                final String msg = problemsOverflowMessage.format(numberToString(count - 9));
                final String imageKey = (validation
                        .severity() == org.eclipse.sapphire.modeling.Status.Severity.ERROR ? "error"
                                : "warning");
                buffer.append("<br/><li style=\"image\" value=\"" + imageKey + "\">" + msg + "</li>");
            }

            buffer.append("</form>");

            text.setText(buffer.toString(), true, false);
            text.setImage("error",
                    ImageData.readFromClassLoader(SwtResourceCache.class, "Error.png").required());
            text.setImage("warning",
                    ImageData.readFromClassLoader(SwtResourceCache.class, "Warning.png").required());
        }

        private String numberToString(final int number) {
            switch (number) {
            case 2:
                return two.text();
            case 3:
                return three.text();
            case 4:
                return four.text();
            case 5:
                return five.text();
            case 6:
                return six.text();
            case 7:
                return seven.text();
            case 8:
                return eight.text();
            case 9:
                return nine.text();
            default:
                return String.valueOf(number);
            }
        }

        private List<org.eclipse.sapphire.modeling.Status> gather(
                final org.eclipse.sapphire.modeling.Status status) {
            final List<org.eclipse.sapphire.modeling.Status> items = new ArrayList<org.eclipse.sapphire.modeling.Status>();
            gather(status, items);
            return items;
        }

        private void gather(final org.eclipse.sapphire.modeling.Status status,
                final List<org.eclipse.sapphire.modeling.Status> items) {
            if (status.children().isEmpty()) {
                items.add(status);
            } else {
                for (org.eclipse.sapphire.modeling.Status child : status.children()) {
                    gather(child, items);
                }
            }
        }
    };

    treeViewer.setContentProvider(contentProvider);
    treeViewer.setLabelProvider(labelProvider);
    treeViewer.setInput(new Object());

    final MutableReference<Boolean> ignoreSelectionChange = new MutableReference<Boolean>(false);
    final MutableReference<Boolean> ignoreExpandedStateChange = new MutableReference<Boolean>(false);

    final Listener contentTreeListener = new Listener() {
        @Override
        public void handle(final org.eclipse.sapphire.Event event) {
            if (event instanceof MasterDetailsContentOutline.SelectionChangedEvent) {
                if (ignoreSelectionChange.get() == true) {
                    return;
                }

                final MasterDetailsContentOutline.SelectionChangedEvent evt = (MasterDetailsContentOutline.SelectionChangedEvent) event;
                final List<MasterDetailsContentNodePart> selection = evt.selection();

                final IStructuredSelection sel;

                if (selection.isEmpty()) {
                    sel = StructuredSelection.EMPTY;
                } else {
                    sel = new StructuredSelection(selection);
                }

                if (!treeViewer.getSelection().equals(sel)) {
                    for (MasterDetailsContentNodePart node : selection) {
                        treeViewer.reveal(node);
                    }

                    treeViewer.setSelection(sel);
                }
            } else if (event instanceof MasterDetailsContentOutline.NodeExpandedStateChangedEvent) {
                if (ignoreExpandedStateChange.get() == true) {
                    return;
                }

                final MasterDetailsContentOutline.NodeExpandedStateChangedEvent evt = (MasterDetailsContentOutline.NodeExpandedStateChangedEvent) event;
                final MasterDetailsContentNodePart node = evt.node();

                final boolean expandedState = node.isExpanded();

                if (treeViewer.getExpandedState(node) != expandedState) {
                    treeViewer.setExpandedState(node, expandedState);
                }
            } else if (event instanceof MasterDetailsContentOutline.FilterChangedEvent) {
                final MasterDetailsContentOutline.FilterChangedEvent evt = (MasterDetailsContentOutline.FilterChangedEvent) event;
                filteredTree.changeFilterText(evt.filter());
            }
        }
    };

    outline.attach(contentTreeListener);

    treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
        public void selectionChanged(final SelectionChangedEvent event) {
            ignoreSelectionChange.set(true);

            try {
                final IStructuredSelection selection = (IStructuredSelection) event.getSelection();
                final List<MasterDetailsContentNodePart> nodes = new ArrayList<MasterDetailsContentNodePart>();

                for (Iterator<?> itr = selection.iterator(); itr.hasNext();) {
                    nodes.add((MasterDetailsContentNodePart) itr.next());
                }

                outline.setSelectedNodes(nodes);
            } finally {
                ignoreSelectionChange.set(false);
            }
        }
    });

    treeViewer.addDoubleClickListener(new IDoubleClickListener() {
        public void doubleClick(DoubleClickEvent event) {
            IStructuredSelection thisSelection = (IStructuredSelection) event.getSelection();
            if (thisSelection.size() == 1) {
                MasterDetailsContentNodePart selectedNode = (MasterDetailsContentNodePart) thisSelection
                        .getFirstElement();
                selectedNode.setExpanded(!selectedNode.isExpanded());
            }
        }
    });

    treeViewer.addTreeListener(new ITreeViewerListener() {
        public void treeExpanded(final TreeExpansionEvent event) {
            ignoreExpandedStateChange.set(true);

            try {
                final MasterDetailsContentNodePart node = (MasterDetailsContentNodePart) event.getElement();
                node.setExpanded(true);
            } finally {
                ignoreExpandedStateChange.set(false);
            }
        }

        public void treeCollapsed(final TreeExpansionEvent event) {
            ignoreExpandedStateChange.set(true);

            try {
                final MasterDetailsContentNodePart node = (MasterDetailsContentNodePart) event.getElement();
                node.setExpanded(false);
            } finally {
                ignoreExpandedStateChange.set(false);
            }
        }
    });

    final ContentOutlineActionSupport actionSupport = new ContentOutlineActionSupport(outline, tree);

    treeViewer.setExpandedElements(outline.getExpandedNodes().toArray());
    contentTreeListener
            .handle(new MasterDetailsContentOutline.SelectionChangedEvent(outline.getSelectedNodes()));

    filteredTree.changeFilterText(outline.getFilterText());

    final ElementsTransfer transfer = new ElementsTransfer(
            getModelElement().type().getModelElementClass().getClassLoader());
    final Transfer[] transfers = new Transfer[] { transfer };

    final DragSource dragSource = new DragSource(tree, DND.DROP_COPY | DND.DROP_MOVE);
    dragSource.setTransfer(transfers);

    final List<Element> dragElements = new ArrayList<Element>();

    dragSource.addDragListener(new DragSourceListener() {
        public void dragStart(final DragSourceEvent event) {
            final TreeItem[] selection = tree.getSelection();
            final String filter = outline().getFilterText();

            if ((filter == null || filter.length() == 0) && draggable(selection)) {
                event.doit = true;

                for (TreeItem item : selection) {
                    final MasterDetailsContentNodePart node = (MasterDetailsContentNodePart) item.getData();
                    dragElements.add(node.getModelElement());
                }
            } else {
                event.doit = false;
            }
        }

        protected boolean draggable(final TreeItem[] selection) {
            if (selection.length > 0) {
                for (TreeItem item : selection) {
                    final MasterDetailsContentNodePart node = (MasterDetailsContentNodePart) item.getData();

                    if (!draggable(node)) {
                        return false;
                    }
                }

                return true;
            }

            return false;
        }

        protected boolean draggable(final MasterDetailsContentNodePart node) {
            final Element element = node.getModelElement();

            if (element.parent() instanceof ElementList && node.controls(element)) {
                return true;
            }

            return false;
        }

        public void dragSetData(final DragSourceEvent event) {
            event.data = dragElements;
        }

        public void dragFinished(final DragSourceEvent event) {
            if (event.detail == DND.DROP_MOVE) {
                // When drop target is the same editor as drag source, the drop handler takes care of removing
                // elements from their original location. The following block of code accounts for the case when 
                // dropping into another editor.

                boolean droppedIntoAnotherEditor = false;

                for (Element dragElement : dragElements) {
                    if (!dragElement.disposed()) {
                        droppedIntoAnotherEditor = true;
                        break;
                    }
                }

                if (droppedIntoAnotherEditor) {
                    final TreeItem[] selection = tree.getSelection();
                    final List<MasterDetailsContentNodePart> dragNodes = new ArrayList<MasterDetailsContentNodePart>();

                    for (TreeItem item : selection) {
                        dragNodes.add((MasterDetailsContentNodePart) item.getData());
                    }

                    final MasterDetailsContentNodePart parentNode = dragNodes.get(0).getParentNode();

                    MasterDetailsContentNodePart selectionPostDelete = findSelectionPostDelete(
                            parentNode.nodes().visible(), dragNodes);

                    if (selectionPostDelete == null) {
                        selectionPostDelete = parentNode;
                    }

                    final Disposable suspension = outline.listeners().queue()
                            .suspend(SelectionChangedEventFilter.INSTANCE);

                    try {
                        for (Element dragElement : dragElements) {
                            final ElementList<?> dragElementContainer = (ElementList<?>) dragElement.parent();
                            dragElementContainer.remove(dragElement);
                        }
                    } catch (Exception e) {
                        // Log this exception unless the cause is EditFailedException. These exception
                        // are the result of the user declining a particular action that is necessary
                        // before the edit can happen (such as making a file writable).

                        final EditFailedException editFailedException = EditFailedException.findAsCause(e);

                        if (editFailedException == null) {
                            Sapphire.service(LoggingService.class).log(e);
                        }
                    } finally {
                        suspension.dispose();
                        outline.listeners().queue().process();
                    }

                    parentNode.getContentTree().setSelectedNode(selectionPostDelete);
                }
            }

            dragElements.clear();
        }
    });

    final DropTarget target = new DropTarget(tree, DND.DROP_COPY | DND.DROP_MOVE);
    target.setTransfer(transfers);

    target.addDropListener(new DropTargetAdapter() {
        public void dragOver(final DropTargetEvent event) {
            if (event.item != null) {
                final TreeItem dragOverItem = (TreeItem) event.item;
                final MasterDetailsContentNodePart dragOverNode = (MasterDetailsContentNodePart) dragOverItem
                        .getData();
                final MasterDetailsContentNodePart parentNode = dragOverNode.getParentNode();
                final List<MasterDetailsContentNodePart> siblingNodes = parentNode.nodes().visible();

                final Point pt = dragOverItem.getDisplay().map(null, tree, event.x, event.y);
                final Rectangle bounds = dragOverItem.getBounds();

                boolean dragOverNodeAcceptedDrop = false;

                if (pt.y > bounds.y + bounds.height / 3
                        && pt.y < bounds.y + bounds.height - bounds.height / 3) {
                    for (final PropertyDef dragOverTargetChildProperty : dragOverNode
                            .getChildNodeFactoryProperties()) {
                        if (dragOverTargetChildProperty instanceof ListProperty
                                && !dragOverTargetChildProperty.isReadOnly()) {
                            dragOverNodeAcceptedDrop = true;
                            event.feedback = DND.FEEDBACK_SELECT;

                            break;
                        }
                    }
                }

                if (!dragOverNodeAcceptedDrop) {
                    MasterDetailsContentNodePart precedingNode = null;
                    MasterDetailsContentNodePart trailingNode = null;

                    if (pt.y < bounds.y + bounds.height / 2) {
                        precedingNode = findPrecedingItem(siblingNodes, dragOverNode);
                        trailingNode = dragOverNode;

                        event.feedback = DND.FEEDBACK_INSERT_BEFORE;
                    } else {
                        precedingNode = dragOverNode;
                        trailingNode = findTrailingItem(siblingNodes, dragOverNode);

                        event.feedback = DND.FEEDBACK_INSERT_AFTER;
                    }

                    boolean ok = false;

                    if (precedingNode != null) {
                        final Element precedingElement = precedingNode.getModelElement();

                        if (precedingElement.parent() instanceof ElementList
                                && precedingNode.controls(precedingElement)) {
                            ok = true;
                        }
                    }

                    if (!ok && trailingNode != null) {
                        final Element trailingElement = trailingNode.getModelElement();

                        if (trailingElement.parent() instanceof ElementList
                                && trailingNode.controls(trailingElement)) {
                            ok = true;
                        }
                    }

                    if (!ok) {
                        event.feedback = DND.FEEDBACK_NONE;
                    }
                }
            }

            event.feedback |= DND.FEEDBACK_SCROLL;
        }

        @SuppressWarnings("unchecked")

        public void drop(final DropTargetEvent event) {
            if (event.data == null || event.item == null) {
                event.detail = DND.DROP_NONE;
                return;
            }

            // Determine where something was dropped.

            final List<ElementData> droppedElements = (List<ElementData>) event.data;
            final TreeItem dropTargetItem = (TreeItem) event.item;
            final MasterDetailsContentNodePart dropTargetNode = (MasterDetailsContentNodePart) dropTargetItem
                    .getData();
            final MasterDetailsContentNodePart parentNode = dropTargetNode.getParentNode();
            final List<MasterDetailsContentNodePart> siblingNodes = parentNode.nodes().visible();

            final Point pt = tree.getDisplay().map(null, tree, event.x, event.y);
            final Rectangle bounds = dropTargetItem.getBounds();

            MasterDetailsContentNodePart precedingNode = null;
            MasterDetailsContentNodePart trailingNode = null;

            boolean dropTargetNodeAcceptedDrop = false;

            if (pt.y > bounds.y + bounds.height / 3 && pt.y < bounds.y + bounds.height - bounds.height / 3) {
                for (final PropertyDef dropTargetChildProperty : dropTargetNode
                        .getChildNodeFactoryProperties()) {
                    if (dropTargetChildProperty instanceof ListProperty
                            && !dropTargetChildProperty.isReadOnly()) {
                        dropTargetNodeAcceptedDrop = true;
                        break;
                    }
                }
            }

            if (!dropTargetNodeAcceptedDrop) {
                if (pt.y < bounds.y + bounds.height / 2) {
                    precedingNode = findPrecedingItem(siblingNodes, dropTargetNode);
                    trailingNode = dropTargetNode;
                } else {
                    precedingNode = dropTargetNode;
                    trailingNode = findTrailingItem(siblingNodes, dropTargetNode);
                }
            }

            // Determine whether the drop was valid from model standpoint and figure out
            // where in the model the dropped elements are to be inserted.

            ElementList<?> list = null;
            int position = -1;

            if (precedingNode != null) {
                final Element precedingElement = precedingNode.getModelElement();

                if (precedingElement.parent() instanceof ElementList
                        && !precedingElement.parent().definition().isReadOnly()
                        && precedingNode.controls(precedingElement)) {
                    list = (ElementList<?>) precedingElement.parent();

                    final Set<ElementType> possibleListElementTypes = list.definition()
                            .service(PossibleTypesService.class).types();

                    for (final ElementData droppedElement : droppedElements) {
                        if (!possibleListElementTypes.contains(droppedElement.type())) {
                            list = null;
                            break;
                        }
                    }

                    if (list != null) {
                        position = list.indexOf(precedingElement) + 1;
                    }
                }
            }

            if (list == null && trailingNode != null) {
                final Element trailingElement = trailingNode.getModelElement();

                if (trailingElement.parent() instanceof ElementList
                        && !trailingElement.parent().definition().isReadOnly()
                        && trailingNode.controls(trailingElement)) {
                    list = (ElementList<?>) trailingElement.parent();

                    final Set<ElementType> possibleListElementTypes = list.definition()
                            .service(PossibleTypesService.class).types();

                    for (final ElementData droppedElement : droppedElements) {
                        if (!possibleListElementTypes.contains(droppedElement.type())) {
                            list = null;
                            break;
                        }
                    }

                    if (list != null) {
                        position = list.indexOf(trailingElement);
                    }
                }
            }

            if (list == null) {
                for (PropertyDef dropTargetChildProperty : dropTargetNode.getChildNodeFactoryProperties()) {
                    if (dropTargetChildProperty instanceof ListProperty
                            && !dropTargetChildProperty.isReadOnly()) {
                        final ListProperty dropTargetChildListProperty = (ListProperty) dropTargetChildProperty;

                        boolean compatible = true;

                        final Set<ElementType> possibleListElementTypes = dropTargetChildListProperty
                                .service(PossibleTypesService.class).types();

                        for (final ElementData droppedElement : droppedElements) {
                            if (!possibleListElementTypes.contains(droppedElement.type())) {
                                compatible = false;
                                break;
                            }
                        }

                        if (compatible) {
                            list = dropTargetNode.getLocalModelElement().property(dropTargetChildListProperty);
                            position = list.size();
                        }
                    }
                }
            }

            if (list == null) {
                event.detail = DND.DROP_NONE;
                return;
            }

            // Prevent a drop within a drag element.

            for (Property p = list; p != null; p = p.element().parent()) {
                for (final Element dragElement : dragElements) {
                    if (p.element() == dragElement) {
                        event.detail = DND.DROP_NONE;
                        return;
                    }
                }
            }

            // Perform the removal and insertion into the new location.

            final Disposable suspension = outline.listeners().queue()
                    .suspend(SelectionChangedEventFilter.INSTANCE);

            try {
                if (event.detail == DND.DROP_MOVE) {
                    for (Element dragElement : dragElements) {
                        final ElementList<?> dragElementContainer = (ElementList<?>) dragElement.parent();

                        if (dragElementContainer == list
                                && dragElementContainer.indexOf(dragElement) < position) {
                            position--;
                        }

                        dragElementContainer.remove(dragElement);
                    }
                }

                final List<MasterDetailsContentNodePart> newSelection = new ArrayList<MasterDetailsContentNodePart>();

                for (final ElementData droppedElement : droppedElements) {
                    final Element insertedElement = list.insert(droppedElement.type(), position);
                    insertedElement.copy(droppedElement);

                    newSelection.add(parentNode.findNode(insertedElement));

                    position++;
                }

                parentNode.getContentTree().setSelectedNodes(newSelection);
            } catch (Exception e) {
                // Log this exception unless the cause is EditFailedException. These exception
                // are the result of the user declining a particular action that is necessary
                // before the edit can happen (such as making a file writable).

                final EditFailedException editFailedException = EditFailedException.findAsCause(e);

                if (editFailedException == null) {
                    Sapphire.service(LoggingService.class).log(e);
                }

                event.detail = DND.DROP_NONE;
            } finally {
                suspension.dispose();
                outline.listeners().queue().process();
            }
        }
    });

    tree.addDisposeListener(new DisposeListener() {
        public void widgetDisposed(final DisposeEvent event) {
            outline.detach(contentTreeListener);
            actionSupport.dispose();
        }
    });

    return filteredTree;
}

From source file:org.eclipse.tcf.te.ui.views.editor.pages.AbstractTreeViewerExplorerEditorPage.java

License:Open Source License

@Override
public void doubleClick(final DoubleClickEvent event) {
    // If an handled and enabled command is registered for the ICommonActionConstants.OPEN
    // retargetable action id, redirect the double click handling to the command handler.
    ///*from  w w  w  . jav a 2 s.  co m*/
    // Note: The default tree node expansion must be re-implemented in the active handler!
    String commandId = getDoubleClickCommandId();
    Command cmd = null;
    if (commandId != null) {
        ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
        cmd = service != null ? service.getCommand(commandId) : null;
    }
    if (cmd != null && cmd.isDefined() && cmd.isEnabled()) {
        final Command command = cmd;
        SafeRunner.run(new SafeRunnable() {
            @Override
            public void handleException(Throwable e) {
                // Ignore exception
            }

            @Override
            public void run() throws Exception {
                IHandlerService handlerSvc = (IHandlerService) PlatformUI.getWorkbench()
                        .getService(IHandlerService.class);
                Assert.isNotNull(handlerSvc);

                ISelection selection = event.getSelection();
                EvaluationContext ctx = new EvaluationContext(handlerSvc.getCurrentState(), selection);
                ctx.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME, selection);
                ctx.addVariable(ISources.ACTIVE_MENU_SELECTION_NAME, selection);
                ctx.setAllowPluginActivation(true);

                ParameterizedCommand pCmd = ParameterizedCommand.generateCommand(command, null);
                Assert.isNotNull(pCmd);

                handlerSvc.executeCommandInContext(pCmd, null, ctx);
            }
        });
    } else {
        IStructuredSelection selection = (IStructuredSelection) event.getSelection();
        Object element = selection.getFirstElement();
        TreeViewer viewer = (TreeViewer) treeControl.getViewer();
        if (viewer.isExpandable(element)) {
            viewer.setExpandedState(element, !viewer.getExpandedState(element));
        }
    }
}

From source file:org.eclipse.tcf.te.ui.views.handler.OpenEditorHandler.java

License:Open Source License

@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
    // The selection is the Target Explorer tree selection
    ISelection selection = HandlerUtil.getCurrentSelection(event);
    // The active part is the Target Explorer view instance
    IWorkbenchPart part = HandlerUtil.getActivePart(event);
    // Get the currently active workbench window
    // In Eclipse 4.x, the HandlerUtil.getActiveWorkbenchWindow(event) may return null
    IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
    if (window == null)
        window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
    // ALT - Key pressed?
    Object ctrlPressed = HandlerUtil.getVariable(event, "ctrlPressed"); //$NON-NLS-1$

    boolean expand = ctrlPressed instanceof Boolean ? ((Boolean) ctrlPressed).booleanValue() : false;

    if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
        // If the tree node is expandable, expand or collapse it
        TreeViewer viewer = ((CommonNavigator) part).getCommonViewer();
        Object element = ((IStructuredSelection) selection).getFirstElement();
        if (selection instanceof TreeSelection) {
            TreePath[] path = ((TreeSelection) selection).getPaths();
            if (path != null && path.length > 0) {
                element = path[0].getLastSegment();
            }//from  w ww.ja  va  2 s .c o  m
        }
        if (viewer.isExpandable(element) && expand) {
            viewer.setExpandedState(element, !viewer.getExpandedState(element));
        } else {
            openEditorOnSelection(window, selection);
        }
    }

    return null;
}