diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/PropertySheetPage.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/PropertySheetPage.java | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/PropertySheetPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/PropertySheetPage.java new file mode 100644 index 000000000..58fddc0ee --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/properties/PropertySheetPage.java @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2012 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.layout.properties; + +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.internal.editors.IconFactory; +import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo; +import com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart; +import com.android.ide.eclipse.adt.internal.editors.layout.properties.PropertyFactory.SortingMode; +import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode; +import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener; +import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.Page; +import org.eclipse.ui.views.properties.IPropertySheetPage; +import org.eclipse.wb.internal.core.editor.structure.IPage; +import org.eclipse.wb.internal.core.model.property.Property; +import org.eclipse.wb.internal.core.model.property.table.IPropertyExceptionHandler; +import org.eclipse.wb.internal.core.model.property.table.PropertyTable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * Property sheet page used when the graphical layout editor is chosen + */ +public class PropertySheetPage extends Page + implements IPropertySheetPage, IUiUpdateListener, IPage { + private PropertyTable mPropertyTable; + private final GraphicalEditorPart mEditor; + private Property mActiveProperty; + private Action mDefaultValueAction; + private Action mShowAdvancedPropertiesAction; + private Action mSortAlphaAction; + private Action mCollapseAll; + private Action mExpandAll; + private List<CanvasViewInfo> mSelection; + + private static final String EXPAND_DISABLED_ICON = "expandall-disabled"; //$NON-NLS-1$ + private static final String EXPAND_ICON = "expandall"; //$NON-NLS-1$ + private static final String DEFAULT_ICON = "properties_default"; //$NON-NLS-1$ + private static final String ADVANCED_ICON = "filter_advanced_properties"; //$NON-NLS-1$ + private static final String ALPHA_ICON = "sort_alpha"; //$NON-NLS-1$ + // TODO: goto-definition.png + + /** + * Constructs a new {@link PropertySheetPage} associated with the given + * editor + * + * @param editor the editor associated with this property sheet page + */ + public PropertySheetPage(GraphicalEditorPart editor) { + mEditor = editor; + } + + private PropertyFactory getPropertyFactory() { + return mEditor.getPropertyFactory(); + } + + @Override + public void createControl(Composite parent) { + assert parent != null; + mPropertyTable = new PropertyTable(parent, SWT.NONE); + mPropertyTable.setExceptionHandler(new IPropertyExceptionHandler() { + @Override + public void handle(Throwable e) { + AdtPlugin.log(e, null); + } + }); + mPropertyTable.setDefaultCollapsedNames(Arrays.asList( + "Deprecated", + "Layout Parameters", + "Layout Parameters|Margins")); + + createActions(); + setPropertyTableContextMenu(); + } + + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + if (selection instanceof TreeSelection + && mPropertyTable != null && !mPropertyTable.isDisposed()) { + TreeSelection treeSelection = (TreeSelection) selection; + + // We get a lot of repeated selection requests for the same selection + // as before, so try to eliminate these + if (mSelection != null) { + if (mSelection.isEmpty()) { + if (treeSelection.isEmpty()) { + return; + } + } else { + int selectionCount = treeSelection.size(); + if (selectionCount == mSelection.size()) { + boolean same = true; + Iterator<?> iterator = treeSelection.iterator(); + for (int i = 0, n = selectionCount; i < n && iterator.hasNext(); i++) { + Object next = iterator.next(); + if (next instanceof CanvasViewInfo) { + CanvasViewInfo info = (CanvasViewInfo) next; + if (info != mSelection.get(i)) { + same = false; + break; + } + } else { + same = false; + break; + } + } + if (same) { + return; + } + } + } + } + + stopTrackingSelection(); + + if (treeSelection.isEmpty()) { + mSelection = Collections.emptyList(); + } else { + int selectionCount = treeSelection.size(); + List<CanvasViewInfo> newSelection = new ArrayList<CanvasViewInfo>(selectionCount); + Iterator<?> iterator = treeSelection.iterator(); + while (iterator.hasNext()) { + Object next = iterator.next(); + if (next instanceof CanvasViewInfo) { + CanvasViewInfo info = (CanvasViewInfo) next; + newSelection.add(info); + } + } + mSelection = newSelection; + } + + startTrackingSelection(); + + refreshProperties(); + } + } + + @Override + public void dispose() { + stopTrackingSelection(); + super.dispose(); + } + + private void startTrackingSelection() { + if (mSelection != null && !mSelection.isEmpty()) { + for (CanvasViewInfo item : mSelection) { + UiViewElementNode node = item.getUiViewNode(); + if (node != null) { + node.addUpdateListener(this); + } + } + } + } + + private void stopTrackingSelection() { + if (mSelection != null && !mSelection.isEmpty()) { + for (CanvasViewInfo item : mSelection) { + UiViewElementNode node = item.getUiViewNode(); + if (node != null) { + node.removeUpdateListener(this); + } + } + } + mSelection = null; + } + + // Implements IUiUpdateListener + @Override + public void uiElementNodeUpdated(UiElementNode node, UiUpdateState state) { + refreshProperties(); + } + + @Override + public Control getControl() { + return mPropertyTable; + } + + @Override + public void setFocus() { + mPropertyTable.setFocus(); + } + + @Override + public void makeContributions(IMenuManager menuManager, + IToolBarManager toolBarManager, IStatusLineManager statusLineManager) { + toolBarManager.add(mShowAdvancedPropertiesAction); + toolBarManager.add(new Separator()); + toolBarManager.add(mSortAlphaAction); + toolBarManager.add(new Separator()); + toolBarManager.add(mDefaultValueAction); + toolBarManager.add(new Separator()); + toolBarManager.add(mExpandAll); + toolBarManager.add(mCollapseAll); + toolBarManager.add(new Separator()); + } + + private void createActions() { + ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages(); + IconFactory iconFactory = IconFactory.getInstance(); + + mExpandAll = new PropertySheetAction( + IAction.AS_PUSH_BUTTON, + "Expand All", + ACTION_EXPAND, + iconFactory.getImageDescriptor(EXPAND_ICON), + iconFactory.getImageDescriptor(EXPAND_DISABLED_ICON)); + + mCollapseAll = new PropertySheetAction( + IAction.AS_PUSH_BUTTON, + "Collapse All", + ACTION_COLLAPSE, + sharedImages.getImageDescriptor(ISharedImages.IMG_ELCL_COLLAPSEALL), + sharedImages.getImageDescriptor(ISharedImages.IMG_ELCL_COLLAPSEALL_DISABLED)); + + mShowAdvancedPropertiesAction = new PropertySheetAction( + IAction.AS_CHECK_BOX, + "Show Advanced Properties", + ACTION_SHOW_ADVANCED, + iconFactory.getImageDescriptor(ADVANCED_ICON), + null); + + mSortAlphaAction = new PropertySheetAction( + IAction.AS_CHECK_BOX, + "Sort Alphabetically", + ACTION_SORT_ALPHA, + iconFactory.getImageDescriptor(ALPHA_ICON), + null); + + mDefaultValueAction = new PropertySheetAction( + IAction.AS_PUSH_BUTTON, + "Restore Default Value", + ACTION_DEFAULT_VALUE, + iconFactory.getImageDescriptor(DEFAULT_ICON), + null); + + // Listen on the selection in the property sheet so we can update the + // Restore Default Value action + ISelectionChangedListener listener = new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + StructuredSelection selection = (StructuredSelection) event.getSelection(); + mActiveProperty = (Property) selection.getFirstElement(); + updateDefaultValueAction(); + } + }; + mPropertyTable.addSelectionChangedListener(listener); + } + + /** + * Updates the state of {@link #mDefaultValueAction}. + */ + private void updateDefaultValueAction() { + if (mActiveProperty != null) { + try { + mDefaultValueAction.setEnabled(mActiveProperty.isModified()); + } catch (Exception e) { + AdtPlugin.log(e, null); + } + } else { + mDefaultValueAction.setEnabled(false); + } + } + + /** + * Sets the context menu for {@link #mPropertyTable}. + */ + private void setPropertyTableContextMenu() { + final MenuManager manager = new MenuManager(); + manager.setRemoveAllWhenShown(true); + manager.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(IMenuManager m) { + // dispose items to avoid caching + for (MenuItem item : manager.getMenu().getItems()) { + item.dispose(); + } + // apply new items + fillContextMenu(); + } + + private void fillContextMenu() { + manager.add(mDefaultValueAction); + manager.add(mSortAlphaAction); + manager.add(mShowAdvancedPropertiesAction); + } + }); + + mPropertyTable.setMenu(manager.createContextMenu(mPropertyTable)); + } + + /** + * Shows {@link Property}'s of current objects. + */ + private void refreshProperties() { + PropertyFactory factory = getPropertyFactory(); + mPropertyTable.setInput(factory.getProperties(mSelection)); + updateDefaultValueAction(); + } + + // ---- Actions ---- + + private static final int ACTION_DEFAULT_VALUE = 1; + private static final int ACTION_SHOW_ADVANCED = 2; + private static final int ACTION_COLLAPSE = 3; + private static final int ACTION_EXPAND = 4; + private static final int ACTION_SORT_ALPHA = 5; + + private class PropertySheetAction extends Action { + private final int mAction; + + private PropertySheetAction(int style, String label, int action, + ImageDescriptor imageDesc, ImageDescriptor disabledImageDesc) { + super(label, style); + mAction = action; + setImageDescriptor(imageDesc); + if (disabledImageDesc != null) { + setDisabledImageDescriptor(disabledImageDesc); + } + setToolTipText(label); + } + + @Override + public void run() { + switch (mAction) { + case ACTION_COLLAPSE: { + mPropertyTable.collapseAll(); + break; + } + case ACTION_EXPAND: { + mPropertyTable.expandAll(); + break; + } + case ACTION_SHOW_ADVANCED: { + boolean show = mShowAdvancedPropertiesAction.isChecked(); + mPropertyTable.setShowAdvancedProperties(show); + break; + } + case ACTION_SORT_ALPHA: { + boolean isAlphabetical = mSortAlphaAction.isChecked(); + getPropertyFactory().setSortingMode( + isAlphabetical ? SortingMode.ALPHABETICAL : PropertyFactory.DEFAULT_MODE); + refreshProperties(); + break; + } + case ACTION_DEFAULT_VALUE: + try { + mActiveProperty.setValue(Property.UNKNOWN_VALUE); + } catch (Exception e) { + // Ignore warnings from setters + } + break; + default: + assert false : mAction; + } + } + } + + @Override + public void setToolBar(IToolBarManager toolBarManager) { + makeContributions(null, toolBarManager, null); + toolBarManager.update(false); + } +} |