diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/NewItemSelectionDialog.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/NewItemSelectionDialog.java | 415 |
1 files changed, 0 insertions, 415 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/NewItemSelectionDialog.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/NewItemSelectionDialog.java deleted file mode 100644 index 385a53a5f..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/NewItemSelectionDialog.java +++ /dev/null @@ -1,415 +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.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.dialogs.AbstractElementListSelectionDialog; -import org.eclipse.ui.dialogs.ISelectionStatusValidator; -import org.eclipse.ui.part.FileEditorInput; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; - -/** - * A selection dialog to select the type of the new element node to - * create, either in the application node or the selected sub node. - */ -public class NewItemSelectionDialog extends AbstractElementListSelectionDialog { - - /** The UI node selected in the tree view before creating the new item selection dialog. - * Can be null -- which means new items must be created in the root_node. */ - private UiElementNode mSelectedUiNode; - /** The root node chosen by the user, either root_node or the one passed - * to the constructor if not null */ - private UiElementNode mChosenRootNode; - private UiElementNode mLocalRootNode; - /** 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. */ - private ElementDescriptor[] mDescriptorFilters; - /** The key for the {@link #setLastUsedXmlName(Object[])}. It corresponds to the full - * workspace path of the currently edited file, if this can be computed. This is computed - * by {@link #getLastUsedXmlName(UiElementNode)}, called from the constructor. */ - private String mLastUsedKey; - /** A static map of known XML Names used for a given file. The map has full workspace - * paths as key and XML names as values. */ - private static final Map<String, String> sLastUsedXmlName = new HashMap<String, String>(); - /** The potential XML Name to initially select in the selection dialog. This is computed - * in the constructor and set by {@link #setInitialSelection(UiElementNode)}. */ - private String mInitialXmlName; - - /** - * Creates the new item selection dialog. - * - * @param shell The parent shell for the list. - * @param labelProvider ILabelProvider for the list. - * @param descriptorFilters The element allows at the root of the tree. Can be null. - * @param ui_node The selected node, or null if none is selected. - * @param root_node The root of the Ui Tree, either the UiDocumentNode or a sub-node. - */ - public NewItemSelectionDialog(Shell shell, ILabelProvider labelProvider, - ElementDescriptor[] descriptorFilters, - UiElementNode ui_node, - UiElementNode root_node) { - super(shell, labelProvider); - mDescriptorFilters = descriptorFilters; - mLocalRootNode = root_node; - - // Only accept the UI node if it is not the UI root node and it can have children. - // If the node cannot have children, select its parent as a potential target. - if (ui_node != null && ui_node != mLocalRootNode) { - if (ui_node.getDescriptor().hasChildren()) { - mSelectedUiNode = ui_node; - } else { - UiElementNode parent = ui_node.getUiParent(); - if (parent != null && parent != mLocalRootNode) { - mSelectedUiNode = parent; - } - } - } - - setHelpAvailable(false); - setMultipleSelection(false); - - setValidator(new ISelectionStatusValidator() { - @Override - public IStatus validate(Object[] selection) { - if (selection.length == 1 && selection[0] instanceof ViewElementDescriptor) { - return new Status(IStatus.OK, // severity - AdtPlugin.PLUGIN_ID, //plugin id - IStatus.OK, // code - ((ViewElementDescriptor) selection[0]).getFullClassName(), //msg - null); // exception - } else if (selection.length == 1 && selection[0] instanceof ElementDescriptor) { - return new Status(IStatus.OK, // severity - AdtPlugin.PLUGIN_ID, //plugin id - IStatus.OK, // code - "", //$NON-NLS-1$ // msg - null); // exception - } else { - return new Status(IStatus.ERROR, // severity - AdtPlugin.PLUGIN_ID, //plugin id - IStatus.ERROR, // code - "Invalid selection", // msg, translatable - null); // exception - } - } - }); - - // Determine the initial selection using a couple heuristics. - - // First check if we can get the last used node type for this file. - // The heuristic is that generally one keeps adding the same kind of items to the - // same file, so reusing the last used item type makes most sense. - String xmlName = getLastUsedXmlName(root_node); - if (xmlName == null) { - // Another heuristic is to find the most used item and default to that. - xmlName = getMostUsedXmlName(root_node); - } - if (xmlName == null) { - // Finally the last heuristic is to see if there's an item with a name - // similar to the edited file name. - xmlName = getLeafFileName(root_node); - } - // Set the potential name. Selecting the right item is done later by setInitialSelection(). - mInitialXmlName = xmlName; - } - - /** - * Returns a potential XML name based on the file name. - * The item name is marked with an asterisk to identify it as a partial match. - */ - private String getLeafFileName(UiElementNode ui_node) { - if (ui_node != null) { - AndroidXmlEditor editor = ui_node.getEditor(); - if (editor != null) { - IEditorInput editorInput = editor.getEditorInput(); - if (editorInput instanceof FileEditorInput) { - IFile f = ((FileEditorInput) editorInput).getFile(); - if (f != null) { - String leafName = f.getFullPath().removeFileExtension().lastSegment(); - return "*" + leafName; //$NON-NLS-1$ - } - } - } - } - - return null; - } - - /** - * Given a potential non-null root node, this method looks for the currently edited - * file path and uses it as a key to retrieve the last used item for this file by this - * selection dialog. Returns null if nothing can be found, otherwise returns the string - * name of the item. - */ - private String getLastUsedXmlName(UiElementNode ui_node) { - if (ui_node != null) { - AndroidXmlEditor editor = ui_node.getEditor(); - if (editor != null) { - IEditorInput editorInput = editor.getEditorInput(); - if (editorInput instanceof FileEditorInput) { - IFile f = ((FileEditorInput) editorInput).getFile(); - if (f != null) { - mLastUsedKey = f.getFullPath().toPortableString(); - - return sLastUsedXmlName.get(mLastUsedKey); - } - } - } - } - - return null; - } - - /** - * Sets the last used item for this selection dialog for this file. - * @param objects The currently selected items. Only the first one is used if it is an - * {@link ElementDescriptor}. - */ - private void setLastUsedXmlName(Object[] objects) { - if (mLastUsedKey != null && - objects != null && - objects.length > 0 && - objects[0] instanceof ElementDescriptor) { - ElementDescriptor desc = (ElementDescriptor) objects[0]; - sLastUsedXmlName.put(mLastUsedKey, desc.getXmlName()); - } - } - - /** - * Returns the most used sub-element name, if any, or null. - */ - private String getMostUsedXmlName(UiElementNode ui_node) { - if (ui_node != null) { - TreeMap<String, Integer> counts = new TreeMap<String, Integer>(); - int max = -1; - - for (UiElementNode child : ui_node.getUiChildren()) { - String name = child.getDescriptor().getXmlName(); - Integer i = counts.get(name); - int count = i == null ? 1 : i.intValue() + 1; - counts.put(name, count); - max = Math.max(max, count); - } - - if (max > 0) { - // Find first key with this max and return it - for (Entry<String, Integer> entry : counts.entrySet()) { - if (entry.getValue().intValue() == max) { - return entry.getKey(); - } - } - } - } - return null; - } - - /** - * @return The root node selected by the user, either root node or the - * one passed to the constructor if not null. - */ - public UiElementNode getChosenRootNode() { - return mChosenRootNode; - } - - /** - * Internal helper to compute the result. Returns the selection from - * the list view, if any. - */ - @Override - protected void computeResult() { - setResult(Arrays.asList(getSelectedElements())); - setLastUsedXmlName(getSelectedElements()); - } - - /** - * Creates the dialog area. - * - * First add a radio area, which may be either 2 radio controls or - * just a message area if there's only one choice (the app root node). - * - * Then uses the default from the AbstractElementListSelectionDialog - * which is to add both a filter text and a filtered list. Adding both - * is necessary (since the base class accesses both internal directly - * fields without checking for null pointers.) - * - * Finally sets the initial selection list. - */ - @Override - protected Control createDialogArea(Composite parent) { - Composite contents = (Composite) super.createDialogArea(parent); - - createRadioControl(contents); - createFilterText(contents); - createFilteredList(contents); - - // We don't want the builtin message area label (we use a radio control - // instead), but if we don't create it, Bad Stuff happens on - // Eclipse 3.8 and later (see issue 32527). - Label label = createMessageArea(contents); - if (label != null) { - GridData data = (GridData) label.getLayoutData(); - data.exclude = true; - } - - // Initialize the list state. - // This must be done after the filtered list as been created. - chooseNode(mChosenRootNode); - - // Set the initial selection - setInitialSelection(mChosenRootNode); - return contents; - } - - /** - * Tries to set the initial selection based on the {@link #mInitialXmlName} computed - * in the constructor. The selection is only set if there's an element descriptor - * that matches the same exact XML name. When {@link #mInitialXmlName} starts with an - * asterisk, it means to do a partial case-insensitive match on the start of the - * strings. - */ - private void setInitialSelection(UiElementNode rootNode) { - ElementDescriptor initialElement = null; - - if (mInitialXmlName != null && mInitialXmlName.length() > 0) { - String name = mInitialXmlName; - boolean partial = name.startsWith("*"); //$NON-NLS-1$ - if (partial) { - name = name.substring(1).toLowerCase(Locale.US); - } - - for (ElementDescriptor desc : getAllowedDescriptors(rootNode)) { - if (!partial && desc.getXmlName().equals(name)) { - initialElement = desc; - break; - } else if (partial) { - String name2 = desc.getXmlLocalName().toLowerCase(Locale.US); - if (name.startsWith(name2) || name2.startsWith(name)) { - initialElement = desc; - break; - } - } - } - } - - setSelection(initialElement == null ? null : new ElementDescriptor[] { initialElement }); - } - - /** - * Creates the message text widget and sets layout data. - * @param content the parent composite of the message area. - */ - private Composite createRadioControl(Composite content) { - - if (mSelectedUiNode != null) { - Button radio1 = new Button(content, SWT.RADIO); - radio1.setText(String.format("Create a new element at the top level, in %1$s.", - mLocalRootNode.getShortDescription())); - - Button radio2 = new Button(content, SWT.RADIO); - radio2.setText(String.format("Create a new element in the selected element, %1$s.", - mSelectedUiNode.getBreadcrumbTrailDescription(false /* include_root */))); - - // Set the initial selection before adding the listeners - // (they can't be run till the filtered list has been created) - radio1.setSelection(false); - radio2.setSelection(true); - mChosenRootNode = mSelectedUiNode; - - radio1.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - chooseNode(mLocalRootNode); - } - }); - - radio2.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - chooseNode(mSelectedUiNode); - } - }); - } else { - setMessage(String.format("Create a new element at the top level, in %1$s.", - mLocalRootNode.getShortDescription())); - createMessageArea(content); - - mChosenRootNode = mLocalRootNode; - } - - return content; - } - - /** - * Internal helper to remember the root node choosen by the user. - * It also sets the list view to the adequate list of children that can - * be added to the chosen root node. - * - * If the chosen root node is mLocalRootNode and a descriptor filter was specified - * when creating the master-detail part, we use this as the set of nodes that - * can be created on the root node. - * - * @param ui_node The chosen root node, either mLocalRootNode or - * mSelectedUiNode. - */ - private void chooseNode(UiElementNode ui_node) { - mChosenRootNode = ui_node; - setListElements(getAllowedDescriptors(ui_node)); - } - - /** - * Returns the list of {@link ElementDescriptor}s that can be added to the given - * UI node. - * - * @param ui_node The UI node to which element should be added. Cannot be null. - * @return A non-null array of {@link ElementDescriptor}. The array might be empty. - */ - private ElementDescriptor[] getAllowedDescriptors(UiElementNode ui_node) { - if (ui_node == mLocalRootNode && - mDescriptorFilters != null && - mDescriptorFilters.length != 0) { - return mDescriptorFilters; - } else { - return ui_node.getDescriptor().getChildren(); - } - } -} |