Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian de Alwis2011-12-05 02:58:36 +0000
committerBrian de Alwis2011-12-05 02:58:36 +0000
commit06c7ad375100fb67c527a72bce9e49656a3347ac (patch)
tree50eea6e590da61c951e66d359a160fc4b59887f0
parent803897d9e64563377509d623c19efb8f333b42a1 (diff)
parentbc9605c14340508a5d8fc6bdfcb34dbffa7ca634 (diff)
downloadorg.eclipse.e4.tools-06c7ad375100fb67c527a72bce9e49656a3347ac.tar.gz
org.eclipse.e4.tools-06c7ad375100fb67c527a72bce9e49656a3347ac.tar.xz
org.eclipse.e4.tools-06c7ad375100fb67c527a72bce9e49656a3347ac.zip
Merge CSS Spy branch
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/.classpath7
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/.project28
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/META-INF/MANIFEST.MF22
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/build.properties5
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/plugin.xml13
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/Activator.java55
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CSSPropertiesContentProvider.java59
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CSSPropertyProvider.java55
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CssSpyDialog.java705
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/OpenSpyHandler.java65
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/SpyInstaller.java115
-rw-r--r--bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/WidgetTreeProvider.java79
-rw-r--r--features/org.eclipse.e4.tools.css.spy.feature/.classpath6
-rw-r--r--features/org.eclipse.e4.tools.css.spy.feature/.project23
-rw-r--r--features/org.eclipse.e4.tools.css.spy.feature/build.properties4
-rw-r--r--features/org.eclipse.e4.tools.css.spy.feature/feature.xml34
17 files changed, 1282 insertions, 0 deletions
diff --git a/bundles/org.eclipse.e4.tools.css.spy/.classpath b/bundles/org.eclipse.e4.tools.css.spy/.classpath
new file mode 100644
index 00000000..64c5e31b
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.tools.css.spy/.project b/bundles/org.eclipse.e4.tools.css.spy/.project
new file mode 100644
index 00000000..f29584da
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.tools.css.spy</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.tools.css.spy/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.tools.css.spy/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..af0f20f9
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.e4.tools.css.spy/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.tools.css.spy/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..3dcd3fd6
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/META-INF/MANIFEST.MF
@@ -0,0 +1,22 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: CSS Spy
+Bundle-SymbolicName: org.eclipse.e4.tools.css.spy;singleton:=true
+Bundle-Version: 0.0.0.qualifier
+Bundle-Activator: org.eclipse.e4.tools.css.spy.Activator
+Bundle-Vendor: Eclipse.org
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.0";resolution:=optional,
+ org.eclipse.e4.ui.css.core;bundle-version="0.9.0",
+ org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.jface;bundle-version="3.8.0",
+ org.eclipse.e4.ui.css.swt;bundle-version="0.10.0",
+ org.eclipse.e4.ui.css.swt.theme;bundle-version="0.9.1"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0",
+ org.eclipse.e4.core.contexts,
+ org.eclipse.e4.core.di.annotations,
+ org.eclipse.e4.core.services.statusreporter,
+ org.eclipse.e4.ui.services,
+ org.w3c.css.sac;version="1.3.0"
diff --git a/bundles/org.eclipse.e4.tools.css.spy/build.properties b/bundles/org.eclipse.e4.tools.css.spy/build.properties
new file mode 100644
index 00000000..e9863e28
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/bundles/org.eclipse.e4.tools.css.spy/plugin.xml b/bundles/org.eclipse.e4.tools.css.spy/plugin.xml
new file mode 100644
index 00000000..c442ab42
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/plugin.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="css.spy"
+ point="org.eclipse.e4.workbench.model">
+ <processor
+ beforefragment="false"
+ class="org.eclipse.e4.tools.css.spy.SpyInstaller">
+ </processor>
+ </extension>
+
+</plugin>
diff --git a/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/Activator.java b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/Activator.java
new file mode 100644
index 00000000..cf8f4c62
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/Activator.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Manumitting Technologies, Inc.
+ * 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
+ *
+ * Contributors:
+ * Brian de Alwis (MT) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.tools.css.spy;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ private static BundleContext context;
+
+ static BundleContext getContext() {
+ return context;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bundleContext) throws Exception {
+ Activator.context = bundleContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bundleContext) throws Exception {
+ Activator.context = null;
+ }
+
+ public static String join(String[] elements, String glue) {
+ StringBuilder sb = new StringBuilder();
+ join(sb, elements, glue);
+ return sb.toString();
+ }
+
+ public static void join(StringBuilder sb, String[] elements, String glue) {
+ for (int i = 0; i < elements.length; i++) {
+ sb.append(elements[i]);
+ if (i < elements.length - 1) {
+ sb.append(glue);
+ }
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CSSPropertiesContentProvider.java b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CSSPropertiesContentProvider.java
new file mode 100644
index 00000000..6442e268
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CSSPropertiesContentProvider.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Manumitting Technologies, Inc.
+ * 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
+ *
+ * Contributors:
+ * Brian de Alwis (MT) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.tools.css.spy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.e4.ui.css.core.dom.CSSStylableElement;
+import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.swt.dom.WidgetElement;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Widget;
+
+public class CSSPropertiesContentProvider implements IStructuredContentProvider {
+
+ protected CSSEngine cssEngine;
+ protected CSSStylableElement input;
+
+ public void dispose() {
+ cssEngine = null;
+ input = null;
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (newInput instanceof CSSStylableElement) {
+ this.input = (CSSStylableElement) newInput;
+ this.cssEngine = WidgetElement.getEngine((Widget) input.getNativeWidget());
+ } else if (newInput instanceof Widget) {
+ this.cssEngine = WidgetElement.getEngine((Widget) newInput);
+ this.input = (CSSStylableElement) cssEngine.getElement((Widget) newInput);
+ }
+ }
+
+ public Object[] getElements(Object inputElement) {
+ Map<String, ICSSPropertyHandler> handlerMap = cssEngine
+ .getCSSPropertyHandlers(input);
+ if (handlerMap == null) {
+ return null;
+ }
+ List<CSSPropertyProvider> properties = new ArrayList<CSSPropertyProvider>(handlerMap.size());
+ for (Entry<String, ICSSPropertyHandler> entry : handlerMap.entrySet()) {
+ properties.add(new CSSPropertyProvider(entry.getKey(), input, entry.getValue(), cssEngine));
+ }
+ return properties.toArray();
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CSSPropertyProvider.java b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CSSPropertyProvider.java
new file mode 100644
index 00000000..ffca1dda
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CSSPropertyProvider.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Manumitting Technologies, Inc.
+ * 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
+ *
+ * Contributors:
+ * Brian de Alwis (MT) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.tools.css.spy;
+
+import org.eclipse.e4.ui.css.core.dom.CSSStylableElement;
+import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * A getter and setter of a particular CSS property for a particular element.
+ */
+public class CSSPropertyProvider {
+
+ private String propertyName;
+ private CSSStylableElement element;
+ private ICSSPropertyHandler handler;
+ private CSSEngine engine;
+
+ public CSSPropertyProvider(String propertyName, CSSStylableElement element,
+ ICSSPropertyHandler handler, CSSEngine engine) {
+ this.propertyName = propertyName;
+ this.element = element;
+ this.handler = handler;
+ this.engine = engine;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public String getValue() throws Exception {
+ return handler.retrieveCSSProperty(element, propertyName, "", engine);
+ }
+
+ public void setValue(String value) throws Exception {
+ CSSValue v = engine.parsePropertyValue(value);
+ handler.applyCSSProperty(element, propertyName, v, "", engine);
+ }
+
+
+ @Override
+ public String toString() {
+ return propertyName;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CssSpyDialog.java b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CssSpyDialog.java
new file mode 100644
index 00000000..4eb11336
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CssSpyDialog.java
@@ -0,0 +1,705 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Manumitting Technologies, Inc.
+ * 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
+ *
+ * Contributors:
+ * Brian de Alwis (MT) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.tools.css.spy;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.e4.ui.css.core.dom.CSSStylableElement;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.swt.dom.WidgetElement;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.layout.TreeColumnLayout;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ColumnViewerEditor;
+import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
+import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.TableViewerEditor;
+import org.eclipse.jface.viewers.TableViewerFocusCellManager;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Region;
+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.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.css.sac.SelectorList;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.css.CSSStyleDeclaration;
+
+public class CssSpyDialog extends Dialog {
+ /** @return the CSS element corresponding to the argument, or null if none */
+ public static CSSStylableElement getCSSElement(Object o) {
+ if (o instanceof CSSStylableElement) {
+ return (CSSStylableElement) o;
+ } else if (o instanceof Widget) {
+ CSSEngine engine = WidgetElement.getEngine((Widget) o);
+ return (CSSStylableElement) engine.getElement(o);
+ }
+ return null;
+ }
+
+ /** @return the CSS engine governing the argument, or null if none */
+ public static CSSEngine getCSSEngine(Object o) {
+ if (o instanceof CSSStylableElement) {
+ CSSStylableElement element = (CSSStylableElement) o;
+ return WidgetElement.getEngine((Widget) element.getNativeWidget());
+ } else if (o instanceof Widget) {
+ return WidgetElement.getEngine((Widget) o);
+ }
+ return null;
+ }
+
+ private Display display;
+ private Widget specimen;
+ private Widget shown;
+
+ private TableViewer cssPropertiesViewer;
+ private TreeViewer widgetTreeViewer;
+ private Text cssRules;
+
+ private List<Shell> highlights = new LinkedList<Shell>();
+ private List<Region> highlightRegions = new LinkedList<Region>();
+ private Text cssSearchBox;
+ private Button showUnsetProperties;
+
+ protected ViewerFilter unsetPropertyFilter = new ViewerFilter() {
+
+ @Override
+ public boolean select(Viewer viewer, Object parentElement,
+ Object element) {
+ if (element instanceof CSSPropertyProvider) {
+ try {
+ return ((CSSPropertyProvider) element).getValue() != null;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ return false;
+ }
+ };
+
+ /**
+ * Create the dialog.
+ *
+ * @param parentShell
+ */
+ public CssSpyDialog(Shell parentShell) {
+ super(parentShell);
+ display = parentShell.getDisplay();
+ setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE/* | SWT.PRIMARY_MODAL */);
+ }
+
+ public Widget getSpecimen() {
+ return specimen;
+ }
+
+ private boolean isLive() {
+ return specimen == null;
+ }
+
+ public void setSpecimen(Widget specimen) {
+ this.specimen = specimen;
+ update();
+ }
+
+ private Widget getActiveSpecimen() {
+ if (specimen != null) {
+ return specimen;
+ }
+ return display.getCursorControl();
+ }
+
+ protected boolean shouldDismissOnLostFocus() {
+ return false;
+ }
+
+ protected void update() {
+ if (getShell() == null) {
+ return;
+ }
+ Widget current = getActiveSpecimen();
+ if (shown == current) {
+ return;
+ }
+ shown = current;
+
+ CSSEngine engine = WidgetElement.getEngine(shown);
+ CSSStylableElement element = (CSSStylableElement) engine
+ .getElement(shown);
+ if (element == null) {
+ return;
+ }
+
+ widgetTreeViewer
+ .setInput(new Object[] { shown instanceof Control ? ((Control) shown)
+ .getShell() : shown });
+ widgetTreeViewer.reveal(shown);
+ widgetTreeViewer.setSelection(new StructuredSelection(shown));
+
+ populate(shown);
+ }
+
+ protected void populate(Widget selected) {
+ CSSStylableElement element = getCSSElement(selected);
+ if (element == null) {
+ return;
+ }
+
+ cssPropertiesViewer.setInput(selected);
+
+ StringBuilder sb = new StringBuilder();
+ CSSEngine engine = getCSSEngine(element);
+ CSSStyleDeclaration decl = engine.getViewCSS().getComputedStyle(
+ element, null);
+
+ if (element.getCSSStyle() != null) {
+ sb.append("\nCSS Inline Style(s):\n ");
+ Activator.join(sb, element.getCSSStyle().split(";"), ";\n ");
+ }
+
+ if (decl != null) {
+ sb.append("\n\nCSS Properties:\n");
+ try {
+ if (decl != null) {
+ sb.append(decl.getCssText());
+ }
+ } catch (Throwable e) {
+ sb.append(e);
+ }
+ }
+ if (element.getStaticPseudoInstances().length > 0) {
+ sb.append("\nStatic Pseudoinstances:\n ");
+ Activator.join(sb, element.getStaticPseudoInstances(), "\n ");
+ }
+
+ if (element.getCSSClass() != null) {
+ sb.append("\n\nCSS Classes:\n ");
+ Activator.join(sb, element.getCSSClass().split(" +"), "\n ");
+ }
+
+ // FIXME: shouldn't this be getCSSStyle?
+ if (element.getAttribute("style") != null) {
+ sb.append("\n\nSWT Style Bits:\n ");
+ Activator.join(sb, element.getAttribute("style").split(" +"),
+ "\n ");
+ }
+
+ sb.append("\n\nCSS Class Element:\n ").append(
+ element.getClass().getName());
+
+ // this is useful for diagnosing issues
+ if (element.getNativeWidget() instanceof Composite) {
+ sb.append("\n\nSWT Layout:\n ").append(
+ ((Composite) element.getNativeWidget()).getLayout());
+ }
+
+ cssRules.setText(sb.toString().trim());
+
+ disposeHighlights();
+ highlightWidget(selected);
+ }
+
+ private void highlightWidget(Widget selected) {
+ widgetTreeViewer.reveal(selected);
+
+ Rectangle bounds = getBounds(selected); // relative to absolute display,
+ // not the widget
+ if (bounds == null /* || bounds.height == 0 || bounds.width == 0 */) {
+ return;
+ }
+ // emulate a transparent background as per SWT Snippet180
+ Shell selectedShell = getShell(selected);
+ if (selectedShell != null) {
+ // bounds = slectedShell.getDisplay().map(null, selectedShell,
+ // bounds);
+ }
+ Shell highlight = new Shell(selectedShell, SWT.NO_TRIM | SWT.MODELESS); // appears
+ // on
+ // top
+ highlight.setBackground(display.getSystemColor(SWT.COLOR_RED));
+ Region highlightRegion = new Region();
+ highlightRegion.add(0, 0, 1, bounds.height + 2);
+ highlightRegion.add(0, 0, bounds.width + 2, 1);
+ highlightRegion.add(bounds.width + 1, 0, 1, bounds.height + 2);
+ highlightRegion.add(0, bounds.height + 1, bounds.width + 2, 1);
+ highlight.setRegion(highlightRegion);
+ highlight.setBounds(bounds.x - 1, bounds.y - 1, bounds.width + 2,
+ bounds.height + 2);
+ highlight.setEnabled(false);
+ highlight.setVisible(true); // not open(): setVisible() prevents taking
+ // focus
+
+ highlights.add(highlight);
+ highlightRegions.add(highlightRegion);
+ }
+
+ private Shell getShell(Widget widget) {
+ if (widget instanceof Control) {
+ return ((Control) widget).getShell();
+ }
+ return null;
+ }
+
+ private void disposeHighlights() {
+ for (Shell highlight : highlights) {
+ highlight.dispose();
+ }
+ highlights.clear();
+ for (Region region : highlightRegions) {
+ region.dispose();
+ }
+ highlightRegions.clear();
+ }
+
+ private Rectangle getBounds(Widget widget) {
+ if (widget instanceof Shell) {
+ // Shell bounds are already in display coordinates
+ return ((Shell) widget).getBounds();
+ } else if (widget instanceof Control) {
+ Control control = (Control) widget;
+ Rectangle bounds = control.getBounds();
+ return control.getDisplay().map(control.getParent(), null, bounds);
+ } else if (widget instanceof ToolItem) {
+ ToolItem item = (ToolItem) widget;
+ Rectangle bounds = item.getBounds();
+ return item.getDisplay().map(item.getParent(), null, bounds);
+ }
+ // FIXME: figure out how to map items to a position
+ return null;
+ }
+
+ /**
+ * Create contents of the dialog.
+ *
+ * @param parent
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite outer = (Composite) super.createDialogArea(parent);
+
+ cssSearchBox = new Text(outer, SWT.BORDER | SWT.SEARCH
+ | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
+ cssSearchBox.setMessage("CSS Selector");
+ cssSearchBox.setToolTipText("Highlight matching widgets");
+ cssSearchBox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
+ false, 1, 1));
+
+ SashForm sashForm = new SashForm(outer, SWT.VERTICAL);
+ sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1,
+ 1));
+
+ // / THE WIDGET TREE
+ Composite widgetsComposite = new Composite(sashForm, SWT.NONE);
+
+ widgetTreeViewer = new TreeViewer(widgetsComposite, SWT.BORDER);
+ widgetTreeViewer.setContentProvider(new WidgetTreeProvider());
+ widgetTreeViewer.setAutoExpandLevel(0);
+ widgetTreeViewer.getTree().setLinesVisible(true);
+ widgetTreeViewer.getTree().setHeaderVisible(true);
+ ColumnViewerToolTipSupport.enableFor(widgetTreeViewer);
+
+ TreeViewerColumn widgetTypeColumn = new TreeViewerColumn(
+ widgetTreeViewer, SWT.NONE);
+ widgetTypeColumn.getColumn().setWidth(100);
+ widgetTypeColumn.getColumn().setText("Widget");
+ widgetTypeColumn.setLabelProvider(new ColumnLabelProvider() {
+ @Override
+ public String getText(Object item) {
+ CSSStylableElement element = CssSpyDialog.getCSSElement(item);
+ return element.getLocalName() + " ("
+ + element.getNamespaceURI() + ")";
+ }
+ });
+
+ TreeViewerColumn widgetClassColumn = new TreeViewerColumn(
+ widgetTreeViewer, SWT.NONE);
+ widgetClassColumn.getColumn().setText("CSS Class");
+ widgetClassColumn.getColumn().setWidth(100);
+ widgetClassColumn.setLabelProvider(new ColumnLabelProvider() {
+ @Override
+ public String getText(Object item) {
+ CSSStylableElement element = CssSpyDialog.getCSSElement(item);
+ if (element.getCSSClass() == null) {
+ return null;
+ }
+ String classes[] = element.getCSSClass().split(" +");
+ return classes.length <= 1 ? classes[0] : classes[0] + " (+"
+ + (classes.length - 1) + " others)";
+ }
+
+ @Override
+ public String getToolTipText(Object item) {
+ CSSStylableElement element = CssSpyDialog.getCSSElement(item);
+ if (element == null) {
+ return null;
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append(element.getLocalName()).append(" (")
+ .append(element.getNamespaceURI()).append(")");
+ if (element.getCSSClass() != null) {
+ sb.append("\nClasses:\n ");
+ Activator.join(sb, element.getCSSClass().split(" +"),
+ "\n ");
+ }
+ return sb.toString();
+ }
+ });
+
+ TreeViewerColumn widgetIdColumn = new TreeViewerColumn(
+ widgetTreeViewer, SWT.NONE);
+ widgetIdColumn.getColumn().setWidth(100);
+ widgetIdColumn.getColumn().setText("CSS Id");
+ widgetIdColumn.setLabelProvider(new ColumnLabelProvider() {
+ @Override
+ public String getText(Object item) {
+ CSSStylableElement element = CssSpyDialog.getCSSElement(item);
+ return element.getCSSId();
+ }
+ });
+
+ TreeColumnLayout widgetsTableLayout = new TreeColumnLayout();
+ widgetsTableLayout.setColumnData(widgetTypeColumn.getColumn(),
+ new ColumnWeightData(50));
+ widgetsTableLayout.setColumnData(widgetIdColumn.getColumn(),
+ new ColumnWeightData(40));
+ widgetsTableLayout.setColumnData(widgetClassColumn.getColumn(),
+ new ColumnWeightData(40));
+ widgetsComposite.setLayout(widgetsTableLayout);
+
+ // / HEADERS
+ Composite container = new Composite(sashForm, SWT.NONE);
+ container.setLayout(new GridLayout(2, true));
+
+ Label lblCssProperties = new Label(container, SWT.NONE);
+ lblCssProperties.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER,
+ false, false, 1, 1));
+ lblCssProperties.setText("CSS Properties");
+
+ Label lblCssRules = new Label(container, SWT.NONE);
+ lblCssRules.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false,
+ false, 1, 1));
+ lblCssRules.setText("CSS Rules");
+
+ // // THE CSS PROPERTIES TABLE
+ Composite propsComposite = new Composite(container, SWT.BORDER
+ | SWT.H_SCROLL | SWT.V_SCROLL);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
+ gridData.minimumHeight = 50;
+ propsComposite.setLayoutData(gridData);
+
+ cssPropertiesViewer = new TableViewer(propsComposite, SWT.BORDER
+ | SWT.V_SCROLL | SWT.FULL_SELECTION);
+ cssPropertiesViewer
+ .setContentProvider(new CSSPropertiesContentProvider());
+ cssPropertiesViewer.getTable().setLinesVisible(true);
+ cssPropertiesViewer.getTable().setHeaderVisible(true);
+ cssPropertiesViewer.setComparator(new ViewerComparator());
+
+ final TextCellEditor textCellEditor = new TextCellEditor(
+ cssPropertiesViewer.getTable());
+ TableViewerEditor
+ .create(cssPropertiesViewer,
+ new TableViewerFocusCellManager(cssPropertiesViewer,
+ new FocusCellOwnerDrawHighlighter(
+ cssPropertiesViewer)),
+ new ColumnViewerEditorActivationStrategy(
+ cssPropertiesViewer),
+ ColumnViewerEditor.TABBING_HORIZONTAL
+ | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR
+ | ColumnViewerEditor.TABBING_VERTICAL
+ | ColumnViewerEditor.KEYBOARD_ACTIVATION);
+
+
+ TableViewerColumn propName = new TableViewerColumn(cssPropertiesViewer,
+ SWT.NONE);
+ propName.getColumn().setWidth(100);
+ propName.getColumn().setText("Property");
+ propName.setLabelProvider(new ColumnLabelProvider() {
+ @Override
+ public String getText(Object element) {
+ return ((CSSPropertyProvider) element).getPropertyName();
+ }
+ });
+
+ TableViewerColumn propValue = new TableViewerColumn(
+ cssPropertiesViewer, SWT.NONE);
+ propValue.getColumn().setWidth(100);
+ propValue.getColumn().setText("Value");
+ propValue.setLabelProvider(new ColumnLabelProvider() {
+ @Override
+ public String getText(Object element) {
+ try {
+ return ((CSSPropertyProvider) element).getValue();
+ } catch (Exception e) {
+ System.err.println("Error fetching property: " + element
+ + ": " + e);
+ return null;
+ }
+ }
+ });
+ propValue.setEditingSupport(new EditingSupport(cssPropertiesViewer) {
+ @Override
+ protected CellEditor getCellEditor(Object element) {
+ // do the fancy footwork here to return an appropriate editor to
+ // the value-type
+ return textCellEditor;
+ }
+
+ @Override
+ protected boolean canEdit(Object element) {
+ return true;
+ }
+
+ @Override
+ protected Object getValue(Object element) {
+ try {
+ String value = ((CSSPropertyProvider) element).getValue();
+ return value == null ? "" : value;
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ @Override
+ protected void setValue(Object element, Object value) {
+ try {
+ if(value == null || ((String)value).trim().isEmpty()) { return; }
+ CSSPropertyProvider provider = (CSSPropertyProvider) element;
+ provider.setValue((String) value);
+ } catch (Throwable e) {
+ MessageDialog.openError(getShell(), "Error",
+ "Unable to set property:\n\n"
+ + e.getMessage());
+ }
+ cssPropertiesViewer.update(element, null);
+ }
+ });
+
+ TableColumnLayout propsTableLayout = new TableColumnLayout();
+ propsTableLayout.setColumnData(propName.getColumn(),
+ new ColumnWeightData(50));
+ propsTableLayout.setColumnData(propValue.getColumn(),
+ new ColumnWeightData(50));
+ propsComposite.setLayout(propsTableLayout);
+
+ // / THE CSS RULES
+ cssRules = new Text(container, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL
+ | SWT.MULTI);
+ cssRules.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1,
+ 1));
+
+ // / THE CSS PROPERTIES TABLE (again)
+ showUnsetProperties = new Button(container, SWT.CHECK);
+ showUnsetProperties.setText("Show unset properties");
+
+ // and for balance
+ new Label(container, SWT.NONE);
+
+ // / The listeners
+
+ cssSearchBox.addModifyListener(new ModifyListener() {
+ private Runnable updater;
+
+ public void modifyText(ModifyEvent e) {
+ display.timerExec(200, updater = new Runnable() {
+ public void run() {
+ if (updater == this) {
+ performCSSSearch(cssSearchBox.getText());
+ }
+ }
+ });
+ }
+ });
+ cssSearchBox.addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if (e.keyCode == SWT.ARROW_DOWN
+ && (e.stateMask & SWT.MODIFIER_MASK) == 0) {
+ widgetTreeViewer.getControl().setFocus();
+ }
+ }
+ });
+
+ widgetTreeViewer
+ .addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (!event.getSelection().isEmpty()) {
+ populate((Widget) ((StructuredSelection) event
+ .getSelection()).getFirstElement());
+ }
+ }
+ });
+ if (isLive()) {
+ container.addMouseMoveListener(new MouseMoveListener() {
+ public void mouseMove(MouseEvent e) {
+ update();
+ }
+ });
+ }
+
+ if (shouldDismissOnLostFocus()) {
+ container.addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusLost(FocusEvent e) {
+ setReturnCode(Window.OK);
+ close();
+ }
+ });
+ }
+ container.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ if (e.character == SWT.ESC) {
+ cancelPressed();
+ } else if (e.character == SWT.CR | e.character == SWT.LF) {
+ okPressed();
+ }
+ }
+ });
+
+ outer.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ dispose();
+ }
+ });
+
+ showUnsetProperties.setSelection(true);
+ showUnsetProperties.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (showUnsetProperties.getSelection()) {
+ cssPropertiesViewer.removeFilter(unsetPropertyFilter);
+ } else {
+ cssPropertiesViewer.addFilter(unsetPropertyFilter);
+ }
+ }
+ });
+
+ update();
+ sashForm.setWeights(new int[] { 50, 50 });
+ widgetTreeViewer.getControl().setFocus();
+ return outer;
+ }
+
+ private String searchInProgress;
+
+ private void performCSSSearch(String text) {
+ disposeHighlights();
+ widgetTreeViewer.collapseAll();
+ if (text.trim().isEmpty()) {
+ return;
+ }
+ searchInProgress = text;
+ CSSStylableElement element = getCSSElement(getShell(shown));
+ if (element == null) {
+ return;
+ }
+
+ CSSEngine engine = WidgetElement.getEngine(shown);
+ try {
+ SelectorList selectors = engine.parseSelectors(text);
+ processCSSSearch(text, null, engine, selectors, element);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private void processCSSSearch(String text, String pseudo, CSSEngine engine,
+ SelectorList selectors, CSSStylableElement element) {
+ if (text != searchInProgress) {
+ return;
+ }
+ boolean matched = false;
+ for (int i = 0; i < selectors.getLength(); i++) {
+ if (matched = engine.matches(selectors.item(i), element, pseudo)) {
+ break;
+ }
+ }
+ if (matched) {
+ highlightWidget((Widget) element.getNativeWidget());
+ }
+ NodeList children = element.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ if (text != searchInProgress) {
+ return;
+ }
+ processCSSSearch(text, pseudo, engine, selectors,
+ (CSSStylableElement) children.item(i));
+ }
+ }
+
+ protected void dispose() {
+ disposeHighlights();
+ }
+
+ /**
+ * Create contents of the button bar.
+ *
+ * @param parent
+ */
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
+ true);
+ createButton(parent, IDialogConstants.CANCEL_ID,
+ IDialogConstants.CANCEL_LABEL, false);
+ }
+
+ /**
+ * Return the initial size of the dialog.
+ */
+ @Override
+ protected Point getInitialSize() {
+ return new Point(600, 500);
+ }
+}
diff --git a/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/OpenSpyHandler.java b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/OpenSpyHandler.java
new file mode 100644
index 00000000..7da7582d
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/OpenSpyHandler.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Manumitting Technologies, Inc.
+ * 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
+ *
+ * Contributors:
+ * Brian de Alwis (MT) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.tools.css.spy;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.swt.engine.CSSSWTEngineImpl;
+import org.eclipse.e4.ui.css.swt.internal.theme.ThemeEngine;
+import org.eclipse.e4.ui.css.swt.theme.IThemeEngine;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+
+public class OpenSpyHandler {
+
+ @Inject
+ @Optional
+ protected Display display;
+
+ @Inject
+ protected IEclipseContext context;
+
+ @Inject
+ protected Provider<StatusReporter> reporter;
+
+ @Execute
+ public void openSpy() {
+ Control control = display.getCursorControl();
+ // it may be that only the shell was selected
+ if (control == null) {
+ control = display.getActiveShell();
+ }
+ CssSpyDialog spy = new CssSpyDialog(control.getShell());
+ spy.setSpecimen(control);
+ spy.open();
+ }
+
+ private CSSEngine findCSSEngine() {
+ if(display != null) {
+ Object themeEngine = display.getData("org.eclipse.e4.ui.css.swt.theme");
+ if(themeEngine instanceof ThemeEngine) { return ((ThemeEngine)themeEngine)
+ .getCSSEngine(); }
+ }
+ if(context != null) {
+ Object themeEngine = context.get(IThemeEngine.class);
+ if(themeEngine instanceof ThemeEngine) { return ((ThemeEngine)themeEngine)
+ .getCSSEngine(); }
+ }
+ // otherwise just create a copy of the engine.
+ return new CSSSWTEngineImpl(display, true);
+ }
+}
diff --git a/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/SpyInstaller.java b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/SpyInstaller.java
new file mode 100644
index 00000000..87f65e54
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/SpyInstaller.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Manumitting Technologies, Inc.
+ * 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
+ *
+ * Contributors:
+ * Brian de Alwis (MT) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.tools.css.spy;
+
+import javax.inject.Inject;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.commands.MBindingContext;
+import org.eclipse.e4.ui.model.application.commands.MBindingTable;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
+import org.eclipse.e4.ui.model.application.commands.MCommandsFactory;
+import org.eclipse.e4.ui.model.application.commands.MHandler;
+import org.eclipse.e4.ui.model.application.commands.MKeyBinding;
+
+public class SpyInstaller {
+ public static final String OPEN_SPY_COMMAND_ID = "org.eclipse.e4.css.OpenSpy";
+ private static final String SPY_HANDLER_ID = OpenSpyHandler.class.getName();
+ private static final String SPY_HANDLER_URI = "platform:/plugin/org.eclipse.e4.tools.css.spy/"
+ + OpenSpyHandler.class.getName();
+
+ @Inject
+ protected MApplication app;
+
+ @Execute
+ public void execute() {
+ MCommand cmd = installSpyCommand();
+ installSpyHandler(cmd);
+ installSpyBinding("org.eclipse.ui.contexts.dialogAndWindow", cmd, "M2+M3+F4");
+ }
+
+ private MCommand installSpyCommand() {
+ for(MCommand cmd : app.getCommands()) {
+ if(OPEN_SPY_COMMAND_ID.equals(cmd.getElementId())) {
+ System.err.println("CSS Spy command already setup");
+ return cmd;
+ }
+ }
+
+ MCommand cmd = MCommandsFactory.INSTANCE.createCommand();
+ cmd.setCommandName("Open CSS Spy");
+ cmd.setElementId(OPEN_SPY_COMMAND_ID);
+ app.getCommands().add(cmd);
+ return cmd;
+ }
+
+ private MHandler installSpyHandler(MCommand cmd) {
+ for(MHandler hdlr : app.getHandlers()) {
+ if(SPY_HANDLER_ID.equals(hdlr.getElementId())) {
+ System.err.println("CSS Spy handler already setup");
+ return hdlr;
+ }
+ }
+
+ MHandler hdlr = MCommandsFactory.INSTANCE.createHandler();
+ hdlr.setElementId(SPY_HANDLER_ID);
+ hdlr.setContributionURI(SPY_HANDLER_URI);
+ hdlr.setCommand(cmd);
+ app.getHandlers().add(hdlr);
+ return hdlr;
+ }
+
+ private void installSpyBinding(String bindingContextId, MCommand cmd, String keySeq) {
+ for(MBindingTable table : app.getBindingTables()) {
+ for(MKeyBinding binding : table.getBindings()) {
+ if(binding.getCommand() == cmd) {
+ System.err.println("Spy binding already installed");
+ return;
+ }
+ }
+ }
+
+ MBindingContext context = null;
+ for(MBindingContext ctxt : app.getBindingContexts()) {
+ if(ctxt.getElementId().equals(bindingContextId)) {
+ context = ctxt;
+ break;
+ }
+ }
+ if(context == null) {
+ System.err.println("Cannot find binding context: " + bindingContextId);
+ return;
+ }
+
+ MBindingTable bindingTable = null;
+ String tableId = "bt." + cmd.getElementId();
+ for(MBindingTable table : app.getBindingTables()) {
+ if(tableId.equals(table.getElementId())) {
+ bindingTable = table;
+ }
+ }
+
+ if(bindingTable == null) {
+ bindingTable = MCommandsFactory.INSTANCE.createBindingTable();
+ bindingTable.setElementId(tableId);
+ bindingTable.setBindingContext(context);
+ app.getBindingTables().add(bindingTable);
+ }
+
+ MKeyBinding binding = MCommandsFactory.INSTANCE.createKeyBinding();
+ binding.setCommand(cmd);
+ binding.setKeySequence(keySeq);
+ binding.setElementId("kb." + cmd.getElementId());
+ bindingTable.getBindings().add(binding);
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/WidgetTreeProvider.java b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/WidgetTreeProvider.java
new file mode 100644
index 00000000..605ffb81
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/WidgetTreeProvider.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Manumitting Technologies, Inc.
+ * 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
+ *
+ * Contributors:
+ * Brian de Alwis (MT) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.tools.css.spy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.e4.ui.css.core.dom.CSSStylableElement;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Control;
+import org.w3c.dom.NodeList;
+
+public class WidgetTreeProvider implements ITreeContentProvider {
+ private static final Object[] EMPTY_ARRAY = new Object[0];
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof Object[]) {
+ return (Object[]) inputElement;
+ } else if (inputElement instanceof Collection< ? >) {
+ return ((Collection< ? >) inputElement).toArray();
+ }
+ return getChildren(inputElement);
+ }
+
+
+ public Object[] getChildren(Object parentElement) {
+ CSSStylableElement element = CssSpyDialog.getCSSElement(parentElement);
+ if (element == null) {
+ return new Object[0];
+ }
+ NodeList kids = element.getChildNodes();
+ ArrayList<Object> children = new ArrayList<Object>(kids.getLength());
+ for (int i = 0; i < kids.getLength(); i++) {
+ children.add(((CSSStylableElement) kids.item(i)).getNativeWidget());
+ }
+ // if (parentElement instanceof Shell) {
+ // // ToolBar is part of the children
+ // //Collections.addAll(children, ((Shell) parentElement).getToolBar());
+ // Collections.addAll(children, ((Shell) parentElement).getMenuBar());
+ // }
+ // if (parentElement instanceof Menu) {
+ // Collections.addAll(children, ((Menu) parentElement).getItems());
+ // }
+ // if (parentElement instanceof ToolBar) {
+ // Collections.addAll(children, ((ToolBar) parentElement).getItems());
+ // }
+ // if (parentElement instanceof Composite) {
+ // Collections.addAll(children, ((Composite) parentElement).getChildren());
+ // }
+ return children.toArray();
+ }
+
+ public Object getParent(Object element) {
+ // if(element instanceof Item) {
+ // return ((Item)element).get???
+ // }
+ return ((Control) element).getParent();
+ }
+
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length > 0;
+ }
+
+ public void dispose() {
+ }
+
+}
diff --git a/features/org.eclipse.e4.tools.css.spy.feature/.classpath b/features/org.eclipse.e4.tools.css.spy.feature/.classpath
new file mode 100644
index 00000000..fb501163
--- /dev/null
+++ b/features/org.eclipse.e4.tools.css.spy.feature/.classpath
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/features/org.eclipse.e4.tools.css.spy.feature/.project b/features/org.eclipse.e4.tools.css.spy.feature/.project
new file mode 100644
index 00000000..5f79d73d
--- /dev/null
+++ b/features/org.eclipse.e4.tools.css.spy.feature/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.tools.css.spy.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.tools.css.spy.feature/build.properties b/features/org.eclipse.e4.tools.css.spy.feature/build.properties
new file mode 100644
index 00000000..3dca147b
--- /dev/null
+++ b/features/org.eclipse.e4.tools.css.spy.feature/build.properties
@@ -0,0 +1,4 @@
+source.Eclipse.org/ = src/
+output.Eclipse.org/ = bin/
+bin.includes = feature.xml,\
+ Eclipse.org/
diff --git a/features/org.eclipse.e4.tools.css.spy.feature/feature.xml b/features/org.eclipse.e4.tools.css.spy.feature/feature.xml
new file mode 100644
index 00000000..62e8b9ab
--- /dev/null
+++ b/features/org.eclipse.e4.tools.css.spy.feature/feature.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.e4.tools.css.spy.feature"
+ label="CSS Spy Feature"
+ version="0.0.0.qualifier">
+ <install-handler library="Eclipse.org/"/>
+
+ <description url="http://www.example.com/description">
+ [Enter Feature Description here.]
+ </description>
+
+ <copyright url="http://www.example.com/copyright">
+ [Enter Copyright Description here.]
+ </copyright>
+
+ <license url="http://www.example.com/license">
+ [Enter License Description here.]
+ </license>
+
+ <requires>
+ <import plugin="org.eclipse.e4.ui.css.core" version="0.9.0" match="greaterOrEqual"/>
+ <import plugin="org.eclipse.swt" version="3.6.0" match="greaterOrEqual"/>
+ <import plugin="org.eclipse.jface" version="3.8.0" match="greaterOrEqual"/>
+ <import plugin="org.w3c.css.sac"/>
+ </requires>
+
+ <plugin
+ id="org.eclipse.e4.tools.css.spy"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>

Back to the top