aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiTreeBlock.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiTreeBlock.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiTreeBlock.java946
1 files changed, 0 insertions, 946 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiTreeBlock.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiTreeBlock.java
deleted file mode 100644
index d11b8a4c6..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiTreeBlock.java
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
-import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper.ManifestSectionPart;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.TargetChangeListener;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IMenuListener;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.ITreeSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.jface.viewers.TreeSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerComparator;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.ToolBar;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.ui.forms.DetailsPart;
-import org.eclipse.ui.forms.IDetailsPage;
-import org.eclipse.ui.forms.IDetailsPageProvider;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.MasterDetailsBlock;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Section;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-
-/**
- * {@link UiTreeBlock} is a {@link MasterDetailsBlock} which displays a tree view for
- * a specific set of {@link UiElementNode}.
- * <p/>
- * For a given UI element node, the tree view displays all first-level children that
- * match a given type (given by an {@link ElementDescriptor}. All children from these
- * nodes are also displayed.
- * <p/>
- * In the middle next to the tree are some controls to add or delete tree nodes.
- * On the left is a details part that displays all the visible UI attributes for a given
- * selected UI element node.
- */
-public final class UiTreeBlock extends MasterDetailsBlock implements ICommitXml {
-
- /** Height hint for the tree view. Helps the grid layout resize properly on smaller screens. */
- private static final int TREE_HEIGHT_HINT = 50;
-
- /** Container editor */
- AndroidXmlEditor mEditor;
- /** The root {@link UiElementNode} which contains all the elements that are to be
- * manipulated by this tree view. In general this is the manifest UI node. */
- private UiElementNode mUiRootNode;
- /** The descriptor of the elements to be displayed as root in this tree view. All elements
- * of the same type in the root will be displayed. Can be null or empty to mean everything
- * can be displayed. */
- private ElementDescriptor[] mDescriptorFilters;
- /** The title for the master-detail part (displayed on the top "tab" on top of the tree) */
- private String mTitle;
- /** The description for the master-detail part (displayed on top of the tree view) */
- private String mDescription;
- /** The master-detail part, composed of a main tree and an auxiliary detail part */
- private ManifestSectionPart mMasterPart;
- /** The tree viewer in the master-detail part */
- private TreeViewer mTreeViewer;
- /** The "add" button for the tree view */
- private Button mAddButton;
- /** The "remove" button for the tree view */
- private Button mRemoveButton;
- /** The "up" button for the tree view */
- private Button mUpButton;
- /** The "down" button for the tree view */
- private Button mDownButton;
- /** The Managed Form used to create the master part */
- private IManagedForm mManagedForm;
- /** Reference to the details part of the tree master block. */
- private DetailsPart mDetailsPart;
- /** Reference to the clipboard for copy-paste */
- private Clipboard mClipboard;
- /** Listener to refresh the tree viewer when the parent's node has been updated */
- private IUiUpdateListener mUiRefreshListener;
- /** Listener to enable/disable the UI based on the application node's presence */
- private IUiUpdateListener mUiEnableListener;
- /** An adapter/wrapper to use the add/remove/up/down tree edit actions. */
- private UiTreeActions mUiTreeActions;
- /**
- * True if the root node can be created on-demand (i.e. as needed as
- * soon as children exist). False if an external entity controls the existence of the
- * root node. In practise, this is false for the manifest application page (the actual
- * "application" node is managed by the ApplicationToggle part) whereas it is true
- * for all other tree pages.
- */
- private final boolean mAutoCreateRoot;
-
-
- /**
- * Creates a new {@link MasterDetailsBlock} that will display all UI nodes matching the
- * given filter in the given root node.
- *
- * @param editor The parent manifest editor.
- * @param uiRootNode The root {@link UiElementNode} which contains all the elements that are
- * to be manipulated by this tree view. In general this is the manifest UI node or the
- * application UI node. This cannot be null.
- * @param autoCreateRoot True if the root node can be created on-demand (i.e. as needed as
- * soon as children exist). False if an external entity controls the existence of the
- * root node. In practise, this is false for the manifest application page (the actual
- * "application" node is managed by the ApplicationToggle part) whereas it is true
- * for all other tree pages.
- * @param descriptorFilters A list of descriptors of the elements to be displayed as root in
- * this tree view. Use null or an empty list to accept any kind of node.
- * @param title Title for the section
- * @param description Description for the section
- */
- public UiTreeBlock(AndroidXmlEditor editor,
- UiElementNode uiRootNode,
- boolean autoCreateRoot,
- ElementDescriptor[] descriptorFilters,
- String title,
- String description) {
- mEditor = editor;
- mUiRootNode = uiRootNode;
- mAutoCreateRoot = autoCreateRoot;
- mDescriptorFilters = descriptorFilters;
- mTitle = title;
- mDescription = description;
- }
-
- /** @returns The container editor */
- AndroidXmlEditor getEditor() {
- return mEditor;
- }
-
- /** @returns The reference to the clipboard for copy-paste */
- Clipboard getClipboard() {
- return mClipboard;
- }
-
- /** @returns The master-detail part, composed of a main tree and an auxiliary detail part */
- ManifestSectionPart getMasterPart() {
- return mMasterPart;
- }
-
- /**
- * Returns the {@link UiElementNode} for the current model.
- * <p/>
- * This is used by the content provider attached to {@link #mTreeViewer} since
- * the uiRootNode changes after each call to
- * {@link #changeRootAndDescriptors(UiElementNode, ElementDescriptor[], boolean)}.
- */
- public UiElementNode getRootNode() {
- return mUiRootNode;
- }
-
- @Override
- protected void createMasterPart(final IManagedForm managedForm, Composite parent) {
- FormToolkit toolkit = managedForm.getToolkit();
-
- mManagedForm = managedForm;
- mMasterPart = new ManifestSectionPart(parent, toolkit);
- Section section = mMasterPart.getSection();
- section.setText(mTitle);
- section.setDescription(mDescription);
- section.setLayout(new GridLayout());
- section.setLayoutData(new GridData(GridData.FILL_BOTH));
-
- Composite grid = SectionHelper.createGridLayout(section, toolkit, 2);
-
- Tree tree = createTreeViewer(toolkit, grid, managedForm);
- createButtons(toolkit, grid);
- createTreeContextMenu(tree);
- createSectionActions(section, toolkit);
- }
-
- private void createSectionActions(Section section, FormToolkit toolkit) {
- ToolBarManager manager = new ToolBarManager(SWT.FLAT);
- manager.removeAll();
-
- ToolBar toolbar = manager.createControl(section);
- section.setTextClient(toolbar);
-
- ElementDescriptor[] descs = mDescriptorFilters;
- if (descs == null && mUiRootNode != null) {
- descs = mUiRootNode.getDescriptor().getChildren();
- }
-
- if (descs != null && descs.length > 1) {
- for (ElementDescriptor desc : descs) {
- manager.add(new DescriptorFilterAction(desc));
- }
- }
-
- manager.add(new TreeSortAction());
-
- manager.update(true /*force*/);
- }
-
- /**
- * Creates the tree and its viewer
- * @return The tree control
- */
- private Tree createTreeViewer(FormToolkit toolkit, Composite grid,
- final IManagedForm managedForm) {
- // Note: we *could* use a FilteredTree instead of the Tree+TreeViewer here.
- // However the class must be adapted to create an adapted toolkit tree.
- final Tree tree = toolkit.createTree(grid, SWT.MULTI);
- GridData gd = new GridData(GridData.FILL_BOTH);
- gd.widthHint = AndroidXmlEditor.TEXT_WIDTH_HINT;
- gd.heightHint = TREE_HEIGHT_HINT;
- tree.setLayoutData(gd);
-
- mTreeViewer = new TreeViewer(tree);
- mTreeViewer.setContentProvider(new UiModelTreeContentProvider(mUiRootNode, mDescriptorFilters));
- mTreeViewer.setLabelProvider(new UiModelTreeLabelProvider());
- mTreeViewer.setInput("unused"); //$NON-NLS-1$
-
- // Create a listener that reacts to selections on the tree viewer.
- // When a selection is made, ask the managed form to propagate an event to
- // all parts in the managed form.
- // This is picked up by UiElementDetail.selectionChanged().
- mTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
- @Override
- public void selectionChanged(SelectionChangedEvent event) {
- managedForm.fireSelectionChanged(mMasterPart, event.getSelection());
- adjustTreeButtons(event.getSelection());
- }
- });
-
- // Create three listeners:
- // - One to refresh the tree viewer when the parent's node has been updated
- // - One to refresh the tree viewer when the framework resources have changed
- // - One to enable/disable the UI based on the application node's presence.
- mUiRefreshListener = new IUiUpdateListener() {
- @Override
- public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) {
- mTreeViewer.refresh();
- }
- };
-
- mUiEnableListener = new IUiUpdateListener() {
- @Override
- public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) {
- // The UiElementNode for the application XML node always exists, even
- // if there is no corresponding XML node in the XML file.
- //
- // Normally, we enable the UI here if the XML node is not null.
- //
- // However if mAutoCreateRoot is true, the root node will be created on-demand
- // so the tree/block is always enabled.
- boolean exists = mAutoCreateRoot || (ui_node.getXmlNode() != null);
- if (mMasterPart != null) {
- Section section = mMasterPart.getSection();
- if (section.getEnabled() != exists) {
- section.setEnabled(exists);
- for (Control c : section.getChildren()) {
- c.setEnabled(exists);
- }
- }
- }
- }
- };
-
- /** Listener to update the root node if the target of the file is changed because of a
- * SDK location change or a project target change */
- final ITargetChangeListener targetListener = new TargetChangeListener() {
- @Override
- public IProject getProject() {
- if (mEditor != null) {
- return mEditor.getProject();
- }
-
- return null;
- }
-
- @Override
- public void reload() {
- // If a details part has been created, we need to "refresh" it too.
- if (mDetailsPart != null) {
- // The details part does not directly expose access to its internal
- // page book. Instead it is possible to resize the page book to 0 and then
- // back to its original value, which has the side effect of removing all
- // existing cached pages.
- int limit = mDetailsPart.getPageLimit();
- mDetailsPart.setPageLimit(0);
- mDetailsPart.setPageLimit(limit);
- }
- // Refresh the tree, preserving the selection if possible.
- mTreeViewer.refresh();
- }
- };
-
- // Setup the listeners
- changeRootAndDescriptors(mUiRootNode, mDescriptorFilters, false /* refresh */);
-
- // Listen on resource framework changes to refresh the tree
- AdtPlugin.getDefault().addTargetListener(targetListener);
-
- // Remove listeners when the tree widget gets disposed.
- tree.addDisposeListener(new DisposeListener() {
- @Override
- public void widgetDisposed(DisposeEvent e) {
- if (mUiRootNode != null) {
- UiElementNode node = mUiRootNode.getUiParent() != null ?
- mUiRootNode.getUiParent() :
- mUiRootNode;
-
- if (node != null) {
- node.removeUpdateListener(mUiRefreshListener);
- }
- mUiRootNode.removeUpdateListener(mUiEnableListener);
- }
-
- AdtPlugin.getDefault().removeTargetListener(targetListener);
- if (mClipboard != null) {
- mClipboard.dispose();
- mClipboard = null;
- }
- }
- });
-
- // Get a new clipboard reference. It is disposed when the tree is disposed.
- mClipboard = new Clipboard(tree.getDisplay());
-
- return tree;
- }
-
- /**
- * Changes the UI root node and the descriptor filters of the tree.
- * <p/>
- * This removes the listeners attached to the old root node and reattaches them to the
- * new one.
- *
- * @param uiRootNode The root {@link UiElementNode} which contains all the elements that are
- * to be manipulated by this tree view. In general this is the manifest UI node or the
- * application UI node. This cannot be null.
- * @param descriptorFilters A list of descriptors of the elements to be displayed as root in
- * this tree view. Use null or an empty list to accept any kind of node.
- * @param forceRefresh If tree, forces the tree to refresh
- */
- public void changeRootAndDescriptors(UiElementNode uiRootNode,
- ElementDescriptor[] descriptorFilters, boolean forceRefresh) {
- UiElementNode node;
-
- // Remove previous listeners if any
- if (mUiRootNode != null) {
- node = mUiRootNode.getUiParent() != null ? mUiRootNode.getUiParent() : mUiRootNode;
- node.removeUpdateListener(mUiRefreshListener);
- mUiRootNode.removeUpdateListener(mUiEnableListener);
- }
-
- mUiRootNode = uiRootNode;
- mDescriptorFilters = descriptorFilters;
-
- mTreeViewer.setContentProvider(
- new UiModelTreeContentProvider(mUiRootNode, mDescriptorFilters));
-
- // Listen on structural changes on the root node of the tree
- // If the node has a parent, listen on the parent instead.
- if (mUiRootNode != null) {
- node = mUiRootNode.getUiParent() != null ? mUiRootNode.getUiParent() : mUiRootNode;
-
- if (node != null) {
- node.addUpdateListener(mUiRefreshListener);
- }
-
- // Use the root node to listen to its presence.
- mUiRootNode.addUpdateListener(mUiEnableListener);
-
- // Initialize the enabled/disabled state
- mUiEnableListener.uiElementNodeUpdated(mUiRootNode, null /* state, not used */);
- }
-
- if (forceRefresh) {
- mTreeViewer.refresh();
- }
-
- createSectionActions(mMasterPart.getSection(), mManagedForm.getToolkit());
- }
-
- /**
- * Creates the buttons next to the tree.
- */
- private void createButtons(FormToolkit toolkit, Composite grid) {
-
- mUiTreeActions = new UiTreeActions();
-
- Composite button_grid = SectionHelper.createGridLayout(grid, toolkit, 1);
- button_grid.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
- mAddButton = toolkit.createButton(button_grid, "Add...", SWT.PUSH);
- SectionHelper.addControlTooltip(mAddButton, "Adds a new element.");
- mAddButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL |
- GridData.VERTICAL_ALIGN_BEGINNING));
-
- mAddButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- super.widgetSelected(e);
- doTreeAdd();
- }
- });
-
- mRemoveButton = toolkit.createButton(button_grid, "Remove...", SWT.PUSH);
- SectionHelper.addControlTooltip(mRemoveButton, "Removes an existing selected element.");
- mRemoveButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- mRemoveButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- super.widgetSelected(e);
- doTreeRemove();
- }
- });
-
- mUpButton = toolkit.createButton(button_grid, "Up", SWT.PUSH);
- SectionHelper.addControlTooltip(mRemoveButton, "Moves the selected element up.");
- mUpButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- mUpButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- super.widgetSelected(e);
- doTreeUp();
- }
- });
-
- mDownButton = toolkit.createButton(button_grid, "Down", SWT.PUSH);
- SectionHelper.addControlTooltip(mRemoveButton, "Moves the selected element down.");
- mDownButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- mDownButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- super.widgetSelected(e);
- doTreeDown();
- }
- });
-
- adjustTreeButtons(TreeSelection.EMPTY);
- }
-
- private void createTreeContextMenu(Tree tree) {
- MenuManager menuManager = new MenuManager();
- menuManager.setRemoveAllWhenShown(true);
- menuManager.addMenuListener(new IMenuListener() {
- /**
- * The menu is about to be shown. The menu manager has already been
- * requested to remove any existing menu item. This method gets the
- * tree selection and if it is of the appropriate type it re-creates
- * the necessary actions.
- */
- @Override
- public void menuAboutToShow(IMenuManager manager) {
- ISelection selection = mTreeViewer.getSelection();
- if (!selection.isEmpty() && selection instanceof ITreeSelection) {
- ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
- doCreateMenuAction(manager, selected);
- return;
- }
- doCreateMenuAction(manager, null /* ui_node */);
- }
- });
- Menu contextMenu = menuManager.createContextMenu(tree);
- tree.setMenu(contextMenu);
- }
-
- /**
- * Adds the menu actions to the context menu when the given UI node is selected in
- * the tree view.
- *
- * @param manager The context menu manager
- * @param selected The UI nodes selected in the tree. Can be null, in which case the root
- * is to be modified.
- */
- private void doCreateMenuAction(IMenuManager manager, ArrayList<UiElementNode> selected) {
- if (selected != null) {
- boolean hasXml = false;
- for (UiElementNode uiNode : selected) {
- if (uiNode.getXmlNode() != null) {
- hasXml = true;
- break;
- }
- }
-
- if (hasXml) {
- manager.add(new CopyCutAction(getEditor(), getClipboard(),
- null, selected, true /* cut */));
- manager.add(new CopyCutAction(getEditor(), getClipboard(),
- null, selected, false /* cut */));
-
- // Can't paste with more than one element selected (the selection is the target)
- if (selected.size() <= 1) {
- // Paste is not valid if it would add a second element on a terminal element
- // which parent is a document -- an XML document can only have one child. This
- // means paste is valid if the current UI node can have children or if the
- // parent is not a document.
- UiElementNode ui_root = selected.get(0).getUiRoot();
- if (ui_root.getDescriptor().hasChildren() ||
- !(ui_root.getUiParent() instanceof UiDocumentNode)) {
- manager.add(new PasteAction(getEditor(), getClipboard(), selected.get(0)));
- }
- }
- manager.add(new Separator());
- }
- }
-
- // Append "add" and "remove" actions. They do the same thing as the add/remove
- // buttons on the side.
- IconFactory factory = IconFactory.getInstance();
-
- // "Add" makes sense only if there's 0 or 1 item selected since the
- // one selected item becomes the target.
- if (selected == null || selected.size() <= 1) {
- manager.add(new Action("Add...", factory.getImageDescriptor("add")) { //$NON-NLS-1$
- @Override
- public void run() {
- super.run();
- doTreeAdd();
- }
- });
- }
-
- if (selected != null) {
- if (selected != null) {
- manager.add(new Action("Remove", factory.getImageDescriptor("delete")) { //$NON-NLS-1$
- @Override
- public void run() {
- super.run();
- doTreeRemove();
- }
- });
- }
- manager.add(new Separator());
-
- manager.add(new Action("Up", factory.getImageDescriptor("up")) { //$NON-NLS-1$
- @Override
- public void run() {
- super.run();
- doTreeUp();
- }
- });
- manager.add(new Action("Down", factory.getImageDescriptor("down")) { //$NON-NLS-1$
- @Override
- public void run() {
- super.run();
- doTreeDown();
- }
- });
- }
- }
-
-
- /**
- * This is called by the tree when a selection is made.
- * It enables/disables the buttons associated with the tree depending on the current
- * selection.
- *
- * @param selection The current tree selection (same as mTreeViewer.getSelection())
- */
- private void adjustTreeButtons(ISelection selection) {
- mRemoveButton.setEnabled(!selection.isEmpty() && selection instanceof ITreeSelection);
- mUpButton.setEnabled(canDoTreeUp(selection));
- mDownButton.setEnabled(canDoTreeDown(selection));
- }
-
- /**
- * An adapter/wrapper to use the add/remove/up/down tree edit actions.
- */
- private class UiTreeActions extends UiActions {
- @Override
- protected UiElementNode getRootNode() {
- return mUiRootNode;
- }
-
- @Override
- protected void selectUiNode(UiElementNode uiNodeToSelect) {
- // Select the new item
- if (uiNodeToSelect != null) {
- LinkedList<UiElementNode> segments = new LinkedList<UiElementNode>();
- for (UiElementNode ui_node = uiNodeToSelect; ui_node != mUiRootNode;
- ui_node = ui_node.getUiParent()) {
- segments.add(0, ui_node);
- }
- if (segments.size() > 0) {
- mTreeViewer.setSelection(new TreeSelection(new TreePath(segments.toArray())));
- } else {
- mTreeViewer.setSelection(null);
- }
- }
- }
-
- @Override
- public void commitPendingXmlChanges() {
- commitManagedForm();
- }
- }
-
- /**
- * Filters an ITreeSelection to only keep the {@link UiElementNode}s (in case there's
- * something else in there).
- *
- * @return A new list of {@link UiElementNode} with at least one item or null.
- */
- private ArrayList<UiElementNode> filterSelection(ITreeSelection selection) {
- ArrayList<UiElementNode> selected = new ArrayList<UiElementNode>();
-
- for (Iterator<Object> it = selection.iterator(); it.hasNext(); ) {
- Object selectedObj = it.next();
-
- if (selectedObj instanceof UiElementNode) {
- selected.add((UiElementNode) selectedObj);
- }
- }
-
- return selected.size() > 0 ? selected : null;
- }
-
- /**
- * Called when the "Add..." button next to the tree view is selected.
- *
- * Displays a selection dialog that lets the user select which kind of node
- * to create, depending on the current selection.
- */
- private void doTreeAdd() {
- UiElementNode ui_node = mUiRootNode;
- ISelection selection = mTreeViewer.getSelection();
- if (!selection.isEmpty() && selection instanceof ITreeSelection) {
- ITreeSelection tree_selection = (ITreeSelection) selection;
- Object first = tree_selection.getFirstElement();
- if (first != null && first instanceof UiElementNode) {
- ui_node = (UiElementNode) first;
- }
- }
-
- mUiTreeActions.doAdd(
- ui_node,
- mDescriptorFilters,
- mTreeViewer.getControl().getShell(),
- (ILabelProvider) mTreeViewer.getLabelProvider());
- }
-
- /**
- * Called when the "Remove" button is selected.
- *
- * If the tree has a selection, remove it.
- * This simply deletes the XML node attached to the UI node: when the XML model fires the
- * update event, the tree will get refreshed.
- */
- protected void doTreeRemove() {
- ISelection selection = mTreeViewer.getSelection();
- if (!selection.isEmpty() && selection instanceof ITreeSelection) {
- ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
- mUiTreeActions.doRemove(selected, mTreeViewer.getControl().getShell());
- }
- }
-
- /**
- * Called when the "Up" button is selected.
- * <p/>
- * If the tree has a selection, move it up, either in the child list or as the last child
- * of the previous parent.
- */
- protected void doTreeUp() {
- ISelection selection = mTreeViewer.getSelection();
- if (!selection.isEmpty() && selection instanceof ITreeSelection) {
- ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
- mUiTreeActions.doUp(selected, mDescriptorFilters);
- }
- }
-
- /**
- * Checks whether the "up" action can be done on the current selection.
- *
- * @param selection The current tree selection.
- * @return True if all the selected nodes can be moved up.
- */
- protected boolean canDoTreeUp(ISelection selection) {
- if (!selection.isEmpty() && selection instanceof ITreeSelection) {
- ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
- return mUiTreeActions.canDoUp(selected, mDescriptorFilters);
- }
-
- return false;
- }
-
- /**
- * Called when the "Down" button is selected.
- *
- * If the tree has a selection, move it down, either in the same child list or as the
- * first child of the next parent.
- */
- protected void doTreeDown() {
- ISelection selection = mTreeViewer.getSelection();
- if (!selection.isEmpty() && selection instanceof ITreeSelection) {
- ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
- mUiTreeActions.doDown(selected, mDescriptorFilters);
- }
- }
-
- /**
- * Checks whether the "down" action can be done on the current selection.
- *
- * @param selection The current tree selection.
- * @return True if all the selected nodes can be moved down.
- */
- protected boolean canDoTreeDown(ISelection selection) {
- if (!selection.isEmpty() && selection instanceof ITreeSelection) {
- ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
- return mUiTreeActions.canDoDown(selected, mDescriptorFilters);
- }
-
- return false;
- }
-
- /**
- * Commits the current managed form (the one associated with our master part).
- * As a side effect, this will commit the current UiElementDetails page.
- */
- void commitManagedForm() {
- if (mManagedForm != null) {
- mManagedForm.commit(false /* onSave */);
- }
- }
-
- /* Implements ICommitXml for CopyCutAction */
- @Override
- public void commitPendingXmlChanges() {
- commitManagedForm();
- }
-
- @Override
- protected void createToolBarActions(IManagedForm managedForm) {
- // Pass. Not used, toolbar actions are defined by createSectionActions().
- }
-
- @Override
- protected void registerPages(DetailsPart inDetailsPart) {
- // Keep a reference on the details part (the super class doesn't provide a getter
- // for it.)
- mDetailsPart = inDetailsPart;
-
- // The page selection mechanism does not use pages registered by association with
- // a node class. Instead it uses a custom details page provider that provides a
- // new UiElementDetail instance for each node instance. A limit of 5 pages is
- // then set (the value is arbitrary but should be reasonable) for the internal
- // page book.
- inDetailsPart.setPageLimit(5);
-
- final UiTreeBlock tree = this;
-
- inDetailsPart.setPageProvider(new IDetailsPageProvider() {
- @Override
- public IDetailsPage getPage(Object key) {
- if (key instanceof UiElementNode) {
- return new UiElementDetail(tree);
- }
- return null;
- }
-
- @Override
- public Object getPageKey(Object object) {
- return object; // use node object as key
- }
- });
- }
-
- /**
- * An alphabetic sort action for the tree viewer.
- */
- private class TreeSortAction extends Action {
-
- private ViewerComparator mComparator;
-
- public TreeSortAction() {
- super("Sorts elements alphabetically.", AS_CHECK_BOX);
- setImageDescriptor(IconFactory.getInstance().getImageDescriptor("az_sort")); //$NON-NLS-1$
-
- if (mTreeViewer != null) {
- boolean is_sorted = mTreeViewer.getComparator() != null;
- setChecked(is_sorted);
- }
- }
-
- /**
- * Called when the button is selected. Toggles the tree viewer comparator.
- */
- @Override
- public void run() {
- if (mTreeViewer == null) {
- notifyResult(false /*success*/);
- return;
- }
-
- ViewerComparator comp = mTreeViewer.getComparator();
- if (comp != null) {
- // Tree is currently sorted.
- // Save currently comparator and remove it
- mComparator = comp;
- mTreeViewer.setComparator(null);
- } else {
- // Tree is not currently sorted.
- // Reuse or add a new comparator.
- if (mComparator == null) {
- mComparator = new ViewerComparator();
- }
- mTreeViewer.setComparator(mComparator);
- }
-
- notifyResult(true /*success*/);
- }
- }
-
- /**
- * A filter on descriptor for the tree viewer.
- * <p/>
- * The tree viewer will contain many of these actions and only one can be enabled at a
- * given time. When no action is selected, everything is displayed.
- * <p/>
- * Since "radio"-like actions do not allow for unselecting all of them, we manually
- * handle the exclusive radio button-like property: when an action is selected, it manually
- * removes all other actions as needed.
- */
- private class DescriptorFilterAction extends Action {
-
- private final ElementDescriptor mDescriptor;
- private ViewerFilter mFilter;
-
- public DescriptorFilterAction(ElementDescriptor descriptor) {
- super(String.format("Displays only %1$s elements.", descriptor.getUiName()),
- AS_CHECK_BOX);
-
- mDescriptor = descriptor;
- setImageDescriptor(descriptor.getImageDescriptor());
- }
-
- /**
- * Called when the button is selected.
- * <p/>
- * Find any existing {@link DescriptorFilter}s and remove them. Install ours.
- */
- @Override
- public void run() {
- super.run();
-
- if (isChecked()) {
- if (mFilter == null) {
- // create filter when required
- mFilter = new DescriptorFilter(this);
- }
-
- // we add our filter first, otherwise the UI might show the full list
- mTreeViewer.addFilter(mFilter);
-
- // Then remove the any other filters except ours. There should be at most
- // one other filter, since that's how the actions are made to look like
- // exclusive radio buttons.
- for (ViewerFilter filter : mTreeViewer.getFilters()) {
- if (filter instanceof DescriptorFilter && filter != mFilter) {
- DescriptorFilterAction action = ((DescriptorFilter) filter).getAction();
- action.setChecked(false);
- mTreeViewer.removeFilter(filter);
- }
- }
- } else if (mFilter != null){
- mTreeViewer.removeFilter(mFilter);
- }
- }
-
- /**
- * Filters the tree viewer for the given descriptor.
- * <p/>
- * The filter is linked to the action so that an action can iterate through the list
- * of filters and un-select the actions.
- */
- private class DescriptorFilter extends ViewerFilter {
-
- private final DescriptorFilterAction mAction;
-
- public DescriptorFilter(DescriptorFilterAction action) {
- mAction = action;
- }
-
- public DescriptorFilterAction getAction() {
- return mAction;
- }
-
- /**
- * Returns true if an element should be displayed, that if the element or
- * any of its parent matches the requested descriptor.
- */
- @Override
- public boolean select(Viewer viewer, Object parentElement, Object element) {
- while (element instanceof UiElementNode) {
- UiElementNode uiNode = (UiElementNode)element;
- if (uiNode.getDescriptor() == mDescriptor) {
- return true;
- }
- element = uiNode.getUiParent();
- }
- return false;
- }
- }
- }
-
-}