diff --git a/ui/org.eclipse.pde.spy.adapter/.classpath b/ui/org.eclipse.pde.spy.adapter/.classpath new file mode 100644 index 00000000000..375961e4d61 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ui/org.eclipse.pde.spy.adapter/.project b/ui/org.eclipse.pde.spy.adapter/.project new file mode 100644 index 00000000000..a5f9836e6ad --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/.project @@ -0,0 +1,28 @@ + + + org.eclipse.pde.spy.adapter + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/ui/org.eclipse.pde.spy.adapter/.settings/org.eclipse.core.resources.prefs b/ui/org.eclipse.pde.spy.adapter/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000000..99f26c0203a --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/ui/org.eclipse.pde.spy.adapter/.settings/org.eclipse.jdt.core.prefs b/ui/org.eclipse.pde.spy.adapter/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..306cb687c4f --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,15 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=21 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 +encoding/org.eclipse.pde.spy.adapter=UTF-8 \ No newline at end of file diff --git a/ui/org.eclipse.pde.spy.adapter/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.spy.adapter/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..9386a2517af --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/META-INF/MANIFEST.MF @@ -0,0 +1,25 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %name +Bundle-SymbolicName: org.eclipse.pde.spy.adapter;singleton:=true +Bundle-Version: 0.1.0.qualifier +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.swt, + org.eclipse.e4.core.contexts, + org.eclipse.e4.core.di, + org.eclipse.e4.core.services, + org.eclipse.e4.ui.di, + org.eclipse.e4.ui.workbench, + org.eclipse.emf.ecore, + org.eclipse.jface, + org.eclipse.equinox.common, + org.eclipse.e4.ui.services +Bundle-RequiredExecutionEnvironment: JavaSE-21 +Automatic-Module-Name: org.eclipse.pde.spy.adapter +Bundle-ActivationPolicy: lazy +Bundle-Vendor: %provider-name +Import-Package: jakarta.annotation;version="[2.1.0,3.0.0)", + jakarta.inject;version="[2.0.0,3.0.0)" +Bundle-Localization: plugin +Export-Package: org.eclipse.pde.spy.adapter +Require-Capability: eclipse.swt;filter:="(image.format=svg)" diff --git a/ui/org.eclipse.pde.spy.adapter/about.html b/ui/org.eclipse.pde.spy.adapter/about.html new file mode 100644 index 00000000000..3c90a2af4be --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/about.html @@ -0,0 +1,31 @@ + + + + +About + + +

About This Content

+ +

January 30, 2014

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 2.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v20.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

+ + + + + + diff --git a/ui/org.eclipse.pde.spy.adapter/build.properties b/ui/org.eclipse.pde.spy.adapter/build.properties new file mode 100644 index 00000000000..639937d9fc7 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/build.properties @@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + icons/,\ + plugin.xml,\ + plugin.properties diff --git a/ui/org.eclipse.pde.spy.adapter/icons/ext_point_obj.png b/ui/org.eclipse.pde.spy.adapter/icons/ext_point_obj.png new file mode 100644 index 00000000000..60f8dce5bba Binary files /dev/null and b/ui/org.eclipse.pde.spy.adapter/icons/ext_point_obj.png differ diff --git a/ui/org.eclipse.pde.spy.adapter/icons/ext_point_obj@2x.png b/ui/org.eclipse.pde.spy.adapter/icons/ext_point_obj@2x.png new file mode 100644 index 00000000000..b8cd13b201e Binary files /dev/null and b/ui/org.eclipse.pde.spy.adapter/icons/ext_point_obj@2x.png differ diff --git a/ui/org.eclipse.pde.spy.adapter/icons/from_type.png b/ui/org.eclipse.pde.spy.adapter/icons/from_type.png new file mode 100644 index 00000000000..bc915da4420 Binary files /dev/null and b/ui/org.eclipse.pde.spy.adapter/icons/from_type.png differ diff --git a/ui/org.eclipse.pde.spy.adapter/icons/innerinterface_public_obj.png b/ui/org.eclipse.pde.spy.adapter/icons/innerinterface_public_obj.png new file mode 100644 index 00000000000..e091ec43dbd Binary files /dev/null and b/ui/org.eclipse.pde.spy.adapter/icons/innerinterface_public_obj.png differ diff --git a/ui/org.eclipse.pde.spy.adapter/icons/osgi.png b/ui/org.eclipse.pde.spy.adapter/icons/osgi.png new file mode 100644 index 00000000000..15cf6e3af70 Binary files /dev/null and b/ui/org.eclipse.pde.spy.adapter/icons/osgi.png differ diff --git a/ui/org.eclipse.pde.spy.adapter/icons/to_type.png b/ui/org.eclipse.pde.spy.adapter/icons/to_type.png new file mode 100644 index 00000000000..ab848c24925 Binary files /dev/null and b/ui/org.eclipse.pde.spy.adapter/icons/to_type.png differ diff --git a/ui/org.eclipse.pde.spy.adapter/notice.html b/ui/org.eclipse.pde.spy.adapter/notice.html new file mode 100644 index 00000000000..f19c483b9c8 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/notice.html @@ -0,0 +1,108 @@ + + + + + +Eclipse Foundation Software User Agreement + + + +

Eclipse Foundation Software User Agreement

+

February 1, 2011

+ +

Usage Of Content

+ +

THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

+ +

Applicable Licenses

+ +

Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

+ +

Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code + repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").

+ + + +

The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

+ + + +

Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

+ +

THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

+ + + +

IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

+ + +

Use of Provisioning Technology

+ +

The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse + Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or + other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to + install, extend and update Eclipse-based products. Information about packaging Installable Software is available at http://eclipse.org/equinox/p2/repository_packaging.html + ("Specification").

+ +

You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the + applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology + in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the + Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:

+ +
    +
  1. A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology + on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based + product.
  2. +
  3. During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be + accessed and copied to the Target Machine.
  4. +
  5. Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable + Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target + Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern + the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such + indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.
  6. +
+ +

Cryptography

+ +

Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

+ +

Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.

+ + diff --git a/ui/org.eclipse.pde.spy.adapter/plugin.properties b/ui/org.eclipse.pde.spy.adapter/plugin.properties new file mode 100644 index 00000000000..959be25e3a6 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/plugin.properties @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) Lacherp. +# +# 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: +# Lacherp - initial API and implementation +############################################################################### +# +# +name = Adapter Spy +provider-name = Eclipse.org +description = Adapter spy to display the adapter hierarchy \ No newline at end of file diff --git a/ui/org.eclipse.pde.spy.adapter/plugin.xml b/ui/org.eclipse.pde.spy.adapter/plugin.xml new file mode 100644 index 00000000000..4ace6694510 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/plugin.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/AdapterSpyPart.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/AdapterSpyPart.java new file mode 100644 index 00000000000..3250205d1f1 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/AdapterSpyPart.java @@ -0,0 +1,421 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.e4.core.contexts.ContextInjectionFactory; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.ui.di.UISynchronize; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.pde.spy.adapter.model.AdapterData; +import org.eclipse.pde.spy.adapter.model.AdapterRepository; +import org.eclipse.pde.spy.adapter.tools.AdapterHelper; +import org.eclipse.pde.spy.adapter.viewer.AdapterContentProvider; +import org.eclipse.pde.spy.adapter.viewer.AdapterDataComparator; +import org.eclipse.pde.spy.adapter.viewer.AdapterFilter; +import org.eclipse.pde.spy.adapter.viewer.ColumnViewerToolTipSupportCustom; +import org.eclipse.pde.spy.adapter.viewer.FilterData; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +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.Text; +import org.eclipse.swt.widgets.Tree; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; +import jakarta.inject.Inject; +import jakarta.inject.Named; + + +/** + * Adapter Spy part + * @author pascal + * + */ +public class AdapterSpyPart { + + private TreeViewer adapterTreeViewer; + + private AdapterContentProvider adapterContentProvider; + + private static final String NAMED_UPDATE_TREE_SOURCE_TO_DESTINATION = "updateTreeSourceToDestination"; + private static final String NAMED_UPDATE_TREE_DESTINATION_TO_SOURCE = "updateTreeDestinationToSource"; + private static final String SOURCE_TYPE = "Source Type"; + private static final String DESTINATION_TYPE = "Destination Type"; + private static final String DISPLAY_SOURCE_TYPE = "Display " + SOURCE_TYPE; + private static final String DISPLAY_DESTINATION_TYPE = "Display " + DESTINATION_TYPE; + private static final String TOOLTIP_SOURCE_TYPE = "Display the source type first, and list\nall destination types derived from that source as child elements."; + private static final String TOOLTIP_DESTINATION_TYPE = "Display the destination type first, and list\nall source types that can adapt to it as child elements."; + + @Inject + UISynchronize uisync; + + @Inject + IEclipseContext context; + + + @Inject + AdapterRepository adapterRepo; + + @Inject + ESelectionService selectService; + + AdapterFilter adapterFilter; + + boolean sourceToDestination = true; + + private TreeViewerColumn sourceOrDestinationTvc; + + private AdapterDataComparator comparator; + + @Inject + public AdapterSpyPart(IEclipseContext context) { + // wrap eclipse adapter + AdapterHelper.wrapperEclipseAdapter(); + adapterFilter = ContextInjectionFactory.make(AdapterFilter.class, context); + context.set(ImageRegistry.class, AdapterHelper.getImageRegistry(this)); + } + + @PostConstruct + public void createControls(Composite parent, IExtensionRegistry extensionRegistry, ImageRegistry imgr) { + + parent.setLayout(new GridLayout(1, false)); + createToolBarZone(parent, imgr); + + SashForm sashForm = new SashForm(parent, SWT.VERTICAL | SWT.V_SCROLL | SWT.H_SCROLL); + sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + AdapterHelper.getServicesContext().set(AdapterRepository.class, adapterRepo); + adapterRepo.clear(); + + Collection adapterDatalist = adapterRepo.getAdapters(); + + // Adapter TreeViewer + adapterTreeViewer = new TreeViewer(sashForm); + adapterContentProvider = ContextInjectionFactory.make(AdapterContentProvider.class, context); + adapterContentProvider.setColumnIndex(0); + adapterTreeViewer.setContentProvider(adapterContentProvider); + adapterTreeViewer.setLabelProvider(adapterContentProvider); + adapterTreeViewer.setFilters(adapterFilter); + + // add comparator + comparator = new AdapterDataComparator(0); + adapterTreeViewer.setComparator(comparator); + + // define columns + final Tree cTree = adapterTreeViewer.getTree(); + cTree.setHeaderVisible(true); + cTree.setLinesVisible(true); + cTree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + sourceOrDestinationTvc = new TreeViewerColumn(adapterTreeViewer, SWT.NONE); + sourceOrDestinationTvc.getColumn().setText("Source Type"); + sourceOrDestinationTvc.getColumn().setWidth(500); + sourceOrDestinationTvc.setLabelProvider(adapterContentProvider); + cTree.setSortColumn(sourceOrDestinationTvc.getColumn()); + sourceOrDestinationTvc.getColumn().addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + comparator.setColumn(0); + adapterTreeViewer.getTree().setSortDirection(comparator.getDirection()); + adapterTreeViewer.refresh(); + } + }); + sourceOrDestinationTvc.setEditingSupport(new EditingSupport(adapterTreeViewer) { + + @Override + protected void setValue(Object element, Object value) { + } + + @Override + protected Object getValue(Object element) { + return null; + } + + @Override + protected CellEditor getCellEditor(Object element) { + return null; + } + @Override + protected boolean canEdit(Object element) { + if(element instanceof AdapterData) + { + ((AdapterData)element).setSelectedColumn(0); + selectService.setSelection(element); + } + return false; + } + }); + + + TreeViewerColumn adapterFactoryClassTvc = new TreeViewerColumn(adapterTreeViewer, SWT.NONE); + adapterFactoryClassTvc.getColumn().setText("AdapterFactory"); + adapterFactoryClassTvc.getColumn().setWidth(700); + AdapterContentProvider adapterContentProvider2 = ContextInjectionFactory.make(AdapterContentProvider.class, context); + adapterContentProvider2.setColumnIndex(1); + adapterFactoryClassTvc.setLabelProvider(adapterContentProvider2); + adapterFactoryClassTvc.setEditingSupport(new EditingSupport(adapterTreeViewer) { + + @Override + protected void setValue(Object element, Object value) { + } + @Override + protected Object getValue(Object element) { + return null; + } + @Override + protected CellEditor getCellEditor(Object element) { + return null; + } + + @Override + protected boolean canEdit(Object element) { + if(element instanceof AdapterData) + { + ((AdapterData)element).setSelectedColumn(1); + selectService.setSelection(element); + } + return false; + } + }); + + + ColumnViewerToolTipSupportCustom.enableFor(adapterTreeViewer); + context.set(NAMED_UPDATE_TREE_SOURCE_TO_DESTINATION, adapterDatalist); + + } + + @Inject + @Optional + private void updateAdapterTreeViewerSourceToType( + @Named(NAMED_UPDATE_TREE_SOURCE_TO_DESTINATION) Collection adapaters) { + if (adapaters == null) { + return; + } + refreshAdapterTree(NAMED_UPDATE_TREE_SOURCE_TO_DESTINATION, adapaters); + } + + @Inject + @Optional + private void updateAdapterTreeViewTypeToSource( + @Named(NAMED_UPDATE_TREE_DESTINATION_TO_SOURCE) Collection adapaters) { + if (adapaters == null) { + return; + } + // reduce source Type + Collection reduceresult = reduceType(adapaters); + refreshAdapterTree(NAMED_UPDATE_TREE_SOURCE_TO_DESTINATION, reduceresult); + } + + @PreDestroy + public void dispose() { + adapterTreeViewer = null; + if (adapterContentProvider != null) { + ContextInjectionFactory.uninject(adapterContentProvider, context); + } + if (adapterFilter != null) { + ContextInjectionFactory.uninject(adapterFilter, context); + } + AdapterHelper.restoreOriginalEclipseAdapter(); + context.set(AdapterFilter.UPDATE_CTX_FILTER, null); + adapterRepo.clear(); + + } + + @Inject + @Optional + public void handleSelection(@Named(IServiceConstants.ACTIVE_SELECTION) AdapterData adapterDataSelected) { + if (adapterDataSelected == null) { + return; + } + String toCopy =""; + if( adapterDataSelected.getSelectedColumn() == 0 && adapterDataSelected.getParent() == null ) { + toCopy = ((sourceToDestination)? adapterDataSelected.getSourceType():adapterDataSelected.getDestinationType()); + } + if( adapterDataSelected.getSelectedColumn() == 0 && adapterDataSelected.getParent() != null ) { + toCopy = ((sourceToDestination)? adapterDataSelected.getDestinationType():adapterDataSelected.getSourceType()); + } + if( adapterDataSelected.getSelectedColumn() == 1 ) { + if (!sourceToDestination) + toCopy = adapterDataSelected.getAdapterDataParent().getAdapterClassName(); + else + toCopy = adapterDataSelected.getAdapterClassName(); + } + Clipboard clipboard = new Clipboard(null); + try { + TextTransfer textTransfer = TextTransfer.getInstance(); + Transfer[] transfers = new Transfer[] { textTransfer }; + Object[] data = new Object[] { toCopy }; + clipboard.setContents(data, transfers); + } finally { + clipboard.dispose(); + } + + } + + private void createToolBarZone(Composite parent, ImageRegistry imgr) { + final Composite comp = new Composite(parent, SWT.NONE); + comp.setLayout(new GridLayout(4, false)); + + Text filterText = new Text(comp, SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL); + GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.CENTER).hint(250, SWT.DEFAULT).applyTo(filterText); + + filterText.setMessage("Search data"); + filterText.setToolTipText("Find any element in tree"); + + filterText.addModifyListener(e -> { + FilterData fdata = getFilterData(); + if (filterText.getText().isEmpty()) { + fdata.setTxtSearchFilter(""); + } else { + fdata.setTxtSearchFilter(filterText.getText()); + } + context.set(AdapterFilter.UPDATE_CTX_FILTER, fdata); + adapterTreeViewer.refresh(true); + + }); + + Button showPackageFilter = new Button(comp, SWT.CHECK); + showPackageFilter.setText("Show package"); + + showPackageFilter.setToolTipText("Show source type with packages name"); + showPackageFilter.setEnabled(true); + showPackageFilter.setSelection(true); + showPackageFilter.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + FilterData fdata = getFilterData(); + fdata.setShowPackage(!fdata.getShowPackage()); + context.set(AdapterFilter.UPDATE_CTX_FILTER, fdata); + adapterTreeViewer.refresh(true); + } + }); + + // --- Vertical radio buttons to choose display direction --- + Composite radioGroup = new Composite(comp, SWT.NONE); + radioGroup.setLayout(new GridLayout(1, false)); + + Button rbSource = new Button(radioGroup, SWT.RADIO); + rbSource.setText(DISPLAY_SOURCE_TYPE); + rbSource.setToolTipText(TOOLTIP_SOURCE_TYPE); + + Button rbDestination = new Button(radioGroup, SWT.RADIO); + rbDestination.setText(DISPLAY_DESTINATION_TYPE); + rbDestination.setToolTipText(TOOLTIP_DESTINATION_TYPE); + + rbSource.setSelection(sourceToDestination); + rbDestination.setSelection(!sourceToDestination); + + // Factorized refresh logic + Runnable refreshView = () -> { + FilterData fdata = getFilterData(); + fdata.setSourceToDestination(sourceToDestination); + context.set(AdapterFilter.UPDATE_CTX_FILTER, fdata); + + if (sourceToDestination) { + sourceOrDestinationTvc.getColumn().setText(SOURCE_TYPE); + context.set(NAMED_UPDATE_TREE_SOURCE_TO_DESTINATION, adapterRepo.getAdapters()); + } else { + sourceOrDestinationTvc.getColumn().setText(DESTINATION_TYPE); + context.set(NAMED_UPDATE_TREE_DESTINATION_TO_SOURCE, adapterRepo.revertSourceToType()); + } + adapterTreeViewer.refresh(true); + }; + + // Listeners + rbSource.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (rbSource.getSelection()) { + sourceToDestination = true; + refreshView.run(); + } + } + }); + + rbDestination.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (rbDestination.getSelection()) { + sourceToDestination = false; + refreshView.run(); + } + } + }); + + uisync.asyncExec(() -> comp.pack()); + + } + + private FilterData getFilterData() { + if (context.get(AdapterFilter.UPDATE_CTX_FILTER) == null) { + return new FilterData(); + } + return new FilterData((FilterData) context.get(AdapterFilter.UPDATE_CTX_FILTER)); + } + + + + private Collection reduceType(Collection originalList) { + Collection reduceresult = originalList; + + Map> resultmap = groupBy(originalList); + reduceresult.clear(); + resultmap.forEach((k, v) -> { + AdapterData firstElem = v.get(0); + reduceresult.add(firstElem); + for (int idx = 1; idx < v.size(); idx++) { + firstElem.getChildrenList().addAll(v.get(idx).getChildrenList()); + } + }); + + return reduceresult; + } + + private Map> groupBy(Collection originalList) { + return originalList.stream().collect(Collectors.groupingBy(AdapterData::getDestinationType)); + } + + + private void refreshAdapterTree(String namedContext, Collection result) { + uisync.syncExec(() -> { + if (adapterTreeViewer != null) { + adapterTreeViewer.setInput(result); + context.set(namedContext, null); + } + }); + } + +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/Messages.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/Messages.java new file mode 100644 index 00000000000..1f26ba8f76d --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/Messages.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter; + +import org.eclipse.pde.spy.adapter.tools.AdapterHelper; +import org.eclipse.osgi.util.NLS; + +/** + * Messages constant class + * @author pascal + * + */ +public class Messages extends NLS { + + public static String rootSourceTypeTooltip; + public static String rootDestinationTypeToolTip; + public static String childSourceTypeToolTip; + public static String childDestinationTypeToolTip; + public static String adapterFactory; + + + static { + // load message values from bundle file + reloadMessages(); + } + + public static void reloadMessages() { + NLS.initializeMessages(AdapterHelper.BUNDLE_ID+ ".Messages", Messages.class); + } +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/Messages.properties b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/Messages.properties new file mode 100644 index 00000000000..d50b4ba52e6 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/Messages.properties @@ -0,0 +1,25 @@ +################################################################################ +# Copyright (c) Lacherp. +# +# 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: +# Lacherp - initial API and implementation +################################################################################ + +# root node tooltip +rootSourceTypeTooltip = expand this node to know the types in which \"{0}\" can be adapted +rootDestinationTypeToolTip = expand this node to know the types that can be adapted to \"{0}\" + +# child node tooltip +childSourceTypeToolTip = \"{0}\" can be adapted to \"{1}\"\n by the \"{2}\" +childDestinationTypeToolTip = \"{0}\" can be obtained from \"{1}\" using \"{2}\" adapter factory + +# Adapter Factory column +adapterFactory = \"{0}\" adapter factory can transform \"{1}\" to \"{2}\" + diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/hook/EclipseAdapterHook.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/hook/EclipseAdapterHook.java new file mode 100644 index 00000000000..588cb99ff88 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/hook/EclipseAdapterHook.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter.hook; + +import org.eclipse.e4.core.internal.services.EclipseAdapter; + +@SuppressWarnings("restriction") +public class EclipseAdapterHook extends EclipseAdapter { + + + @Override + public T adapt(Object element, Class adapterType) { + return super.adapt(element, adapterType); + } + + +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/model/AdapterData.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/model/AdapterData.java new file mode 100644 index 00000000000..ebd079cfdf2 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/model/AdapterData.java @@ -0,0 +1,464 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.pde.spy.adapter.Messages; +import org.eclipse.pde.spy.adapter.tools.AdapterHelper; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.widgets.Display; +import org.osgi.framework.Bundle; + +/** + * Adapter data model Object This class is used to store ConfigurationElement + * elements which use an adapter + * + * @author pascal + * + */ +public class AdapterData implements Comparable { + + String sourceType; + String destinationType; + String adapterClassName; + boolean isInterface = false; + boolean checkInterfaceClass = false; + AdapterData parent; + List children = new ArrayList<>(); + AdapterElementType elemType; + boolean visibilityFilter = true; + Boolean showPackage; + + int selectedColumn; + + /** + * @return the selectedColumn + */ + public int getSelectedColumn() { + return selectedColumn; + } + + /** + * @param selectedColumn the selectedColumn to set + */ + public void setSelectedColumn(int selectedColumn) { + this.selectedColumn = selectedColumn; + } + + /** + * Ctor + * + * @param elemType + */ + public AdapterData(AdapterElementType elemType) { + this.elemType = elemType; + showPackage = Boolean.TRUE; + } + + public AdapterData(AdapterData adapterData) { + this.elemType = adapterData.getAdapterElementType(); + this.showPackage = Boolean.TRUE; + this.destinationType = adapterData.getDestinationType(); + this.adapterClassName = adapterData.getAdapterClassName(); + this.sourceType = adapterData.getSourceType(); + } + + /** + * propagate visibility to children + */ + public void propagateVisibility() { + children.forEach(d -> { + d.setVisibilityFilter(isVisibilityFilter()); + d.propagateVisibility(); + }); + } + + public void textSearch(String txtSearch, AtomicBoolean bfound) { + + if (bfound.get()) { + return; + } + String txt = this.toString(); + bfound.set(txt.contains(txtSearch)); + // check in adapter class + children.forEach(d -> { + d.textSearch(txtSearch, bfound); + }); + + } + + /** + * @return the sourceType + */ + public String getSourceType() { + return checkNull(sourceType); + } + + /** + * @param sourceType the sourceType to set + */ + public void setSourceType(String sourceType) { + this.sourceType = sourceType; + } + + /** + * @return the destinationType + */ + public String getDestinationType() { + return checkNull(destinationType); + } + + /** + * @param destinationType the destinationType to set + */ + public void setDestinationType(String destinationType) { + this.destinationType = destinationType; + } + + /** + * @return the adapterClassName + */ + public String getAdapterClassName() { + return checkNull(adapterClassName); + } + + /** + * @param adapterClassName the adapterClassName to set + */ + public void setAdapterClassName(String adapterClassName) { + this.adapterClassName = adapterClassName; + } + + public boolean hasChildren() { + return !children.isEmpty(); + } + + public List getChildrenList() { + return this.children; + } + + public Object getChildren(boolean sourceToDestination) { + if (!children.isEmpty()) { + Collections.sort(children); + if( sourceToDestination) { + Map> childs = children.stream().collect(Collectors.groupingBy(AdapterData::getDestinationType)); + children.clear(); + childs.values().forEach(ls-> children.add(ls.get(0))); + return children.toArray(); + }else { + Map> childs = children.stream().collect(Collectors.groupingBy(AdapterData::getSourceType)); + children.clear(); + childs.values().forEach(ls-> children.add(ls.get(0))); + return children.toArray(); + } + } + return new AdapterData[0]; + } + + public Object getParent() { + return this.parent; + } + + public AdapterData getAdapterDataParent() { + return (AdapterData) this.parent; + } + + public void setParent(AdapterData parent) { + this.parent = parent; + } + + public AdapterElementType getAdapterElementType() { + return this.elemType; + } + + /** + * @return the isInterface + */ + public boolean isInterface() { + return isInterface; + } + + /** + * @param isInterface the isInterface to set + */ + public void setInterface(boolean isInterface) { + this.isInterface = isInterface; + } + + /** + * @return the showPackage + */ + public boolean isShowPackage() { + return showPackage; + } + + /** + * @param showPackage the showPackage to set + */ + public void setShowPackage(boolean showPackage) { + this.showPackage = showPackage; + } + + public String getText(int columnIndex) { + if (columnIndex == 0) { + return elemType.equals(AdapterElementType.SOURCE_TYPE) ? displayPackage(getSourceType()) + : displayPackage(getDestinationType()); + } + if (columnIndex == 1 && getParent() != null) { + + return elemType.equals(AdapterElementType.DESTINATION_TYPE) ? displayPackage(getAdapterClassName()) + : displayPackage(((AdapterData) getParent()).getAdapterClassName()); + } + return ""; + } + + public String getImageName() { + String className = elemType.equals(AdapterElementType.SOURCE_TYPE) ? getSourceType():getDestinationType(); + if (elemType.equals(AdapterElementType.DESTINATION_TYPE)) { + return AdapterHelper.DESTINATION_TYPE_IMG_KEY; + } + if(!checkInterfaceClass) { + Bundle bundle = AdapterHelper.getBundleForClassName(className); + if (bundle != null) + setInterface(AdapterHelper.isInterfaceTypeClass(bundle, className)); + else { + // may be it's an interface + if (subStringPackage(className).startsWith("I")) { + return AdapterHelper.INTERFACE_IMG_KEY; + } + return AdapterHelper.SOURCE_TYPE_IMG_KEY; + } + checkInterfaceClass = true; + } + if (elemType.equals(AdapterElementType.SOURCE_TYPE)) { + if( isInterface()) { + return AdapterHelper.INTERFACE_IMG_KEY; + } + return AdapterHelper.SOURCE_TYPE_IMG_KEY; + } + + return null; + + } + + /** + * @return the visibilityFilter + */ + public boolean isVisibilityFilter() { + return visibilityFilter; + } + + /** + * @param visibilityFilter the visibilityFilter to set + */ + public void setVisibilityFilter(boolean visibilityFilter) { + this.visibilityFilter = visibilityFilter; + } + + public Stream convertSourceToType() { + final ArrayList result = new ArrayList<>(); + this.getChildrenList().forEach(child -> { + AdapterData newAdapterData = new AdapterData(child); + AdapterData soon = new AdapterData(this); + soon.setParent(child); + newAdapterData.getChildrenList().add(soon); + + result.add(newAdapterData); + }); + return result.stream(); + } + + @Override + public String toString() { + return getSourceType() + "@" + getDestinationType() + getAdapterClassName(); + } + + + @Override + public int compareTo(AdapterData o) { + return this.getText(0).compareTo(o.getText(0)); + } + + public String getToolTipText(boolean sourceToDestination, int columnIndex) { + + if (columnIndex == 1) { + return getAdapterClassName().isEmpty() ? "" : getAdapterFactorySourceTooltip(); + } + // column 0 + if (sourceToDestination && getParent() == null) { + return getRootSourceTypeTooltip(); + } + if (!sourceToDestination && getParent() == null) { + return getRootDesinationTypeTooltip(); + } + if (sourceToDestination && getParent() != null) { + return getChildSourceTypeToolTip(); + } + return getChildDestinationTypeToolTip(); + + } + + public StyleRange[] getToolTipStyleRanges(Boolean sourceToDestination, int columnIndex) { + if (columnIndex == 1) { + return getAdapterClassName().isEmpty() ? null : getAdapterFactorySourceTooltipStyleRanges(); + } + // column 0 + if (sourceToDestination && getParent() == null) { + return getRootSourceTypeTooltipStyleRanges(); + } + if (!sourceToDestination && getParent() == null) { + return getRootDesinationTypeTooltipStyleRanges(); + } + if (sourceToDestination && getParent() != null) { + return getChildSourceTypeToolTipStyleRanges(); + } + return getChildDestinationTypeToolTipStyleRanges(); + + } + + private String getRootSourceTypeTooltip() { + return NLS.bind(Messages.rootSourceTypeTooltip, subStringPackage(getSourceType())); + } + + private String getRootDesinationTypeTooltip() { + return NLS.bind(Messages.rootDestinationTypeToolTip, subStringPackage(getDestinationType())); + } + + private String getAdapterFactorySourceTooltip() { + List bindings = Arrays.asList(subStringPackage(getAdapterClassName()), + subStringPackage(((AdapterData) getParent()).getSourceType()), concatChildren(true)); + return NLS.bind(Messages.adapterFactory, bindings.toArray()); + } + + private String getChildDestinationTypeToolTip() { + List bindings = Arrays.asList(subStringPackage(getSourceType()), + subStringPackage(((AdapterData) getParent()).getDestinationType()), + subStringPackage(((AdapterData) getParent()).getAdapterClassName())); + return NLS.bind(Messages.childDestinationTypeToolTip, bindings.toArray()); + } + + private String getChildSourceTypeToolTip() { + List bindings = Arrays.asList(subStringPackage(((AdapterData) getParent()).getSourceType()), + subStringPackage(getDestinationType()), subStringPackage(getAdapterClassName())); + return NLS.bind(Messages.childSourceTypeToolTip, bindings.toArray()); + } + + private StyleRange[] getAdapterFactorySourceTooltipStyleRanges() { + int length0 = subStringPackage(getAdapterClassName()).length(); + int length1 =subStringPackage(((AdapterData) getParent()).getSourceType()).length(); + int length2 = concatChildren(true).length(); + + StyleRange [] styleRanges = new StyleRange[4]; + styleRanges[0] = getBoldStyle(0, length0); + styleRanges[1] = getStandard(length0+1, 30); + styleRanges[2] = getBoldStyle(length0+31, length1); + styleRanges[3] = getBoldStyle(length0+35+length1, length2); + + return styleRanges; + } + + private StyleRange[] getRootSourceTypeTooltipStyleRanges() { + StyleRange [] styleRanges = new StyleRange[2]; + styleRanges[0] = getStandard(0, 43); + styleRanges[1] = getBoldStyle(44, subStringPackage(getSourceType()).length()); + return styleRanges; + } + + private StyleRange[] getRootDesinationTypeTooltipStyleRanges() { + StyleRange [] styleRanges = new StyleRange[2]; + styleRanges[0] = getStandard(0, 57); + styleRanges[1] = getBoldStyle(58, subStringPackage(getDestinationType()).length()); + return styleRanges; + } + + private StyleRange[] getChildSourceTypeToolTipStyleRanges() { + + int length0 = subStringPackage(((AdapterData) getParent()).getSourceType()).length(); + int length1 = subStringPackage(getDestinationType()).length(); + int length2 = subStringPackage(getAdapterClassName()).length(); + StyleRange [] styleRanges = new StyleRange[4]; + styleRanges[0] = getBoldStyle(0, length0); + styleRanges[1] = getStandard(length0+1, 18); + styleRanges[2] = getBoldStyle(length0+19, length1); + styleRanges[3] = getBoldStyle(length0+28+length1, length2); + return styleRanges; + } + + private StyleRange[] getChildDestinationTypeToolTipStyleRanges() { + + int length0 = subStringPackage(getSourceType()).length(); + int length1 = subStringPackage(((AdapterData) getParent()).getDestinationType()).length(); + int length2 = subStringPackage(((AdapterData) getParent()).getAdapterClassName()).length(); + StyleRange [] styleRanges = new StyleRange[4]; + styleRanges[0] = getBoldStyle(0, length0); + styleRanges[1] = getStandard(length0+1, 20); + styleRanges[2] = getBoldStyle(length0+22, length1); + styleRanges[3] = getBoldStyle(length0+28+length1, length2); + return styleRanges; + } + + private StyleRange getStandard(int start,int length) { + StyleRange styleRange = new StyleRange(); + styleRange.start = start; + styleRange.length = length; + styleRange.fontStyle = SWT.NORMAL; + styleRange.foreground = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); + return styleRange; + } + + private StyleRange getBoldStyle(int start,int length) { + StyleRange styleRange = new StyleRange(); + styleRange.start = start; + styleRange.length = length; + styleRange.fontStyle = SWT.BOLD; + styleRange.foreground = Display.getDefault().getSystemColor(SWT.COLOR_BLUE); + return styleRange; + } + + private String checkNull(String val) { + return (val == null) ? "" : val; + } + + private String displayPackage(String value) { + if (Boolean.TRUE.equals(showPackage)) { + return value; + } + return subStringPackage(value); + } + + + + private String subStringPackage(String value) { + return value.substring(value.lastIndexOf(".") + 1, value.length()); + } + + private String concatChildren(boolean sourceToDestination) { + if (sourceToDestination) + return ((AdapterData) getParent()).children.stream().map((a) -> a.subStringPackage(a.getDestinationType())) + .collect(Collectors.joining(", ")); + else + return ""; + } + +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/model/AdapterElementType.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/model/AdapterElementType.java new file mode 100644 index 00000000000..018284e31ee --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/model/AdapterElementType.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter.model; + +public enum AdapterElementType { + PLUGIN, + SOURCE_TYPE, + DESTINATION_TYPE; +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/model/AdapterRepository.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/model/AdapterRepository.java new file mode 100644 index 00000000000..534fe416ad9 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/model/AdapterRepository.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +import org.eclipse.core.internal.runtime.AdapterManager; +import org.eclipse.core.internal.runtime.IAdapterFactoryExt; +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.e4.core.di.annotations.Creatable; +import org.eclipse.pde.spy.adapter.tools.AdapterHelper; + +import jakarta.inject.Inject; +import jakarta.inject.Singleton; + + +@SuppressWarnings("restriction") +@Creatable +@Singleton +public class AdapterRepository { + + @Inject + IExtensionRegistry extensionRegistry; + + Map sourceTypeToAdapterDataMap = new HashMap<>(); + Map destinationTypeToAdapterDataMap = new HashMap<>(); + List configEleme; + + public Collection getAdapters() { + + if(!sourceTypeToAdapterDataMap.isEmpty()) { + return sourceTypeToAdapterDataMap.values(); + } + + Map> factories = Collections.synchronizedMap(AdapterManager.getDefault().getFactories()); + AtomicReference refAdapterData= new AtomicReference<>(); + factories.forEach( (k,v) -> { + + if (!sourceTypeToAdapterDataMap.containsKey(k)) + { + AdapterData adapData = new AdapterData(AdapterElementType.SOURCE_TYPE); + adapData.setSourceType(k); + sourceTypeToAdapterDataMap.put(k, adapData); + } + refAdapterData.set(sourceTypeToAdapterDataMap.get(k)); + final List configsForSourceType = getAdapterFactoryClassFromExtension(k); + v.forEach(l -> { + if( l instanceof IAdapterFactoryExt) { + + IAdapterFactoryExt adapfext = (IAdapterFactoryExt) l; + AtomicReference refClassName = new AtomicReference<>(); + for( String targetType :adapfext.getAdapterNames()) { + AdapterData adapData = new AdapterData(AdapterElementType.DESTINATION_TYPE); + adapData.setParent(refAdapterData.get()); + adapData.setDestinationType(targetType); + destinationTypeToAdapterDataMap.put(targetType, adapData); + refClassName.set(""); + configsForSourceType.forEach( config -> { + for ( IConfigurationElement child :config.getChildren()) { + String type = child.getAttribute(AdapterHelper.EXT_POINT_ATTR_TYPE); + if( type.equals(targetType)) + { + refClassName.set(config.getAttribute(AdapterHelper.EXT_POINT_ATTR_CLASS)); + } + } + }); + adapData.setAdapterClassName(refClassName.get()); + refAdapterData.get().getChildrenList().add(adapData); + } + } + }); + + }); + destinationTypeToAdapterDataMap.values().forEach( ad -> { + String destType = ad.getDestinationType(); + Optional found = sourceTypeToAdapterDataMap.values().stream().filter( ads -> ads.getSourceType().equals(destType)).findAny(); + if(found.isPresent()) { + found.get().getChildrenList().forEach( adchild -> { + if (((AdapterData)ad.getParent()).getSourceType().equals(adchild.getDestinationType())) { + AdapterData adpd=new AdapterData(adchild); + ad.getChildrenList().add(adpd); + return; + } + ad.getChildrenList().add(adchild); + }); + } + }); + return sourceTypeToAdapterDataMap.values(); + } + + + public List revertSourceToType(){ + return sourceTypeToAdapterDataMap.values().stream().flatMap(AdapterData::convertSourceToType) + .collect(Collectors.toList()); + } + + + public void clear() { + sourceTypeToAdapterDataMap.clear(); + destinationTypeToAdapterDataMap.clear(); + } + + + private List getAdapterFactoryClassFromExtension(String sourceType) { + if( configEleme ==null) { + configEleme = Arrays.asList(extensionRegistry.getConfigurationElementsFor(AdapterHelper.EXT_POINT_ID)); + } + return configEleme.stream().filter( config-> config.getAttribute(AdapterHelper.EXT_POINT_ATTR_ADAPTABLE_TYPE).equals(sourceType)).collect(Collectors.toList()); + + } + +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/tools/AdapterHelper.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/tools/AdapterHelper.java new file mode 100644 index 00000000000..f5acdc8b0c0 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/tools/AdapterHelper.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter.tools; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.e4.core.contexts.ContextInjectionFactory; +import org.eclipse.e4.core.contexts.EclipseContextFactory; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.internal.services.EclipseAdapter; +import org.eclipse.e4.core.services.adapter.Adapter; +import org.eclipse.pde.spy.adapter.hook.EclipseAdapterHook; +import org.eclipse.pde.spy.adapter.model.AdapterRepository; +import org.eclipse.e4.ui.internal.workbench.E4Workbench; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +/** + * Helper class + * @author pascal + * + */ +@SuppressWarnings("restriction") +public final class AdapterHelper { + + // Bundle ID + public static final String BUNDLE_ID ="org.eclipse.pde.spy.adapter"; + + // Image keys constants + public static final String BUNDLE_IMG_KEY = "icons/osgi.png"; + public static final String SOURCE_TYPE_IMG_KEY = "icons/from_type.png"; + public static final String DESTINATION_TYPE_IMG_KEY = "icons/to_type.png"; + public static final String INTERFACE_IMG_KEY = "icons/innerinterface_public_obj.png"; + + // extension constant string + public static final String EXT_POINT_ID = "org.eclipse.core.runtime.adapters"; + public static final String EXT_POINT_ATTR_ADAPTABLE_TYPE = "adaptableType"; + public static final String EXT_POINT_ATTR_CLASS = "class"; + public static final String EXT_POINT_ATTR_ADAPTER = "adapter"; + public static final String EXT_POINT_ATTR_TYPE = "type"; + + private static final Map classNameToBundleMap =new HashMap<>(); + private static List bundlesList = new ArrayList<>(); + private static final BundleContext bc = FrameworkUtil.getBundle(AdapterRepository.class).getBundleContext(); + + private static EclipseAdapter originalEclipseAdapter; + + private static BundleContext bcontext; + + private static Color TOOLTIP_BACKGROUND; + + private AdapterHelper() { + // do nothing + } + + + + public static void wrapperEclipseAdapter() { + IEclipseContext serviceContext = E4Workbench.getServiceContext(); + if (serviceContext == null) { + System.err.println("service context is null, unable to wrap eclipse adapter"); + return; + } + EclipseAdapter eclipseAdapter = (EclipseAdapter) serviceContext.get(Adapter.class); + if (originalEclipseAdapter == null) { + originalEclipseAdapter = (EclipseAdapter) serviceContext.get(Adapter.class); + } + if (!(eclipseAdapter instanceof EclipseAdapterHook)) { + serviceContext.set(Adapter.class, ContextInjectionFactory.make(EclipseAdapterHook.class, serviceContext)); + } + } + + public static void restoreOriginalEclipseAdapter() { + IEclipseContext serviceContext = E4Workbench.getServiceContext(); + if (serviceContext != null && originalEclipseAdapter != null) { + serviceContext.set(Adapter.class, originalEclipseAdapter); + } + } + + public static IEclipseContext getServicesContext() { + return EclipseContextFactory.getServiceContext(bcontext); + } + + public static ImageRegistry getImageRegistry(Object instance) { + Bundle b = FrameworkUtil.getBundle(instance.getClass()); + bcontext = b.getBundleContext(); + ImageRegistry imgReg = new ImageRegistry(); + imgReg.put(BUNDLE_IMG_KEY, ImageDescriptor.createFromURL(b.getEntry(BUNDLE_IMG_KEY))); + imgReg.put(SOURCE_TYPE_IMG_KEY, ImageDescriptor.createFromURL(b.getEntry(SOURCE_TYPE_IMG_KEY))); + imgReg.put(DESTINATION_TYPE_IMG_KEY, ImageDescriptor.createFromURL(b.getEntry(DESTINATION_TYPE_IMG_KEY))); + imgReg.put(INTERFACE_IMG_KEY, ImageDescriptor.createFromURL(b.getEntry(INTERFACE_IMG_KEY))); + return imgReg; + } + + public static boolean isInterfaceTypeClass(Bundle bundle,String className){ + + try { + Class clazz = bundle.loadClass(className); + return clazz.isInterface(); + } catch (ClassNotFoundException e) { + } + return false; + } + + public static synchronized Bundle getBundleForClassName(String className) { + if (bundlesList.isEmpty()) + { + bundlesList = Arrays.asList(bc.getBundles()); + } + if (!classNameToBundleMap.containsKey(className)) + { + final String classpath = "/"+className.replace(".", "/") +".class"; + Bundle bundlefound = bundlesList.parallelStream().filter( b -> b.getEntry( classpath)!= null).findFirst().orElse(null); + classNameToBundleMap.put(className, bundlefound); + } + return classNameToBundleMap.get(className); + } + + public static Color getColor(Display display,String colorName) { + if( colorName != null && "TOOLTIP_BACKGROUND".equals(colorName)) { + return TOOLTIP_BACKGROUND == null ? (TOOLTIP_BACKGROUND = new Color(display, new RGB(245, 245, 220))): TOOLTIP_BACKGROUND; + } + return null; + + } + + +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/AdapterContentProvider.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/AdapterContentProvider.java new file mode 100644 index 00000000000..cfc1fa36c26 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/AdapterContentProvider.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter.viewer; + +import java.util.Collection; + +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.pde.spy.adapter.model.AdapterData; +import org.eclipse.pde.spy.adapter.tools.AdapterHelper; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +import jakarta.inject.Inject; +import jakarta.inject.Named; + +/** + * This provider is used to display available plugins which contribute to + * adapters.exsd extension point + * + * @author pascal + * + */ +public class AdapterContentProvider extends ColumnLabelProviderCustom implements ITreeContentProvider { + + @Inject + private ImageRegistry imgReg; + + private int columnIndex; + + private Boolean sourceToDestination = true; + + @Override + public Object[] getElements(Object inputElement) { + + if (inputElement instanceof Collection) { + return ((Collection) inputElement).toArray(); + } + return (Object[]) inputElement; + } + + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof AdapterData) { + return (Object[]) ((AdapterData) parentElement).getChildren(sourceToDestination); + } + + return new Object[0]; + } + + @Override + public Object getParent(Object element) { + if (element instanceof AdapterData) { + return ((AdapterData) element).getParent(); + } + return null; + } + + @Override + public boolean hasChildren(Object element) { + + if (element instanceof AdapterData) { + return ((AdapterData) element).hasChildren(); + } + return false; + } + + @Override + public String getText(Object element) { + + if (element instanceof AdapterData) { + return ((AdapterData) element).getText(columnIndex); + } + return ""; + } + + @Override + public Image getImage(Object element) { + if (columnIndex == 0) { + if (element instanceof AdapterData) { + String imgname = ((AdapterData) element).getImageName(); + return imgname == null ? super.getImage(element) : imgReg.get(imgname); + } + + } + return super.getImage(element); + } + + @Override + public int getToolTipStyle(Object object) { + return SWT.SHADOW_OUT; + } + + @Override + public Color getToolTipBackgroundColor(Object object) { + return AdapterHelper.getColor(Display.getDefault(),"TOOLTIP_BACKGROUND"); + + } + + @Override + protected StyleRange[] getToolTipStyleRanges(Object element) { + if (element instanceof AdapterData) { + return ((AdapterData) element).getToolTipStyleRanges(sourceToDestination, columnIndex); + } + return null; + } + + @Override + public String getToolTipText(Object element) { + if (element instanceof AdapterData && ((AdapterData) element).getToolTipText(sourceToDestination, columnIndex) != null) { + return ((AdapterData) element).getToolTipText(sourceToDestination, columnIndex).replaceAll("\"",""); + } + return ""; + } + + @Inject + @Optional + public void updateTextSearchFilter(@Named(AdapterFilter.UPDATE_CTX_FILTER) FilterData filterData) { + if (filterData == null) { + return; + } + this.sourceToDestination = filterData.getSourceToDestination(); + } + + public void setColumnIndex(int columnIndex) { + this.columnIndex = columnIndex; + + } +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/AdapterDataComparator.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/AdapterDataComparator.java new file mode 100644 index 00000000000..7188851907a --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/AdapterDataComparator.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter.viewer; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.pde.spy.adapter.model.AdapterData; +import org.eclipse.swt.SWT; + +public class AdapterDataComparator extends ViewerComparator { + + private int columnIndex; + private int direction; + + public AdapterDataComparator(int columnIndex) { + this.columnIndex = columnIndex; + direction = SWT.UP; + } + + /** Called when click on table header, reverse order */ + public void setColumn(int column) { + if (column == columnIndex) { + // Same column as last sort; toggle the direction + direction = (direction == SWT.UP) ? SWT.DOWN : SWT.UP; + } else { + // New column; do a descending sort + columnIndex = column; + direction = SWT.DOWN; + } + } + + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + // Now can compare the text from label provider. + if (e1 instanceof AdapterData && e2 instanceof AdapterData) { + int rc = ((AdapterData) e1).compareTo((AdapterData) e2); + // If descending order, flip the direction + return (direction == SWT.DOWN) ? -rc : rc; + } + return -1; + } + + public int getDirection() { + return direction; + } +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/AdapterFilter.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/AdapterFilter.java new file mode 100644 index 00000000000..a12c684e8a5 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/AdapterFilter.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter.viewer; + +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.pde.spy.adapter.model.AdapterData; +import org.eclipse.pde.spy.adapter.model.AdapterElementType; + +import jakarta.inject.Inject; +import jakarta.inject.Named; + +/** + * Adapter Tree viewer filter + * @author pascal + * + */ +public class AdapterFilter extends ViewerFilter { + + public static final String UPDATE_CTX_FILTER ="updateCtxfilter"; + + private String txtSeachFilter; + private Boolean showPackageFilter = Boolean.TRUE; + private Boolean sourceToDestination = Boolean.TRUE; + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + + if(element instanceof AdapterData) { + + ((AdapterData)element).setShowPackage(showPackageFilter); + } + + if (txtSeachFilter != null && !txtSeachFilter.isEmpty()) { + doFilter((AdapterData) element); + } + if(txtSeachFilter != null && txtSeachFilter.isEmpty()) + { + ((AdapterData)element).setVisibilityFilter(true); + ((AdapterData)element).propagateVisibility(); + } + return ((AdapterData)element).isVisibilityFilter(); + } + + @Inject + @Optional + public void updateTextSearchFilter(@Named(UPDATE_CTX_FILTER) FilterData filterData) { + if( filterData == null ) + { + return; + } + this.txtSeachFilter = filterData.getTxtSearchFilter(); + this.showPackageFilter= filterData.getShowPackage(); + this.sourceToDestination = filterData.getSourceToDestination(); + } + + + private void doFilter(AdapterData adapterData) + { + if( Boolean.TRUE.equals(sourceToDestination) && adapterData.getAdapterElementType().equals(AdapterElementType.SOURCE_TYPE)) + { + doVisibility(adapterData); + } + if( Boolean.FALSE.equals(sourceToDestination) && adapterData.getAdapterElementType().equals(AdapterElementType.DESTINATION_TYPE)) + { + doVisibility(adapterData); + } + } + + private void doVisibility(AdapterData adapterData) { + AtomicBoolean bfound = new AtomicBoolean(false); + adapterData.textSearch(txtSeachFilter, bfound); + adapterData.setVisibilityFilter(bfound.get()); + adapterData.propagateVisibility(); + } +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/ColumnLabelProviderCustom.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/ColumnLabelProviderCustom.java new file mode 100644 index 00000000000..708e39244a9 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/ColumnLabelProviderCustom.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter.viewer; + +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.custom.StyleRange; + +public class ColumnLabelProviderCustom extends ColumnLabelProvider { + + protected StyleRange[] getToolTipStyleRanges(Object element) { + return null; + } + +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/ColumnViewerToolTipSupportCustom.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/ColumnViewerToolTipSupportCustom.java new file mode 100644 index 00000000000..330268ac2f2 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/ColumnViewerToolTipSupportCustom.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter.viewer; + +import org.eclipse.jface.util.Policy; +import org.eclipse.jface.viewers.CellLabelProvider; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; +import org.eclipse.jface.viewers.ViewerRow; +import org.eclipse.jface.window.ToolTip; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; + +public class ColumnViewerToolTipSupportCustom extends ColumnViewerToolTipSupport { + + private ColumnViewer viewer; + private static final String VIEWER_CELL_KEY = Policy.JFACE + + "_VIEWER_CELL_KEY"; //$NON-NLS-1$ + + private StyleRange [] ranges; + protected ColumnViewerToolTipSupportCustom(ColumnViewer viewer, int style, boolean manualActivation) { + super(viewer, style, manualActivation); + this.viewer = viewer; + } + + /** + * Enable ToolTip support for the viewer by creating an instance from this + * class. To get all necessary informations this support class consults the + * {@link CellLabelProvider}. + * + * @param viewer + * the viewer the support is attached to + */ + public static void enableFor(ColumnViewer viewer) { + new ColumnViewerToolTipSupportCustom(viewer, ToolTip.NO_RECREATE, false); + } + + @Override + protected boolean shouldCreateToolTip(Event event) { + boolean rv = super.shouldCreateToolTip(event); + if (!rv) { + return false; + } + Point pt = new Point(event.x,event.y); + ViewerRow row = viewer.getCell(pt).getViewerRow(); + Object element = row.getItem().getData(); + ColumnLabelProviderCustom customlabelProvider = (ColumnLabelProviderCustom) viewer.getLabelProvider(viewer.getCell(pt).getColumnIndex()); + ranges = customlabelProvider.getToolTipStyleRanges(element); + String txt = customlabelProvider.getToolTipText(element); + return !txt.isEmpty(); + } + + + @Override + protected Composite createToolTipContentArea(Event event, Composite parent) { + setData(VIEWER_CELL_KEY, null); + String text = getText(event); + Color bgColor = getBackgroundColor(event); + StyledText styledText = new StyledText(parent, SWT.NONE); + if (text != null) { + styledText.setText(text); + } + if ( ranges != null) { + + styledText.setStyleRanges(ranges); + } + if(bgColor != null) { + styledText.setBackground(bgColor); + } + return styledText; + } + +} diff --git a/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/FilterData.java b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/FilterData.java new file mode 100644 index 00000000000..a53d80cf6a2 --- /dev/null +++ b/ui/org.eclipse.pde.spy.adapter/src/org/eclipse/pde/spy/adapter/viewer/FilterData.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) Lacherp. + * + * 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: + * Lacherp - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.spy.adapter.viewer; + +/** + * This class is used to store data filter in the context + * @author pascal + * + */ +public class FilterData { + + String txtSearchFilter; + boolean showPackage; + boolean sourceToDestination; + /** + * Ctor + */ + public FilterData() { + showPackage = Boolean.TRUE; + sourceToDestination = Boolean.TRUE; + } + + /** + * Copy ctor + * @param fdata + */ + public FilterData(FilterData fdata) + { + this.txtSearchFilter = fdata.txtSearchFilter; + this.showPackage = fdata.showPackage; + this.sourceToDestination = fdata.sourceToDestination; + } + /** + * @return the txtSearchFilter + */ + public String getTxtSearchFilter() { + return txtSearchFilter; + } + + /** + * @param txtSearchFilter the txtSearchFilter to set + */ + public void setTxtSearchFilter(String txtSearchFilter) { + this.txtSearchFilter = txtSearchFilter; + + } + + /** + * @return the showPackage + */ + public Boolean getShowPackage() { + return showPackage; + } + + /** + * @param showPackage the showPackage to set + */ + public void setShowPackage(Boolean showPackage) { + this.showPackage = showPackage; + } + + /** + * @return the sourceToDestination + */ + public Boolean getSourceToDestination() { + return sourceToDestination; + } + + /** + * @param sourceToDestination the sourceToDestination to set + */ + public void setSourceToDestination(Boolean sourceToDestination) { + this.sourceToDestination = sourceToDestination; + } + + +}