[271844] XML editor's design page should use table columns for a more native feel
diff --git a/bundles/org.eclipse.wst.xml.ui/plugin.xml b/bundles/org.eclipse.wst.xml.ui/plugin.xml index d9fc7ff..db478c8 100644 --- a/bundles/org.eclipse.wst.xml.ui/plugin.xml +++ b/bundles/org.eclipse.wst.xml.ui/plugin.xml
@@ -992,34 +992,6 @@ </reference> </visibleWhen> </command> - <separator - name="sed.tabletree.separator.2" - visible="true"> - </separator> - <command - commandId="sed.tabletree.expandAll" - icon="icons/full/etool16/expand_all.gif" - id="ExpandAll" - style="push"> - <visibleWhen - checkEnabled="false"> - <reference - definitionId="org.eclipse.wst.xml.ui.expand"> - </reference> - </visibleWhen> - </command> - <command - commandId="sed.tabletree.collapseAll" - icon="icons/full/etool16/collapse_all.gif" - id="CollapseAll" - style="push"> - <visibleWhen - checkEnabled="false"> - <reference - definitionId="org.eclipse.wst.xml.ui.expand"> - </reference> - </visibleWhen> - </command> </toolbar> </menuContribution>
diff --git a/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLEditorMessages.java b/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLEditorMessages.java index c0471bf..4fbac12 100644 --- a/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLEditorMessages.java +++ b/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLEditorMessages.java
@@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 IBM Corporation and others. + * Copyright (c) 2005, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -21,6 +21,8 @@ private static final String BUNDLE_NAME = "org.eclipse.wst.xml.ui.internal.tabletree.XMLEditorResources";//$NON-NLS-1$ public static String XMLTableTreeViewer_0; + public static String XMLTableTreeViewer_1; + public static String XMLTableTreeViewer_2; public static String XMLMultiPageEditorPart_0; public static String XMLTreeExtension_0; public static String XMLTreeExtension_1;
diff --git a/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLEditorResources.properties b/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLEditorResources.properties index 2fc1735..1943b11 100644 --- a/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLEditorResources.properties +++ b/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLEditorResources.properties
@@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2004, 2005 IBM Corporation and others. +# Copyright (c) 2004, 2009 IBM Corporation and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at @@ -9,6 +9,8 @@ # IBM Corporation - initial API and implementation ############################################################################### XMLTableTreeViewer_0=Design +XMLTableTreeViewer_1=Node +XMLTableTreeViewer_2=Content XMLMultiPageEditorPart_0=Source XMLTreeExtension_0=Structure XMLTreeExtension_1=Value
diff --git a/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLMultiPageEditorPart.java b/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLMultiPageEditorPart.java index a3578cd..b1fed5c 100644 --- a/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLMultiPageEditorPart.java +++ b/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLMultiPageEditorPart.java
@@ -17,10 +17,12 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextInputListener; import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.AbstractTreeViewer; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.IPostSelectionProvider; import org.eclipse.jface.viewers.ISelection; @@ -30,9 +32,13 @@ import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IEditorActionBarContributor; @@ -586,15 +592,42 @@ // note: By adding the design page as a Control instead of an // IEditorPart, page switches will indicate // a "null" active editor when the design page is made active - fDesignPageIndex = addPage(designViewer.getControl()); + fDesignPageIndex = addPage(designViewer.getControl().getParent()); setPageText(fDesignPageIndex, designViewer.getTitle()); } protected IDesignViewer createDesignPage() { - XMLTableTreeViewer tableTreeViewer = new XMLTableTreeViewer(getContainer()); + Composite container = new Composite(getContainer(), SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.marginWidth = 0; + container.setLayout(layout); + + ToolBar tb = new ToolBar(container, SWT.FLAT); + + ToolBarManager manager = new ToolBarManager(tb); + tb.setLayoutData(new GridData(GridData.END, GridData.VERTICAL_ALIGN_BEGINNING, true, false)); + + IDesignViewer designViewer = new XMLTableTreeViewer(container); + designViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH)); // Set the default infopop for XML design viewer. - XMLUIPlugin.getInstance().getWorkbench().getHelpSystem().setHelp(tableTreeViewer.getControl(), XMLTableTreeHelpContextIds.XML_DESIGN_VIEW_HELPID); - return tableTreeViewer; + XMLUIPlugin.getInstance().getWorkbench().getHelpSystem().setHelp(designViewer.getControl(), XMLTableTreeHelpContextIds.XML_DESIGN_VIEW_HELPID); + + addToolBarActions(manager, designViewer); + + return designViewer; + } + + private void addToolBarActions(ToolBarManager manager, IDesignViewer viewer) { + ViewerExpandCollapseAction expand = new ViewerExpandCollapseAction(true); + ViewerExpandCollapseAction collapse = new ViewerExpandCollapseAction(false); + manager.add(expand); + manager.add(collapse); + manager.update(true); + + expand.setViewer((AbstractTreeViewer) viewer); + collapse.setViewer((AbstractTreeViewer) viewer); } /**
diff --git a/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLTableTreeContentProvider.java b/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLTableTreeContentProvider.java index 3383d00..95125b6 100644 --- a/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLTableTreeContentProvider.java +++ b/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLTableTreeContentProvider.java
@@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,18 +14,24 @@ import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ITableColorProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier; import org.eclipse.wst.sse.ui.internal.contentoutline.IJFaceNodeAdapter; import org.eclipse.wst.sse.ui.internal.contentoutline.IJFaceNodeAdapterFactory; import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument; +import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration; import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManager; import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManagerListener; import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery; +import org.eclipse.wst.xml.core.internal.contentmodel.util.CMDescriptionBuilder; import org.eclipse.wst.xml.core.internal.contentmodel.util.CMDocumentCache; import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; @@ -39,7 +45,7 @@ import org.w3c.dom.Text; -public class XMLTableTreeContentProvider implements ITreeContentProvider, ITableLabelProvider, ILabelProvider, CMDocumentManagerListener { +public class XMLTableTreeContentProvider implements ITreeContentProvider, ITableLabelProvider, ITableColorProvider, ILabelProvider, CMDocumentManagerListener { protected CMDocumentManager documentManager; @@ -47,6 +53,10 @@ private TreeContentHelper treeContentHelper = new TreeContentHelper(); + private CMDescriptionBuilder descriptionBuilder = new CMDescriptionBuilder(); + + private Color fCMColor = null; + public XMLTableTreeContentProvider() { super(); } @@ -83,6 +93,9 @@ } } } + if (fCMColor != null) { + fCMColor.dispose(); + } } private void doDelayedRefreshForViewers() { @@ -118,6 +131,22 @@ } else if ((column == 1) && (object instanceof Node)) { result = treeContentHelper.getNodeValue((Node) object); + if (result == null) + result = getElementValueHelper((Element) object); + + } + return result != null ? result : ""; //$NON-NLS-1$ + } + + private String getElementValueHelper(Element element) { + String result = null; + + ModelQuery mq = ModelQueryUtil.getModelQuery(element.getOwnerDocument()); + if ((result == null) && (mq != null)) { + CMElementDeclaration ed = mq.getCMElementDeclaration(element); + if ((ed != null) && !Boolean.TRUE.equals(ed.getProperty("isInferred"))) { //$NON-NLS-1$ + result = descriptionBuilder.buildDescription(ed); + } } return result != null ? result : ""; //$NON-NLS-1$ } @@ -328,4 +357,25 @@ // since we always return 'false' for "isLabelProperty", // not need to listen. Maybe that should change some day? } + + public Color getBackground(Object element, int columnIndex) { + return null; + } + + public Color getForeground(Object element, int columnIndex) { + if (columnIndex == 1 && treeContentHelper.getNodeValue((Node) element) == null) + return getCMColor(); + return null; + } + + private Color getCMColor() { + if (fCMColor == null) { + Color background = Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND); + int r = Math.abs(background.getRed() - 125); + int g = Math.abs(background.getGreen() - 85); + int b = Math.abs(background.getBlue() - 105); + fCMColor = new Color(Display.getCurrent(), r, g, b); + } + return fCMColor; + } }
diff --git a/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLTableTreeViewer.java b/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLTableTreeViewer.java index 331f2d6..00694e7 100644 --- a/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLTableTreeViewer.java +++ b/bundles/org.eclipse.wst.xml.ui/src-multipage/org/eclipse/wst/xml/ui/internal/tabletree/XMLTableTreeViewer.java
@@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation and others. All rights reserved. This + * Copyright (c) 2004, 2009 IBM Corporation and others. All rights reserved. This * program and the accompanying materials are made available under the terms * of the Eclipse Public License v1.0 which accompanies this distribution, and * is available at http://www.eclipse.org/legal/epl-v10.html @@ -17,12 +17,16 @@ import org.eclipse.jface.util.LocalSelectionTransfer; import org.eclipse.jface.util.SafeRunnable; import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.IPostSelectionProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableLayout; +import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DND; @@ -34,13 +38,19 @@ import org.eclipse.swt.dnd.DropTargetListener; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Item; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.views.properties.IPropertyDescriptor; import org.eclipse.wst.sse.core.StructuredModelManager; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion; @@ -137,22 +147,50 @@ } } - protected CellEditor cellEditor; + private PaintListener fContentPaintListener = new PaintListener() { - protected XMLTreeExtension treeExtension; - + public void paintControl(PaintEvent e) { + GC gc = e.gc; + if (getTree().getItemCount() == 0) { + gc.setForeground(getTree().getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND)); + gc.setBackground(getTree().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + gc.drawString(XMLEditorMessages.XMLTreeExtension_3, 10, 10); + gc.drawString(XMLEditorMessages.XMLTreeExtension_4, 10, 10 + gc.getFontMetrics().getHeight()); + } + } + + }; + private ISelectionProvider fSelectionProvider = new SelectionProvider(); public XMLTableTreeViewer(Composite parent) { super(parent, SWT.FULL_SELECTION | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + + TableLayout layout = new TableLayout(); + + layout.addColumnData(new ColumnWeightData(40)); + TreeColumn column = new TreeColumn(this.getTree(), SWT.LEFT); + column.setText(XMLEditorMessages.XMLTableTreeViewer_1); + + layout.addColumnData(new ColumnWeightData(60)); + column = new TreeColumn(this.getTree(), SWT.LEFT); + column.setText(XMLEditorMessages.XMLTableTreeViewer_2); + + this.getTree().setHeaderVisible(true); + this.getTree().setLinesVisible(true); + this.getTree().setLayout(layout); // set up providers - this.treeExtension = new XMLTreeExtension(getTree()); + propertyDescriptorFactory = new XMLTableTreePropertyDescriptorFactory(); XMLTableTreeContentProvider provider = new XMLTableTreeContentProvider(); setContentProvider(provider); setLabelProvider(provider); + setColumnProperties(new String[] {STRUCTURE_PROPERTY, VALUE_PROPERTY}); + setCellEditors(new CellEditor[] {null, new TextCellEditor(this.getTree())}); + + setCellModifier(new XMLCMCellModifier()); createContextMenu(); DragSource dragSource = new DragSource(getControl(), DND.DROP_COPY | DND.DROP_MOVE); @@ -161,6 +199,8 @@ DropTarget dropTarget = new DropTarget(getControl(), DND.DROP_COPY | DND.DROP_MOVE); dropTarget.addDropListener(createDropTargetListener()); dropTarget.setTransfer(new Transfer[] {LocalSelectionTransfer.getTransfer()}); + + this.getTree().addPaintListener(fContentPaintListener); } /** @@ -265,7 +305,6 @@ } protected void doRefresh(Object o, boolean fromDelayed) { - treeExtension.resetCachedData(); super.refresh(o); } @@ -279,32 +318,10 @@ protected void handleDispose(DisposeEvent event) { super.handleDispose(event); - treeExtension.dispose(); + this.getTree().removePaintListener(fContentPaintListener); setDocument(null); } - public void refresh() { - treeExtension.resetCachedData(); - super.refresh(); - } - - public void refresh(Object o) { - treeExtension.resetCachedData(); - super.refresh(o); - } - - public void refresh(boolean updateLabels) { - treeExtension.resetCachedData(); - super.refresh(updateLabels); - getControl().redraw(); - } - - public void refresh(Object element, boolean updateLabels) { - treeExtension.resetCachedData(); - super.refresh(element, updateLabels); - getControl().redraw(); - } - public void setDocument(IDocument document) { /* * let the text editor to be the one that manages the model's lifetime @@ -317,10 +334,6 @@ Document domDoc = null; domDoc = ((IDOMModel) model).getDocument(); setInput(domDoc); - treeExtension.setIsUnsupportedInput(false); - } - else { - treeExtension.setIsUnsupportedInput(true); } } finally { @@ -330,5 +343,56 @@ } } + + protected TreeContentHelper treeContentHelper = new TreeContentHelper(); + protected XMLTableTreePropertyDescriptorFactory propertyDescriptorFactory; + + private final static String STRUCTURE_PROPERTY = XMLEditorMessages.XMLTreeExtension_0; + private final static String VALUE_PROPERTY = XMLEditorMessages.XMLTreeExtension_1; + + public class XMLCMCellModifier implements ICellModifier, TreeExtension.ICellEditorProvider { + public boolean canModify(Object element, String property) { + boolean result = false; + if (element instanceof Node) { + Node node = (Node) element; + if (property == VALUE_PROPERTY) { + result = treeContentHelper.isEditable(node); + if (result) { + /* Set up the cell editor based on the element */ + CellEditor[] editors = getCellEditors(); + if (editors.length > 0) { + if (editors[1] != null) + editors[1].dispose(); + editors[1] = getCellEditor(element, 1); + } + } + + } + } + return result; + } + + public Object getValue(Object object, String property) { + String result = null; + if (object instanceof Node) { + result = treeContentHelper.getNodeValue((Node) object); + } + return (result != null) ? result : ""; //$NON-NLS-1$ + } + + public void modify(Object element, String property, Object value) { + Item item = (Item) element; + String oldValue = treeContentHelper.getNodeValue((Node) item.getData()); + String newValue = value.toString(); + if ((newValue != null) && !newValue.equals(oldValue)) { + treeContentHelper.setNodeValue((Node) item.getData(), value.toString()); + } + } + + public CellEditor getCellEditor(Object o, int col) { + IPropertyDescriptor pd = propertyDescriptorFactory.createPropertyDescriptor(o); + return pd != null ? pd.createPropertyEditor(XMLTableTreeViewer.this.getTree()) : null; + } + } } \ No newline at end of file