diff options
Diffstat (limited to 'bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CssSpyPart.java')
-rw-r--r-- | bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CssSpyPart.java | 912 |
1 files changed, 0 insertions, 912 deletions
diff --git a/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CssSpyPart.java b/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CssSpyPart.java deleted file mode 100644 index 8a974132..00000000 --- a/bundles/org.eclipse.e4.tools.css.spy/src/org/eclipse/e4/tools/css/spy/CssSpyPart.java +++ /dev/null @@ -1,912 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011, 2016 Manumitting Technologies, Inc. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Brian de Alwis (MT) - initial API and implementation - * Olivier Prouvost <olivier.prouvost@opcoach.com> - Bug 428903 - *******************************************************************************/ -package org.eclipse.e4.tools.css.spy; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.inject.Inject; -import javax.inject.Named; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.e4.core.contexts.IEclipseContext; -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.e4.ui.css.swt.engine.CSSSWTEngineImpl; -import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.services.IServiceConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -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.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -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.swt.SWT; -import org.eclipse.swt.custom.CTabItem; -import org.eclipse.swt.custom.SashForm; -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.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -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.CSSParseException; -import org.w3c.css.sac.SelectorList; -import org.w3c.dom.NodeList; -import org.w3c.dom.css.CSSStyleDeclaration; -import org.w3c.dom.css.CSSValue; - -@SuppressWarnings("restriction") -public class CssSpyPart { - - @Inject - @Named(IServiceConstants.ACTIVE_SHELL) - private Shell activeShell; - - /** - * @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 { - CSSEngine engine = getCSSEngine(o); - if (engine != null) { - return (CSSStylableElement) engine.getElement(o); - } - } - return null; - } - - /** @return the CSS engine governing the argument, or null if none */ - public static CSSEngine getCSSEngine(Object o) { - CSSEngine engine = null; - if (o instanceof CSSStylableElement) { - CSSStylableElement element = (CSSStylableElement) o; - engine = WidgetElement.getEngine((Widget) element.getNativeWidget()); - } - if (engine == null && o instanceof Widget) { - if (((Widget) o).isDisposed()) { - return null; - } - engine = WidgetElement.getEngine((Widget) o); - } - if (engine == null && Display.getCurrent() != null) { - engine = new CSSSWTEngineImpl(Display.getCurrent()); - } - return engine; - } - - @Inject - private Display display; - - private Widget specimen; // specimen (can be reused if reopened) - - @Inject - IEclipseContext mpartContext; // Used to remember of last specimen. - - private Widget shown; - - private TreeViewer widgetTreeViewer; - private WidgetTreeProvider widgetTreeProvider; - private Button followSelection; - private Button showAllShells; - private TableViewer cssPropertiesViewer; - private Text cssRules; - - private List<Shell> highlights = new LinkedList<>(); - private List<Region> highlightRegions = new LinkedList<>(); - private Text cssSearchBox; - private Button showUnsetProperties; - private Button showCssFragment; - - 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; - } - }; - - private Composite outer; - - 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 void update() { - if (activeShell == null) { - return; - } - Widget current = getActiveSpecimen(); - if (shown == current) { - return; - } - shown = current; - - CSSEngine engine = getCSSEngine(shown); - CSSStylableElement element = (CSSStylableElement) engine.getElement(shown); - if (element == null) { - return; - } - - updateWidgetTreeInput(); - revealAndSelect(Collections.singletonList(shown)); - } - - private <T> void revealAndSelect(List<T> elements) { - widgetTreeViewer.setSelection(new StructuredSelection(elements), true); - } - - private void updateForWidgetSelection(ISelection sel) { - disposeHighlights(); - if (sel.isEmpty()) { - return; - } - StructuredSelection selection = (StructuredSelection) sel; - for (Object s : selection.toList()) { - if (s instanceof Widget) { - highlightWidget((Widget) s); - } - } - populate(selection.size() == 1 && selection.getFirstElement() instanceof Widget - ? (Widget) selection.getFirstElement() : null); - } - - private void updateWidgetTreeInput() { - if (showAllShells.getSelection()) { - widgetTreeViewer.setInput(display); - } else { - widgetTreeViewer.setInput(new Object[] { shown instanceof Control ? ((Control) shown).getShell() : shown }); - } - performCSSSearch(new NullProgressMonitor()); - } - - protected void populate(Widget selected) { - if (selected == null) { - cssPropertiesViewer.setInput(null); - cssRules.setText(""); - return; - } - if (selected.isDisposed()) { - cssPropertiesViewer.setInput(null); - cssRules.setText("*DISPOSED*"); - return; - } - - CSSStylableElement element = getCSSElement(selected); - if (element == null) { - cssPropertiesViewer.setInput(null); - cssRules.setText("Not a stylable element"); - 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 "); - Util.join(sb, element.getCSSStyle().split(";"), ";\n "); - } - - if (decl != null) { - sb.append("\n\nCSS Properties:\n"); - try { - if (decl != null) { - sb.append(decl.getCssText()); - } - } catch (Exception e) { - sb.append(e); - } - } - if (element.getStaticPseudoInstances().length > 0) { - sb.append("\n\nStatic Pseudoinstances:\n "); - Util.join(sb, element.getStaticPseudoInstances(), "\n "); - } - - if (element.getCSSClass() != null) { - sb.append("\n\nCSS Classes:\n "); - Util.join(sb, element.getCSSClass().split(" +"), "\n "); - } - - if (element.getCSSId() != null) { - sb.append("\n\nCSS ID:\n "); - Util.join(sb, element.getCSSId().split(" +"), "\n "); - } - - if (element.getAttribute("style") != null) { - sb.append("\n\nSWT Style Bits:\n "); - Util.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 Shell && ((Shell) element.getNativeWidget()).getParent() != null) { - Shell nw = (Shell) element.getNativeWidget(); - sb.append("\n\nShell parent: ").append(nw.getParent()); - } - if (element.getNativeWidget() instanceof Composite) { - Composite nw = (Composite) element.getNativeWidget(); - sb.append("\n\nSWT Layout: ").append(nw.getLayout()); - } - Rectangle bounds = getBounds(selected); - if (bounds != null) { - sb.append("\nBounds: x=").append(bounds.x).append(" y=").append(bounds.y); - sb.append(" h=").append(bounds.height).append(" w=").append(bounds.width); - } - - if (element.getNativeWidget() instanceof Widget) { - Widget w = (Widget) element.getNativeWidget(); - if (w.getData() != null) { - sb.append("\nWidget data: ").append(w.getData()); - } - if (w.getData(SWT.SKIN_ID) != null) { - sb.append("\nWidget Skin ID (").append(SWT.SKIN_ID).append("): ").append(w.getData(SWT.SKIN_ID)); - } - if (w.getData(SWT.SKIN_CLASS) != null) { - sb.append("\nWidget Skin Class (").append(SWT.SKIN_CLASS).append("): ") - .append(w.getData(SWT.SKIN_CLASS)); - } - } - - cssRules.setText(sb.toString().trim()); - - disposeHighlights(); - highlightWidget(selected); - } - - private Shell getShell(Widget widget) { - if (widget instanceof Control) { - return ((Control) widget).getShell(); - } - return null; - } - - /** Add a highlight-rectangle for the selected widget */ - private void highlightWidget(Widget selected) { - if (selected == null || selected.isDisposed()) { - return; - } - - 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); - // create the highlight; want it to appear on top - Shell highlight = new Shell(selectedShell, SWT.NO_TRIM | SWT.MODELESS | SWT.NO_FOCUS | SWT.ON_TOP); - highlight.setBackground(display.getSystemColor(SWT.COLOR_RED)); - // set CSS ID for the dark theme - highlight.setData("org.eclipse.e4.ui.css.id", "css-spy"); - 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 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); - } else if (widget instanceof CTabItem) { - CTabItem item = (CTabItem) 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 spy. - * - * @param parent - */ - @PostConstruct - protected Control createDialogArea(Composite parent, IEclipseContext ctx) { - outer = parent; - outer.setLayout(new GridLayout()); - outer.setLayoutData(new GridData(GridData.FILL_BOTH)); - - Composite top = new Composite(outer, SWT.NONE); - GridLayoutFactory.swtDefaults().numColumns(3).applyTo(top); - cssSearchBox = new Text(top, SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL); - cssSearchBox.setMessage("CSS Selector"); - cssSearchBox.setToolTipText("Highlight matching widgets"); - GridDataFactory.fillDefaults().grab(true, false).applyTo(cssSearchBox); - - followSelection = new Button(top, SWT.CHECK); - followSelection.setSelection(true); - followSelection.setText("Follow UI Selection"); - GridDataFactory.swtDefaults().applyTo(followSelection); - - showAllShells = new Button(top, SWT.CHECK); - showAllShells.setText("All shells"); - GridDataFactory.swtDefaults().applyTo(showAllShells); - - GridDataFactory.fillDefaults().applyTo(top); - - 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 | SWT.MULTI); - widgetTreeProvider = new WidgetTreeProvider(); - widgetTreeViewer.setContentProvider(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 = CssSpyPart.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 = CssSpyPart.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 = CssSpyPart.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 "); - Util.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 = CssSpyPart.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); - 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.H_SCROLL | 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().length() == 0) { - return; - } - CSSPropertyProvider provider = (CSSPropertyProvider) element; - provider.setValue((String) value); - } catch (Exception e) { - MessageDialog.openError(activeShell, "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"); - showCssFragment = new Button(container, SWT.PUSH); - showCssFragment.setText("Show CSS fragment"); - showCssFragment.setToolTipText("Generates CSS rule block for the selected widget"); - - // and for balance - new Label(container, SWT.NONE); - - // / The listeners - - cssSearchBox.addModifyListener(new ModifyListener() { - private Runnable updater; - private IProgressMonitor monitor; - - @Override - public void modifyText(ModifyEvent e) { - if (monitor != null) { - monitor.setCanceled(false); - } - display.timerExec(200, updater = new Runnable() { - @Override - public void run() { - if (updater == this) { - performCSSSearch(monitor = new NullProgressMonitor()); - } - } - }); - } - }); - 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(event -> { - updateForWidgetSelection(event.getSelection()); - showCssFragment.setEnabled(!event.getSelection().isEmpty()); - }); - if (isLive()) { - container.addMouseMoveListener(e -> { - if (followSelection.getSelection()) { - update(); - } - } - ); - } - - showAllShells.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - updateWidgetTreeInput(); - } - }); - - outer.addDisposeListener(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); - } - } - }); - - showCssFragment.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - showCssFragment(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - widgetSelected(e); - } - }); - - sashForm.setWeights(new int[] { 50, 50 }); - widgetTreeViewer.getControl().setFocus(); - - return outer; - } - - /** - * This method listen to current part and adapt the contents of spy part. - */ - @Inject - protected void reactOnActivate(@Named(IServiceConstants.ACTIVE_PART) MPart p, MPart cssPart, - @Named(IServiceConstants.ACTIVE_SHELL) Shell s) { - if (followSelection == null || !followSelection.getSelection()) { - return; - } - if (outer == null) { - // Do nothing if no UI created. - return; - } - activeShell = s; - - // Check if control is in the css spy part shell. - Control control = display.getCursorControl(); - - Shell controlShell = (control == null) ? display.getActiveShell() : control.getShell(); - Shell spyPartShell = outer.getShell(); - - if (p != cssPart) { - // Must remove the highlights if selected - disposeHighlights(); - - } else if (spyPartShell != controlShell) { - // A widget has been selected in another shell.. We can display the - // corresponding control as a specimen - shown = null; - setSpecimen(control); - } - - } - - protected void showCssFragment() { - if (!(widgetTreeViewer.getSelection() instanceof IStructuredSelection) - || widgetTreeViewer.getSelection().isEmpty()) { - return; - } - - StringBuilder sb = new StringBuilder(); - for (Object o : ((IStructuredSelection) widgetTreeViewer.getSelection()).toArray()) { - if (o instanceof Widget) { - if (sb.length() > 0) { - sb.append('\n'); - } - addCssFragment((Widget) o, sb); - } - } - TextPopupDialog tpd = new TextPopupDialog(widgetTreeViewer.getControl().getShell(), "CSS", sb.toString(), true, - "Escape to dismiss"); - tpd.open(); - } - - private void addCssFragment(Widget w, StringBuilder sb) { - CSSStylableElement element = getCSSElement(w); - if (element == null) { - return; - } - - sb.append(element.getLocalName()); - if (element.getCSSId() != null) { - sb.append("#").append(element.getCSSId()); - } - sb.append(" {"); - - CSSEngine engine = getCSSEngine(element); - // we first check the viewCSS and then the property values - CSSStyleDeclaration decl = engine.getViewCSS().getComputedStyle(element, null); - - List<String> propertyNames = new ArrayList<>(engine.getCSSProperties(element)); - Collections.sort(propertyNames); - - int count = 0; - - // First list the generated properties - for (Iterator<String> iter = propertyNames.iterator(); iter.hasNext();) { - String propertyName = iter.next(); - String genValue = trim(engine.retrieveCSSProperty(element, propertyName, "")); - String declValue = null; - - if (genValue == null) { - continue; - } - - if (decl != null) { - CSSValue cssValue = decl.getPropertyCSSValue(propertyName); - if (cssValue != null) { - declValue = trim(cssValue.getCssText()); - } - } - if (count == 0) { - sb.append("\n /* actual values */"); - } - sb.append("\n ").append(propertyName).append(": ").append(genValue).append(";"); - if (declValue != null) { - sb.append("\t/* declared in CSS: ").append(declValue).append(" */"); - } - count++; - iter.remove(); // remove so we don't re-report below - } - - // then list any declared properties; generated properties already - // removed - if (decl != null) { - int declCount = 0; - for (String propertyName : propertyNames) { - String declValue = null; - CSSValue cssValue = decl.getPropertyCSSValue(propertyName); - if (cssValue != null) { - declValue = trim(cssValue.getCssText()); - } - if (declValue == null) { - continue; - } - if (declCount == 0) { - sb.append("\n\n /* declared in CSS rules */"); - } - sb.append("\n ").append(propertyName).append(": ").append(declValue).append(";"); - count++; - declCount++; - } - } - sb.append(count > 0 ? "\n}" : "}"); - } - - /** Trim the string; return null if empty */ - private String trim(String s) { - if (s == null) { - return null; - } - s = s.trim(); - return s.length() > 0 ? s : null; - } - - protected void performCSSSearch(IProgressMonitor progress) { - List<Widget> widgets = new ArrayList<>(); - performCSSSearch(progress, cssSearchBox.getText(), widgets); - if (!progress.isCanceled()) { - revealAndSelect(widgets); - } - } - - private void performCSSSearch(IProgressMonitor monitor, String text, Collection<Widget> results) { - if (text.trim().length() == 0) { - return; - } - widgetTreeViewer.collapseAll(); - Object[] roots = widgetTreeProvider.getElements(widgetTreeViewer.getInput()); - monitor.beginTask("Searching for \"" + text + "\"", roots.length * 10); - for (Object root : roots) { - if (monitor.isCanceled()) { - return; - } - - CSSStylableElement element = getCSSElement(root); - if (element == null) { - continue; - } - - CSSEngine engine = getCSSEngine(root); - try { - SelectorList selectors = engine.parseSelectors(text); - monitor.worked(2); - processCSSSearch(new SubProgressMonitor(monitor, 8), engine, selectors, element, null, results); - } catch (CSSParseException | IOException e) { - System.out.println(e.toString()); - } - } - monitor.done(); - } - - private void processCSSSearch(IProgressMonitor monitor, CSSEngine engine, SelectorList selectors, - CSSStylableElement element, String pseudo, Collection<Widget> results) { - if (monitor.isCanceled()) { - return; - } - NodeList children = element.getChildNodes(); - monitor.beginTask("Searching", 5 + 5 * children.getLength()); - boolean matched = false; - for (int i = 0; i < selectors.getLength(); i++) { - if (matched = engine.matches(selectors.item(i), element, pseudo)) { - break; - } - } - if (matched) { - results.add((Widget) element.getNativeWidget()); - } - monitor.worked(5); - for (int i = 0; i < children.getLength(); i++) { - if (monitor.isCanceled()) { - return; - } - processCSSSearch(new SubProgressMonitor(monitor, 5), engine, selectors, - (CSSStylableElement) children.item(i), pseudo, results); - } - monitor.done(); - } - - protected void dispose() { - disposeHighlights(); - } - -} |