Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui')
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/ViewsUtil.java155
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/NewActionProvider.java148
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/WorkingSetActionProvider.java409
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/WorkingSetRootModeActionGroup.java210
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/activator/UIPlugin.java125
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/AbstractCustomFormToolkitEditorPage.java63
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/AbstractEditorPage.java105
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/events/AbstractEventListener.java320
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/events/ViewerContentChangeEvent.java84
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/expressions/EditorPropertyTester.java36
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageBinding.java93
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageBindingExtensionPointManager.java178
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageExtensionPointManager.java102
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/handler/OpenCommandHandler.java72
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/handler/PropertiesCommandHandler.java74
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IEditorPage.java20
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IRoot.java19
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IUIConstants.java38
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/ImageConsts.java58
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/workingsets/IWorkingSetIDs.java26
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/workingsets/IWorkingSetNameIDs.java25
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/View.java299
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewRoot.java39
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java106
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerSorter.java89
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/editor/Editor.java215
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/editor/EditorInput.java177
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/navigator/ContentProviderDelegate.java67
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/navigator/LabelProviderDelegate.java21
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/listeners/WorkbenchPartListener.java113
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/listeners/WorkbenchWindowListener.java68
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/nls/Messages.java64
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/nls/Messages.properties45
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/perspective/PerspectiveFactory.java68
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/OthersWorkingSetElementUpdater.java128
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementAdapter.java63
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolder.java137
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolderAdapterFactory.java41
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolderFactory.java36
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementUpdater.java115
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetFilter.java133
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetViewerSorter.java39
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetsContentProvider.java298
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetsLabelProvider.java44
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/pages/AbstractWorkingSetWizardPage.java535
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/pages/TargetWorkingSetPage.java141
46 files changed, 5441 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/ViewsUtil.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/ViewsUtil.java
new file mode 100644
index 000000000..0fdcb639b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/ViewsUtil.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views;
+
+import java.util.Collections;
+
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.navigator.CommonNavigator;
+
+/**
+ * Utility methods to deal with views.
+ */
+public class ViewsUtil {
+
+ /**
+ * Returns the workbench part identified by the given id.
+ *
+ * @param id The view id. Must not be <code>null</code>.
+ * @return The workbench part or <code>null</code>.
+ */
+ public static IWorkbenchPart getPart(String id) {
+ // Check the active workbench window and active page instances
+ if (PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null && PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() != null) {
+ // Get the view reference
+ IViewReference reference = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findViewReference(id);
+ // Return the view part from the reference, but do not restore it
+ return reference != null ? reference.getPart(false) : null;
+ }
+ return null;
+ }
+
+ /**
+ * Asynchronously refresh the view identified by the given id.
+ *
+ * @param id The view id. Must not be <code>null</code>.
+ */
+ public static void refresh(final String id) {
+ Assert.isNotNull(id);
+
+ // Create the runnable
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ // Check the active workbench window and active page instances
+ if (PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null && PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() != null) {
+ // Get the view reference
+ IViewReference reference = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findViewReference(id);
+ // Get the view part from the reference, but do not restore it
+ IWorkbenchPart part = reference != null ? reference.getPart(false) : null;
+ // If the part is a common navigator, get the common viewer
+ Viewer viewer = part instanceof CommonNavigator ? ((CommonNavigator)part).getCommonViewer() : null;
+ // If not a common navigator, try to adapt to the viewer
+ if (viewer == null) viewer = part != null ? (Viewer)part.getAdapter(Viewer.class) : null;
+ // Refresh the viewer
+ if (viewer != null) viewer.refresh();
+ }
+ }
+ };
+
+ // Execute asynchronously
+ if (PlatformUI.isWorkbenchRunning()) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(runnable);
+ }
+ }
+
+ /**
+ * Asynchronously set the given selection to the view identified by the given id.
+ *
+ * @param id The view id. Must not be <code>null</code>.
+ * @param selection The selection or <code>null</code>.
+ */
+ public static void setSelection(final String id, final ISelection selection) {
+ Assert.isNotNull(id);
+
+ // Create the runnable
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ // Check the active workbench window and active page instances
+ if (PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null && PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() != null) {
+ // Get the view reference
+ IViewReference reference = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findViewReference(id);
+ // Get the view part from the reference, but do not restore it
+ IWorkbenchPart part = reference != null ? reference.getPart(false) : null;
+ // Get the selection provider
+ ISelectionProvider selectionProvider = part != null && part.getSite() != null ? part.getSite().getSelectionProvider() : null;
+ // And apply the selection
+ if (selectionProvider != null) selectionProvider.setSelection(selection);
+ }
+ }
+ };
+
+ // Execute asynchronously
+ if (PlatformUI.isWorkbenchRunning()) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(runnable);
+ }
+ }
+
+ /**
+ * Opens the properties editor or dialog on the given selection.
+ *
+ * @param selection The selection. Must be not <code>null</code>.
+ */
+ public static void openProperties(final ISelection selection) {
+ Assert.isNotNull(selection);
+
+ // Create the runnable
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ ICommandService service = (ICommandService)PlatformUI.getWorkbench().getAdapter(ICommandService.class);
+ if (service != null) {
+ final Command command = service.getCommand("org.eclipse.ui.file.properties"); //$NON-NLS-1$
+ if (command != null && command.isDefined()) {
+ // Construct the application context
+ EvaluationContext context = new EvaluationContext(null, selection);
+ // Apply the selection to the "activeMenuSelection" and "selection" variable too
+ context.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME, selection);
+ context.addVariable(ISources.ACTIVE_MENU_SELECTION_NAME, selection);
+ context.addVariable(ISources.ACTIVE_WORKBENCH_WINDOW_NAME, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
+ // Construct the execution event
+ ExecutionEvent execEvent = new ExecutionEvent(command, Collections.EMPTY_MAP, this, context);
+ // And execute the event
+ try {
+ command.executeWithChecks(execEvent);
+ } catch (Exception e) { /* ignored on purpose */ }
+ }
+ }
+ }
+ };
+
+ // Execute asynchronously
+ if (PlatformUI.isWorkbenchRunning()) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(runnable);
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/NewActionProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/NewActionProvider.java
new file mode 100644
index 000000000..4d72d9a71
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/NewActionProvider.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.actions;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.tcf.te.ui.views.nls.Messages;
+import org.eclipse.tcf.te.ui.interfaces.IContextHelpIds;
+import org.eclipse.tcf.te.ui.interfaces.ImageConsts;
+import org.eclipse.tcf.te.ui.wizards.newWizard.NewWizardRegistry;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.internal.actions.CommandAction;
+import org.eclipse.ui.navigator.CommonActionProvider;
+import org.eclipse.ui.navigator.ICommonActionExtensionSite;
+import org.eclipse.ui.navigator.ICommonMenuConstants;
+import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite;
+import org.eclipse.ui.navigator.WizardActionGroup;
+
+/**
+ * Action provider implementation providing the "New >" content menu
+ * content.
+ */
+@SuppressWarnings("restriction")
+public class NewActionProvider extends CommonActionProvider {
+ // Reference to the action showing the "Other..." dialog (context menu)
+ private CommandAction newWizardCommandAction = null;
+ // Reference to the action showing the "Other..." dialog (toolbar)
+ private CommandAction newWizardCommandActionToolbar = null;
+ // Reference to the action group managing the context sensitive new wizards
+ private WizardActionGroup newWizardActionGroup = null;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonActionProvider#init(org.eclipse.ui.navigator.ICommonActionExtensionSite)
+ */
+ @Override
+ public void init(ICommonActionExtensionSite site) {
+ super.init(site);
+
+ if (site.getViewSite() instanceof ICommonViewerWorkbenchSite) {
+ // To initialize the actions, the workbench window instance is required
+ IWorkbenchWindow window = ((ICommonViewerWorkbenchSite)site.getViewSite()).getWorkbenchWindow();
+ // Initialize the actions
+ newWizardCommandAction = new CommandAction(window, "org.eclipse.tcf.te.ui.command.newWizards"); //$NON-NLS-1$
+ newWizardCommandAction.setImageDescriptor(null);
+ newWizardCommandAction.setDisabledImageDescriptor(null);
+ newWizardCommandAction.setText(Messages.NewActionProvider_NewWizardCommandAction_label);
+ newWizardCommandAction.setToolTipText(Messages.NewActionProvider_NewWizardCommandAction_tooltip);
+ window.getWorkbench().getHelpSystem().setHelp(newWizardCommandAction, IContextHelpIds.NEW_TARGET_WIZARD);
+
+ newWizardCommandActionToolbar = new CommandAction(window, "org.eclipse.tcf.te.ui.command.newWizards"); //$NON-NLS-1$
+ newWizardCommandActionToolbar.setImageDescriptor(org.eclipse.tcf.te.ui.activator.UIPlugin.getImageDescriptor(ImageConsts.NEW_TARGET_WIZARD_ENABLED));
+ newWizardCommandActionToolbar.setDisabledImageDescriptor(org.eclipse.tcf.te.ui.activator.UIPlugin.getImageDescriptor(ImageConsts.NEW_TARGET_WIZARD_DISABLED));
+ newWizardCommandActionToolbar.setText(Messages.NewActionProvider_NewWizardCommandAction_label);
+ newWizardCommandActionToolbar.setToolTipText(Messages.NewActionProvider_NewWizardCommandAction_tooltip);
+ window.getWorkbench().getHelpSystem().setHelp(newWizardCommandActionToolbar, IContextHelpIds.NEW_TARGET_WIZARD);
+
+ newWizardActionGroup = new WizardActionGroup(window,
+ NewWizardRegistry.getInstance(),
+ WizardActionGroup.TYPE_NEW,
+ site.getContentService());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.actions.ActionGroup#dispose()
+ */
+ @Override
+ public void dispose() {
+ if (newWizardCommandAction != null) {
+ newWizardCommandAction.dispose();
+ newWizardCommandAction = null;
+ }
+ if (newWizardActionGroup != null) {
+ newWizardActionGroup.dispose();
+ newWizardActionGroup = null;
+ }
+ super.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.actions.ActionGroup#fillContextMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ @Override
+ public void fillContextMenu(IMenuManager menu) {
+ // If none of the actions got created, there is nothing to do here
+ if (newWizardCommandAction == null && newWizardActionGroup == null) {
+ return;
+ }
+
+ // Create the new sub menu
+ IMenuManager newMenu = new MenuManager(Messages.NewActionProvider_NewMenu_label,
+ org.eclipse.tcf.te.ui.activator.UIPlugin.getImageDescriptor(ImageConsts.NEW_TARGET_WIZARD_ENABLED),
+ IUIConstants.ID_EXPLORER + ".menu.new"); //$NON-NLS-1$
+
+ // Add the context sensitive wizards (commonWizard element)
+ if (newWizardActionGroup != null) {
+ newWizardActionGroup.setContext(getContext());
+ newWizardActionGroup.fillContextMenu(newMenu);
+ }
+
+ // Add the standard additions marker
+ newMenu.add(new Separator(ICommonMenuConstants.GROUP_ADDITIONS));
+
+ // Add the "Other..." dialog action
+ if (newWizardCommandAction != null) {
+ newMenu.add(new Separator());
+ newMenu.add(newWizardCommandAction);
+ }
+
+ // The menu will be appended after the GROUP_NEW group.
+ menu.insertAfter(ICommonMenuConstants.GROUP_NEW, newMenu);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.actions.ActionGroup#fillActionBars(org.eclipse.ui.IActionBars)
+ */
+ @Override
+ public void fillActionBars(IActionBars actionBars) {
+ // If none of the actions got created, there is nothing to do here
+ if (newWizardCommandActionToolbar == null) {
+ return;
+ }
+
+ // Get the toolbar manager
+ IToolBarManager toolbar = actionBars.getToolBarManager();
+
+ // Check for the newWizard action in the toolbar. If found,
+ // drop out immediately to avoid adding the items to the toolbar
+ // again and again
+ if (toolbar.find("org.eclipse.tcf.te.ui.command.newWizards") != null) { //$NON-NLS-1$
+ return;
+ }
+
+ // Add the items to the toolbar
+ toolbar.insertAfter(ICommonMenuConstants.GROUP_NEW, newWizardCommandActionToolbar);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/WorkingSetActionProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/WorkingSetActionProvider.java
new file mode 100644
index 000000000..68de84446
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/WorkingSetActionProvider.java
@@ -0,0 +1,409 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.actions;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.tcf.te.ui.views.activator.UIPlugin;
+import org.eclipse.tcf.te.ui.views.internal.ViewRoot;
+import org.eclipse.tcf.te.ui.views.nls.Messages;
+import org.eclipse.tcf.te.ui.views.workingsets.WorkingSetFilter;
+import org.eclipse.tcf.te.ui.views.workingsets.WorkingSetsContentProvider;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IAggregateWorkingSet;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.WorkingSetFilterActionGroup;
+import org.eclipse.ui.internal.navigator.NavigatorFilterService;
+import org.eclipse.ui.navigator.CommonActionProvider;
+import org.eclipse.ui.navigator.CommonViewer;
+import org.eclipse.ui.navigator.ICommonActionExtensionSite;
+import org.eclipse.ui.navigator.IExtensionActivationListener;
+import org.eclipse.ui.navigator.IExtensionStateModel;
+import org.eclipse.ui.navigator.INavigatorContentService;
+
+/**
+ * Working set action provider implementation.
+ * <p>
+ * Copied and adapted from <code>org.eclipse.ui.internal.navigator.resources.actions.WorkingSetActionProvider</code>.
+ */
+@SuppressWarnings("restriction")
+public class WorkingSetActionProvider extends CommonActionProvider {
+
+ private static final String TAG_CURRENT_WORKING_SET_NAME = "currentWorkingSetName"; //$NON-NLS-1$
+
+ private static final String WORKING_SET_FILTER_ID = "org.eclipse.tcf.te.ui.views.navigator.filters.workingSet"; //$NON-NLS-1$
+
+ private boolean contributedToViewMenu = false;
+
+ /* default */ CommonViewer viewer;
+
+ /* default */ INavigatorContentService contentService;
+
+ private NavigatorFilterService filterService;
+
+ private WorkingSetFilterActionGroup workingSetActionGroup;
+ /* default */ WorkingSetRootModeActionGroup workingSetRootModeActionGroup;
+
+ private Object originalViewerInput = null;
+
+ /* default */ IExtensionStateModel extensionStateModel;
+
+ /* default */ boolean emptyWorkingSet;
+ /* default */ IWorkingSet workingSet;
+
+ /* default */ IPropertyChangeListener topLevelModeListener;
+
+ /* default */ boolean ignoreFilterChangeEvents;
+
+ /**
+ * Provides a smart listener to monitor changes to the Working Set Manager.
+ *
+ */
+ public class WorkingSetManagerListener implements IPropertyChangeListener {
+
+ private boolean listening = false;
+
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ String property = event.getProperty();
+ Object newValue = event.getNewValue();
+ Object oldValue = event.getOldValue();
+
+ String newLabel = null;
+ if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property) && oldValue == workingSet) {
+ newLabel = ""; //$NON-NLS-1$
+ setWorkingSet(null);
+ } else if (IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE.equals(property) && newValue == workingSet) {
+ newLabel = workingSet.getLabel();
+ } else if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE.equals(property) && newValue == workingSet) {
+ if (workingSet.isAggregateWorkingSet() && workingSet.isEmpty()) {
+ // act as if the working set has been made null
+ if (!emptyWorkingSet) {
+ emptyWorkingSet = true;
+ setWorkingSetFilter(null);
+ }
+ } else {
+ // we've gone from empty to non-empty on our set.
+ // Restore it.
+ if (emptyWorkingSet) {
+ emptyWorkingSet = false;
+ setWorkingSetFilter(workingSet);
+ newLabel = workingSet.getLabel();
+ }
+ }
+ }
+ if (viewer != null) {
+ if (newLabel != null)
+ viewer.getCommonNavigator().setWorkingSetLabel(newLabel);
+ viewer.getFrameList().reset();
+ viewer.refresh();
+ }
+ }
+
+ /**
+ * Begin listening to the correct source if not already listening.
+ */
+ public synchronized void listen() {
+ if (!listening) {
+ PlatformUI.getWorkbench().getWorkingSetManager().addPropertyChangeListener(managerChangeListener);
+ listening = true;
+ }
+ }
+
+ /**
+ * Begin listening to the correct source if not already listening.
+ */
+ public synchronized void ignore() {
+ if (listening) {
+ PlatformUI.getWorkbench().getWorkingSetManager().removePropertyChangeListener(managerChangeListener);
+ listening = false;
+ }
+ }
+ }
+
+ private IPropertyChangeListener filterChangeListener = new IPropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+
+ if (ignoreFilterChangeEvents)
+ return;
+
+ IWorkingSet newWorkingSet = (IWorkingSet) event.getNewValue();
+
+ setWorkingSet(newWorkingSet);
+ if (newWorkingSet != null) {
+ if (!contentService.isActive(WorkingSetsContentProvider.EXTENSION_ID)) {
+ contentService.getActivationService().activateExtensions(
+ new String[] { WorkingSetsContentProvider.EXTENSION_ID }, false);
+ contentService.getActivationService().persistExtensionActivations();
+ }
+ if (newWorkingSet.isAggregateWorkingSet()) {
+ IAggregateWorkingSet agWs = (IAggregateWorkingSet) newWorkingSet;
+ IWorkingSet[] comps = agWs.getComponents();
+ if (comps.length > 1) {
+ viewer.getCommonNavigator().setWorkingSetLabel(Messages.WorkingSetActionProvider_multipleWorkingSets);
+ } else if (comps.length > 0) {
+ viewer.getCommonNavigator().setWorkingSetLabel(comps[0].getLabel());
+ } else {
+ viewer.getCommonNavigator().setWorkingSetLabel(null);
+ }
+ } else
+ viewer.getCommonNavigator().setWorkingSetLabel(workingSet.getLabel());
+ } else {
+ viewer.getCommonNavigator().setWorkingSetLabel(null);
+ }
+
+ viewer.getFrameList().reset();
+ }
+ };
+
+ /* default */ WorkingSetManagerListener managerChangeListener = new WorkingSetManagerListener();
+
+ private IExtensionActivationListener activationListener = new IExtensionActivationListener() {
+
+ private IWorkingSet savedWorkingSet;
+
+ @Override
+ public void onExtensionActivation(String aViewerId, String[] theNavigatorExtensionIds, boolean isActive) {
+
+ for (int i = 0; i < theNavigatorExtensionIds.length; i++) {
+ if (WorkingSetsContentProvider.EXTENSION_ID.equals(theNavigatorExtensionIds[i])) {
+ if (isActive) {
+ extensionStateModel = contentService.findStateModel(WorkingSetsContentProvider.EXTENSION_ID);
+ workingSetRootModeActionGroup.setStateModel(extensionStateModel);
+ extensionStateModel.addPropertyChangeListener(topLevelModeListener);
+
+ if (savedWorkingSet != null) {
+ setWorkingSet(savedWorkingSet);
+ }
+ managerChangeListener.listen();
+
+ } else {
+ savedWorkingSet = workingSet;
+ setWorkingSet(null);
+ viewer.getCommonNavigator().setWorkingSetLabel(null);
+ managerChangeListener.ignore();
+ workingSetRootModeActionGroup.setShowTopLevelWorkingSets(false);
+ extensionStateModel.removePropertyChangeListener(topLevelModeListener);
+
+ }
+ }
+ }
+ }
+
+ };
+
+ @Override
+ public void init(ICommonActionExtensionSite site) {
+ viewer = (CommonViewer) site.getStructuredViewer();
+ contentService = site.getContentService();
+ filterService = (NavigatorFilterService) contentService.getFilterService();
+ originalViewerInput = ViewRoot.getInstance();
+
+ extensionStateModel = contentService.findStateModel(WorkingSetsContentProvider.EXTENSION_ID);
+
+ workingSetActionGroup = new WorkingSetFilterActionGroup(site.getViewSite().getShell(), filterChangeListener);
+ workingSetRootModeActionGroup = new WorkingSetRootModeActionGroup(viewer, extensionStateModel);
+
+ topLevelModeListener = new IPropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ setWorkingSet(workingSet);
+ viewer.getFrameList().reset();
+ }
+ };
+
+ if (contentService.isActive(WorkingSetsContentProvider.EXTENSION_ID)) {
+ managerChangeListener.listen();
+ extensionStateModel.addPropertyChangeListener(topLevelModeListener);
+ }
+
+ contentService.getActivationService().addExtensionActivationListener(activationListener);
+ }
+
+ /**
+ * Restores the working set filter from the persistence store.
+ */
+ protected void initWorkingSetFilter(String workingSetName) {
+ IWorkingSet workingSet = null;
+
+ if (workingSetName != null && workingSetName.length() > 0) {
+ IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager();
+ workingSet = workingSetManager.getWorkingSet(workingSetName);
+ } else if (PlatformUI.getPreferenceStore().getBoolean(IWorkbenchPreferenceConstants.USE_WINDOW_WORKING_SET_BY_DEFAULT)) {
+ // use the window set by default if the global preference is set
+ workingSet = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getAggregateWorkingSet();
+ }
+
+ if (workingSet != null) {
+ setWorkingSet(workingSet);
+ }
+ }
+
+ /* default */ void setWorkingSetFilter(IWorkingSet workingSet) {
+ setWorkingSetFilter(workingSet, true);
+ }
+
+ private void setWorkingSetFilter(IWorkingSet workingSet, boolean firstTime) {
+ WorkingSetFilter workingSetFilter = null;
+ ViewerFilter[] filters = viewer.getFilters();
+ for (int i = 0; i < filters.length; i++) {
+ if (filters[i] instanceof WorkingSetFilter) {
+ workingSetFilter = (WorkingSetFilter) filters[i];
+ break;
+ }
+ }
+ if (workingSetFilter == null) {
+ if (firstTime) {
+ filterService.addActiveFilterIds(new String[] { WORKING_SET_FILTER_ID });
+ filterService.updateViewer();
+ setWorkingSetFilter(workingSet, false);
+ return;
+ }
+
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ "Required filter " + WORKING_SET_FILTER_ID //$NON-NLS-1$
+ + " is not present. Working set support will not function correctly."); //$NON-NLS-1$
+ UIPlugin.getDefault().getLog().log(status);
+ return;
+ }
+ workingSetFilter.setActive(extensionStateModel.getBooleanProperty(WorkingSetsContentProvider.SHOW_TOP_LEVEL_WORKING_SETS));
+ }
+
+ /**
+ * Set current active working set.
+ *
+ * @param workingSet
+ * working set to be activated, may be <code>null</code>
+ */
+ protected void setWorkingSet(IWorkingSet workingSet) {
+ this.workingSet = workingSet;
+ emptyWorkingSet = workingSet != null && workingSet.isAggregateWorkingSet() && workingSet.isEmpty();
+
+ ignoreFilterChangeEvents = true;
+ try {
+ workingSetActionGroup.setWorkingSet(workingSet);
+ } finally {
+ ignoreFilterChangeEvents = false;
+ }
+
+ if (viewer != null) {
+ setWorkingSetFilter(workingSet);
+ if (workingSet == null || emptyWorkingSet
+ || !extensionStateModel.getBooleanProperty(WorkingSetsContentProvider.SHOW_TOP_LEVEL_WORKING_SETS)) {
+ if (viewer.getInput() != originalViewerInput) {
+ viewer.setInput(originalViewerInput);
+ } else {
+ viewer.refresh();
+ }
+ } else {
+ if (!workingSet.isAggregateWorkingSet()) {
+ IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager();
+ viewer.setInput(workingSetManager.createAggregateWorkingSet(
+ "", "", new IWorkingSet[] { workingSet })); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ viewer.setInput(workingSet);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void restoreState(final IMemento aMemento) {
+ super.restoreState(aMemento);
+
+ // Need to run this async to avoid being reentered when processing a selection change
+ viewer.getControl().getShell().getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ boolean showWorkingSets = true;
+ if (aMemento != null) {
+ Integer showWorkingSetsInt = aMemento
+ .getInteger(WorkingSetsContentProvider.SHOW_TOP_LEVEL_WORKING_SETS);
+ showWorkingSets = showWorkingSetsInt == null || showWorkingSetsInt.intValue() == 1;
+ extensionStateModel.setBooleanProperty(WorkingSetsContentProvider.SHOW_TOP_LEVEL_WORKING_SETS,
+ showWorkingSets);
+ workingSetRootModeActionGroup.setShowTopLevelWorkingSets(showWorkingSets);
+
+ String lastWorkingSetName = aMemento.getString(TAG_CURRENT_WORKING_SET_NAME);
+ initWorkingSetFilter(lastWorkingSetName);
+ } else {
+ showWorkingSets = false;
+
+ extensionStateModel.setBooleanProperty(WorkingSetsContentProvider.SHOW_TOP_LEVEL_WORKING_SETS,
+ showWorkingSets);
+ workingSetRootModeActionGroup.setShowTopLevelWorkingSets(showWorkingSets);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void saveState(IMemento aMemento) {
+ super.saveState(aMemento);
+
+ if (aMemento != null) {
+ int showWorkingSets = extensionStateModel
+ .getBooleanProperty(WorkingSetsContentProvider.SHOW_TOP_LEVEL_WORKING_SETS) ? 1 : 0;
+ aMemento.putInteger(WorkingSetsContentProvider.SHOW_TOP_LEVEL_WORKING_SETS, showWorkingSets);
+
+ if (workingSet != null) {
+ aMemento.putString(TAG_CURRENT_WORKING_SET_NAME, workingSet.getName());
+ }
+ }
+
+ }
+
+ @Override
+ public void fillActionBars(IActionBars actionBars) {
+ if (!contributedToViewMenu) {
+ try {
+ super.fillActionBars(actionBars);
+ workingSetActionGroup.fillActionBars(actionBars);
+ if (workingSetRootModeActionGroup != null) {
+ workingSetRootModeActionGroup.fillActionBars(actionBars);
+ }
+ } finally {
+ contributedToViewMenu = true;
+ }
+ }
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ workingSetActionGroup.dispose();
+ if (workingSetRootModeActionGroup != null) {
+ workingSetRootModeActionGroup.dispose();
+ }
+
+ managerChangeListener.ignore();
+ extensionStateModel.removePropertyChangeListener(topLevelModeListener);
+
+ contentService.getActivationService().removeExtensionActivationListener(activationListener);
+ }
+
+ /**
+ * This is used only for the tests.
+ *
+ * @return a PropertyChangeListener
+ */
+ public IPropertyChangeListener getFilterChangeListener() {
+ return filterChangeListener;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/WorkingSetRootModeActionGroup.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/WorkingSetRootModeActionGroup.java
new file mode 100644
index 000000000..8420eea34
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/actions/WorkingSetRootModeActionGroup.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.tcf.te.ui.views.activator.UIPlugin;
+import org.eclipse.tcf.te.ui.views.interfaces.ImageConsts;
+import org.eclipse.tcf.te.ui.views.nls.Messages;
+import org.eclipse.tcf.te.ui.views.workingsets.WorkingSetsContentProvider;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.navigator.IExtensionStateModel;
+
+/**
+ * Provides the radio buttons at the top of the view menu that control the root of the Target
+ * Explorer, which is either working sets or targets. When the state is changed through the
+ * actions, the WorkingSetsContentProvider.SHOW_TOP_LEVEL_WORKING_SETS property in the extension
+ * state model is updated.
+ *
+ * This is installed by the WorkingSetActionProvider.
+ *
+ * <p>
+ * Copied and adapted from <code>org.eclipse.ui.internal.navigator.resources.actions.WorkingSetRootModeActionGroup</code>.
+ */
+public class WorkingSetRootModeActionGroup extends ActionGroup {
+
+ /* default */ IExtensionStateModel stateModel;
+ /* default */ StructuredViewer viewer;
+
+ private boolean hasContributedToViewMenu = false;
+ private IAction workingSetsAction = null;
+ private IAction targetsAction = null;
+ /* default */ IAction[] actions;
+ /* default */ int currentSelection;
+ /* default */ MenuItem[] items;
+
+ private class TopLevelContentAction extends Action {
+
+ private final boolean groupWorkingSets;
+
+ /**
+ * Construct an Action that represents a toggle-able state between Showing top level Working
+ * Sets and Projects.
+ *
+ * @param toGroupWorkingSets
+ */
+ public TopLevelContentAction(boolean toGroupWorkingSets) {
+ super("", AS_RADIO_BUTTON); //$NON-NLS-1$
+ groupWorkingSets = toGroupWorkingSets;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ if (stateModel.getBooleanProperty(WorkingSetsContentProvider.SHOW_TOP_LEVEL_WORKING_SETS) != groupWorkingSets) {
+ stateModel.setBooleanProperty(WorkingSetsContentProvider.SHOW_TOP_LEVEL_WORKING_SETS, groupWorkingSets);
+
+ viewer.getControl().setRedraw(false);
+ try {
+ viewer.refresh();
+ }
+ finally {
+ viewer.getControl().setRedraw(true);
+ }
+ }
+ }
+ }
+
+ /**
+ * Create an action group that will listen to the stateModel and update the structuredViewer
+ * when necessary.
+ *
+ * @param viewer
+ * @param stateModel
+ */
+ public WorkingSetRootModeActionGroup(StructuredViewer viewer, IExtensionStateModel stateModel) {
+ super();
+ this.viewer = viewer;
+ this.stateModel = stateModel;
+ }
+
+ /* (non-Javadoc)
+ * @see ActionGroup#fillActionBars(IActionBars)
+ */
+ @Override
+ public void fillActionBars(IActionBars actionBars) {
+ if (hasContributedToViewMenu) return;
+ IMenuManager topLevelSubMenu = new MenuManager(Messages.WorkingSetRootModeActionGroup_Top_Level_Element);
+ addActions(topLevelSubMenu);
+ actionBars.getMenuManager().insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, topLevelSubMenu);
+ hasContributedToViewMenu = true;
+ }
+
+ /**
+ * Adds the actions to the given menu manager.
+ */
+ protected void addActions(IMenuManager viewMenu) {
+ if (actions == null) actions = createActions();
+
+ viewMenu.add(new Separator());
+ items = new MenuItem[actions.length];
+
+ for (int i = 0; i < actions.length; i++) {
+ final int j = i;
+
+ viewMenu.add(new ContributionItem() {
+
+ @Override
+ public void fill(Menu menu, int index) {
+
+ int style = SWT.CHECK;
+ if ((actions[j].getStyle() & IAction.AS_RADIO_BUTTON) != 0) style = SWT.RADIO;
+
+ final MenuItem mi = new MenuItem(menu, style, index);
+ items[j] = mi;
+ mi.setText(actions[j].getText());
+ mi.setSelection(currentSelection == j);
+ mi.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (currentSelection == j) {
+ items[currentSelection].setSelection(true);
+ return;
+ }
+ actions[j].run();
+
+ // Update checked state
+ items[currentSelection].setSelection(false);
+ currentSelection = j;
+ items[currentSelection].setSelection(true);
+ }
+
+ });
+
+ }
+
+ @Override
+ public boolean isDynamic() {
+ return false;
+ }
+ });
+ }
+ }
+
+ private IAction[] createActions() {
+
+ targetsAction = new TopLevelContentAction(false);
+ targetsAction.setText(Messages.WorkingSetRootModeActionGroup_Target);
+ targetsAction.setImageDescriptor(UIPlugin.getImageDescriptor(ImageConsts.VIEW));
+
+ workingSetsAction = new TopLevelContentAction(true);
+ workingSetsAction.setText(Messages.WorkingSetRootModeActionGroup_Working_Set);
+ workingSetsAction.setImageDescriptor(UIPlugin.getImageDescriptor(ImageConsts.WORKING_SETS));
+
+ return new IAction[] { targetsAction, workingSetsAction };
+ }
+
+ /**
+ * Toggle whether top level working sets should be displayed as a group or collapse to just show
+ * their contents.
+ *
+ * @param showTopLevelWorkingSets
+ */
+ public void setShowTopLevelWorkingSets(boolean showTopLevelWorkingSets) {
+ if (actions == null) actions = createActions();
+
+ currentSelection = showTopLevelWorkingSets ? 1 : 0;
+ workingSetsAction.setChecked(showTopLevelWorkingSets);
+ targetsAction.setChecked(!showTopLevelWorkingSets);
+
+ if (items != null) {
+ for (int i = 0; i < items.length; i++) {
+ if (items[i] != null && actions[i] != null) items[i].setSelection(actions[i]
+ .isChecked());
+ }
+ }
+ if (stateModel != null) {
+ stateModel.setBooleanProperty(WorkingSetsContentProvider.SHOW_TOP_LEVEL_WORKING_SETS, showTopLevelWorkingSets);
+ }
+ }
+
+ /**
+ * @param stateModel
+ */
+ public void setStateModel(IExtensionStateModel stateModel) {
+ this.stateModel = stateModel;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/activator/UIPlugin.java
new file mode 100644
index 000000000..4bd2226b5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/activator/UIPlugin.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.activator;
+
+import java.net.URL;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.ui.views.interfaces.ImageConsts;
+import org.eclipse.tcf.te.ui.views.listeners.WorkbenchWindowListener;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class UIPlugin extends AbstractUIPlugin {
+
+ // The shared instance
+ private static UIPlugin plugin;
+
+ // The global window listener instance
+ private IWindowListener windowListener;
+
+ /**
+ * The constructor
+ */
+ public UIPlugin() {
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static UIPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getDefault() != null && getDefault().getBundle() != null) {
+ return getDefault().getBundle().getSymbolicName();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+
+ if (windowListener == null && PlatformUI.getWorkbench() != null) {
+ windowListener = new WorkbenchWindowListener();
+ PlatformUI.getWorkbench().addWindowListener(windowListener);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ if (windowListener != null && PlatformUI.getWorkbench() != null) {
+ PlatformUI.getWorkbench().removeWindowListener(windowListener);
+ windowListener = null;
+ }
+
+ plugin = null;
+ super.stop(context);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry)
+ */
+ @Override
+ protected void initializeImageRegistry(ImageRegistry registry) {
+ URL url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_EVIEW + "prop_ps.gif"); //$NON-NLS-1$
+ registry.put(ImageConsts.EDITOR, ImageDescriptor.createFromURL(url));
+ url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_EVIEW + "targets_view.gif"); //$NON-NLS-1$
+ registry.put(ImageConsts.VIEW, ImageDescriptor.createFromURL(url));
+ url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ + "workingset.gif"); //$NON-NLS-1$
+ registry.put(ImageConsts.WORKING_SET, ImageDescriptor.createFromURL(url));
+ url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ + "workingsets.gif"); //$NON-NLS-1$
+ registry.put(ImageConsts.WORKING_SETS, ImageDescriptor.createFromURL(url));
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>Image</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>Image</code> object instance or <code>null</code>.
+ */
+ public static Image getImage(String key) {
+ return getDefault().getImageRegistry().get(key);
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>ImageDescriptor</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>ImageDescriptor</code> object instance or <code>null</code>.
+ */
+ public static ImageDescriptor getImageDescriptor(String key) {
+ return getDefault().getImageRegistry().getDescriptor(key);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/AbstractCustomFormToolkitEditorPage.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/AbstractCustomFormToolkitEditorPage.java
new file mode 100644
index 000000000..105e7e7d8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/AbstractCustomFormToolkitEditorPage.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.editor;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.tcf.te.ui.forms.CustomFormToolkit;
+import org.eclipse.ui.forms.IManagedForm;
+
+/**
+ * Abstract details editor page implementation managing
+ * an custom form toolkit instance.
+ */
+public class AbstractCustomFormToolkitEditorPage extends AbstractEditorPage {
+ // Reference to the form toolkit instance
+ private CustomFormToolkit toolkit = null;
+
+ /**
+ * Returns the custom form toolkit instance.
+ *
+ * @return The custom form toolkit instance or <code>null</code>.
+ */
+ protected final CustomFormToolkit getFormToolkit() {
+ return toolkit;
+ }
+
+ /**
+ * Sets the custom form toolkit instance.
+ *
+ * @param toolkit The custom form toolkit instance or <code>null</code>.
+ */
+ protected final void setFormToolkit(CustomFormToolkit toolkit) {
+ this.toolkit = toolkit;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormPage#createFormContent(org.eclipse.ui.forms.IManagedForm)
+ */
+ @Override
+ protected void createFormContent(IManagedForm managedForm) {
+ super.createFormContent(managedForm);
+
+ Assert.isNotNull(managedForm);
+
+ // Create the toolkit instance
+ toolkit = new CustomFormToolkit(managedForm.getToolkit());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormPage#dispose()
+ */
+ @Override
+ public void dispose() {
+ if (toolkit != null) { toolkit.dispose(); toolkit = null; }
+ super.dispose();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/AbstractEditorPage.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/AbstractEditorPage.java
new file mode 100644
index 000000000..c9608ed4c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/AbstractEditorPage.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.editor;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tcf.te.ui.views.activator.UIPlugin;
+import org.eclipse.tcf.te.ui.views.interfaces.IEditorPage;
+import org.eclipse.tcf.te.runtime.nls.Messages;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.editor.FormPage;
+
+
+/**
+ * Abstract details editor page implementation.
+ */
+public abstract class AbstractEditorPage extends FormPage implements IEditorPage {
+ // The unique page id
+ private String id;
+
+ /**
+ * Constructor.
+ */
+ public AbstractEditorPage() {
+ super("", ""); // //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void setInitializationData(IConfigurationElement config, String propertyName, Object data) {
+ super.setInitializationData(config, propertyName, data);
+
+ if (config != null) {
+ // Initialize the id field by reading the <id> extension attribute.
+ // Throws an exception if the id is empty or null.
+ id = config.getAttribute("id"); //$NON-NLS-1$
+ if (id == null || id.trim().length() == 0) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ NLS.bind(Messages.Extension_error_missingRequiredAttribute, "id", config.getContributor().getName())); //$NON-NLS-1$
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormPage#getId()
+ */
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormPage#createFormContent(org.eclipse.ui.forms.IManagedForm)
+ */
+ @Override
+ protected void createFormContent(IManagedForm managedForm) {
+ super.createFormContent(managedForm);
+ Assert.isNotNull(managedForm);
+ managedForm.setInput(getEditorInputNode());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
+ */
+ @Override
+ protected void setInput(IEditorInput input) {
+ super.setInput(input);
+ // Update the managed form too
+ if (getManagedForm() != null) getManagedForm().setInput(getEditorInputNode());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#setInputWithNotify(org.eclipse.ui.IEditorInput)
+ */
+ @Override
+ protected void setInputWithNotify(IEditorInput input) {
+ super.setInputWithNotify(input);
+ // Update the managed form too
+ if (getManagedForm() != null) getManagedForm().setInput(getEditorInputNode());
+ }
+
+ /**
+ * Returns the node associated with the current editor input.
+ *
+ * @return The node or <code>null</code>.
+ */
+ public Object getEditorInputNode() {
+ IEditorInput input = getEditorInput();
+ return input != null ? input.getAdapter(Object.class) : null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/events/AbstractEventListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/events/AbstractEventListener.java
new file mode 100644
index 000000000..9fdd09ec8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/events/AbstractEventListener.java
@@ -0,0 +1,320 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.events;
+
+import java.util.Iterator;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNodeProvider;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.navigator.CommonNavigator;
+import org.eclipse.ui.navigator.CommonViewer;
+
+/**
+ * Abstract UI event listener updating the target explorer view.
+ */
+public abstract class AbstractEventListener extends org.eclipse.tcf.te.ui.events.AbstractEventListener {
+ // Reference to the target explorer viewer instance
+ private CommonViewer viewer = null;
+ // Reference to the refresh job
+ private RefreshJob refreshJob = null;
+ // Reference to the update job
+ private UpdateJob updateJob = null;
+
+ /**
+ * Returns the Target Explorer view.
+ *
+ * @return The Target Explorer view or <code>null</code>.
+ */
+ protected CommonViewer getViewer() {
+ if (viewer == null) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow window = workbench != null ? workbench.getActiveWorkbenchWindow() : null;
+ IWorkbenchPage page = window != null ? window.getActivePage() : null;
+ if (page != null) {
+ IViewPart part = page.findView(IUIConstants.ID_EXPLORER);
+ if (part instanceof CommonNavigator) {
+ viewer = ((CommonNavigator)part).getCommonViewer();
+ }
+ }
+ }
+ return viewer;
+ }
+
+ /**
+ * Trigger a refresh of the given node. If the node
+ * is <code>null</code>, everything will be refreshed.
+ *
+ * @param node The node or <code>null</code>.
+ * @param scheduled <code>True</code> to schedule the refresh for asynchronous execution, <code>false</code> to
+ * execute the refresh synchronously.
+ *
+ * @see CommonViewer#refresh()
+ * @see CommonViewer#refresh(Object)
+ */
+ protected void refresh(Object node, boolean scheduled) {
+ CommonViewer viewer = getViewer();
+ if (viewer == null) return;
+
+ if (scheduled) {
+ scheduleRefreshJob(node != null ? node : viewer, viewer);
+ } else {
+ if (node != null) {
+ viewer.refresh(node);
+ } else {
+ viewer.refresh();
+ }
+ }
+ }
+
+ /**
+ * Trigger a update of the given node.
+ *
+ * @param node The node. Must not be <code>null</code>.
+ * @param scheduled <code>True</code> to schedule the update for asynchronous execution, <code>false</code> to
+ * execute the update synchronously.
+ *
+ * @see CommonViewer#update(Object, String[])
+ */
+ protected void update(Object node, boolean scheduled) {
+ Assert.isNotNull(node);
+
+ CommonViewer viewer = getViewer();
+ if (viewer == null) return;
+
+ if (scheduled) {
+ scheduleUpdateJob(node, viewer);
+ } else {
+ viewer.update(node, null);
+ }
+ }
+
+ private static final int SCHEDULE_TIME = 1000;
+
+ /**
+ * Abstract refresh or update job implementation
+ */
+ private abstract class AbstractJob extends Job {
+
+ /* default */ final CommonViewer parentViewer;
+ private final Queue<Object> nodes = new ConcurrentLinkedQueue<Object>();
+ private boolean done = true;
+
+ /**
+ * Constructor.
+ *
+ * @param name The job name.
+ * @param viewer The viewer instance. Must not be <code>null</code>.
+ */
+ protected AbstractJob(String name, CommonViewer viewer) {
+ super(name);
+
+ Assert.isNotNull(viewer);
+ this.parentViewer = viewer;
+
+ setPriority(Job.SHORT);
+ setSystem(true);
+ }
+
+ /**
+ * Adds the given node to the job.
+ *
+ * @param element The element to add or <code>null</code> to refresh everything.
+ */
+ protected void addNode(Object element) {
+ // if whole tree should be refreshed, clear the queue
+ if (element instanceof CommonViewer) {
+ nodes.clear();
+ }
+ // if the element to refresh is not in list
+ else if (!nodes.contains(element)) {
+ // if model node look at parent/child relationship
+ if (element instanceof IModelNodeProvider) {
+ IModelNode node = ((IModelNodeProvider)element).getModelNode();
+ Iterator<Object> it = nodes.iterator();
+ while (it.hasNext() && element != null && node != null) {
+ Object obj = it.next();
+ if (obj instanceof IModelNodeProvider) {
+ IModelNode rNode = ((IModelNodeProvider)obj).getModelNode();
+ if (rNode != null) {
+ // if parent already in list -> skip
+ if (rNode.equals(node.getParent())) {
+ element = null;
+ }
+ // if child in list -> remove child
+ else if (node.equals(rNode.getParent())) {
+ it.remove();
+ }
+ }
+ }
+ }
+ }
+ }
+ // skip element if already in list
+ else {
+ element = null;
+ }
+ // add to list if not skipped
+ if (element != null) nodes.add(element);
+
+ // if job is not scheduled, reschedule it
+ if (done) {
+ done = false;
+ this.schedule(SCHEDULE_TIME);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ Object node = nodes.poll();
+ while (node != null) {
+ Runnable runnable = newRunnable(node);
+ if (runnable != null) {
+ try {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(runnable);
+ }
+ catch (Exception e) {
+ // if display is disposed, silently ignore.
+ }
+ }
+ // get the next element to refresh
+ node = nodes.poll();
+ }
+ // set job to done so the next add would reschedule it
+ done = true;
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * Creates the runnable.
+ *
+ * @param node The node. Must not be <code>null</code>.
+ * @return The runnable or <code>null</code>
+ */
+ protected Runnable newRunnable(final Object node) {
+ Assert.isNotNull(node);
+ return null;
+ }
+ }
+
+ /**
+ * Refresh Job implementation.
+ */
+ private class RefreshJob extends AbstractJob {
+
+ /**
+ * Constructor.
+ *
+ * @param viewer The viewer instance. Must not be <code>null</code>.
+ */
+ public RefreshJob(CommonViewer viewer) {
+ super(RefreshJob.class.getSimpleName(), viewer);
+ }
+
+ /* (non-Javadoc)
+ * @see com.windriver.te.tcf.softice.ui.internal.events.EventListener.AbstractJob#newRunnable(java.lang.Object)
+ */
+ @Override
+ protected Runnable newRunnable(final Object node) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ if (node instanceof CommonViewer) {
+ parentViewer.refresh();
+ } else {
+ parentViewer.refresh(node);
+ }
+ }
+ };
+ }
+ }
+
+ /**
+ * Update Job implementation.
+ */
+ private class UpdateJob extends AbstractJob {
+
+ /**
+ * Constructor.
+ *
+ * @param viewer The viewer instance. Must not be <code>null</code>.
+ */
+ public UpdateJob(CommonViewer viewer) {
+ super(UpdateJob.class.getSimpleName(), viewer);
+ }
+
+
+ /* (non-Javadoc)
+ * @see com.windriver.te.tcf.softice.ui.internal.events.EventListener.AbstractJob#newRunnable(java.lang.Object)
+ */
+ @Override
+ protected Runnable newRunnable(final Object node) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ if (node instanceof CommonViewer) {
+ parentViewer.refresh();
+ } else {
+ parentViewer.update(node, null);
+ }
+ }
+ };
+ }
+ }
+
+ /**
+ * Schedule the asynchronous refresh job.
+ *
+ * @param node The node. Must not be <code>null</code>.
+ * @param viewer The viewer instance. Must not be <code>null</code>.
+ */
+ private void scheduleRefreshJob(Object node, CommonViewer viewer) {
+ Assert.isNotNull(node);
+ Assert.isNotNull(viewer);
+
+ if (refreshJob == null) {
+ refreshJob = new RefreshJob(viewer);
+ }
+ refreshJob.addNode(node);
+ }
+
+
+ /**
+ * Schedule the asynchronous update job.
+ *
+ * @param node The node. Must not be <code>null</code>.
+ * @param viewer The viewer instance. Must not be <code>null</code>.
+ */
+ private void scheduleUpdateJob(Object node, CommonViewer viewer) {
+ Assert.isNotNull(node);
+ Assert.isNotNull(viewer);
+
+ if (updateJob == null) {
+ updateJob = new UpdateJob(viewer);
+ }
+ updateJob.addNode(node);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/events/ViewerContentChangeEvent.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/events/ViewerContentChangeEvent.java
new file mode 100644
index 000000000..7dabf37ab
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/events/ViewerContentChangeEvent.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.events;
+
+import java.util.EventObject;
+
+import org.eclipse.tcf.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tcf.te.runtime.interfaces.tracing.ITraceIds;
+
+/**
+ * Target Explorer view viewer change event implementation.
+ */
+public class ViewerContentChangeEvent extends EventObject {
+ private static final long serialVersionUID = 7168841012111347036L;
+
+ private String eventId;
+
+ /**
+ * Event id used if elements got directly added to the viewer.
+ */
+ public static final String ADD = "add"; //$NON-NLS-1$
+
+ /**
+ * Event id used if elements got directly removed the viewer.
+ */
+ public static final String REMOVE = "remove"; //$NON-NLS-1$
+
+ /**
+ * Event id used if the viewer got refreshed.
+ */
+ public static final String REFRESH = "refresh"; //$NON-NLS-1$
+
+ /**
+ * Constructor.
+ *
+ * @param source The source object. Must not be <code>null</code>.
+ * @param eventId The event id. Must not be <code>null</code>.
+ *
+ * @exception IllegalArgumentException if eventId == null.
+ */
+ public ViewerContentChangeEvent(Object source, String eventId) {
+ super(source);
+
+ if (eventId == null) throw new IllegalArgumentException("null eventId"); //$NON-NLS-1$
+ this.eventId = eventId;
+ }
+
+ /**
+ * Returns the event id.
+ *
+ * @return The event id.
+ */
+ public final String getEventId() {
+ return eventId;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.EventObject#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder toString = new StringBuilder(getClass().getName());
+
+ String prefix = ""; //$NON-NLS-1$
+ // if tracing the event, formating them a little bit better readable.
+ if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_EVENTS))
+ prefix = "\n\t\t"; //$NON-NLS-1$
+
+ toString.append(prefix + "{eventId="); //$NON-NLS-1$
+ toString.append(eventId);
+ toString.append("," + prefix + "source="); //$NON-NLS-1$ //$NON-NLS-2$
+ toString.append(source);
+ toString.append("}"); //$NON-NLS-1$
+
+ return toString.toString();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/expressions/EditorPropertyTester.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/expressions/EditorPropertyTester.java
new file mode 100644
index 000000000..dbb3ac9cc
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/expressions/EditorPropertyTester.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.expressions;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.tcf.te.ui.views.extensions.EditorPageBindingExtensionPointManager;
+import org.eclipse.tcf.te.ui.views.internal.editor.EditorInput;
+import org.eclipse.ui.IEditorInput;
+
+
+/**
+ * Details editor property tester implementation.
+ */
+public class EditorPropertyTester extends PropertyTester {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
+ */
+ @Override
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ if ("hasApplicableEditorBindings".equals(property)) { //$NON-NLS-1$
+ // Create a fake editor input object
+ IEditorInput input = new EditorInput(receiver);
+ return expectedValue.equals(Boolean.valueOf(EditorPageBindingExtensionPointManager.getInstance().getApplicableEditorPageBindings(input).length > 0));
+ }
+ return false;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageBinding.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageBinding.java
new file mode 100644
index 000000000..11b51c6ea
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageBinding.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.extensions;
+
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.ExpressionConverter;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.tcf.te.runtime.extensions.ExecutableExtension;
+
+/**
+ * Details editor page binding implementation.
+ */
+public class EditorPageBinding extends ExecutableExtension {
+ // The mandatory page identifier
+ private String pageId;
+ // The insertBefore element
+ private String insertBefore;
+ // The insertAfter element
+ private String insertAfter;
+ // The converted expression
+ private Expression expression;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.extensions.ExecutableExtension#doSetInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void doSetInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
+ super.doSetInitializationData(config, propertyName, data);
+
+ // Initialize the page id field by reading the <pageId> extension attribute.
+ // Throws an exception if the id is empty or null.
+ pageId = config != null ? config.getAttribute("pageId") : null; //$NON-NLS-1$
+ if (pageId == null || (pageId != null && "".equals(pageId.trim()))) { //$NON-NLS-1$
+ throw createMissingMandatoryAttributeException("pageId", config.getContributor().getName()); //$NON-NLS-1$
+ }
+
+ // Read the sub elements of the extension
+ IConfigurationElement[] children = config != null ? config.getChildren() : null;
+ // The "enablement" element is the only expected one
+ if (children != null && children.length > 0) {
+ expression = ExpressionConverter.getDefault().perform(children[0]);
+ }
+
+ // Read the "insertBefore" attribute
+ insertBefore = config != null ? config.getAttribute("insertBefore") : null; //$NON-NLS-1$
+ // Read the "insertAfter" attribute
+ insertAfter = config != null ? config.getAttribute("insertAfter") : null; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the editor page id which is associated with this binding.
+ *
+ * @return The editor page id.
+ */
+ public String getPageId() {
+ return pageId;
+ }
+
+ /**
+ * Returns the enablement expression which is associated with this binding.
+ *
+ * @return The enablement expression or <code>null</code>.
+ */
+ public Expression getEnablement() {
+ return expression;
+ }
+
+ /**
+ * Returns the &quot;insertBefore&quot; property for this binding.
+ *
+ * @return The &quot;insertBefore&quot; property or an empty string.
+ */
+ public String getInsertBefore() {
+ return insertBefore != null ? insertBefore.trim() : ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the &quot;insertAfter&quot; property for this binding.
+ *
+ * @return The &quot;insertAfter&quot; property or an empty string.
+ */
+ public String getInsertAfter() {
+ return insertAfter != null ? insertAfter.trim() : ""; //$NON-NLS-1$
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageBindingExtensionPointManager.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageBindingExtensionPointManager.java
new file mode 100644
index 000000000..a294d4c00
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageBindingExtensionPointManager.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.extensions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.tcf.te.ui.views.activator.UIPlugin;
+import org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager;
+import org.eclipse.tcf.te.runtime.extensions.ExecutableExtensionProxy;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.ISources;
+
+
+/**
+ * Details editor page binding extension point manager implementation.
+ */
+public class EditorPageBindingExtensionPointManager extends AbstractExtensionPointManager<EditorPageBinding> {
+
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstance {
+ public static EditorPageBindingExtensionPointManager instance = new EditorPageBindingExtensionPointManager();
+ }
+
+ /**
+ * Constructor.
+ */
+ EditorPageBindingExtensionPointManager() {
+ super();
+ }
+
+ /**
+ * Returns the singleton instance of the extension point manager.
+ */
+ public static EditorPageBindingExtensionPointManager getInstance() {
+ return LazyInstance.instance;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager#getExtensionPointId()
+ */
+ @Override
+ protected String getExtensionPointId() {
+ return "org.eclipse.tcf.te.ui.views.editorPageBindings"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager#getConfigurationElementName()
+ */
+ @Override
+ protected String getConfigurationElementName() {
+ return "editorPageBinding"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager#doCreateExtensionProxy(org.eclipse.core.runtime.IConfigurationElement)
+ */
+ @Override
+ protected ExecutableExtensionProxy<EditorPageBinding> doCreateExtensionProxy(IConfigurationElement element) throws CoreException {
+ return new ExecutableExtensionProxy<EditorPageBinding>(element) {
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.extensions.ExecutableExtensionProxy#newInstance()
+ */
+ @Override
+ public EditorPageBinding newInstance() {
+ EditorPageBinding instance = new EditorPageBinding();
+ try {
+ instance.setInitializationData(getConfigurationElement(), null, null);
+ } catch (CoreException e) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ e.getLocalizedMessage(), e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ return instance;
+ }
+ };
+ }
+
+ /**
+ * Returns the applicable editor page bindings for the given data source model node..
+ *
+ * @param input The active editor input or <code>null</code>.
+ * @return The list of applicable editor page bindings or an empty array.
+ */
+ public EditorPageBinding[] getApplicableEditorPageBindings(IEditorInput input) {
+ List<EditorPageBinding> applicable = new ArrayList<EditorPageBinding>();
+
+ for (EditorPageBinding binding : getEditorPageBindings()) {
+ Expression enablement = binding.getEnablement();
+
+ // The page binding is applicable by default if no expression
+ // is specified.
+ boolean isApplicable = enablement == null;
+
+ if (enablement != null && input != null) {
+ // Extract the node from the editor input
+ Object node = input.getAdapter(Object.class);
+ if (node != null) {
+ // Set the default variable to the data source model node instance.
+ EvaluationContext context = new EvaluationContext(null, node);
+ // Set the "activeEditorInput" variable to the data source model node instance.
+ context.addVariable(ISources.ACTIVE_EDITOR_INPUT_NAME, node);
+ // Evaluate the expression
+ try {
+ isApplicable = enablement.evaluate(context).equals(EvaluationResult.TRUE);
+ } catch (CoreException e) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ e.getLocalizedMessage(), e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ } else {
+ // The enablement is false by definition if we cannot
+ // determine the data source model node.
+ isApplicable = false;
+ }
+ }
+
+ // Add the page if applicable
+ if (isApplicable) applicable.add(binding);
+ }
+
+ return applicable.toArray(new EditorPageBinding[applicable.size()]);
+ }
+
+ /**
+ * Returns the list of all contributed editor page bindings.
+ *
+ * @return The list of contributed editor page bindings, or an empty array.
+ */
+ public EditorPageBinding[] getEditorPageBindings() {
+ List<EditorPageBinding> contributions = new ArrayList<EditorPageBinding>();
+ Collection<ExecutableExtensionProxy<EditorPageBinding>> editorPageBindings = getExtensions().values();
+ for (ExecutableExtensionProxy<EditorPageBinding> editorPageBinding : editorPageBindings) {
+ EditorPageBinding instance = editorPageBinding.getInstance();
+ if (instance != null && !contributions.contains(instance)) {
+ contributions.add(instance);
+ }
+ }
+
+ return contributions.toArray(new EditorPageBinding[contributions.size()]);
+ }
+
+ /**
+ * Returns the editor page binding identified by its unique id. If no editor
+ * page binding with the specified id is registered, <code>null</code> is returned.
+ *
+ * @param id The unique id of the editor page binding or <code>null</code>
+ *
+ * @return The editor page instance or <code>null</code>.
+ */
+ public EditorPageBinding getEditorPageBinding(String id) {
+ EditorPageBinding contribution = null;
+ if (getExtensions().containsKey(id)) {
+ ExecutableExtensionProxy<EditorPageBinding> proxy = getExtensions().get(id);
+ // Get the extension instance
+ contribution = proxy.getInstance();
+ }
+
+ return contribution;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageExtensionPointManager.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageExtensionPointManager.java
new file mode 100644
index 000000000..b99362520
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/extensions/EditorPageExtensionPointManager.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.extensions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.tcf.te.ui.views.interfaces.IEditorPage;
+import org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager;
+import org.eclipse.tcf.te.runtime.extensions.ExecutableExtensionProxy;
+
+
+/**
+ * Details editor page extension point manager implementation.
+ */
+public class EditorPageExtensionPointManager extends AbstractExtensionPointManager<IEditorPage> {
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstance {
+ public static EditorPageExtensionPointManager instance = new EditorPageExtensionPointManager();
+ }
+
+ /**
+ * Constructor.
+ */
+ EditorPageExtensionPointManager() {
+ super();
+ }
+
+ /**
+ * Returns the singleton instance of the extension point manager.
+ */
+ public static EditorPageExtensionPointManager getInstance() {
+ return LazyInstance.instance;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager#getExtensionPointId()
+ */
+ @Override
+ protected String getExtensionPointId() {
+ return "org.eclipse.tcf.te.ui.views.editorPages"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager#getConfigurationElementName()
+ */
+ @Override
+ protected String getConfigurationElementName() {
+ return "editorPage"; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the list of all contributed editor pages.
+ *
+ * @param unique If <code>true</code>, the method returns new instances for each
+ * contributed editor page.
+ *
+ * @return The list of contributed editor pages, or an empty array.
+ */
+ public IEditorPage[] getEditorPages(boolean unique) {
+ List<IEditorPage> contributions = new ArrayList<IEditorPage>();
+ Collection<ExecutableExtensionProxy<IEditorPage>> editorPages = getExtensions().values();
+ for (ExecutableExtensionProxy<IEditorPage> editorPage : editorPages) {
+ IEditorPage instance = unique ? editorPage.newInstance() : editorPage.getInstance();
+ if (instance != null && !contributions.contains(instance)) {
+ contributions.add(instance);
+ }
+ }
+
+ return contributions.toArray(new IEditorPage[contributions.size()]);
+ }
+
+ /**
+ * Returns the editor page identified by its unique id. If no editor
+ * page with the specified id is registered, <code>null</code> is returned.
+ *
+ * @param id The unique id of the editor page or <code>null</code>
+ * @param unique If <code>true</code>, the method returns new instances of the editor page contribution.
+ *
+ * @return The editor page instance or <code>null</code>.
+ */
+ public IEditorPage getEditorPage(String id, boolean unique) {
+ IEditorPage contribution = null;
+ if (getExtensions().containsKey(id)) {
+ ExecutableExtensionProxy<IEditorPage> proxy = getExtensions().get(id);
+ // Get the extension instance
+ contribution = unique ? proxy.newInstance() : proxy.getInstance();
+ }
+
+ return contribution;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/handler/OpenCommandHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/handler/OpenCommandHandler.java
new file mode 100644
index 000000000..6e2d80777
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/handler/OpenCommandHandler.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.handler;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.tcf.te.ui.views.activator.UIPlugin;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.navigator.CommonNavigator;
+
+/**
+ * TCF tree elements open command handler implementation.
+ */
+public class OpenCommandHandler extends AbstractHandler {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ // The selection is the Target Explorer tree selection
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ // The active part is the Target Explorer view instance
+ IWorkbenchPart part = HandlerUtil.getActivePart(event);
+
+ if (selection instanceof IStructuredSelection && !selection.isEmpty() && part instanceof CommonNavigator) {
+ // If the tree node is expandable, expand or collapse it
+ TreeViewer viewer = ((CommonNavigator)part).getCommonViewer();
+ Object element = ((IStructuredSelection)selection).getFirstElement();
+ if (viewer.isExpandable(element)) {
+ viewer.setExpandedState(element, !viewer.getExpandedState(element));
+ } else {
+ // Node is not an expandable node, forward to the properties action.
+ ICommandService service = (ICommandService)PlatformUI.getWorkbench().getService(ICommandService.class);
+ Command command = service != null ? service.getCommand(ActionFactory.PROPERTIES.getCommandId()) : null;
+ if (command != null && command.isDefined() && command.isEnabled()) {
+ try {
+ command.executeWithChecks(event);
+ } catch (Exception e) {
+ // If the platform is in debug mode, we print the exception to the log view
+ if (Platform.inDebugMode()) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), e.getLocalizedMessage(), e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/handler/PropertiesCommandHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/handler/PropertiesCommandHandler.java
new file mode 100644
index 000000000..72dfa79cc
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/handler/PropertiesCommandHandler.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.handler;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tcf.te.ui.views.activator.UIPlugin;
+import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.tcf.te.ui.views.internal.editor.EditorInput;
+import org.eclipse.tcf.te.ui.views.nls.Messages;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+
+/**
+ * Properties command handler implementation.
+ */
+public class PropertiesCommandHandler extends AbstractHandler {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ // Get the active selection
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ Object element = ((IStructuredSelection)selection).getFirstElement();
+ if (element != null) {
+ // Get the currently active workbench window
+ IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
+ if (window == null) window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window != null) {
+ // Get the active page
+ IWorkbenchPage page = window.getActivePage();
+ // Create the editor input object
+ IEditorInput input = new EditorInput(element);
+ // Check for the Target Explorer editor already opened
+ IEditorReference[] references = page.findEditors(input, IUIConstants.ID_EDITOR, IWorkbenchPage.MATCH_INPUT);
+ if (references.length == 0) {
+ try {
+ // Opens the Target Explorer properties editor
+ page.openEditor(input, IUIConstants.ID_EDITOR);
+ } catch (PartInitException e) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ Messages.PropertiesCommandHandler_error_initPartFailed, e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IEditorPage.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IEditorPage.java
new file mode 100644
index 000000000..2cd529cf3
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IEditorPage.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.interfaces;
+
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.ui.forms.editor.IFormPage;
+
+/**
+ * Details editor page public interface.
+ */
+public interface IEditorPage extends IFormPage, IExecutableExtension {
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IRoot.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IRoot.java
new file mode 100644
index 000000000..2dcd90300
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IRoot.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.interfaces;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+/**
+ * Target Explorer root node.
+ */
+public interface IRoot extends IAdaptable {
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IUIConstants.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IUIConstants.java
new file mode 100644
index 000000000..f7cd861d8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IUIConstants.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.interfaces;
+
+/**
+ * Target Explorer UI constants.
+ */
+public interface IUIConstants {
+
+ /**
+ * The target explorer view id.
+ */
+ public static final String ID_EXPLORER = "org.eclipse.tcf.te.ui.views.TargetExplorer"; //$NON-NLS-1$
+
+ /**
+ * The target explorer editor id.
+ */
+ public static final String ID_EDITOR = "org.eclipse.tcf.te.ui.view.Editor"; //$NON-NLS-1$
+
+ // ***** Define the constants for the Target Explorer view root mode *****
+
+ /**
+ * Root nodes are working sets.
+ */
+ public static final int MODE_WORKING_SETS = 0;
+
+ /**
+ * Root nodes are whatever is contributed to the view.
+ */
+ public static final int MODE_NORMAL = 1;
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/ImageConsts.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/ImageConsts.java
new file mode 100644
index 000000000..3ac69785a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/ImageConsts.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.interfaces;
+
+/**
+ * Image registry constants.
+ */
+public interface ImageConsts {
+
+ // ***** The directory structure constants *****
+
+ /**
+ * The root directory where to load the images from, relative to
+ * the bundle directory.
+ */
+ public final static String IMAGE_DIR_ROOT = "icons/"; //$NON-NLS-1$
+
+ /**
+ * The directory where to load view related images from, relative to
+ * the image root directory.
+ */
+ public final static String IMAGE_DIR_EVIEW = "eview16/"; //$NON-NLS-1$
+
+ /**
+ * The directory where to load model object images from,
+ * relative to the image root directory.
+ */
+ public final static String IMAGE_DIR_OBJ = "obj16/"; //$NON-NLS-1$
+
+ // ***** The image constants *****
+
+ /**
+ * The key to access the Target Explorer editor image.
+ */
+ public static final String EDITOR = "TargetExplorerEditor"; //$NON-NLS-1$
+
+ /**
+ * The key to access the Target Explorer view image.
+ */
+ public static final String VIEW = "TargetExplorerView"; //$NON-NLS-1$
+
+ /**
+ * The key to access the Target Explorer working sets image.
+ */
+ public static final String WORKING_SETS = "TargetExplorerWorkingSets"; //$NON-NLS-1$
+
+ /**
+ * The key to access the Target Explorer working set image.
+ */
+ public static final String WORKING_SET = "TargetExplorerWorkingSet"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/workingsets/IWorkingSetIDs.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/workingsets/IWorkingSetIDs.java
new file mode 100644
index 000000000..10833b765
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/workingsets/IWorkingSetIDs.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.interfaces.workingsets;
+
+/**
+ * Target Explorer working set ID constants.
+ */
+public interface IWorkingSetIDs {
+
+ /**
+ * Target Explorer working set id.
+ */
+ public final static String ID_WS_TARGET_EXPLORER = "org.eclipse.tcf.te.ui.views.workingset"; //$NON-NLS-1$
+
+ /**
+ * Target Explorer "Others" working set id.
+ */
+ public final static String ID_WS_OTHERS = "org.eclipse.tcf.te.ui.views.workingset.others"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/workingsets/IWorkingSetNameIDs.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/workingsets/IWorkingSetNameIDs.java
new file mode 100644
index 000000000..677c693ce
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/workingsets/IWorkingSetNameIDs.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.interfaces.workingsets;
+
+/**
+ * Name and IDs used by the working set implementation.
+ */
+public interface IWorkingSetNameIDs {
+
+ /** The element factory id.*/
+ String FACTORY_ID = "factoryId"; //$NON-NLS-1$
+
+ /** The attribute to store the working set element's id. */
+ String ATTR_ELEMENTID = "elementId"; //$NON-NLS-1$
+
+ /** The attribute to store the working set's name. */
+ String ATTR_WORKINGSET_NAME = "workingSetName"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/View.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/View.java
new file mode 100644
index 000000000..fdfa3a5b1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/View.java
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.internal;
+
+import java.util.Collections;
+
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tcf.te.ui.views.activator.UIPlugin;
+import org.eclipse.tcf.te.ui.views.interfaces.IRoot;
+import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.tcf.te.ui.views.nls.Messages;
+import org.eclipse.ui.IAggregateWorkingSet;
+import org.eclipse.ui.ILocalWorkingSetManager;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.internal.navigator.framelist.Frame;
+import org.eclipse.ui.internal.navigator.framelist.FrameList;
+import org.eclipse.ui.internal.navigator.framelist.TreeFrame;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.eclipse.ui.navigator.CommonNavigator;
+import org.eclipse.ui.navigator.CommonViewer;
+import org.eclipse.ui.navigator.ICommonActionConstants;
+
+
+/**
+ * Target Explorer View implementation.
+ * <p>
+ * The view is based on the Eclipse Common Navigator framework.
+ */
+@SuppressWarnings("restriction")
+public class View extends CommonNavigator {
+ // The view root mode
+ private int rootMode = IUIConstants.MODE_NORMAL;
+
+ /**
+ * Used only in the case of top level = MODE_NORMAL and only when some
+ * working sets are selected.
+ */
+ private String workingSetLabel;
+
+ /**
+ * The local working set manager instance.
+ */
+ private final ILocalWorkingSetManager localWorkingSetManager = PlatformUI.getWorkbench().createLocalWorkingSetManager();
+
+ /**
+ * Constructor.
+ */
+ public View() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonNavigator#getInitialInput()
+ */
+ @Override
+ protected Object getInitialInput() {
+ return ViewRoot.getInstance();
+ }
+
+ /**
+ * Sets the view's root mode.
+ *
+ * @param mode The root mode.
+ * @see IUIConstants
+ */
+ @Override
+ public void setRootMode(int mode) {
+ rootMode = mode;
+ }
+
+ /**
+ * Returns the view's root mode.
+ *
+ * @return The root mode
+ * @see IUIConstants
+ */
+ @Override
+ public int getRootMode() {
+ return rootMode;
+ }
+
+ /**
+ * Sets the working set label.
+ *
+ * @param label The working set label or <code>null</code>.
+ */
+ @Override
+ public void setWorkingSetLabel(String label) {
+ workingSetLabel = label;
+ }
+
+ /**
+ * Returns the working set label.
+ *
+ * @return The working set label or <code>null</code>.
+ */
+ @Override
+ public String getWorkingSetLabel() {
+ return workingSetLabel;
+ }
+
+ /**
+ * Returns the local working set manager instance.
+ *
+ * @return The local working set manager instance.
+ */
+ public final ILocalWorkingSetManager getLocalWorkingSetManager() {
+ return localWorkingSetManager;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonNavigator#dispose()
+ */
+ @Override
+ public void dispose() {
+ localWorkingSetManager.dispose();
+ super.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonNavigator#createCommonViewerObject(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected CommonViewer createCommonViewerObject(Composite parent) {
+ return new ViewViewer(getViewSite().getId(), parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonNavigator#createPartControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+
+ // Add the additional custom Target Explorer toolbar groups
+ addCustomToolbarGroups();
+ }
+
+ /**
+ * Adds the custom Target Explorer toolbar groups to the view toolbar.
+ */
+ protected void addCustomToolbarGroups() {
+ if (getViewSite() != null && getViewSite().getActionBars() != null) {
+ IToolBarManager tbManager = getViewSite().getActionBars().getToolBarManager();
+ if (tbManager != null) {
+ tbManager.insertBefore("FRAME_ACTION_GROUP_ID", new GroupMarker("group.new")); //$NON-NLS-1$ //$NON-NLS-2$
+ tbManager.appendToGroup("group.new", new Separator("group.configure")); //$NON-NLS-1$ //$NON-NLS-2$
+ tbManager.appendToGroup("group.configure", new Separator("group.connect")); //$NON-NLS-1$ //$NON-NLS-2$
+ tbManager.appendToGroup("group.connect", new Separator("group.symbols.rd")); //$NON-NLS-1$ //$NON-NLS-2$
+ tbManager.appendToGroup("group.symbols.rd", new GroupMarker("group.symbols")); //$NON-NLS-1$ //$NON-NLS-2$
+ tbManager.appendToGroup("group.symbols", new Separator("group.refresh")); //$NON-NLS-1$ //$NON-NLS-2$
+ tbManager.appendToGroup("group.refresh", new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonNavigator#handleDoubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
+ */
+ @Override
+ protected void handleDoubleClick(DoubleClickEvent dblClickEvent) {
+ // If an handled and enabled command is registered for the ICommonActionConstants.OPEN
+ // retargetable action id, redirect the double click handling to the command handler.
+ //
+ // Note: The default tree node expansion must be re-implemented in the active handler!
+ ICommandService service = (ICommandService)PlatformUI.getWorkbench().getService(ICommandService.class);
+ Command command = service != null ? service.getCommand(ICommonActionConstants.OPEN) : null;
+ if (command != null && command.isDefined() && command.isEnabled()) {
+ try {
+ ISelection selection = dblClickEvent.getSelection();
+ EvaluationContext ctx = new EvaluationContext(null, selection);
+ ctx.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME, selection);
+ ctx.addVariable(ISources.ACTIVE_MENU_SELECTION_NAME, selection);
+ ctx.addVariable(ISources.ACTIVE_WORKBENCH_WINDOW_NAME, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
+ ctx.addVariable(ISources.ACTIVE_PART_ID_NAME, getViewSite().getId());
+ ctx.addVariable(ISources.ACTIVE_PART_NAME, this);
+ ctx.addVariable(ISources.ACTIVE_SITE_NAME, getViewSite());
+ ctx.addVariable(ISources.ACTIVE_SHELL_NAME, getViewSite().getShell());
+ ExecutionEvent event = new ExecutionEvent(command, Collections.EMPTY_MAP, this, ctx);
+ command.executeWithChecks(event);
+ } catch (Exception e) {
+ // If the platform is in debug mode, we print the exception to the log view
+ if (Platform.inDebugMode()) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), e.getLocalizedMessage(), e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ }
+ } else {
+ // Fallback to the default implementation
+ super.handleDoubleClick(dblClickEvent);
+ }
+ }
+
+ /**
+ * The superclass does not deal with the content description, handle it here.
+ *
+ * @noreference
+ */
+ @Override
+ public void updateTitle() {
+ super.updateTitle();
+
+ // Get the input from the common viewer
+ Object input = getCommonViewer().getInput();
+
+ // The content description to set
+ String contentDescription = null;
+
+ if (input instanceof IAdaptable) {
+ IWorkbenchAdapter adapter = (IWorkbenchAdapter) ((IAdaptable) input).getAdapter(IWorkbenchAdapter.class);
+ if (adapter != null) contentDescription = adapter.getLabel(input);
+ }
+ else if (input instanceof IRoot) {
+ // The root node does not have a content description
+ }
+ else if (input != null && !(input instanceof IAggregateWorkingSet)) {
+ contentDescription = input.toString();
+ }
+
+ setContentDescription(contentDescription != null ? contentDescription : ""); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the tool tip text for the given element.
+ *
+ * @param element The element or <code>null</code>.
+ * @return The tooltip or <code>null</code>.
+ */
+ @Override
+ public String getFrameToolTipText(Object element) {
+ String result;
+
+ if (element instanceof IAggregateWorkingSet) {
+ result = Messages.View_workingSetModel;
+ }
+ else if (element instanceof IWorkingSet) {
+ result = ((IWorkingSet) element).getLabel();
+ }
+ else {
+ result = super.getFrameToolTipText(element);
+ }
+
+ if (rootMode == IUIConstants.MODE_NORMAL) {
+ if (workingSetLabel == null) return result;
+ if (result.length() == 0) return NLS.bind(Messages.View_toolTip, workingSetLabel);
+ return NLS.bind(Messages.View_toolTip2, result, workingSetLabel);
+ }
+
+ // Working set mode. During initialization element and viewer can be null.
+ if (element != null && !(element instanceof IWorkingSet) && getCommonViewer() != null) {
+ FrameList frameList = getCommonViewer().getFrameList();
+ // Happens during initialization
+ if (frameList == null) return result;
+ int index = frameList.getCurrentIndex();
+ IWorkingSet ws = null;
+ while (index >= 0) {
+ Frame frame = frameList.getFrame(index);
+ if (frame instanceof TreeFrame) {
+ Object input = ((TreeFrame) frame).getInput();
+ if (input instanceof IWorkingSet && !(input instanceof IAggregateWorkingSet)) {
+ ws = (IWorkingSet) input;
+ break;
+ }
+ }
+ index--;
+ }
+ if (ws != null) {
+ return NLS.bind(Messages.View_toolTip3, ws.getLabel(), result);
+ }
+ return result;
+ }
+ return result;
+
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewRoot.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewRoot.java
new file mode 100644
index 000000000..66944ac2e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewRoot.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.internal;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tcf.te.ui.views.interfaces.IRoot;
+
+/**
+ * Target Explorer view root node implementation
+ */
+public class ViewRoot extends PlatformObject implements IRoot {
+
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstance {
+ public static ViewRoot instance = new ViewRoot();
+ }
+
+ /**
+ * Returns the singleton view root instance.
+ */
+ public static ViewRoot getInstance() {
+ return LazyInstance.instance;
+ }
+
+ /**
+ * Constructor.
+ */
+ /* default */ ViewRoot() {
+ }
+} \ No newline at end of file
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java
new file mode 100644
index 000000000..7e1265d92
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.internal;
+
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tcf.te.ui.views.events.ViewerContentChangeEvent;
+import org.eclipse.tcf.te.runtime.events.EventManager;
+import org.eclipse.ui.navigator.CommonViewer;
+import org.eclipse.ui.navigator.CommonViewerSorter;
+
+/**
+ * Target Explorer common viewer implementation.
+ */
+public class ViewViewer extends CommonViewer {
+
+ /**
+ * Constructor.
+ *
+ * @param viewerId
+ * An id tied to the extensions that is used to focus specific
+ * content to a particular instance of the Common Navigator
+ * @param parent
+ * A Composite parent to contain the actual SWT widget
+ * @param style
+ * A style mask that will be used to create the TreeViewer
+ * Composite.
+ */
+ public ViewViewer(String viewerId, Composite parent, int style) {
+ super(viewerId, parent, style);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonViewer#add(java.lang.Object, java.lang.Object[])
+ */
+ @Override
+ public void add(Object parentElement, Object[] childElements) {
+ super.add(parentElement, childElements);
+
+ ViewerContentChangeEvent event = new ViewerContentChangeEvent(this, ViewerContentChangeEvent.ADD);
+ EventManager.getInstance().fireEvent(event);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonViewer#remove(java.lang.Object[])
+ */
+ @Override
+ public void remove(Object[] elements) {
+ super.remove(elements);
+
+ ViewerContentChangeEvent event = new ViewerContentChangeEvent(this, ViewerContentChangeEvent.REMOVE);
+ EventManager.getInstance().fireEvent(event);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.AbstractTreeViewer#remove(java.lang.Object, java.lang.Object[])
+ */
+ @Override
+ public void remove(Object parent, Object[] elements) {
+ super.remove(parent, elements);
+
+ ViewerContentChangeEvent event = new ViewerContentChangeEvent(this, ViewerContentChangeEvent.REMOVE);
+ EventManager.getInstance().fireEvent(event);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonViewer#refresh(java.lang.Object)
+ */
+ @Override
+ public void refresh(Object element) {
+ super.refresh(element);
+
+ ViewerContentChangeEvent event = new ViewerContentChangeEvent(this, ViewerContentChangeEvent.REFRESH);
+ EventManager.getInstance().fireEvent(event);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonViewer#refresh(java.lang.Object, boolean)
+ */
+ @Override
+ public void refresh(Object element, boolean updateLabels) {
+ super.refresh(element, updateLabels);
+
+ ViewerContentChangeEvent event = new ViewerContentChangeEvent(this, ViewerContentChangeEvent.REFRESH);
+ EventManager.getInstance().fireEvent(event);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonViewer#setSorter(org.eclipse.jface.viewers.ViewerSorter)
+ */
+ @Override
+ public void setSorter(ViewerSorter sorter) {
+ if (sorter instanceof CommonViewerSorter) {
+ sorter = new ViewViewerSorter((CommonViewerSorter)sorter);
+ ((ViewViewerSorter)sorter).setContentService(getNavigatorContentService());
+ }
+ super.setSorter(sorter);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerSorter.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerSorter.java
new file mode 100644
index 000000000..eae72bd89
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerSorter.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.internal;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreePathViewerSorter;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tcf.te.ui.trees.TreeViewerSorter;
+import org.eclipse.ui.navigator.CommonViewerSorter;
+import org.eclipse.ui.navigator.INavigatorContentService;
+
+/**
+ * Wrapper for the common navigator sorter
+ */
+public final class ViewViewerSorter extends TreePathViewerSorter {
+ // Reference to the wrapped common navigator viewer sorter
+ private final CommonViewerSorter sorter;
+ // Reference to the default viewer sorter
+ private final TreeViewerSorter defaultSorter = new TreeViewerSorter();
+
+ /**
+ * Constructor.
+ *
+ * @param sorter the common navigator viewer sorter to wrap. Must not be <code>null</code>.
+ */
+ public ViewViewerSorter(CommonViewerSorter sorter) {
+ super();
+ Assert.isNotNull(sorter);
+ this.sorter = sorter;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerComparator#category(java.lang.Object)
+ */
+ @Override
+ public int category(Object element) {
+ return sorter.category(element);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.TreePathViewerSorter#compare(org.eclipse.jface.viewers.Viewer, org.eclipse.jface.viewers.TreePath, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public int compare(Viewer viewer, TreePath parentPath, Object e1, Object e2) {
+ int result = sorter.compare(viewer, parentPath, e1, e2);
+
+ if (result == category(e1) - category(e2)) {
+ int defaultSorterResult = defaultSorter.compare(viewer, parentPath, e1, e2);
+ if (defaultSorterResult != 0) result = defaultSorterResult;
+ }
+
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerComparator#isSorterProperty(java.lang.Object, java.lang.String)
+ */
+ @Override
+ public boolean isSorterProperty(Object element, String property) {
+ return sorter.isSorterProperty(element, property);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.TreePathViewerSorter#isSorterProperty(org.eclipse.jface.viewers.TreePath, java.lang.Object, java.lang.String)
+ */
+ @Override
+ public boolean isSorterProperty(TreePath parentPath, Object element, String property) {
+ return sorter.isSorterProperty(parentPath, element, property);
+ }
+
+ /**
+ * Sets the content service instance to the common navigator viewer sorter.
+ *
+ * @param contentService The content service instance. Must not be <code>null</code>:
+ */
+ public void setContentService(INavigatorContentService contentService) {
+ Assert.isNotNull(contentService);
+ sorter.setContentService(contentService);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/editor/Editor.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/editor/Editor.java
new file mode 100644
index 000000000..e89d2f29f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/editor/Editor.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.internal.editor;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.tcf.te.ui.views.extensions.EditorPageBinding;
+import org.eclipse.tcf.te.ui.views.extensions.EditorPageBindingExtensionPointManager;
+import org.eclipse.tcf.te.ui.views.extensions.EditorPageExtensionPointManager;
+import org.eclipse.tcf.te.ui.views.interfaces.IEditorPage;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistable;
+import org.eclipse.ui.IPersistableEditor;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.forms.editor.IFormPage;
+
+
+/**
+ * Details editor.
+ */
+public class Editor extends FormEditor implements IPersistableEditor {
+
+ // The reference to an memento to restore once the editor got activated
+ private IMemento mementoToRestore;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
+ */
+ @Override
+ protected void addPages() {
+ // Read extension point and add the contributed pages.
+ IEditorInput input = getEditorInput();
+ // Get all applicable editor page bindings
+ EditorPageBinding[] bindings = EditorPageBindingExtensionPointManager.getInstance().getApplicableEditorPageBindings(input);
+ for (EditorPageBinding binding : bindings) {
+ String pageId = binding.getPageId();
+ if (pageId != null) {
+ // Get the corresponding editor page instance
+ IEditorPage page = EditorPageExtensionPointManager.getInstance().getEditorPage(pageId, true);
+ if (page != null) {
+ try {
+ // Associate this editor with the page instance.
+ // This is typically done in the constructor, but we are
+ // utilizing a default constructor to instantiate the page.
+ page.initialize(this);
+
+ // Read in the "insertBefore" and "insertAfter" properties of the binding
+ String insertBefore = binding.getInsertBefore().trim();
+ String insertAfter = binding.getInsertAfter().trim();
+
+ // insertBefore will eclipse insertAfter is both is specified.
+ if (!"".equals(insertBefore)) { //$NON-NLS-1$
+ // If it is "first", we insert the page at index 0
+ if ("first".equalsIgnoreCase(insertBefore)) { //$NON-NLS-1$
+ addPage(0, page);
+ } else {
+ // Find the index of the page we shall insert this page before
+ int index = getIndexOf(insertBefore);
+ if (index != -1) addPage(index, page);
+ else addPage(page);
+ }
+ } else if (!"".equals(insertAfter) && !"last".equalsIgnoreCase(insertAfter)) { //$NON-NLS-1$ //$NON-NLS-2$
+ // Find the index of the page we shall insert this page after
+ int index = getIndexOf(insertAfter);
+ if (index != -1 && index + 1 < pages.size()) addPage(index + 1, page);
+ else addPage(page);
+ } else {
+ // And add the page to the editor as last page.
+ addPage(page);
+ }
+ } catch (PartInitException e) { /* ignored on purpose */ }
+ }
+ }
+ }
+
+ if (mementoToRestore != null) {
+ // Loop over all registered pages and pass on the editor specific memento
+ // to the pages which implements IPersistableEditor as well
+ for (Object page : pages) {
+ if (page instanceof IPersistableEditor) {
+ ((IPersistableEditor)page).restoreState(mementoToRestore);
+ }
+ }
+ mementoToRestore = null;
+ }
+ }
+
+ /**
+ * Returns the index of the page with the given id.
+ *
+ * @param pageId The page id. Must not be <code>null</code>.
+ * @return The page index or <code>-1</code> if not found.
+ */
+ private int getIndexOf(String pageId) {
+ Assert.isNotNull(pageId);
+ for (int i = 0; i < pages.size(); i++) {
+ Object page = pages.get(i);
+ if (page instanceof IFormPage) {
+ IFormPage fpage = (IFormPage)page;
+ if (fpage.getId().equals(pageId))
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormPage#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
+ */
+ @Override
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+ super.init(site, input);
+
+ // Update the part name
+ if (!"".equals(input.getName())) setPartName(input.getName()); //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ commitPages(true);
+ editorDirtyStateChanged();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#doSaveAs()
+ */
+ @Override
+ public void doSaveAs() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
+ */
+ @Override
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPersistableEditor#restoreState(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public void restoreState(IMemento memento) {
+ // Get the editor specific memento
+ mementoToRestore = internalGetMemento(memento);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public void saveState(IMemento memento) {
+ // Get the editor specific memento
+ memento = internalGetMemento(memento);
+ // Loop over all registered pages and pass on the editor specific memento
+ // to the pages which implements IPersistable as well
+ for (Object page : pages) {
+ if (page instanceof IPersistable) {
+ ((IPersistable)page).saveState(memento);
+ }
+ }
+ }
+
+ /**
+ * Internal helper method accessing our editor local child memento
+ * from the given parent memento.
+ */
+ private IMemento internalGetMemento(IMemento memento) {
+ // Assume the editor memento to be the same as the parent memento
+ IMemento editorMemento = memento;
+
+ // If the parent memento is not null, create a child within the parent
+ if (memento != null) {
+ editorMemento = memento.getChild(Editor.class.getName());
+ if (editorMemento == null) {
+ editorMemento = memento.createChild(Editor.class.getName());
+ }
+ } else {
+ // The parent memento is null. Create a new internal instance
+ // of a XMLMemento. This case is happening if the user switches
+ // to another perspective an the view becomes visible by this switch.
+ editorMemento = XMLMemento.createWriteRoot(Editor.class.getName());
+ }
+
+ return editorMemento;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.MultiPageEditorPart#getAdapter(java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Class adapter) {
+ // We pass on the adapt request to the currently active page
+ Object adapterInstance = getActivePageInstance() != null ? getActivePageInstance().getAdapter(adapter) : null;
+ if (adapterInstance == null) {
+ // If failed to adapt via the currently active page, pass on to the super implementation
+ adapterInstance = super.getAdapter(adapter);
+ }
+ return adapterInstance;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/editor/EditorInput.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/editor/EditorInput.java
new file mode 100644
index 000000000..6fb2ad2d9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/editor/EditorInput.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.internal.editor;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.tcf.te.ui.views.activator.UIPlugin;
+import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.tcf.te.ui.views.interfaces.ImageConsts;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistableElement;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.navigator.CommonNavigator;
+import org.eclipse.ui.navigator.CommonViewer;
+
+
+/**
+ * Details editor input implementation.
+ */
+public class EditorInput implements IEditorInput, IPersistableElement {
+ // The parent editor id
+ private final String id;
+ // The editor input name, once determined
+ private String name;
+ // The node (selection) the editor is showing
+ private final Object node;
+
+ /**
+ * Constructor.
+ *
+ * @param node The node (selection) the editor is showing. Must not be <code>null</code>.
+ */
+ public EditorInput(Object node) {
+ this(node, IUIConstants.ID_EDITOR);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param node The node (selection) the editor is showing. Must not be <code>null</code>.
+ * @param id The parent editor id or <code>null</code>
+ */
+ public EditorInput(Object node, String id) {
+ super();
+ this.id = id;
+ Assert.isNotNull(node);
+ this.node = node;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (node != null && obj instanceof EditorInput) {
+ return node.equals(((EditorInput)obj).node)
+ && (id != null ? id.equals(((EditorInput)obj).id) : ((EditorInput)obj).id == null);
+ }
+ return super.equals(obj);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return node != null ? node.hashCode() << 16 + (id != null ? id.hashCode() : 0) : super.hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#exists()
+ */
+ @Override
+ public boolean exists() {
+ return node != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getImageDescriptor()
+ */
+ @Override
+ public ImageDescriptor getImageDescriptor() {
+ return UIPlugin.getImageDescriptor(ImageConsts.EDITOR);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getName()
+ */
+ @Override
+ public String getName() {
+ if (name == null && node != null) {
+ CommonViewer viewer = getViewer();
+ name = viewer != null && viewer.getLabelProvider() instanceof ILabelProvider ? ((ILabelProvider)viewer.getLabelProvider()).getText(node) : node.toString();
+ }
+
+ return name != null ? name : ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Get the common viewer used by the Target Explorer view instance.
+ *
+ * @return The common viewer or <code>null</code>
+ */
+ protected CommonViewer getViewer() {
+ if (PlatformUI.getWorkbench() != null && PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null
+ && PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() != null) {
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IViewPart part = page.findView(IUIConstants.ID_EXPLORER);
+ if (part instanceof CommonNavigator) {
+ return ((CommonNavigator)part).getCommonViewer();
+ }
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getPersistable()
+ */
+ @Override
+ public IPersistableElement getPersistable() {
+ // We cannot persist this kind of editor input.
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPersistableElement#getFactoryId()
+ */
+ @Override
+ public String getFactoryId() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public void saveState(IMemento memento) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getToolTipText()
+ */
+ @Override
+ public String getToolTipText() {
+ return getName();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (IPersistableElement.class.isAssignableFrom(adapter)) {
+ return getPersistable();
+ }
+
+ // If the adapter can be applied to the node instance, return the node
+ Object adapted = Platform.getAdapterManager().getAdapter(node, adapter);
+ if (adapted != null) return adapted;
+
+ return Platform.getAdapterManager().getAdapter(this, adapter);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/navigator/ContentProviderDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/navigator/ContentProviderDelegate.java
new file mode 100644
index 000000000..ab069dcf1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/navigator/ContentProviderDelegate.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.internal.navigator;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+
+/**
+ * Content provider delegate implementation.
+ */
+public class ContentProviderDelegate implements ITreeContentProvider {
+ private final static Object[] NO_ELEMENTS = new Object[0];
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ return NO_ELEMENTS;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ @Override
+ public Object getParent(Object element) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ @Override
+ public boolean hasChildren(Object element) {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ @Override
+ public void dispose() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/navigator/LabelProviderDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/navigator/LabelProviderDelegate.java
new file mode 100644
index 000000000..aa5fd5be3
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/navigator/LabelProviderDelegate.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.internal.navigator;
+
+import org.eclipse.jface.viewers.LabelProvider;
+
+
+/**
+ * Label provider delegate implementation.
+ */
+public class LabelProviderDelegate extends LabelProvider {
+
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/listeners/WorkbenchPartListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/listeners/WorkbenchPartListener.java
new file mode 100644
index 000000000..1649f023e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/listeners/WorkbenchPartListener.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.listeners;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.contexts.IContextActivation;
+import org.eclipse.ui.contexts.IContextService;
+
+/**
+ * The part listener implementation. Takes care of
+ * activation and deactivation of key binding contexts.
+ */
+public class WorkbenchPartListener implements IPartListener2 {
+
+ // The context activations per workbench part reference
+ private final Map<IWorkbenchPartReference, IContextActivation> activations = new HashMap<IWorkbenchPartReference, IContextActivation>();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPartListener2#partBroughtToTop(org.eclipse.ui.IWorkbenchPartReference)
+ */
+ @Override
+ public void partBroughtToTop(IWorkbenchPartReference partRef) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPartListener2#partOpened(org.eclipse.ui.IWorkbenchPartReference)
+ */
+ @Override
+ public void partOpened(IWorkbenchPartReference partRef) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference)
+ */
+ @Override
+ public void partClosed(IWorkbenchPartReference partRef) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.IWorkbenchPartReference)
+ */
+ @Override
+ public void partVisible(IWorkbenchPartReference partRef) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPartListener2#partHidden(org.eclipse.ui.IWorkbenchPartReference)
+ */
+ @Override
+ public void partHidden(IWorkbenchPartReference partRef) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPartListener2#partActivated(org.eclipse.ui.IWorkbenchPartReference)
+ */
+ @Override
+ public void partActivated(IWorkbenchPartReference partRef) {
+ if (IUIConstants.ID_EXPLORER.equals(partRef.getId())) {
+ IWorkbenchPart part = partRef.getPart(false);
+ if (part != null && part.getSite() != null) {
+ IContextService service = (IContextService)part.getSite().getService(IContextService.class);
+ if (service != null) {
+ IContextActivation activation = service.activateContext(IUIConstants.ID_EXPLORER);
+ if (activation != null) {
+ activations.put(partRef, activation);
+ } else {
+ activations.remove(partRef);
+ }
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPartListener2#partDeactivated(org.eclipse.ui.IWorkbenchPartReference)
+ */
+ @Override
+ public void partDeactivated(IWorkbenchPartReference partRef) {
+ if (IUIConstants.ID_EXPLORER.equals(partRef.getId())) {
+ IWorkbenchPart part = partRef.getPart(false);
+ if (part != null && part.getSite() != null) {
+ IContextService service = (IContextService)part.getSite().getService(IContextService.class);
+ if (service != null) {
+ IContextActivation activation = activations.remove(partRef);
+ if (activation != null) {
+ service.deactivateContext(activation);
+ }
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.IWorkbenchPartReference)
+ */
+ @Override
+ public void partInputChanged(IWorkbenchPartReference partRef) {
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/listeners/WorkbenchWindowListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/listeners/WorkbenchWindowListener.java
new file mode 100644
index 000000000..491c43711
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/listeners/WorkbenchWindowListener.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.listeners;
+
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbenchWindow;
+
+/**
+ * The window listener implementation. Takes care of the
+ * management of the global listeners per workbench window.
+ */
+public class WorkbenchWindowListener implements IWindowListener {
+ // The global part listener instance
+ private final WorkbenchPartListener partListener = new WorkbenchPartListener();
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow)
+ */
+ @Override
+ public void windowActivated(IWorkbenchWindow window) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow)
+ */
+ @Override
+ public void windowDeactivated(IWorkbenchWindow window) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow)
+ */
+ @Override
+ public void windowClosed(IWorkbenchWindow window) {
+ // On close, remove all global listeners from the window
+ if (window != null && window.getPartService() != null) {
+ window.getPartService().removePartListener(partListener);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow)
+ */
+ @Override
+ public void windowOpened(IWorkbenchWindow window) {
+ // On open, register all global listener to the window
+ if (window != null && window.getPartService() != null) {
+ // Get the part service
+ IPartService service = window.getPartService();
+ // Unregister the part listener, just in case
+ service.removePartListener(partListener);
+ // Register the part listener
+ service.addPartListener(partListener);
+ // Signal the active part to the part listener after registration
+ partListener.partActivated(window.getActivePage().getActivePartReference());
+ }
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/nls/Messages.java
new file mode 100644
index 000000000..675ed9708
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/nls/Messages.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.nls;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Target Explorer UI plugin externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tcf.te.ui.views.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String View_toolTip;
+ public static String View_toolTip2;
+ public static String View_toolTip3;
+ public static String View_workingSetModel;
+
+ public static String NewActionProvider_NewMenu_label;
+ public static String NewActionProvider_NewWizardCommandAction_label;
+ public static String NewActionProvider_NewWizardCommandAction_tooltip;
+
+ public static String WorkingSetActionProvider_multipleWorkingSets;
+
+ public static String WorkingSetRootModeActionGroup_Top_Level_Element;
+ public static String WorkingSetRootModeActionGroup_Target;
+ public static String WorkingSetRootModeActionGroup_Working_Set;
+
+ public static String WorkingSetContentProvider_others_name;
+
+ public static String PropertiesCommandHandler_error_initPartFailed;
+
+ public static String TargetWorkingSetPage_workingSet_name;
+ public static String TargetWorkingSetPage_workspace_content;
+ public static String TargetWorkingSetPage_add_button;
+ public static String TargetWorkingSetPage_addAll_button;
+ public static String TargetWorkingSetPage_remove_button;
+ public static String TargetWorkingSetPage_removeAll_button;
+ public static String TargetWorkingSetPage_workingSet_content;
+ public static String TargetWorkingSetPage_warning_nameWhitespace;
+ public static String TargetWorkingSetPage_warning_nameMustNotBeEmpty;
+ public static String TargetWorkingSetPage_warning_workingSetExists;
+ public static String TargetWorkingSetPage_warning_resourceMustBeChecked;
+ public static String TargetWorkingSetPage_title;
+ public static String TargetWorkingSetPage_workingSet_description;
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/nls/Messages.properties
new file mode 100644
index 000000000..d7cec009a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/nls/Messages.properties
@@ -0,0 +1,45 @@
+#
+# org.eclipse.tcf.te.ui.views
+# Externalized Strings.
+#
+
+# ***** View *****
+
+View_toolTip= Working Set: {0}
+View_toolTip2= {0} - Working Set: {1}
+View_toolTip3= {0}/{1}
+View_workingSetModel=Working Sets
+
+# ***** Action Provider *****
+
+NewActionProvider_NewMenu_label=&New
+NewActionProvider_NewWizardCommandAction_label=&Other...
+NewActionProvider_NewWizardCommandAction_tooltip=Open the New target wizard
+
+WorkingSetActionProvider_multipleWorkingSets=Multiple Working Sets
+
+WorkingSetRootModeActionGroup_Top_Level_Element=&Top Level Elements
+WorkingSetRootModeActionGroup_Target=Targets
+WorkingSetRootModeActionGroup_Working_Set=Working Sets
+
+WorkingSetContentProvider_others_name=Other Targets
+
+# ***** Command Handler *****
+
+PropertiesCommandHandler_error_initPartFailed=Failed to initialize the Target Explorer details editor.
+
+# ***** Wizard and Dialog Pages *****
+
+TargetWorkingSetPage_warning_nameMustNotBeEmpty=The name must not be empty.
+TargetWorkingSetPage_workingSet_name=&Working set name\:
+TargetWorkingSetPage_workingSet_description=Enter a working set name and select the working set elements.
+TargetWorkingSetPage_removeAll_button=\ <- R&emove All
+TargetWorkingSetPage_remove_button=<- &Remove
+TargetWorkingSetPage_workspace_content=A&vailable targets\:
+TargetWorkingSetPage_workingSet_content=Working set &content\:
+TargetWorkingSetPage_add_button=&Add ->
+TargetWorkingSetPage_warning_workingSetExists=A working set with that name already exists.
+TargetWorkingSetPage_warning_resourceMustBeChecked=No resources selected.
+TargetWorkingSetPage_addAll_button=A&dd All ->
+TargetWorkingSetPage_title=Target Working Set
+TargetWorkingSetPage_warning_nameWhitespace=The name must not have leading or trailing whitespace.
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/perspective/PerspectiveFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/perspective/PerspectiveFactory.java
new file mode 100644
index 000000000..490d81522
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/perspective/PerspectiveFactory.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.perspective;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+import org.eclipse.ui.IPlaceholderFolderLayout;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Perspective factory.
+ */
+public class PerspectiveFactory extends PlatformObject implements IPerspectiveFactory {
+ private final static String[] VIEWS_FOR_LEFT_AREA = new String[] {
+ "org.eclipse.tcf.te.ui.views.TargetExplorer", //$NON-NLS-1$
+ "org.eclipse.ui.navigator.ProjectExplorer" //$NON-NLS-1$
+ };
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPerspectiveFactory#createInitialLayout(org.eclipse.ui.IPageLayout)
+ */
+ @Override
+ public void createInitialLayout(IPageLayout layout) {
+ // editor is placed for free
+ String editorArea = layout.getEditorArea();
+
+ boolean leftAreaActive = false;
+ for (String viewId : VIEWS_FOR_LEFT_AREA) {
+ leftAreaActive |= PlatformUI.getWorkbench().getViewRegistry().find(viewId) != null;
+ if (leftAreaActive) break;
+ }
+
+ if (leftAreaActive) {
+ // place resource navigator to the left of editor area
+ IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.3f, editorArea); //$NON-NLS-1$
+
+ for (String viewId : VIEWS_FOR_LEFT_AREA) {
+ if (PlatformUI.getWorkbench().getViewRegistry().find(viewId) != null) {
+ left.addView(viewId);
+ }
+ }
+ } else {
+ layout.createPlaceholderFolder("left", IPageLayout.LEFT, 0.3f, editorArea); //$NON-NLS-1$
+ }
+
+ // place console below the main editor
+ IFolderLayout lowerRight = layout.createFolder("lowerRight", IPageLayout.BOTTOM, 0.7f, editorArea); //$NON-NLS-1$
+ if (PlatformUI.getWorkbench().getViewRegistry().find("org.eclipse.pde.runtime.LogView") != null) //$NON-NLS-1$
+ lowerRight.addView("org.eclipse.pde.runtime.LogView"); //$NON-NLS-1$
+ if (PlatformUI.getWorkbench().getViewRegistry().find("org.eclipse.ui.views.TaskList") != null) //$NON-NLS-1$
+ lowerRight.addPlaceholder("org.eclipse.ui.views.TaskList"); //$NON-NLS-1$
+
+ // place details view port to the right of editor area
+ IPlaceholderFolderLayout right = layout.createPlaceholderFolder("right", IPageLayout.RIGHT, 0.75f, editorArea); //$NON-NLS-1$
+ if (PlatformUI.getWorkbench().getViewRegistry().find(IPageLayout.ID_OUTLINE) != null)
+ right.addPlaceholder(IPageLayout.ID_OUTLINE);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/OthersWorkingSetElementUpdater.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/OthersWorkingSetElementUpdater.java
new file mode 100644
index 000000000..28adbc63d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/OthersWorkingSetElementUpdater.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.tcf.te.ui.views.internal.ViewRoot;
+import org.eclipse.tcf.te.runtime.interfaces.workingsets.IWorkingSetElement;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.navigator.CommonViewer;
+
+/**
+ * "Others" working set element updater.
+ */
+public class OthersWorkingSetElementUpdater extends WorkingSetElementUpdater {
+ // The reference to the "Others" working set
+ private IWorkingSet othersWorkingSet;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.workingsets.WorkingSetElementUpdater#add(org.eclipse.ui.IWorkingSet)
+ */
+ @Override
+ public void add(IWorkingSet workingSet) {
+ Assert.isTrue(othersWorkingSet == null);
+ othersWorkingSet = workingSet;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.workingsets.WorkingSetElementUpdater#remove(org.eclipse.ui.IWorkingSet)
+ */
+ @Override
+ public boolean remove(IWorkingSet workingSet) {
+ Assert.isTrue(othersWorkingSet == workingSet);
+ othersWorkingSet = null;
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.workingsets.WorkingSetElementUpdater#contains(org.eclipse.ui.IWorkingSet)
+ */
+ @Override
+ public boolean contains(IWorkingSet workingSet) {
+ return othersWorkingSet == workingSet;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.workingsets.WorkingSetElementUpdater#onUpdateWorkingSets(org.eclipse.ui.navigator.CommonViewer, org.eclipse.ui.IWorkingSet[])
+ */
+ @Override
+ protected void onUpdateWorkingSets(CommonViewer viewer, IWorkingSet[] workingsets) {
+ Assert.isNotNull(viewer);
+ Assert.isNotNull(workingsets);
+
+ // The list of elements not be contained by any other working set
+ List<WorkingSetElementHolder> otherElements = new ArrayList<WorkingSetElementHolder>();
+
+ // Get all (root) elements from the common viewer
+ Object[] elements = viewer.getNavigatorContentService().createCommonContentProvider().getElements(ViewRoot.getInstance());
+
+ // Get all working sets
+ IWorkingSetManager manager = PlatformUI.getWorkbench().getWorkingSetManager();
+ IWorkingSet[] allWorkingSets = manager.getAllWorkingSets();
+
+ // Loop the elements and check if they are contained in a working set
+ for (Object element : elements) {
+ if (!(element instanceof IWorkingSetElement)) continue;
+
+ boolean isContained = isContained((IWorkingSetElement)element, allWorkingSets);
+ if (!isContained) {
+ WorkingSetElementHolder holder = new WorkingSetElementHolder(othersWorkingSet.getName(), ((IWorkingSetElement)element).getElementId());
+ holder.setElement((IWorkingSetElement)element);
+ otherElements.add(holder);
+ }
+ }
+
+ othersWorkingSet.setElements(otherElements.toArray(new IAdaptable[otherElements.size()]));
+ }
+
+ /**
+ * Walks over the given working set list and checks if the element is contained in
+ * one of them.
+ *
+ * @param element The element. Must not be <code>null</code>.
+ * @param allWorkingSets The list of working sets. Must not be <code>null</code>.
+ *
+ * @return <code>True</code> if the element is contained in at least one of the given working sets, <code>false</code> otherwise.
+ */
+ protected boolean isContained(IWorkingSetElement element, IWorkingSet[] allWorkingSets) {
+ Assert.isNotNull(element);
+ Assert.isNotNull(allWorkingSets);
+
+ boolean contained = false;
+
+ for (IWorkingSet workingSet : allWorkingSets) {
+ IAdaptable[] wsElements = workingSet.getElements();
+ for (IAdaptable wsElement : wsElements) {
+ if (!(wsElement instanceof WorkingSetElementHolder)) continue;
+
+ IWorkingSetElement candidate = ((WorkingSetElementHolder)wsElement).getElement();
+ String candidateId = ((WorkingSetElementHolder)wsElement).getElementId();
+
+ if (element.equals(candidate)) {
+ contained = true;
+ break;
+ } else if (candidate == null && element.getElementId().equals(candidateId)) {
+ contained = true;
+ ((WorkingSetElementHolder)wsElement).setElement(element);
+ break;
+ }
+ }
+ if (contained) break;
+ }
+
+ return contained;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementAdapter.java
new file mode 100644
index 000000000..aa47e8c03
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementAdapter.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.tcf.te.runtime.interfaces.workingsets.IWorkingSetElement;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetElementAdapter;
+
+/**
+ * Working set element adapter implementation.
+ */
+public class WorkingSetElementAdapter implements IWorkingSetElementAdapter {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkingSetElementAdapter#adaptElements(org.eclipse.ui.IWorkingSet, org.eclipse.core.runtime.IAdaptable[])
+ */
+ @Override
+ public IAdaptable[] adaptElements(IWorkingSet ws, IAdaptable[] elements) {
+ List<IAdaptable> adapted = new ArrayList<IAdaptable>();
+
+ // All elements of a target explorer working set needs to
+ // be of type WorkingSetElementHolder
+ for (IAdaptable adaptable : elements) {
+ if (adaptable instanceof WorkingSetElementHolder) {
+ adapted.add(adaptable);
+ } else {
+ IWorkingSetElement element = null;
+ if (adaptable instanceof IWorkingSetElement) {
+ element = (IWorkingSetElement) adaptable;
+ } else {
+ element = (IWorkingSetElement) adaptable.getAdapter(IWorkingSetElement.class);
+ }
+ // Create the WorkingSetElementHolder for the element
+ if (element != null) {
+ WorkingSetElementHolder holder = new WorkingSetElementHolder(ws.getName(), element.getElementId());
+ holder.setElement(element);
+ adapted.add(holder);
+ }
+ }
+ }
+
+ return adapted.toArray(new IAdaptable[adapted.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkingSetElementAdapter#dispose()
+ */
+ @Override
+ public void dispose() {
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolder.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolder.java
new file mode 100644
index 000000000..91c4c33d1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolder.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tcf.te.ui.views.interfaces.workingsets.IWorkingSetNameIDs;
+import org.eclipse.tcf.te.runtime.interfaces.workingsets.IWorkingSetElement;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistableElement;
+
+/**
+ * A WorkingSetElementHolder is a place holder for an {@link IWorkingSetElement}. It contains the
+ * working set element's id and its working set name that it belongs to. A WorkingSetElementHolder
+ * can only belong to one working set, while multiple WorkingSetElementHolder which have a same
+ * working set element's id. That means a working set element can be added to multiple working sets
+ * at the same time.
+ * <p>
+ * A WorkingSetElementHolder instance can be persisted and restored by an element factory.
+ */
+public final class WorkingSetElementHolder extends PlatformObject implements IPersistableElement {
+ // The working set element's id.
+ private String elementId;
+ // The working set's name that it belongs to.
+ private String wsName;
+ // The working set element
+ private IWorkingSetElement element;
+
+ /**
+ * Create an empty holder.
+ */
+ public WorkingSetElementHolder() {
+ }
+
+ /**
+ * Create an holder with a specified working set element's id and and a working set name.
+ *
+ * @param wsName The working set name.
+ * @param elementId The working set element's id.
+ */
+ public WorkingSetElementHolder(String wsName, String elementId) {
+ this.elementId = elementId;
+ this.wsName = wsName;
+ }
+
+ /**
+ * Set the working set element's id.
+ *
+ * @param id The working set element's id.
+ */
+ public void setElementId(String id) {
+ this.elementId = id;
+ }
+
+ /**
+ * Get the working set element's id.
+ *
+ * @return The working set element's id.
+ */
+ public String getElementId() {
+ return elementId;
+ }
+
+ /**
+ * Set the working set's name.
+ *
+ * @param name The working set name.
+ */
+ public void setWorkingSetName(String name) {
+ this.wsName = name;
+ }
+
+ /**
+ * Get the working set's name.
+ *
+ * @return The working set's name.
+ */
+ public String getWorkingSetName() {
+ return wsName;
+ }
+
+ /**
+ * Set the working set element.
+ *
+ * @param element The working set element.
+ */
+ public void setElement(IWorkingSetElement element) {
+ this.element = element;
+ }
+
+ /**
+ * Get the working set element.
+ *
+ * @return The working set element.
+ */
+ public IWorkingSetElement getElement() {
+ return element;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPersistableElement#getFactoryId()
+ */
+ @Override
+ public String getFactoryId() {
+ return "org.eclipse.tcf.te.ui.views.workingsets.WorkingSetElementHolderFactory"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public void saveState(IMemento memento) {
+ memento.putString(IWorkingSetNameIDs.FACTORY_ID, getFactoryId());
+ memento.putString(IWorkingSetNameIDs.ATTR_ELEMENTID, elementId);
+ memento.putString(IWorkingSetNameIDs.ATTR_WORKINGSET_NAME, wsName);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (IPersistableElement.class.equals(adapter)) {
+ return this;
+ }
+ if (IWorkingSetElement.class.equals(adapter)) {
+ return element;
+ }
+ return super.getAdapter(adapter);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolderAdapterFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolderAdapterFactory.java
new file mode 100644
index 000000000..ff21620d7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolderAdapterFactory.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.tcf.te.runtime.interfaces.workingsets.IWorkingSetElement;
+
+/**
+ * The adapter factory to adapt a working set element holder to a working set element.
+ */
+@SuppressWarnings("rawtypes")
+public class WorkingSetElementHolderAdapterFactory implements IAdapterFactory {
+ // The adapters.
+ private Class[] adapters = { IWorkingSetElement.class };
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ if (adaptableObject instanceof WorkingSetElementHolder) {
+ return ((WorkingSetElementHolder) adaptableObject).getAdapter(adapterType);
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+ */
+ @Override
+ public Class[] getAdapterList() {
+ return adapters;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolderFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolderFactory.java
new file mode 100644
index 000000000..049ac8f7e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementHolderFactory.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.tcf.te.ui.views.interfaces.workingsets.IWorkingSetNameIDs;
+import org.eclipse.ui.IElementFactory;
+import org.eclipse.ui.IMemento;
+
+/**
+ * A WorkingSetElementHolderFactory is an element factory used to create a working set element
+ * holder from a memento element.
+ */
+public class WorkingSetElementHolderFactory implements IElementFactory {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IElementFactory#createElement(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public IAdaptable createElement(IMemento memento) {
+ WorkingSetElementHolder holder = new WorkingSetElementHolder();
+ String elementId = memento.getString(IWorkingSetNameIDs.ATTR_ELEMENTID);
+ holder.setElementId(elementId);
+ String workingSetName = memento.getString(IWorkingSetNameIDs.ATTR_WORKINGSET_NAME);
+ holder.setWorkingSetName(workingSetName);
+ return holder;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementUpdater.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementUpdater.java
new file mode 100644
index 000000000..b3a0269ff
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetElementUpdater.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets;
+
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.tcf.te.ui.views.events.ViewerContentChangeEvent;
+import org.eclipse.tcf.te.runtime.events.EventManager;
+import org.eclipse.tcf.te.ui.events.AbstractEventListener;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetUpdater;
+import org.eclipse.ui.navigator.CommonViewer;
+
+/**
+ * Working set element updater implementation.
+ */
+public class WorkingSetElementUpdater extends AbstractEventListener implements IWorkingSetUpdater, IExecutableExtension {
+ // List of working sets managed by this updater
+ private final List<IWorkingSet> workingSets = new ArrayList<IWorkingSet>();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
+ // Register ourself as ViewContentChangeEvent listener
+ EventManager.getInstance().addEventListener(this, ViewerContentChangeEvent.class);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkingSetUpdater#add(org.eclipse.ui.IWorkingSet)
+ */
+ @Override
+ public void add(IWorkingSet workingSet) {
+ synchronized (workingSets) {
+ workingSets.add(workingSet);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkingSetUpdater#remove(org.eclipse.ui.IWorkingSet)
+ */
+ @Override
+ public boolean remove(IWorkingSet workingSet) {
+ synchronized (workingSets) {
+ return workingSets.remove(workingSet);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkingSetUpdater#contains(org.eclipse.ui.IWorkingSet)
+ */
+ @Override
+ public boolean contains(IWorkingSet workingSet) {
+ synchronized (workingSets) {
+ return workingSets.contains(workingSet);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkingSetUpdater#dispose()
+ */
+ @Override
+ public void dispose() {
+ synchronized (workingSets) {
+ workingSets.clear();
+ }
+
+ // Remove ourself as event listener
+ EventManager.getInstance().removeEventListener(this);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.interfaces.events.IEventListener#eventFired(java.util.EventObject)
+ */
+ @Override
+ public void eventFired(EventObject event) {
+ if (!(event instanceof ViewerContentChangeEvent) && !(((ViewerContentChangeEvent)event).getSource() instanceof CommonViewer)) {
+ return;
+ }
+
+ // Create a snapshot of the working sets
+ final IWorkingSet[] snapshot;
+ synchronized (workingSets) {
+ snapshot = workingSets.toArray(new IWorkingSet[workingSets.size()]);
+ }
+
+ // Update the working sets
+ onUpdateWorkingSets((CommonViewer)((ViewerContentChangeEvent)event).getSource(), snapshot);
+ }
+
+ /**
+ * Update the managed working sets based on the content of the given viewer.
+ *
+ * @param viewer The viewer. Must not be <code>null</code>.
+ * @param workingsets The working sets. Must not be <code>null</code>.
+ */
+ protected void onUpdateWorkingSets(CommonViewer viewer, IWorkingSet[] workingsets) {
+ Assert.isNotNull(viewer);
+ Assert.isNotNull(workingsets);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetFilter.java
new file mode 100644
index 000000000..dfc0aff13
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetFilter.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.tcf.te.ui.views.interfaces.workingsets.IWorkingSetIDs;
+import org.eclipse.tcf.te.runtime.interfaces.workingsets.IWorkingSetElement;
+import org.eclipse.ui.IAggregateWorkingSet;
+import org.eclipse.ui.IContainmentAdapter;
+import org.eclipse.ui.IWorkingSet;
+
+/**
+ * The working set filter filters elements from a view that are neither a parent nor
+ * children of a working set element.
+ */
+public class WorkingSetFilter extends ViewerFilter {
+ private boolean active = false;
+
+ /**
+ * Sets the working set filter active or inactive.
+ *
+ * @param active <code>True</code> to set the filter active, <code>false</code> to set the filter inactive.
+ */
+ public final void setActive(boolean active) {
+ this.active = active;
+ }
+
+ /**
+ * Determines if an element should be filtered out.
+ *
+ * @see ViewerFilter#select(Viewer, Object, Object)
+ */
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ if (active && parentElement instanceof IWorkingSet) {
+ if (((IWorkingSet)parentElement).isEmpty()) {
+ return true;
+ }
+ if (parentElement instanceof IAggregateWorkingSet) {
+ List<IWorkingSet> workingSets = Arrays.asList(((IAggregateWorkingSet)parentElement).getComponents());
+ if (workingSets.contains(element) || IWorkingSetIDs.ID_WS_OTHERS.equals(((IWorkingSet)element).getId())) {
+ return true;
+ }
+ }
+ if (element != null) {
+ return isEnclosed((IWorkingSet)parentElement, element);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns if the given element is enclosed by a working set element.
+ * The IContainmentAdapter of each working set element is used for the
+ * containment test. If there is no IContainmentAdapter for a working
+ * set element, a simple resource based test is used.
+ *
+ * @param element The element to test for enclosure by a working set element
+ * @return true if element is enclosed by a working set element and false otherwise.
+ */
+ private boolean isEnclosed(IWorkingSet workingSet, Object element) {
+ IAdaptable[] workingSetElements = workingSet.getElements();
+
+ for (int i = 0; i < workingSetElements.length; i++) {
+ IAdaptable workingSetElement = workingSetElements[i];
+ IContainmentAdapter containmentAdapter = (IContainmentAdapter) workingSetElement.getAdapter(IContainmentAdapter.class);
+
+ // if there is no IContainmentAdapter defined for the working
+ // set element type fall back to using resource based
+ // containment check
+ if (containmentAdapter != null) {
+ if (containmentAdapter.contains(workingSetElement, element,
+ IContainmentAdapter.CHECK_CONTEXT
+ | IContainmentAdapter.CHECK_IF_CHILD
+ | IContainmentAdapter.CHECK_IF_ANCESTOR
+ | IContainmentAdapter.CHECK_IF_DESCENDANT)) {
+ return true;
+ }
+ } else if (isEnclosedElement(element, workingSetElement)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns if the given element is enclosed by a working set element.
+ * A element is enclosed if it is either a parent of a working set
+ * element, a child of a working set element or a working set element
+ * itself.
+ *
+ * @param element The element to test for enclosure by a working set element
+ * @param workingSetElement The working set element. Must be not <code>null</code>.
+ *
+ * @return true if element is enclosed by a working set element and false otherwise.
+ */
+ private boolean isEnclosedElement(Object element, IAdaptable workingSetElement) {
+ Assert.isNotNull(workingSetElement);
+
+ if (workingSetElement.equals(element)) {
+ return true;
+ }
+
+ if (element instanceof IWorkingSetElement) {
+ IWorkingSetElement wsElement = (IWorkingSetElement) element;
+ WorkingSetElementHolder holder = (WorkingSetElementHolder) workingSetElement.getAdapter(WorkingSetElementHolder.class);
+ if (holder != null) {
+ if (wsElement.equals(holder.getElement())) {
+ return true;
+ }
+ if (wsElement.getElementId().equals(holder.getElementId())) {
+ holder.setElement(wsElement);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetViewerSorter.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetViewerSorter.java
new file mode 100644
index 000000000..1c6a890a3
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetViewerSorter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tcf.te.ui.views.interfaces.workingsets.IWorkingSetIDs;
+import org.eclipse.tcf.te.ui.trees.TreeViewerSorter;
+import org.eclipse.ui.IWorkingSet;
+
+/**
+ * Working set viewer sorter implementation.
+ */
+public class WorkingSetViewerSorter extends TreeViewerSorter {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.trees.TreeViewerSorter#doCompare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object, java.lang.String, int, int)
+ */
+ @Override
+ protected int doCompare(Viewer viewer, Object node1, Object node2, String sortColumn, int index, int inverter) {
+ if (node1 instanceof IWorkingSet && node2 instanceof IWorkingSet) {
+ // The "Others" working set will appear always at the bottom of the tree
+ if (IWorkingSetIDs.ID_WS_OTHERS.equals(((IWorkingSet)node1).getId())) {
+ return 1;
+ }
+ if (IWorkingSetIDs.ID_WS_OTHERS.equals(((IWorkingSet)node2).getId())) {
+ return -1;
+ }
+ }
+ return super.doCompare(viewer, node1, node2, sortColumn, index, inverter);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetsContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetsContentProvider.java
new file mode 100644
index 000000000..8b3e344b7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetsContentProvider.java
@@ -0,0 +1,298 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tcf.te.ui.views.events.ViewerContentChangeEvent;
+import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.tcf.te.ui.views.interfaces.workingsets.IWorkingSetIDs;
+import org.eclipse.tcf.te.ui.views.internal.View;
+import org.eclipse.tcf.te.ui.views.internal.ViewRoot;
+import org.eclipse.tcf.te.ui.views.nls.Messages;
+import org.eclipse.tcf.te.runtime.events.EventManager;
+import org.eclipse.tcf.te.runtime.interfaces.workingsets.IWorkingSetElement;
+import org.eclipse.ui.IAggregateWorkingSet;
+import org.eclipse.ui.ILocalWorkingSetManager;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.navigator.NavigatorContentService;
+import org.eclipse.ui.navigator.CommonNavigator;
+import org.eclipse.ui.navigator.CommonViewer;
+import org.eclipse.ui.navigator.ICommonContentExtensionSite;
+import org.eclipse.ui.navigator.ICommonContentProvider;
+import org.eclipse.ui.navigator.IExtensionStateModel;
+
+/**
+ * Provides children and parents for IWorkingSets.
+ * <p>
+ * Copied and adapted from <code>org.eclipse.ui.internal.navigator.workingsets.WorkingSetContentProvider</code>.
+ */
+@SuppressWarnings("restriction")
+public class WorkingSetsContentProvider implements ICommonContentProvider {
+
+ /**
+ * The extension id for the WorkingSet extension.
+ */
+ public static final String EXTENSION_ID = "org.eclipse.tcf.te.ui.views.navigator.content.workingSets"; //$NON-NLS-1$
+
+ /**
+ * A key used by the Extension State Model to keep track of whether top level Working Sets or
+ * Projects should be shown in the viewer.
+ */
+ public static final String SHOW_TOP_LEVEL_WORKING_SETS = EXTENSION_ID + ".showTopLevelWorkingSets"; //$NON-NLS-1$
+
+ private static final Object[] NO_CHILDREN = new Object[0];
+
+ private WorkingSetHelper helper;
+ /* default */ IAggregateWorkingSet workingSetRoot;
+ private IExtensionStateModel extensionStateModel;
+ private CommonNavigator targetExplorer;
+ private CommonViewer viewer;
+
+ private ILocalWorkingSetManager localWorkingSetManager;
+
+ private IPropertyChangeListener rootModeListener = new IPropertyChangeListener() {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+ */
+ @SuppressWarnings("synthetic-access")
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ if (SHOW_TOP_LEVEL_WORKING_SETS.equals(event.getProperty())) {
+ updateRootMode();
+ }
+ }
+
+ };
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.ICommonContentProvider#init(org.eclipse.ui.navigator.ICommonContentExtensionSite)
+ */
+ @Override
+ public void init(ICommonContentExtensionSite config) {
+ NavigatorContentService cs = (NavigatorContentService) config.getService();
+ viewer = (CommonViewer) cs.getViewer();
+ targetExplorer = viewer.getCommonNavigator();
+
+ localWorkingSetManager = targetExplorer instanceof View ? ((View)targetExplorer).getLocalWorkingSetManager() : PlatformUI.getWorkbench().createLocalWorkingSetManager();
+
+ extensionStateModel = config.getExtensionStateModel();
+ extensionStateModel.addPropertyChangeListener(rootModeListener);
+
+ updateRootMode();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.IMementoAware#restoreState(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public void restoreState(IMemento memento) {
+ // We can call the local working set manager restoreState(memento) method
+ // only as long the working set manager is empty
+ if (memento != null && localWorkingSetManager.getWorkingSets().length == 0) {
+ localWorkingSetManager.restoreState(memento);
+
+ IWorkingSet old = localWorkingSetManager.getWorkingSet("Others"); //$NON-NLS-1$
+ if (old != null) localWorkingSetManager.removeWorkingSet(old);
+
+ // Create the "Others" working set if not restored from the memento
+ IWorkingSet others = localWorkingSetManager.getWorkingSet(Messages.WorkingSetContentProvider_others_name);
+ if (others == null) {
+ others = localWorkingSetManager.createWorkingSet(Messages.WorkingSetContentProvider_others_name, new IAdaptable[0]);
+ others.setId(IWorkingSetIDs.ID_WS_OTHERS);
+ localWorkingSetManager.addWorkingSet(others);
+ } else {
+ others.setId(IWorkingSetIDs.ID_WS_OTHERS);
+ }
+ }
+
+ // Trigger an update of the "Others" working set
+ ViewerContentChangeEvent event = new ViewerContentChangeEvent(viewer, ViewerContentChangeEvent.REFRESH);
+ EventManager.getInstance().fireEvent(event);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.IMementoAware#saveState(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public void saveState(IMemento memento) {
+ if (memento != null) localWorkingSetManager.saveState(memento);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof IWorkingSet) {
+ IWorkingSet workingSet = (IWorkingSet) parentElement;
+ if (workingSet.isAggregateWorkingSet() && targetExplorer != null) {
+ switch (targetExplorer.getRootMode()) {
+ case IUIConstants.MODE_WORKING_SETS:
+ List<IWorkingSet> allWorkingSets = new ArrayList<IWorkingSet>();
+ allWorkingSets.addAll(Arrays.asList(((IAggregateWorkingSet) workingSet).getComponents()));
+ allWorkingSets.addAll(Arrays.asList(localWorkingSetManager.getWorkingSets()));
+ return allWorkingSets.toArray(new IWorkingSet[allWorkingSets.size()]);
+ case IUIConstants.MODE_NORMAL:
+ return getWorkingSetElements(workingSet);
+ }
+ }
+
+ return getWorkingSetElements(workingSet);
+ }
+ return NO_CHILDREN;
+ }
+
+ /* default */ IAdaptable[] getWorkingSetElements(IWorkingSet workingSet) {
+ Assert.isNotNull(workingSet);
+ List<IAdaptable> elements = new ArrayList<IAdaptable>();
+ for (IAdaptable candidate : workingSet.getElements()) {
+ if (candidate instanceof WorkingSetElementHolder) {
+ WorkingSetElementHolder holder = (WorkingSetElementHolder)candidate;
+ IWorkingSetElement element = holder.getElement();
+ // If the element is null, try to look up the element through the content provider
+ if (element == null) {
+ ITreeContentProvider contentProvider = (ITreeContentProvider)viewer.getContentProvider();
+ for (Object elementCandidate : contentProvider.getElements(ViewRoot.getInstance())) {
+ if (elementCandidate instanceof IWorkingSetElement && ((IWorkingSetElement)elementCandidate).getElementId().equals(holder.getElementId())) {
+ holder.setElement((IWorkingSetElement)elementCandidate);
+ element = holder.getElement();
+ break;
+ }
+ }
+ }
+ if (element != null) elements.add(element);
+ } else {
+ elements.add(candidate);
+ }
+ }
+ return elements.toArray(new IAdaptable[elements.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ @Override
+ public Object getParent(Object element) {
+ if (helper != null) return helper.getParent(element);
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ @Override
+ public boolean hasChildren(Object element) {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object)
+ */
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ @Override
+ public void dispose() {
+ helper = null;
+ extensionStateModel.removePropertyChangeListener(rootModeListener);
+ // If we have create the local working set manager, we have to dispose it
+ if (!(targetExplorer instanceof View)) localWorkingSetManager.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (newInput instanceof IWorkingSet) {
+ IWorkingSet rootSet = (IWorkingSet) newInput;
+ helper = new WorkingSetHelper(rootSet);
+ }
+ }
+
+ private void updateRootMode() {
+ if (targetExplorer == null) {
+ return;
+ }
+ if (extensionStateModel.getBooleanProperty(SHOW_TOP_LEVEL_WORKING_SETS)) {
+ targetExplorer.setRootMode(IUIConstants.MODE_WORKING_SETS);
+ }
+ else {
+ targetExplorer.setRootMode(IUIConstants.MODE_NORMAL);
+ }
+ }
+
+ protected class WorkingSetHelper {
+
+ private final IWorkingSet workingSet;
+ private final Map<Object, Object> parents = new WeakHashMap<Object, Object>();
+
+ /**
+ * Create a Helper class for the given working set
+ *
+ * @param set The set to use to build the item to parent map.
+ */
+ public WorkingSetHelper(IWorkingSet set) {
+ workingSet = set;
+
+ if (workingSet.isAggregateWorkingSet()) {
+ IAggregateWorkingSet aggregateSet = (IAggregateWorkingSet) workingSet;
+ if (workingSetRoot == null) workingSetRoot = aggregateSet;
+
+ IWorkingSet[] components = aggregateSet.getComponents();
+
+ for (int componentIndex = 0; componentIndex < components.length; componentIndex++) {
+ IAdaptable[] elements = getWorkingSetElements(components[componentIndex]);
+ for (int elementsIndex = 0; elementsIndex < elements.length; elementsIndex++) {
+ parents.put(elements[elementsIndex], components[componentIndex]);
+ }
+ parents.put(components[componentIndex], aggregateSet);
+
+ }
+ }
+ else {
+ IAdaptable[] elements = getWorkingSetElements(workingSet);
+ for (int elementsIndex = 0; elementsIndex < elements.length; elementsIndex++) {
+ parents.put(elements[elementsIndex], workingSet);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param element An element from the viewer
+ * @return The parent associated with the element, if any.
+ */
+ public Object getParent(Object element) {
+ if (element instanceof IWorkingSet && element != workingSetRoot) return workingSetRoot;
+ return parents.get(element);
+ }
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetsLabelProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetsLabelProvider.java
new file mode 100644
index 000000000..de1b75a74
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/WorkingSetsLabelProvider.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+
+/**
+ * Provides a text label and icon for Working Sets.
+ * <p>
+ * Copied and adapted from <code>org.eclipse.ui.internal.navigator.workingsets.WorkingSetLabelProvider</code>.
+ */
+public class WorkingSetsLabelProvider extends LabelProvider {
+
+ private WorkbenchLabelProvider labelProvider = new WorkbenchLabelProvider();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+ */
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof IWorkingSet) return labelProvider.getImage(element);
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object element) {
+ if (element instanceof IWorkingSet) return ((IWorkingSet) element).getLabel();
+ return null;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/pages/AbstractWorkingSetWizardPage.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/pages/AbstractWorkingSetWizardPage.java
new file mode 100644
index 000000000..d10fb1e6b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/pages/AbstractWorkingSetWizardPage.java
@@ -0,0 +1,535 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * William Chen (Wind River) [354578] Add support for working sets
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets.pages;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+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.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.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.tcf.te.ui.views.nls.Messages;
+import org.eclipse.tcf.te.ui.views.workingsets.WorkingSetElementHolder;
+import org.eclipse.tcf.te.runtime.interfaces.workingsets.IWorkingSetElement;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.IWorkingSetPage;
+
+/**
+ * A tree viewer on the left is used to show the workspace content, a table viewer on the right is
+ * used to show the working set content. Buttons to move content from right to left and vice versa
+ * are available between the two viewers. A text field allows to set/change the working sets name.
+ * <p>
+ * Copied and adapted from <code>org.eclipse.jdt.internal.ui.workingsets.AbstractWorkingSetWizardPage</code>.
+ */
+public abstract class AbstractWorkingSetWizardPage extends WizardPage implements IWorkingSetPage {
+
+ final class AddedElementsFilter extends ViewerFilter {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ return !selectedElements.contains(element);
+ }
+
+ }
+
+ /* default */ Text workingSetNameControl;
+ /* default */ TreeViewer tree;
+ /* default */ TableViewer table;
+ /* default */ ITreeContentProvider treeContentProvider;
+
+ /* default */ boolean firstCheck;
+ /* default */ final HashSet<Object> selectedElements;
+ /* default */ IWorkingSet workingSet;
+
+ /**
+ * Constructor.
+ *
+ * @param pageName
+ * @param title
+ * @param titleImage
+ */
+ protected AbstractWorkingSetWizardPage(String pageName, String title, ImageDescriptor titleImage) {
+ super(pageName, title, titleImage);
+
+ selectedElements = new HashSet<Object>();
+ firstCheck = true;
+ }
+
+ /**
+ * Returns the page id as specified in the extension point.
+ *
+ * @return the page id
+ */
+ protected abstract String getPageId();
+
+ /**
+ * Configure the tree viewer used on the left side of the dialog.
+ *
+ * Implementors must set:
+ * <ul>
+ * <li>The content provider</li>
+ * <li>The label provider</li>
+ * <li>The viewers input</li>
+ * </ul>
+ * They may also set:
+ * <ul>
+ * <li>The viewer comparator</li>
+ * <li>Any viewer filter</li>
+ * <li>The selection</li>
+ * </ul>
+ *
+ * @param tree
+ * the tree to configure
+ */
+ protected abstract void configureTree(TreeViewer tree);
+
+ /**
+ * Configure the table viewer used on the right side of the dialog.
+ *
+ * Implementors must set:
+ * <ul>
+ * <li>The label provider</li>
+ * </ul>
+ * They may also set:
+ * <ul>
+ * <li>The viewer comparator</li>
+ * </ul>
+ * They must not set:
+ * <ul>
+ * <li>The viewers content provider</li>
+ * <li>The viewers input</li>
+ * <li>Any viewer filter</li>
+ * </ul>
+ *
+ * @param table
+ * the table to configure
+ */
+ protected abstract void configureTable(TableViewer table);
+
+ /**
+ * Returns the elements which are shown in the table initially. Return an
+ * empty array if the table should be empty. The given working set is the
+ * working set which will be configured by this dialog, or <b>null</b> if it
+ * does not yet exist.
+ *
+ * @param workingSet
+ * the working set to configure or <b>null</b> if not yet exist
+ * @return the elements to show in the table
+ */
+ protected abstract Object[] getInitialWorkingSetElements(IWorkingSet workingSet);
+
+ /*
+ * @see
+ * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets
+ * .Composite)
+ */
+ @Override
+ public void createControl(Composite parent) {
+ initializeDialogUnits(parent);
+
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout());
+ composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ setControl(composite);
+
+ Label label = new Label(composite, SWT.WRAP);
+ label.setText(Messages.TargetWorkingSetPage_workingSet_name);
+ GridData gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER);
+ label.setLayoutData(gd);
+
+ workingSetNameControl = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ workingSetNameControl.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
+ workingSetNameControl.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ validateInput();
+ }
+ });
+
+ Composite leftCenterRightComposite = new Composite(composite, SWT.NONE);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.heightHint = convertHeightInCharsToPixels(20);
+ leftCenterRightComposite.setLayoutData(gridData);
+ GridLayout gridLayout = new GridLayout(3, false);
+ gridLayout.marginHeight = 0;
+ gridLayout.marginWidth = 0;
+ leftCenterRightComposite.setLayout(gridLayout);
+
+ Composite leftComposite = new Composite(leftCenterRightComposite, SWT.NONE);
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.widthHint = convertWidthInCharsToPixels(40);
+ leftComposite.setLayoutData(gridData);
+ gridLayout = new GridLayout(1, false);
+ gridLayout.marginHeight = 0;
+ gridLayout.marginWidth = 0;
+ leftComposite.setLayout(gridLayout);
+
+ Composite centerComposite = new Composite(leftCenterRightComposite, SWT.NONE);
+ gridLayout = new GridLayout(1, false);
+ gridLayout.marginHeight = 0;
+ gridLayout.marginWidth = 0;
+ centerComposite.setLayout(gridLayout);
+ centerComposite.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, false));
+
+ Composite rightComposite = new Composite(leftCenterRightComposite, SWT.NONE);
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.widthHint = convertWidthInCharsToPixels(40);
+ rightComposite.setLayoutData(gridData);
+ gridLayout = new GridLayout(1, false);
+ gridLayout.marginHeight = 0;
+ gridLayout.marginWidth = 0;
+ rightComposite.setLayout(gridLayout);
+
+ createTree(leftComposite);
+ createTable(rightComposite);
+
+ if (workingSet != null)
+ workingSetNameControl.setText(workingSet.getName());
+
+ initializeSelectedElements();
+ validateInput();
+
+ table.setInput(selectedElements);
+ table.refresh(true);
+ tree.refresh(true);
+
+ createButtonBar(centerComposite);
+
+ workingSetNameControl.setFocus();
+ workingSetNameControl.setSelection(0, workingSetNameControl.getText().length());
+
+ Dialog.applyDialogFont(composite);
+ }
+
+ private void createTree(Composite parent) {
+
+ Label label = new Label(parent, SWT.NONE);
+ label.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false));
+ label.setText(Messages.TargetWorkingSetPage_workspace_content);
+
+ tree = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
+ tree.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ tree.addFilter(new AddedElementsFilter());
+ tree.setUseHashlookup(true);
+
+ configureTree(tree);
+
+ treeContentProvider = (ITreeContentProvider) tree.getContentProvider();
+ }
+
+ private void createButtonBar(Composite parent) {
+ Label spacer = new Label(parent, SWT.NONE);
+ spacer.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ final Button addButton = new Button(parent, SWT.PUSH);
+ addButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ addButton.setText(Messages.TargetWorkingSetPage_add_button);
+ addButton.setEnabled(!tree.getSelection().isEmpty());
+
+ final Button addAllButton = new Button(parent, SWT.PUSH);
+ addAllButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ addAllButton.setText(Messages.TargetWorkingSetPage_addAll_button);
+ addAllButton.setEnabled(tree.getTree().getItems().length > 0);
+
+ final Button removeButton = new Button(parent, SWT.PUSH);
+ removeButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ removeButton.setText(Messages.TargetWorkingSetPage_remove_button);
+ removeButton.setEnabled(!table.getSelection().isEmpty());
+
+ final Button removeAllButton = new Button(parent, SWT.PUSH);
+ removeAllButton.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, false));
+ removeAllButton.setText(Messages.TargetWorkingSetPage_removeAll_button);
+ removeAllButton.setEnabled(!selectedElements.isEmpty());
+
+ tree.addSelectionChangedListener(new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ addButton.setEnabled(!event.getSelection().isEmpty());
+ }
+ });
+
+ addButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ addTreeSelection();
+
+ removeAllButton.setEnabled(true);
+ addAllButton.setEnabled(tree.getTree().getItems().length > 0);
+ }
+ });
+
+ tree.addDoubleClickListener(new IDoubleClickListener() {
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ addTreeSelection();
+
+ removeAllButton.setEnabled(true);
+ addAllButton.setEnabled(tree.getTree().getItems().length > 0);
+ }
+ });
+
+ table.addSelectionChangedListener(new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ removeButton.setEnabled(!event.getSelection().isEmpty());
+ }
+ });
+
+ removeButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ removeTableSelection();
+
+ addAllButton.setEnabled(true);
+ removeAllButton.setEnabled(!selectedElements.isEmpty());
+ }
+ });
+
+ table.addDoubleClickListener(new IDoubleClickListener() {
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ removeTableSelection();
+
+ addAllButton.setEnabled(true);
+ removeAllButton.setEnabled(!selectedElements.isEmpty());
+ }
+ });
+
+ addAllButton.addSelectionListener(new SelectionAdapter() {
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ TreeItem[] items = tree.getTree().getItems();
+ for (int i = 0; i < items.length; i++) {
+ selectedElements.add(items[i].getData());
+ }
+ table.refresh();
+ tree.refresh();
+
+ addAllButton.setEnabled(false);
+ removeAllButton.setEnabled(true);
+ }
+ });
+
+ removeAllButton.addSelectionListener(new SelectionAdapter() {
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ selectedElements.clear();
+
+ table.refresh();
+ tree.refresh();
+
+ removeAllButton.setEnabled(false);
+ addAllButton.setEnabled(true);
+ }
+ });
+
+ }
+
+ /**
+ * Moves selected elements in the tree into the table
+ */
+ void addTreeSelection() {
+ IStructuredSelection selection = (IStructuredSelection) tree.getSelection();
+ selectedElements.addAll(selection.toList());
+ Object[] selectedElements = selection.toArray();
+ table.add(selectedElements);
+ tree.remove(selectedElements);
+ table.setSelection(selection);
+ table.getControl().setFocus();
+ validateInput();
+ }
+
+ /**
+ * Moves the selected elements in the table into the tree
+ */
+ void removeTableSelection() {
+ IStructuredSelection selection = (IStructuredSelection) table.getSelection();
+ selectedElements.removeAll(selection.toList());
+ Object[] selectedElements = selection.toArray();
+ table.remove(selectedElements);
+ try {
+ tree.getTree().setRedraw(false);
+ for (int i = 0; i < selectedElements.length; i++) {
+ tree.refresh(treeContentProvider.getParent(selectedElements[i]), true);
+ }
+ } finally {
+ tree.getTree().setRedraw(true);
+ }
+ tree.setSelection(selection);
+ tree.getControl().setFocus();
+ validateInput();
+ }
+
+ private void createTable(Composite parent) {
+ Label label = new Label(parent, SWT.WRAP);
+ label.setText(Messages.TargetWorkingSetPage_workingSet_content);
+ label.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ table = new TableViewer(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
+
+ GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
+ table.getControl().setLayoutData(gd);
+
+ table.setUseHashlookup(true);
+
+ configureTable(table);
+
+ table.setContentProvider(new IStructuredContentProvider() {
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return selectedElements.toArray();
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ });
+ }
+
+ /*
+ * Implements method from IWorkingSetPage
+ */
+ @Override
+ public IWorkingSet getSelection() {
+ return workingSet;
+ }
+
+ /*
+ * Implements method from IWorkingSetPage
+ */
+ @Override
+ public void setSelection(IWorkingSet workingSet) {
+ Assert.isNotNull(workingSet, "Working set must not be null"); //$NON-NLS-1$
+ this.workingSet = workingSet;
+ if (getContainer() != null && getShell() != null && workingSetNameControl != null) {
+ firstCheck = false;
+ workingSetNameControl.setText(workingSet.getName());
+ initializeSelectedElements();
+ validateInput();
+ }
+ }
+
+ /*
+ * Implements method from IWorkingSetPage
+ */
+ @Override
+ public void finish() {
+ String workingSetName = workingSetNameControl.getText();
+
+ List<IAdaptable> elements = new ArrayList<IAdaptable>();
+ for (Object candidate : selectedElements) {
+ if (candidate instanceof IWorkingSetElement) {
+ WorkingSetElementHolder holder = new WorkingSetElementHolder(workingSetName, ((IWorkingSetElement)candidate).getElementId());
+ holder.setElement((IWorkingSetElement)candidate);
+ elements.add(holder);
+ }
+ }
+
+ if (workingSet == null) {
+ IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager();
+ workingSet = workingSetManager.createWorkingSet(workingSetName, elements.toArray(new IAdaptable[elements.size()]));
+ workingSet.setId(getPageId());
+ } else {
+ workingSet.setName(workingSetName);
+ workingSet.setElements(elements.toArray(new IAdaptable[elements.size()]));
+ }
+ }
+
+ void validateInput() {
+ String errorMessage = null;
+ String infoMessage = null;
+ String newText = workingSetNameControl.getText();
+
+ if (newText.equals(newText.trim()) == false)
+ errorMessage = Messages.TargetWorkingSetPage_warning_nameWhitespace;
+ if (newText.equals("")) { //$NON-NLS-1$
+ if (firstCheck) {
+ setPageComplete(false);
+ firstCheck = false;
+ return;
+ }
+ errorMessage = Messages.TargetWorkingSetPage_warning_nameMustNotBeEmpty;
+ }
+
+ firstCheck = false;
+
+ if (errorMessage == null && (workingSet == null || newText.equals(workingSet.getName()) == false)) {
+ IWorkingSet[] workingSets = PlatformUI.getWorkbench().getWorkingSetManager().getAllWorkingSets();
+ for (int i = 0; i < workingSets.length; i++) {
+ if (newText.equals(workingSets[i].getName())) {
+ errorMessage = Messages.TargetWorkingSetPage_warning_workingSetExists;
+ }
+ }
+ }
+
+ if (!hasSelectedElement())
+ infoMessage = Messages.TargetWorkingSetPage_warning_resourceMustBeChecked;
+
+ setMessage(infoMessage, INFORMATION);
+ setErrorMessage(errorMessage);
+ setPageComplete(errorMessage == null);
+ }
+
+ private boolean hasSelectedElement() {
+ return !selectedElements.isEmpty();
+ }
+
+ private void initializeSelectedElements() {
+ selectedElements.addAll(Arrays.asList(getInitialWorkingSetElements(workingSet)));
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/pages/TargetWorkingSetPage.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/pages/TargetWorkingSetPage.java
new file mode 100644
index 000000000..416a6383c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/workingsets/pages/TargetWorkingSetPage.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) [354578] Add support for working sets
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.workingsets.pages;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.tcf.te.ui.views.ViewsUtil;
+import org.eclipse.tcf.te.ui.views.activator.UIPlugin;
+import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.tcf.te.ui.views.interfaces.ImageConsts;
+import org.eclipse.tcf.te.ui.views.internal.ViewRoot;
+import org.eclipse.tcf.te.ui.views.nls.Messages;
+import org.eclipse.tcf.te.ui.views.workingsets.WorkingSetElementHolder;
+import org.eclipse.tcf.te.runtime.interfaces.workingsets.IWorkingSetElement;
+import org.eclipse.tcf.te.ui.trees.TreeArrayContentProvider;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.navigator.CommonNavigator;
+import org.eclipse.ui.navigator.INavigatorContentService;
+
+/**
+ * A target working set page is a wizard page used to configure a custom defined
+ * working set. This wizard is used in the configure working set action to edit
+ * the working sets used in the working set viewer.
+ */
+public class TargetWorkingSetPage extends AbstractWorkingSetWizardPage {
+ // The target explorer view content service (Never dispose it in here!)
+ private INavigatorContentService contentService;
+ // The initial selection
+ private IStructuredSelection initialSelection;
+
+ /**
+ * Default constructor.
+ */
+ public TargetWorkingSetPage() {
+ super("targetWorkingSetPage", Messages.TargetWorkingSetPage_title, UIPlugin.getImageDescriptor(ImageConsts.WORKING_SET)); //$NON-NLS-1$
+ setDescription(Messages.TargetWorkingSetPage_workingSet_description);
+ }
+
+ /**
+ * Set the initial selection.
+ * @param selection The initial selection
+ */
+ public void setInitialSelection(IStructuredSelection selection) {
+ initialSelection = selection;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.ui.internal.workingsets.AbstractWorkingSetWizardPage#getPageId()
+ */
+ @Override
+ protected String getPageId() {
+ return "org.eclipse.tcf.te.tcf.ui.TargetWorkingSetPage"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.ui.internal.workingsets.AbstractWorkingSetWizardPage#configureTree(org.eclipse.jface.viewers.TreeViewer)
+ */
+ @Override
+ protected void configureTree(TreeViewer tree) {
+ // Get the content service from the Target Explorer view.
+ IWorkbenchPart part = ViewsUtil.getPart(IUIConstants.ID_EXPLORER);
+ if (part instanceof CommonNavigator) {
+ contentService = ((CommonNavigator)part).getNavigatorContentService();
+
+ tree.setContentProvider(TreeArrayContentProvider.getInstance());
+ tree.setLabelProvider(contentService.createCommonLabelProvider());
+
+ // Filter out everything not implementing IWorkingSetElement
+ tree.addFilter(new ViewerFilter() {
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ return element instanceof IWorkingSetElement;
+ }
+ });
+
+ // Initialize the tree input
+ tree.setInput(contentService.createCommonContentProvider().getElements(ViewRoot.getInstance()));
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.ui.internal.workingsets.AbstractWorkingSetWizardPage#configureTable(org.eclipse.jface.viewers.TableViewer)
+ */
+ @Override
+ protected void configureTable(TableViewer table) {
+ table.setLabelProvider(contentService.createCommonLabelProvider());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.ui.internal.workingsets.AbstractWorkingSetWizardPage#getInitialWorkingSetElements(org.eclipse.ui.IWorkingSet)
+ */
+ @Override
+ protected Object[] getInitialWorkingSetElements(IWorkingSet workingSet) {
+ Object[] elements;
+ if (workingSet == null) {
+ if (initialSelection == null)
+ return new IAdaptable[0];
+ elements = initialSelection.toArray();
+ } else {
+ List<IWorkingSetElement> result = new ArrayList<IWorkingSetElement>();
+ for (IAdaptable adaptable : workingSet.getElements()) {
+ if (!(adaptable instanceof WorkingSetElementHolder)) continue;
+ WorkingSetElementHolder holder = (WorkingSetElementHolder) adaptable;
+ Assert.isNotNull(holder);
+ IWorkingSetElement element = holder.getElement();
+ // If the element is null, try to look up the element through the content provider
+ if (element == null) {
+ ITreeContentProvider contentProvider = (ITreeContentProvider)tree.getContentProvider();
+ for (Object candidate : contentProvider.getElements(tree.getInput())) {
+ if (candidate instanceof IWorkingSetElement && ((IWorkingSetElement)candidate).getElementId().equals(holder.getElementId())) {
+ holder.setElement((IWorkingSetElement)candidate);
+ element = holder.getElement();
+ break;
+ }
+ }
+ }
+
+ if (element != null) result.add(element);
+ }
+ elements = result.toArray();
+ }
+ return elements;
+ }
+}

Back to the top