diff --git a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/ToolTipHandler.java b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/ToolTipHandler.java index 69ed0f7..c6b448c 100644 --- a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/ToolTipHandler.java +++ b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/ToolTipHandler.java @@ -5,7 +5,6 @@ import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; diff --git a/com.minres.scviewer.e4.application/META-INF/MANIFEST.MF b/com.minres.scviewer.e4.application/META-INF/MANIFEST.MF index 23ab042..1b8c1ec 100644 --- a/com.minres.scviewer.e4.application/META-INF/MANIFEST.MF +++ b/com.minres.scviewer.e4.application/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.minres.scviewer.e4.application;singleton:=true -Bundle-Version: 2.4.1.qualifier +Bundle-Version: 2.4.2.qualifier Bundle-Vendor: %Bundle-Vendor Require-Bundle: javax.inject;bundle-version="1.0.0", org.eclipse.core.runtime;bundle-version="3.11.1", @@ -32,7 +32,8 @@ Require-Bundle: javax.inject;bundle-version="1.0.0", com.opcoach.e4.preferences, org.eclipse.e4.core.di.extensions, org.eclipse.e4.ui.css.swt.theme;bundle-version="0.10.0", - org.eclipse.core.resources;bundle-version="3.13.0" + org.eclipse.core.resources;bundle-version="3.13.0", + com.opcoach.e4.preferences.mainmenu;bundle-version="1.2.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: com.minres.scviewer.database, javax.inject;version="1.0.0" diff --git a/com.minres.scviewer.e4.application/pom.xml b/com.minres.scviewer.e4.application/pom.xml index 718f006..5173019 100644 --- a/com.minres.scviewer.e4.application/pom.xml +++ b/com.minres.scviewer.e4.application/pom.xml @@ -1,7 +1,7 @@ 4.0.0 com.minres.scviewer.e4.application - 2.4.1-SNAPSHOT + 2.4.2-SNAPSHOT com.minres.scviewer com.minres.scviewer.parent diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/EnableHover.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/EnableHover.java index 5e08170..2990c28 100644 --- a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/EnableHover.java +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/EnableHover.java @@ -20,7 +20,6 @@ import org.eclipse.jface.preference.IPreferenceStore; import com.minres.scviewer.e4.application.preferences.PreferenceConstants; import com.opcoach.e4.preferences.ScopedPreferenceStore; -@SuppressWarnings("restriction") public class EnableHover { static final String TAG_NAME = "EnableHover"; //$NON-NLS-1$ diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewer.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewer.java index 58a8997..9952cdb 100644 --- a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewer.java +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewer.java @@ -425,7 +425,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis label.setLayoutData(labelGridData); final Table table = new Table(parent, SWT.NONE); - table.setHeaderVisible(false); + table.setHeaderVisible(true); table.setLinesVisible(true); table.setFont(font); label.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); diff --git a/com.minres.scviewer.e4.product/pom.xml b/com.minres.scviewer.e4.product/pom.xml index 2ecb3ec..c1187b6 100644 --- a/com.minres.scviewer.e4.product/pom.xml +++ b/com.minres.scviewer.e4.product/pom.xml @@ -10,7 +10,7 @@ ../com.minres.scviewer.parent com.minres.scviewer.e4.product - 2.4.1-SNAPSHOT + 2.4.2-SNAPSHOT eclipse-repository com.minres.scviewer diff --git a/com.minres.scviewer.e4.product/scviewer.product b/com.minres.scviewer.e4.product/scviewer.product index 46513c7..209a4f1 100644 --- a/com.minres.scviewer.e4.product/scviewer.product +++ b/com.minres.scviewer.e4.product/scviewer.product @@ -1,8 +1,7 @@ - - + @@ -11,7 +10,7 @@ -clearPersistedState -Xmx2G --Dosgi.instance.area=@user.home/.scviewer +-Dosgi.instance.area=@user.home/.scviewer -Dosgi.instance.area.default=@user.home/.scviewer -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts @@ -20,7 +19,6 @@ - @@ -37,7 +35,6 @@ - org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8 org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8 diff --git a/com.minres.scviewer.parent/pom.xml b/com.minres.scviewer.parent/pom.xml index e8a9fef..edd3538 100644 --- a/com.minres.scviewer.parent/pom.xml +++ b/com.minres.scviewer.parent/pom.xml @@ -12,11 +12,9 @@ ../com.minres.scviewer.database.sqlite ../com.minres.scviewer.database.text ../com.minres.scviewer.database.vcd - ../com.minres.scviewer.database.test ../com.minres.scviewer.database.ui ../com.minres.scviewer.database.ui.swt - ../com.opcoach.e4.preferences ../com.minres.scviewer.e4.application ../com.minres.scviewer.ui ../com.minres.scviewer.feature diff --git a/com.opcoach.e4.preferences/src/com/opcoach/e4/preferences/internal/E4PreferenceRegistry.java b/com.opcoach.e4.preferences/src/com/opcoach/e4/preferences/internal/E4PreferenceRegistry.java new file mode 100644 index 0000000..de4baf8 --- /dev/null +++ b/com.opcoach.e4.preferences/src/com/opcoach/e4/preferences/internal/E4PreferenceRegistry.java @@ -0,0 +1,325 @@ +/******************************************************************************* + * Copyright (c) 2014 OPCoach. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * OPCoach - initial API and implementation + *******************************************************************************/ +package com.opcoach.e4.preferences.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.e4.core.contexts.ContextInjectionFactory; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.Creatable; +import org.eclipse.e4.core.services.contributions.IContributionFactory; +import org.eclipse.e4.core.services.log.Logger; +import org.eclipse.jface.preference.IPreferenceNode; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceManager; +import org.eclipse.jface.preference.PreferenceNode; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +import com.opcoach.e4.preferences.IPreferenceStoreProvider; +import com.opcoach.e4.preferences.ScopedPreferenceStore; + +@SuppressWarnings("restriction") +@Creatable +public class E4PreferenceRegistry +{ + + public static final String PREFS_PAGE_XP = "com.opcoach.e4.preferences.e4PreferencePages"; // $NON-NLS-1$ + public static final String PREF_STORE_PROVIDER = "com.opcoach.e4.preferences.e4PreferenceStoreProvider"; // $NON-NLS-1$ + public static final String KEY_PREF_STORE_PROVIDERS = "com.opcoach.e4.preferences.e4PreferenceStoreProviders"; // $NON-NLS-1$ + protected static final String ELMT_PAGE = "page"; // $NON-NLS-1$ + protected static final String ATTR_ID = "id"; // $NON-NLS-1$ + protected static final String ATTR_CATEGORY = "category"; // $NON-NLS-1$ + protected static final String ATTR_CLASS = "class"; // $NON-NLS-1$ + protected static final String ATTR_NAME = "name"; // $NON-NLS-1$ + + protected static final String ATTR_PLUGIN_ID = "pluginId"; // $NON-NLS-1$ + protected static final String ATTR_ID_IN_WBCONTEXT = "idInWorkbenchContext"; // $NON-NLS-1$ + + @Inject + protected Logger logger; + + @Inject + protected IEclipseContext context; + + @Inject + protected IExtensionRegistry registry; + + private PreferenceManager pm = null; + + // A map of (pluginId, { IPreferenceStoreProvider, or key in wbcontext } + private Map psProviders; + + public PreferenceManager getPreferenceManager() + { + + // Remember of the unbounded nodes to order parent pages. + // Map (all nodes except root nodes) + Map> childrenNodes = new HashMap>(); + + if (pm != null) + return pm; + + pm = new PreferenceManager(); + IContributionFactory factory = context.get(IContributionFactory.class); + + for (IConfigurationElement elmt : registry.getConfigurationElementsFor(PREFS_PAGE_XP)) + { + String bundleId = elmt.getNamespaceIdentifier(); + if (!elmt.getName().equals(ELMT_PAGE)) + { + logger.warn("unexpected element: {0}", elmt.getName()); + continue; + } else if (isEmpty(elmt.getAttribute(ATTR_ID)) || isEmpty(elmt.getAttribute(ATTR_NAME))) + { + logger.warn("missing id and/or name: {}", bundleId); + continue; + } + PreferenceNode pn = null; + if (elmt.getAttribute(ATTR_CLASS) != null) + { + PreferencePage page = null; + try + { + String prefPageURI = getClassURI(bundleId, elmt.getAttribute(ATTR_CLASS)); + Object object = factory.create(prefPageURI, context); + if (!(object instanceof PreferencePage)) + { + logger.error("Expected instance of PreferencePage: {0}", elmt.getAttribute(ATTR_CLASS)); + continue; + } + page = (PreferencePage) object; + setPreferenceStore(bundleId, page); + + } catch (ClassNotFoundException e) + { + logger.error(e); + continue; + } + ContextInjectionFactory.inject(page, context); + if ((page.getTitle() == null || page.getTitle().isEmpty()) && elmt.getAttribute(ATTR_NAME) != null) + { + page.setTitle(elmt.getAttribute(ATTR_NAME)); + } + + pn = new PreferenceNode(elmt.getAttribute(ATTR_ID), page); + } else + { + pn = new PreferenceNode(elmt.getAttribute(ATTR_ID), new EmptyPreferencePage(elmt.getAttribute(ATTR_NAME))); + } + + // Issue 2 : Fix bug on order (see : + // https://github.com/opcoach/e4Preferences/issues/2) + // Add only pages at root level and remember of child pages for + // categories + String category = elmt.getAttribute(ATTR_CATEGORY); + if (isEmpty(category)) + { + pm.addToRoot(pn); + } else + { + /* + * IPreferenceNode parent = findNode(pm, category); if (parent + * == null) { // No parent found, but may be the extension has + * not been read yet. So remember of it unboundedNodes.put(pn, + * category); } else { parent.add(pn); } + */ + // Check if this category is already registered. + Collection children = childrenNodes.get(category); + if (children == null) + { + children = new ArrayList(); + childrenNodes.put(category, children); + } + children.add(pn); + } + } + + // Must now bind pages that has not been added in nodes (depends on the + // preference page read order) + // Iterate on all possible categories + Collection categoriesDone = new ArrayList(); + + while (!childrenNodes.isEmpty()) + { + for (String cat : Collections.unmodifiableSet(childrenNodes.keySet())) + { + // Is this category already in preference manager ? If not add + // it later... + IPreferenceNode parent = findNode(pm, cat); + if (parent != null) + { + // Can add the list of children to this parent page... + for (IPreferenceNode pn : childrenNodes.get(cat)) + { + parent.add(pn); + } + // Ok This parent page is done. Can remove it from map + // outside of this loop + categoriesDone.add(cat); + } + } + + for (String keyToRemove : categoriesDone) + childrenNodes.remove(keyToRemove); + categoriesDone.clear(); + + } + + return pm; + } + + private void setPreferenceStore(String bundleId, PreferencePage page) + { + // Affect preference store to this page if this is a + // PreferencePage, else, must manage it internally + // Set the issue#1 on github : + // https://github.com/opcoach/e4Preferences/issues/1 + // And manage the extensions of IP + initialisePreferenceStoreProviders(); + + IPreferenceStore store = null; + + // Get the preference store according to policy. + Object data = psProviders.get(bundleId); + if (data != null) + { + if (data instanceof IPreferenceStore) + store = (IPreferenceStore) data; + else if (data instanceof IPreferenceStoreProvider) + store = ((IPreferenceStoreProvider) data).getPreferenceStore(); + else if (data instanceof String) + store = (IPreferenceStore) context.get((String) data); + + } else + { + // Default behavior : create a preference store for this bundle and remember of it + store = new ScopedPreferenceStore(InstanceScope.INSTANCE, bundleId); + psProviders.put(bundleId, store); + } + + + if (store != null) + page.setPreferenceStore(store); + else + { + logger.warn("Unable to set the preferenceStore for page " + page.getTitle() + " defined in bundle " + bundleId); + } + + } + + /** Read the e4PreferenceStoreProvider extension point */ + private void initialisePreferenceStoreProviders() + { + if (psProviders == null) + { + IContributionFactory factory = context.get(IContributionFactory.class); + + psProviders = new HashMap(); + IExtensionRegistry registry = context.get(IExtensionRegistry.class); + + // Read extensions and fill the map... + for (IConfigurationElement elmt : registry.getConfigurationElementsFor(PREF_STORE_PROVIDER)) + { + String declaringBundle = elmt.getNamespaceIdentifier(); + String pluginId = elmt.getAttribute(ATTR_PLUGIN_ID); + if (isEmpty(pluginId)) + { + logger.warn("missing plugin Id in extension " + PREF_STORE_PROVIDER + " check the plugin " + declaringBundle); + continue; + } + + String classname = elmt.getAttribute(ATTR_CLASS); + String objectId = elmt.getAttribute(ATTR_ID_IN_WBCONTEXT); + + if ((isEmpty(classname) && isEmpty(objectId)) || (((classname != null) && classname.length() > 0) && ((objectId != null) && objectId.length() > 0))) + { + logger.warn("In extension " + PREF_STORE_PROVIDER + " only one of the two attributes (pluginId or idInWorkbenchContext) must be set. Check the plugin " + + declaringBundle); + continue; + } + + // Ok can now work with data... + Object data = objectId; + if (classname != null) + { + data = factory.create("bundleclass://"+declaringBundle+"/"+classname, context); + if (!(data instanceof IPreferenceStoreProvider)) + { + logger.warn("In extension " + PREF_STORE_PROVIDER + " the class must implements IPreferenceStoreProvider. Check the plugin " + declaringBundle); + continue; + } + } + + psProviders.put(pluginId, data); + + } + + context.set(KEY_PREF_STORE_PROVIDERS, psProviders); + } + } + + private IPreferenceNode findNode(PreferenceManager pm, String categoryId) + { + for (Object o : pm.getElements(PreferenceManager.POST_ORDER)) + { + if (o instanceof IPreferenceNode && ((IPreferenceNode) o).getId().equals(categoryId)) + { + return (IPreferenceNode) o; + } + } + return null; + } + + private String getClassURI(String definingBundleId, String spec) throws ClassNotFoundException + { + if (spec.startsWith("platform:")) + { + return spec; + } // $NON-NLS-1$ + return "bundleclass://" + definingBundleId + '/' + spec; + } + + private boolean isEmpty(String value) + { + return value == null || value.trim().isEmpty(); + } + + static class EmptyPreferencePage extends PreferencePage + { + + public EmptyPreferencePage(String title) + { + setTitle(title); + noDefaultAndApplyButton(); + } + + @Override + protected Control createContents(Composite parent) + { + return new Label(parent, SWT.NONE); + } + + } + +}