+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.workbench.internal;\r
+\r
+import java.io.IOException;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.net.URL;\r
+import java.text.Collator;\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+\r
+import org.eclipse.core.internal.resources.Workspace;\r
+import org.eclipse.core.net.proxy.IProxyService;\r
+import org.eclipse.core.resources.IContainer;\r
+import org.eclipse.core.resources.IResource;\r
+import org.eclipse.core.resources.ResourcesPlugin;\r
+import org.eclipse.core.resources.WorkspaceJob;\r
+import org.eclipse.core.runtime.CoreException;\r
+import org.eclipse.core.runtime.FileLocator;\r
+import org.eclipse.core.runtime.IAdaptable;\r
+import org.eclipse.core.runtime.IBundleGroup;\r
+import org.eclipse.core.runtime.IBundleGroupProvider;\r
+import org.eclipse.core.runtime.ILog;\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.MultiStatus;\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.core.runtime.ProgressMonitorWrapper;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.core.runtime.SubMonitor;\r
+import org.eclipse.core.runtime.jobs.Job;\r
+import org.eclipse.e4.core.contexts.IEclipseContext;\r
+import org.eclipse.e4.ui.internal.workbench.E4Workbench;\r
+import org.eclipse.jface.dialogs.ErrorDialog;\r
+import org.eclipse.jface.dialogs.IDialogSettings;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.jface.dialogs.TrayDialog;\r
+import org.eclipse.jface.operation.IRunnableWithProgress;\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.util.Policy;\r
+import org.eclipse.jface.window.Window;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.IPerspectiveDescriptor;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.application.IWorkbenchConfigurer;\r
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;\r
+import org.eclipse.ui.application.WorkbenchAdvisor;\r
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;\r
+import org.eclipse.ui.ide.IDE;\r
+import org.eclipse.ui.internal.ISelectionConversionService;\r
+import org.eclipse.ui.internal.Workbench;\r
+import org.eclipse.ui.internal.ide.AboutInfo;\r
+import org.eclipse.ui.internal.ide.IDEInternalPreferences;\r
+import org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages;\r
+import org.eclipse.ui.internal.ide.IDESelectionConversionService;\r
+import org.eclipse.ui.internal.ide.IDEWorkbenchActivityHelper;\r
+import org.eclipse.ui.internal.ide.IDEWorkbenchErrorHandler;\r
+import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;\r
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;\r
+import org.eclipse.ui.internal.ide.undo.WorkspaceUndoMonitor;\r
+import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog;\r
+import org.eclipse.ui.keys.IBindingService;\r
+import org.eclipse.ui.progress.IProgressService;\r
+import org.eclipse.ui.statushandlers.AbstractStatusHandler;\r
+import org.osgi.framework.Bundle;\r
+import org.osgi.framework.ServiceReference;\r
+import org.osgi.framework.Version;\r
+import org.simantics.CancelStartupException;\r
+import org.simantics.PlatformException;\r
+import org.simantics.Simantics;\r
+import org.simantics.SimanticsPlatform;\r
+import org.simantics.SimanticsPlatform.OntologyRecoveryPolicy;\r
+import org.simantics.SimanticsPlatform.RecoveryPolicy;\r
+import org.simantics.application.arguments.IArguments;\r
+import org.simantics.application.arguments.SimanticsArguments;\r
+import org.simantics.db.common.Indexing;\r
+import org.simantics.db.indexing.DatabaseIndexing;\r
+import org.simantics.db.procore.server.environment.RebootRequiredException;\r
+import org.simantics.db.procore.server.environment.windows.Product;\r
+import org.simantics.db.procore.ui.ProCoreUserAgent;\r
+import org.simantics.internal.TimedSessionCache;\r
+import org.simantics.project.IProject;\r
+import org.simantics.project.ProjectKeys;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.jobs.SessionGarbageCollectorJob;\r
+import org.simantics.ui.workbench.PerspectiveBarsActivator;\r
+import org.simantics.ui.workbench.PerspectiveContextActivator;\r
+import org.simantics.utils.logging.TimeLogger;\r
+import org.simantics.utils.threads.ThreadUtils;\r
+import org.simantics.utils.ui.dialogs.ShowError;\r
+import org.simantics.utils.ui.dialogs.ShowMessage;\r
+\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class SimanticsWorkbenchAdvisor extends WorkbenchAdvisor {\r
+\r
+ private static final boolean PROFILE_PLATFORM_STARTUP = false;\r
+\r
+ private static final String SHUT_DOWN_TASK = "Shutting down...";\r
+\r
+ private static final String SHUT_DOWN_PLATFORM_TASK = "Shutting down platform...";\r
+\r
+ private static final String WORKBENCH_PREFERENCE_CATEGORY_ID = "org.eclipse.ui.preferencePages.Workbench"; //$NON-NLS-1$\r
+\r
+ /**\r
+ * The dialog setting key to access the known installed features since the\r
+ * last time the workbench was run.\r
+ */\r
+ private static final String INSTALLED_FEATURES = "installedFeatures"; //$NON-NLS-1$\r
+\r
+ /**\r
+ * Default database ID\r
+ */\r
+ private static final String DEFAULT_DATABASE_ID = "procore";\r
+ \r
+ /**\r
+ * The arguments received by the application.\r
+ */\r
+ protected final IArguments args;\r
+\r
+ protected final boolean restoredPreviousSession = false;\r
+\r
+ /**\r
+ * Only true while opening the initial windows during {@link #openWindows()}.\r
+ * Used by {@link SimanticsWorkbenchWindowAdvisor#postWindowOpen()} to\r
+ * recognize when to skip all one-time initialization.\r
+ */\r
+ protected boolean workbenchWindowsInitialized = false;\r
+\r
+ /**\r
+ * Whether or not to save unsaved database changes before exiting the\r
+ * workbench.\r
+ */\r
+ protected boolean saveAtExit = false;\r
+\r
+ /**\r
+ * Ordered map of versioned feature ids -> info that are new for this\r
+ * session; <code>null</code> if uninitialized. Key type:\r
+ * <code>String</code>, Value type: <code>AboutInfo</code>.\r
+ */\r
+ private Map<String, AboutInfo> newlyAddedBundleGroups;\r
+\r
+ /**\r
+ * Array of <code>AboutInfo</code> for all new installed features that\r
+ * specify a welcome perspective.\r
+ */\r
+ private AboutInfo[] welcomePerspectiveInfos = null;\r
+\r
+ /**\r
+ * Helper for managing activites in response to workspace changes.\r
+ */\r
+ private IDEWorkbenchActivityHelper activityHelper = null;\r
+\r
+ /**\r
+ * Helper for managing work that is performed when the system is otherwise\r
+ * idle.\r
+ */\r
+ private IDEIdleHelper idleHelper;\r
+\r
+ private Listener settingsChangeListener;\r
+\r
+ /**\r
+ * Support class for monitoring workspace changes and periodically\r
+ * validating the undo history\r
+ */\r
+ private WorkspaceUndoMonitor workspaceUndoMonitor;\r
+\r
+ /**\r
+ * The IDE workbench error handler.\r
+ */\r
+ private AbstractStatusHandler ideWorkbenchErrorHandler;\r
+\r
+ /**\r
+ * Helper class used to process delayed events.\r
+ */\r
+ private DelayedEventsProcessor delayedEventsProcessor;\r
+ \r
+ /**\r
+ * Creates a new workbench advisor instance.\r
+ * @param processor\r
+ */\r
+ public SimanticsWorkbenchAdvisor(IArguments args, DelayedEventsProcessor processor) {\r
+ super();\r
+ this.args = args;\r
+ this.delayedEventsProcessor = processor;\r
+\r
+ Listener closeListener = new Listener() {\r
+ public void handleEvent(Event event) {\r
+ boolean doExit = SimanticsWorkbenchWindowAdvisor.promptOnExit(null);\r
+ event.doit = doExit;\r
+ if (!doExit)\r
+ event.type = SWT.None;\r
+ }\r
+ };\r
+ Display.getDefault().addListener(SWT.Close, closeListener);\r
+ }\r
+\r
+ public IArguments getArguments() {\r
+ return args;\r
+ }\r
+\r
+ public boolean workbenchInitialized() {\r
+ return workbenchWindowsInitialized;\r
+ }\r
+\r
+ public boolean restoredPreviousSession() {\r
+ return restoredPreviousSession;\r
+ }\r
+\r
+ boolean saveAtExit() {\r
+ return saveAtExit;\r
+ }\r
+\r
+ void setSaveAtExit(boolean saveAtExit) {\r
+ this.saveAtExit = saveAtExit;\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ *\r
+ * @see org.eclipse.ui.application.WorkbenchAdvisor#initialize\r
+ */\r
+ @Override\r
+ public void initialize(IWorkbenchConfigurer configurer) {\r
+ // By default, we always save and restore the workbench state.\r
+ configurer.setSaveAndRestore(true);\r
+\r
+ checkWorkspaceDatabaseIndexes();\r
+\r
+ // Start tracking the active perspective to activate contexts based on it.\r
+ new PerspectiveContextActivator();\r
+ new PerspectiveBarsActivator();\r
+\r
+ // register workspace adapters\r
+ IDE.registerAdapters();\r
+\r
+ // register shared images\r
+ declareWorkbenchImages();\r
+\r
+ // initialize the activity helper\r
+ activityHelper = IDEWorkbenchActivityHelper.getInstance();\r
+\r
+ // initialize idle handler\r
+ idleHelper = new IDEIdleHelper(configurer);\r
+\r
+ // initialize the workspace undo monitor\r
+ workspaceUndoMonitor = WorkspaceUndoMonitor.getInstance();\r
+\r
+ // show Help button in JFace dialogs\r
+ TrayDialog.setDialogHelpAvailable(true);\r
+\r
+ Policy.setComparator(Collator.getInstance());\r
+ }\r
+\r
+ private void checkWorkspaceDatabaseIndexes() {\r
+ try {\r
+ DatabaseIndexing.validateIndexes();\r
+ } catch (IOException e) {\r
+ Activator.logError("Problems encountered while checking database indexes, see exception for details.", e);\r
+ }\r
+ }\r
+\r
+ public WorkbenchWindowAdvisor createWorkbenchWindowAdvisorClass(SimanticsWorkbenchAdvisor advisor, IWorkbenchWindowConfigurer configurer) {\r
+ return new SimanticsWorkbenchWindowAdvisor(this, configurer);\r
+ }\r
+\r
+ @Override\r
+ public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {\r
+ // Attach database session watchdog.\r
+ new SessionWatchdog().attach( Simantics.getSessionContextProvider() );\r
+\r
+ return createWorkbenchWindowAdvisorClass(this, configurer);\r
+ }\r
+\r
+ /**\r
+ * For gaining direct access to super.openWindows() in implementations\r
+ * inheriting this one.\r
+ */\r
+ public boolean openWindowsSuper() {\r
+ return super.openWindows();\r
+ }\r
+\r
+ /**\r
+ * Sadly we do not know why key bindings are lost and why this helps. But it\r
+ * does. Visiting the <code>Keys</code> preference page and pressing OK uses\r
+ * this the same call and it seems to salvage the bindings that have been in\r
+ * some cases destroyed by <code>BindingToModelProcessor</code>.\r
+ * \r
+ * <p>\r
+ * Related links:\r
+ * https://techblog.ralph-schuster.eu/2013/10/13/eclipsee4-problem-with-key-bindings/comment-page-1/\r
+ * https://www.eclipse.org/forums/index.php/t/550175/\r
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=461037\r
+ * \r
+ * @see platform issue #6353\r
+ */\r
+ private void fixBindings() {\r
+ try {\r
+ IBindingService bs = PlatformUI.getWorkbench().getAdapter(IBindingService.class);\r
+ bs.savePreferences(bs.getActiveScheme(), bs.getBindings());\r
+ } catch (IOException e) {\r
+ Activator.logError(getClass().getSimpleName() + ".fixBindings failed", e);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public boolean openWindows() {\r
+ boolean platformOk = startPlatform();\r
+ TimeLogger.log("SimanticsWorkbenchAdvisor.startPlatform finished");\r
+\r
+ if (platformOk) {\r
+ // At this point workbenchConfigurer.getSaveAndRestore()\r
+ // returns false iff something has gone terribly wrong\r
+ // before this. Currently saveAndRestore is always true.\r
+ boolean windowsOpened = super.openWindows();\r
+ TimeLogger.log("Opened windows");\r
+ if (windowsOpened) {\r
+ workbenchWindowsInitialized = true;\r
+\r
+ // Start the database garbage collector after a short while.\r
+ SessionGarbageCollectorJob.getInstance().scheduleAfterQuietTime();\r
+\r
+ // Discard database session undo history at this point to prevent\r
+ // the user from undoing any initialization operations performed\r
+ // by the platform startup.\r
+ SimanticsPlatform.INSTANCE.discardSessionUndoHistory();\r
+ TimeLogger.log("Discarded session undo history");\r
+\r
+ // #6353: Workaround for \r
+ fixBindings();\r
+\r
+ return true;\r
+ }\r
+ }\r
+\r
+ // Make sure platform shutdown is ran if window opening fails.\r
+ try {\r
+ platformShutdownRunnable.run(null);\r
+ } catch (InvocationTargetException e) {\r
+ Activator.logError(getClass().getSimpleName() + ".openWindows failed", e);\r
+ } catch (InterruptedException e) {\r
+ Activator.logError(getClass().getSimpleName() + ".openWindows failed", e);\r
+ }\r
+ return false;\r
+ }\r
+\r
+ protected boolean startPlatform() {\r
+ // Verify selected perspective\r
+ if (args.contains(SimanticsArguments.PERSPECTIVE)) {\r
+ String perspectiveId = args.get(SimanticsArguments.PERSPECTIVE);\r
+ IPerspectiveDescriptor perspective = PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(perspectiveId);\r
+ if (perspective == null) {\r
+ StringBuilder msg = new StringBuilder();\r
+ msg.append("Requested perspective not found: '" + perspectiveId + "'\n");\r
+ msg.append("Valid alternatives are:\n");\r
+ for (IPerspectiveDescriptor pd : PlatformUI.getWorkbench().getPerspectiveRegistry().getPerspectives()) {\r
+ msg.append(" " + pd.getId() + "\n");\r
+ }\r
+\r
+ ShowMessage.syncShowError("Invalid Perspective", msg.toString());\r
+ return false;\r
+ }\r
+ }\r
+\r
+ ILog log = Platform.getLog(Activator.getDefault().getBundle());\r
+\r
+ try {\r
+ //\r
+ //\r
+ // Create Simantics Platform Helper.\r
+ //\r
+ // If Simantics is started from Eclipse IDE or with -fixerrors option,\r
+ // there is an attempt to fix errors.\r
+ //\r
+ // On ontology mismatch, there is an attempt to merge new ontology to the\r
+ // existing database. With -reinstall, the database is cleaned and\r
+ // reinstalled.\r
+ //\r
+ //\r
+\r
+ RecoveryPolicy workspacePolicy = Platform.inDevelopmentMode() ? RecoveryPolicy.FixError : RecoveryPolicy.ThrowError;\r
+ OntologyRecoveryPolicy ontologyPolicy = Platform.inDevelopmentMode() ? OntologyRecoveryPolicy.Merge : OntologyRecoveryPolicy.ThrowError;\r
+\r
+ if (args.contains(SimanticsArguments.RECOVERY_POLICY_FIX_ERRORS)) {\r
+ workspacePolicy = RecoveryPolicy.FixError;\r
+ ontologyPolicy = OntologyRecoveryPolicy.Merge;\r
+ }\r
+\r
+ boolean requireSynchronize = true;\r
+\r
+ if (args.contains(SimanticsArguments.ONTOLOGY_RECOVERY_POLICY_REINSTALL)) {\r
+ ontologyPolicy = OntologyRecoveryPolicy.ReinstallDatabase;\r
+ }\r
+\r
+ if (args.contains(SimanticsArguments.DO_NOT_SYNCHRONIZE_ONTOLOGIES)) {\r
+ requireSynchronize = false;\r
+ }\r
+ \r
+ if (args.contains(SimanticsArguments.DISABLE_INDEX)) {\r
+ Indexing.setDefaultDependenciesIndexingEnabled(false);\r
+ }\r
+\r
+ if (args.contains(SimanticsArguments.SERVER)) {\r
+ String serverAddress = args.get(SimanticsArguments.SERVER);\r
+ throw new PlatformException("Argument not supported: " + SimanticsArguments.SERVER + " " + serverAddress);\r
+ }\r
+\r
+ // TODO: Default to procore for now;\r
+ String databaseId = DEFAULT_DATABASE_ID;\r
+ if (args.contains(SimanticsArguments.DATABASE_ID)) {\r
+ databaseId = args.get(SimanticsArguments.DATABASE_ID);\r
+ }\r
+ \r
+ IProgressMonitor mon = null;\r
+ if (PROFILE_PLATFORM_STARTUP)\r
+ mon = new TimingProgressMonitor();\r
+ IWorkbench wb = PlatformUI.getWorkbench();\r
+ SimanticsPlatform.INSTANCE.startUp(databaseId, mon, workspacePolicy, ontologyPolicy, requireSynchronize, new JFaceUserAgent());\r
+\r
+ // Make sure that the default perspective comes from the project if\r
+ // the project has set ProjectKeys#DEFAULT_PERSPECTIVE.\r
+ // This might go wrong if project features interact with\r
+ // PerspectiveRegistry while configuring themselves, since that will\r
+ // cause an invocation to #getInitialWindowPerspectiveId() while\r
+ // the project has not yet been properly initialized.\r
+ getWorkbenchConfigurer().getWorkbench().getPerspectiveRegistry().setDefaultPerspective(getInitialWindowPerspectiveId());\r
+ TimeLogger.log("Completed setting default perspective");\r
+\r
+ return true;\r
+ } catch (CancelStartupException e) {\r
+ return false;\r
+ } catch (PlatformException e) {\r
+ boolean hasStackTrace = e.getStackTrace().length > 0;\r
+ Throwable ee = e;\r
+ while (ee.getCause() != null) {\r
+ ee = ee.getCause();\r
+ hasStackTrace = ee.getStackTrace().length > 0;\r
+ }\r
+\r
+ log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), hasStackTrace ? e : null));\r
+ if (hasStackTrace) {\r
+ new ShowError("Platform Initialization Failed", "Simantics Platform initialization failed:\n\n" + e.getMessage(), e, true);\r
+ } else {\r
+ StringBuilder sb = new StringBuilder(256);\r
+ sb.append(e.getMessage());\r
+ for (Throwable c=e.getCause(); null != c && null != c.getMessage(); c=c.getCause())\r
+ sb.append("\ncause: ").append(c.getMessage());\r
+ new ShowError("Startup Failed", sb.toString(), (Exception) null, true);\r
+ }\r
+\r
+ return false;\r
+ } catch (Exception e) {\r
+ log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));\r
+\r
+ Throwable cause = e.getCause();\r
+ if (cause instanceof RebootRequiredException) {\r
+ RebootRequiredException rre = (RebootRequiredException) cause;\r
+ StringBuilder msg = new StringBuilder();\r
+ msg.append("The application must be restarted after installing the following products:\n");\r
+ for (Product product : rre.products)\r
+ msg.append("\t" + product + "\n");\r
+ msg.append("\nThe application will now close.");\r
+ MessageDialog.openInformation(null, "Restart Required", msg.toString());\r
+ } else {\r
+ new ShowError("Platform Startup Failed", "Simantics Platform startup failed:\n\n" + e.getMessage(), e, true);\r
+ }\r
+ return false;\r
+ }\r
+\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ *\r
+ * @see org.eclipse.ui.application.WorkbenchAdvisor#preStartup()\r
+ */\r
+ @Override\r
+ public void preStartup() {\r
+\r
+ // Suspend background jobs while we startup\r
+ Job.getJobManager().suspend();\r
+\r
+ // Register the build actions\r
+ IProgressService service = PlatformUI.getWorkbench()\r
+ .getProgressService();\r
+ ImageDescriptor newImage = IDEInternalWorkbenchImages\r
+ .getImageDescriptor(IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC);\r
+ service.registerIconForFamily(newImage,\r
+ ResourcesPlugin.FAMILY_MANUAL_BUILD);\r
+ service.registerIconForFamily(newImage,\r
+ ResourcesPlugin.FAMILY_AUTO_BUILD);\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ *\r
+ * @see org.eclipse.ui.application.WorkbenchAdvisor#postStartup()\r
+ */\r
+ @Override\r
+ public void postStartup() {\r
+ try {\r
+ refreshFromLocal();\r
+ activateProxyService();\r
+ ((Workbench) PlatformUI.getWorkbench()).registerService(\r
+ ISelectionConversionService.class,\r
+ new IDESelectionConversionService());\r
+\r
+ initializeSettingsChangeListener();\r
+ Display.getCurrent().addListener(SWT.Settings,\r
+ settingsChangeListener);\r
+ } finally {// Resume background jobs after we startup\r
+ Job.getJobManager().resume();\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Activate the proxy service by obtaining it.\r
+ */\r
+ private void activateProxyService() {\r
+ Bundle bundle = Platform.getBundle("org.eclipse.ui.ide"); //$NON-NLS-1$\r
+ Object proxyService = null;\r
+ if (bundle != null) {\r
+ ServiceReference<?> ref = bundle.getBundleContext().getServiceReference(IProxyService.class.getName());\r
+ if (ref != null)\r
+ proxyService = bundle.getBundleContext().getService(ref);\r
+ }\r
+ if (proxyService == null) {\r
+ IDEWorkbenchPlugin.log("Proxy service could not be found."); //$NON-NLS-1$\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Initialize the listener for settings changes.\r
+ */\r
+ private void initializeSettingsChangeListener() {\r
+ settingsChangeListener = new Listener() {\r
+\r
+ boolean currentHighContrast = Display.getCurrent()\r
+ .getHighContrast();\r
+\r
+ @Override\r
+ public void handleEvent(org.eclipse.swt.widgets.Event event) {\r
+ if (Display.getCurrent().getHighContrast() == currentHighContrast)\r
+ return;\r
+\r
+ currentHighContrast = !currentHighContrast;\r
+\r
+ // make sure they really want to do this\r
+ if (new MessageDialog(null,\r
+ IDEWorkbenchMessages.SystemSettingsChange_title, null,\r
+ IDEWorkbenchMessages.SystemSettingsChange_message,\r
+ MessageDialog.QUESTION, new String[] {\r
+ IDEWorkbenchMessages.SystemSettingsChange_yes,\r
+ IDEWorkbenchMessages.SystemSettingsChange_no },\r
+ 1).open() == Window.OK) {\r
+ PlatformUI.getWorkbench().restart();\r
+ }\r
+ }\r
+ };\r
+\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ *\r
+ * @see org.eclipse.ui.application.WorkbenchAdvisor#postShutdown\r
+ */\r
+ @Override\r
+ public void postShutdown() {\r
+ if (activityHelper != null) {\r
+ activityHelper.shutdown();\r
+ activityHelper = null;\r
+ }\r
+ if (idleHelper != null) {\r
+ idleHelper.shutdown();\r
+ idleHelper = null;\r
+ }\r
+ if (workspaceUndoMonitor != null) {\r
+ workspaceUndoMonitor.shutdown();\r
+ workspaceUndoMonitor = null;\r
+ }\r
+ if (IDEWorkbenchPlugin.getPluginWorkspace() != null) {\r
+ disconnectFromWorkspace();\r
+ }\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ *\r
+ * @see org.eclipse.ui.application.WorkbenchAdvisor#preShutdown()\r
+ */\r
+ @Override\r
+ public boolean preShutdown() {\r
+ Display.getCurrent().removeListener(SWT.Settings,\r
+ settingsChangeListener);\r
+ return super.preShutdown();\r
+ }\r
+\r
+ /**\r
+ * Return true if the intro plugin is present and false otherwise.\r
+ *\r
+ * @return boolean\r
+ */\r
+ public boolean hasIntro() {\r
+ return getWorkbenchConfigurer().getWorkbench().getIntroManager()\r
+ .hasIntro();\r
+ }\r
+\r
+ private void refreshFromLocal() {\r
+ String[] commandLineArgs = Platform.getCommandLineArgs();\r
+ IPreferenceStore store = IDEWorkbenchPlugin.getDefault()\r
+ .getPreferenceStore();\r
+ boolean refresh = store\r
+ .getBoolean(IDEInternalPreferences.REFRESH_WORKSPACE_ON_STARTUP);\r
+ if (!refresh) {\r
+ return;\r
+ }\r
+\r
+ // Do not refresh if it was already done by core on startup.\r
+ for (int i = 0; i < commandLineArgs.length; i++) {\r
+ if (commandLineArgs[i].equalsIgnoreCase("-refresh")) { //$NON-NLS-1$\r
+ return;\r
+ }\r
+ }\r
+\r
+ final IContainer root = ResourcesPlugin.getWorkspace().getRoot();\r
+ Job job = new WorkspaceJob(IDEWorkbenchMessages.Workspace_refreshing) {\r
+ @Override\r
+ public IStatus runInWorkspace(IProgressMonitor monitor)\r
+ throws CoreException {\r
+ root.refreshLocal(IResource.DEPTH_INFINITE, monitor);\r
+ return Status.OK_STATUS;\r
+ }\r
+ };\r
+ job.setRule(root);\r
+ job.schedule();\r
+ }\r
+\r
+ private static class CancelableProgressMonitorWrapper extends ProgressMonitorWrapper {\r
+ private double total = 0;\r
+ private ProgressMonitorJobsDialog dialog;\r
+\r
+ CancelableProgressMonitorWrapper(IProgressMonitor monitor,\r
+ ProgressMonitorJobsDialog dialog) {\r
+ super(monitor);\r
+ this.dialog = dialog;\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ * @see org.eclipse.core.runtime.ProgressMonitorWrapper#internalWorked(double)\r
+ */\r
+ public void internalWorked(double work) {\r
+ super.internalWorked(work);\r
+ total += work;\r
+ updateProgressDetails();\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ * @see org.eclipse.core.runtime.ProgressMonitorWrapper#worked(int)\r
+ */\r
+ public void worked(int work) {\r
+ super.worked(work);\r
+ total += work;\r
+ updateProgressDetails();\r
+ }\r
+\r
+ public void beginTask(String name, int totalWork) {\r
+ super.beginTask(name, totalWork);\r
+ subTask(IDEWorkbenchMessages.IDEWorkbenchAdvisor_preHistoryCompaction);\r
+ }\r
+\r
+ private void updateProgressDetails() {\r
+ if (!isCanceled() && Math.abs(total - 4.0) < 0.0001 /* right before history compacting */) {\r
+ subTask(IDEWorkbenchMessages.IDEWorkbenchAdvisor_cancelHistoryPruning);\r
+ dialog.setCancelable(true);\r
+ }\r
+ if (Math.abs(total - 5.0) < 0.0001 /* history compacting finished */) {\r
+ subTask(IDEWorkbenchMessages.IDEWorkbenchAdvisor_postHistoryCompaction);\r
+ dialog.setCancelable(false);\r
+ }\r
+ }\r
+ }\r
+\r
+ private static class CancelableProgressMonitorJobsDialog extends ProgressMonitorJobsDialog {\r
+\r
+ public CancelableProgressMonitorJobsDialog(Shell parent) {\r
+ super(parent);\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ * @see org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog#createDetailsButton(org.eclipse.swt.widgets.Composite)\r
+ */\r
+ protected void createButtonsForButtonBar(Composite parent) {\r
+ super.createButtonsForButtonBar(parent);\r
+ registerCancelButtonListener();\r
+ }\r
+\r
+ public void registerCancelButtonListener() {\r
+ cancel.addSelectionListener(new SelectionAdapter() {\r
+ public void widgetSelected(SelectionEvent e) {\r
+ subTaskLabel.setText(""); //$NON-NLS-1$\r
+ }\r
+ });\r
+ }\r
+ }\r
+\r
+\r
+ final IRunnableWithProgress platformShutdownRunnable = new IRunnableWithProgress() {\r
+ /**\r
+ * @param monitor\r
+ * the progress monitor to use for reporting progress to the\r
+ * user, or <code>null</code> indicating that no progress\r
+ * should be reported and the operation cannot be cancelled.\r
+ */\r
+ @Override\r
+ public void run(IProgressMonitor monitor) {\r
+ SubMonitor progress = SubMonitor.convert(monitor, SHUT_DOWN_PLATFORM_TASK, 100);\r
+ try {\r
+ try {\r
+ progress.subTask("Platform");\r
+ SimanticsPlatform.INSTANCE.shutdown(progress.newChild(50));\r
+ } catch (PlatformException e) {\r
+ Activator.logError("Problems encountered while shutting down Simantics platform, see exception for details.", e);\r
+ }\r
+\r
+ progress.subTask("Remaining database connections");\r
+ SimanticsUI.closeSessions();\r
+ progress.worked(20);\r
+ TimedSessionCache.close();\r
+ progress.worked(20);\r
+\r
+ progress.subTask("Thread pools");\r
+ ThreadUtils.shutdown();\r
+ progress.worked(5);\r
+\r
+ progress.subTask("Clear index status");\r
+ try {\r
+ // Everything ok, clear index dirty state.\r
+ DatabaseIndexing.clearAllDirty();\r
+ } catch (IOException e) {\r
+ Activator.logError("Problems encountered while refreshing database index states, see exception for details.", e);\r
+ }\r
+ progress.worked(5);\r
+\r
+ progress.setWorkRemaining(0);\r
+ } finally {\r
+ if (monitor != null) {\r
+ monitor.done();\r
+ }\r
+ }\r
+ }\r
+ };\r
+\r
+ /**\r
+ * Disconnect from the workspace and close ProCore sessions.\r
+ */\r
+ private void disconnectFromWorkspace() {\r
+ // save the workspace\r
+ final MultiStatus status = new MultiStatus(\r
+ IDEWorkbenchPlugin.IDE_WORKBENCH, 1,\r
+ IDEWorkbenchMessages.ProblemSavingWorkbench, null);\r
+\r
+ final ProgressMonitorJobsDialog p = new CancelableProgressMonitorJobsDialog(\r
+ null);\r
+\r
+ final boolean applyPolicy = ResourcesPlugin.getWorkspace()\r
+ .getDescription().isApplyFileStatePolicy();\r
+\r
+ final IRunnableWithProgress workspaceShutdownRunnable = new IRunnableWithProgress() {\r
+ @Override\r
+ public void run(IProgressMonitor monitor) {\r
+ try {\r
+ status.merge(((Workspace) ResourcesPlugin.getWorkspace()).save(true, true, monitor));\r
+ } catch (CoreException e) {\r
+ status.merge(e.getStatus());\r
+ }\r
+ }\r
+ };\r
+\r
+ IRunnableWithProgress shutdownRunnable = new IRunnableWithProgress() {\r
+ @Override\r
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {\r
+ if (applyPolicy)\r
+ monitor = new CancelableProgressMonitorWrapper(\r
+ monitor, p);\r
+\r
+ SubMonitor progress = SubMonitor.convert(monitor, SHUT_DOWN_TASK, 2);\r
+ try {\r
+ workspaceShutdownRunnable.run(progress.newChild(1, SubMonitor.SUPPRESS_NONE));\r
+ platformShutdownRunnable.run(progress.newChild(1, SubMonitor.SUPPRESS_NONE));\r
+ } finally {\r
+ monitor.done();\r
+ }\r
+ }\r
+ };\r
+\r
+ try {\r
+ new ProgressMonitorJobsDialog(null).run(true, false, shutdownRunnable);\r
+ } catch (InvocationTargetException e) {\r
+ status.merge(new Status(IStatus.ERROR,\r
+ IDEWorkbenchPlugin.IDE_WORKBENCH, 1,\r
+ IDEWorkbenchMessages.InternalError, e.getTargetException()));\r
+ } catch (InterruptedException e) {\r
+ status.merge(new Status(IStatus.ERROR,\r
+ IDEWorkbenchPlugin.IDE_WORKBENCH, 1,\r
+ IDEWorkbenchMessages.InternalError, e));\r
+ }\r
+ ErrorDialog.openError(null,\r
+ IDEWorkbenchMessages.ProblemsSavingWorkspace, null, status,\r
+ IStatus.ERROR | IStatus.WARNING);\r
+ if (!status.isOK()) {\r
+ IDEWorkbenchPlugin.log(\r
+ IDEWorkbenchMessages.ProblemsSavingWorkspace, status);\r
+ }\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ *\r
+ * @see org.eclipse.ui.application.WorkbenchAdvisor#getDefaultPageInput\r
+ */\r
+ @Override\r
+ public IAdaptable getDefaultPageInput() {\r
+ return ResourcesPlugin.getWorkspace().getRoot();\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ *\r
+ * @see org.eclipse.ui.application.WorkbenchAdvisor\r
+ */\r
+ @Override\r
+ public String getInitialWindowPerspectiveId() {\r
+ int index = PlatformUI.getWorkbench().getWorkbenchWindowCount() - 1;\r
+\r
+ String perspectiveId = null;\r
+ AboutInfo[] welcomeInfos = getWelcomePerspectiveInfos();\r
+ if (index >= 0 && welcomeInfos != null && index < welcomeInfos.length) {\r
+ perspectiveId = welcomeInfos[index].getWelcomePerspectiveId();\r
+ }\r
+\r
+ if (perspectiveId == null && args.contains(SimanticsArguments.PERSPECTIVE)) {\r
+ String id = args.get(SimanticsArguments.PERSPECTIVE);\r
+ IPerspectiveDescriptor perspective = PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(id);\r
+ if (perspective != null)\r
+ perspectiveId = id;\r
+ }\r
+\r
+ if (perspectiveId == null) {\r
+ IProject project = SimanticsUI.peekProject();\r
+ if (project != null)\r
+ perspectiveId = project.getHint(ProjectKeys.DEFAULT_PERSPECTIVE);\r
+ }\r
+\r
+ //System.out.println("Initial perspective: " + perspectiveId);\r
+\r
+ return perspectiveId;\r
+ }\r
+\r
+ /**\r
+ * Returns the map of versioned feature ids -> info object for all installed\r
+ * features. The format of the versioned feature id (the key of the map) is\r
+ * featureId + ":" + versionId.\r
+ *\r
+ * @return map of versioned feature ids -> info object (key type:\r
+ * <code>String</code>, value type: <code>AboutInfo</code>)\r
+ * @since 3.0\r
+ */\r
+ private Map<String, AboutInfo> computeBundleGroupMap() {\r
+ // use tree map to get predicable order\r
+ Map<String, AboutInfo> ids = new TreeMap<String, AboutInfo>();\r
+\r
+ IBundleGroupProvider[] providers = Platform.getBundleGroupProviders();\r
+ for (int i = 0; i < providers.length; ++i) {\r
+ IBundleGroup[] groups = providers[i].getBundleGroups();\r
+ for (int j = 0; j < groups.length; ++j) {\r
+ IBundleGroup group = groups[j];\r
+ AboutInfo info = new AboutInfo(group);\r
+\r
+ String version = info.getVersionId();\r
+ version = version == null ? "0.0.0" //$NON-NLS-1$\r
+ : new Version(version).toString();\r
+ String versionedFeature = group.getIdentifier() + ":" + version; //$NON-NLS-1$\r
+\r
+ ids.put(versionedFeature, info);\r
+ }\r
+ }\r
+\r
+ return ids;\r
+ }\r
+\r
+ /**\r
+ * Returns the ordered map of versioned feature ids -> AboutInfo that are\r
+ * new for this session.\r
+ *\r
+ * @return ordered map of versioned feature ids (key type:\r
+ * <code>String</code>) -> infos (value type:\r
+ * <code>AboutInfo</code>).\r
+ */\r
+ public Map<String, AboutInfo> getNewlyAddedBundleGroups() {\r
+ if (newlyAddedBundleGroups == null) {\r
+ newlyAddedBundleGroups = createNewBundleGroupsMap();\r
+ }\r
+ return newlyAddedBundleGroups;\r
+ }\r
+\r
+ /**\r
+ * Updates the old features setting and returns a map of new features.\r
+ */\r
+ private Map<String, AboutInfo> createNewBundleGroupsMap() {\r
+ // retrieve list of installed bundle groups from last session\r
+ IDialogSettings settings = IDEWorkbenchPlugin.getDefault()\r
+ .getDialogSettings();\r
+ String[] previousFeaturesArray = settings.getArray(INSTALLED_FEATURES);\r
+\r
+ // get a map of currently installed bundle groups and store it for next\r
+ // session\r
+ Map<String, AboutInfo> bundleGroups = computeBundleGroupMap();\r
+ String[] currentFeaturesArray = new String[bundleGroups.size()];\r
+ bundleGroups.keySet().toArray(currentFeaturesArray);\r
+ settings.put(INSTALLED_FEATURES, currentFeaturesArray);\r
+\r
+ // remove the previously known from the current set\r
+ if (previousFeaturesArray != null) {\r
+ for (int i = 0; i < previousFeaturesArray.length; ++i) {\r
+ bundleGroups.remove(previousFeaturesArray[i]);\r
+ }\r
+ }\r
+\r
+ return bundleGroups;\r
+ }\r
+\r
+ /**\r
+ * Declares all IDE-specific workbench images. This includes both "shared"\r
+ * images (named in {@link IDE.SharedImages}) and internal images (named in\r
+ * {@link org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages}).\r
+ *\r
+ * @see IWorkbenchConfigurer#declareImage\r
+ */\r
+ private void declareWorkbenchImages() {\r
+\r
+ final String ICONS_PATH = "$nl$/icons/full/";//$NON-NLS-1$\r
+ final String PATH_ELOCALTOOL = ICONS_PATH + "elcl16/"; // Enabled //$NON-NLS-1$\r
+\r
+ // toolbar\r
+ // icons.\r
+ final String PATH_DLOCALTOOL = ICONS_PATH + "dlcl16/"; // Disabled //$NON-NLS-1$\r
+ // //$NON-NLS-1$\r
+ // toolbar\r
+ // icons.\r
+ final String PATH_ETOOL = ICONS_PATH + "etool16/"; // Enabled toolbar //$NON-NLS-1$\r
+ // //$NON-NLS-1$\r
+ // icons.\r
+ final String PATH_DTOOL = ICONS_PATH + "dtool16/"; // Disabled toolbar //$NON-NLS-1$\r
+ // //$NON-NLS-1$\r
+ // icons.\r
+ final String PATH_OBJECT = ICONS_PATH + "obj16/"; // Model object //$NON-NLS-1$\r
+ // //$NON-NLS-1$\r
+ // icons\r
+ final String PATH_WIZBAN = ICONS_PATH + "wizban/"; // Wizard //$NON-NLS-1$\r
+ // //$NON-NLS-1$\r
+ // icons\r
+\r
+ Bundle ideBundle = Platform.getBundle(IDEWorkbenchPlugin.IDE_WORKBENCH);\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC, PATH_ETOOL\r
+ + "build_exec.gif", false); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC_HOVER,\r
+ PATH_ETOOL + "build_exec.gif", false); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC_DISABLED,\r
+ PATH_DTOOL + "build_exec.gif", false); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_ETOOL_SEARCH_SRC, PATH_ETOOL\r
+ + "search_src.gif", false); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_ETOOL_SEARCH_SRC_HOVER,\r
+ PATH_ETOOL + "search_src.gif", false); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_ETOOL_SEARCH_SRC_DISABLED,\r
+ PATH_DTOOL + "search_src.gif", false); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_ETOOL_NEXT_NAV, PATH_ETOOL\r
+ + "next_nav.gif", false); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_ETOOL_PREVIOUS_NAV, PATH_ETOOL\r
+ + "prev_nav.gif", false); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_WIZBAN_NEWPRJ_WIZ, PATH_WIZBAN\r
+ + "newprj_wiz.png", false); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_WIZBAN_NEWFOLDER_WIZ,\r
+ PATH_WIZBAN + "newfolder_wiz.png", false); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_WIZBAN_NEWFILE_WIZ, PATH_WIZBAN\r
+ + "newfile_wiz.png", false); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_WIZBAN_IMPORTDIR_WIZ,\r
+ PATH_WIZBAN + "importdir_wiz.png", false); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_WIZBAN_IMPORTZIP_WIZ,\r
+ PATH_WIZBAN + "importzip_wiz.png", false); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_WIZBAN_EXPORTDIR_WIZ,\r
+ PATH_WIZBAN + "exportdir_wiz.png", false); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_WIZBAN_EXPORTZIP_WIZ,\r
+ PATH_WIZBAN + "exportzip_wiz.png", false); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_WIZBAN_RESOURCEWORKINGSET_WIZ,\r
+ PATH_WIZBAN + "workset_wiz.png", false); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_DLGBAN_SAVEAS_DLG, PATH_WIZBAN\r
+ + "saveas_wiz.png", false); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_DLGBAN_QUICKFIX_DLG, PATH_WIZBAN\r
+ + "quick_fix.png", false); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OBJ_PROJECT,\r
+ PATH_OBJECT + "prj_obj.gif", true); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDE.SharedImages.IMG_OBJ_PROJECT_CLOSED, PATH_OBJECT\r
+ + "cprj_obj.gif", true); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OPEN_MARKER,\r
+ PATH_ELOCALTOOL + "gotoobj_tsk.gif", true); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_ELCL_QUICK_FIX_ENABLED,\r
+ PATH_ELOCALTOOL + "smartmode_co.gif", true); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_DLCL_QUICK_FIX_DISABLED,\r
+ PATH_DLOCALTOOL + "smartmode_co.gif", true); //$NON-NLS-1$\r
+\r
+ // task objects\r
+ // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_HPRIO_TSK,\r
+ // PATH_OBJECT+"hprio_tsk.gif");\r
+ // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_MPRIO_TSK,\r
+ // PATH_OBJECT+"mprio_tsk.gif");\r
+ // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_LPRIO_TSK,\r
+ // PATH_OBJECT+"lprio_tsk.gif");\r
+\r
+ declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OBJS_TASK_TSK,\r
+ PATH_OBJECT + "taskmrk_tsk.gif", true); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OBJS_BKMRK_TSK,\r
+ PATH_OBJECT + "bkmrk_tsk.gif", true); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_OBJS_COMPLETE_TSK, PATH_OBJECT\r
+ + "complete_tsk.gif", true); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_OBJS_INCOMPLETE_TSK, PATH_OBJECT\r
+ + "incomplete_tsk.gif", true); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_OBJS_WELCOME_ITEM, PATH_OBJECT\r
+ + "welcome_item.gif", true); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_OBJS_WELCOME_BANNER, PATH_OBJECT\r
+ + "welcome_banner.gif", true); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_OBJS_ERROR_PATH, PATH_OBJECT\r
+ + "error_tsk.gif", true); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_OBJS_WARNING_PATH, PATH_OBJECT\r
+ + "warn_tsk.gif", true); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_OBJS_INFO_PATH, PATH_OBJECT\r
+ + "info_tsk.gif", true); //$NON-NLS-1$\r
+\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_LCL_FLAT_LAYOUT, PATH_ELOCALTOOL\r
+ + "flatLayout.gif", true); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_LCL_HIERARCHICAL_LAYOUT,\r
+ PATH_ELOCALTOOL + "hierarchicalLayout.gif", true); //$NON-NLS-1$\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_ETOOL_PROBLEM_CATEGORY,\r
+ PATH_ETOOL + "problem_category.gif", true); //$NON-NLS-1$\r
+ /*\r
+ declareWorkbenchImage(ideBundle,\r
+ IDEInternalWorkbenchImages.IMG_LCL_LINKTO_HELP, PATH_ELOCALTOOL\r
+ + "linkto_help.gif", false); //$NON-NLS-1$\r
+ */\r
+\r
+ // synchronization indicator objects\r
+ // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_WBET_STAT,\r
+ // PATH_OVERLAY+"wbet_stat.gif");\r
+ // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_SBET_STAT,\r
+ // PATH_OVERLAY+"sbet_stat.gif");\r
+ // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_CONFLICT_STAT,\r
+ // PATH_OVERLAY+"conflict_stat.gif");\r
+\r
+ // content locality indicator objects\r
+ // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_NOTLOCAL_STAT,\r
+ // PATH_STAT+"notlocal_stat.gif");\r
+ // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_LOCAL_STAT,\r
+ // PATH_STAT+"local_stat.gif");\r
+ // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_FILLLOCAL_STAT,\r
+ // PATH_STAT+"filllocal_stat.gif");\r
+ }\r
+\r
+ /**\r
+ * Declares an IDE-specific workbench image.\r
+ *\r
+ * @param symbolicName\r
+ * the symbolic name of the image\r
+ * @param path\r
+ * the path of the image file; this path is relative to the base\r
+ * of the IDE plug-in\r
+ * @param shared\r
+ * <code>true</code> if this is a shared image, and\r
+ * <code>false</code> if this is not a shared image\r
+ * @see IWorkbenchConfigurer#declareImage\r
+ */\r
+ private void declareWorkbenchImage(Bundle ideBundle, String symbolicName,\r
+ String path, boolean shared) {\r
+ URL url = FileLocator.find(ideBundle, new Path(path), null);\r
+ ImageDescriptor desc = ImageDescriptor.createFromURL(url);\r
+ getWorkbenchConfigurer().declareImage(symbolicName, desc, shared);\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ *\r
+ * @see org.eclipse.ui.application.WorkbenchAdvisor#getMainPreferencePageId\r
+ */\r
+ @Override\r
+ public String getMainPreferencePageId() {\r
+ // indicate that we want the Workench preference page to be prominent\r
+ return WORKBENCH_PREFERENCE_CATEGORY_ID;\r
+ }\r
+\r
+ /**\r
+ * @return the workspace location string, or <code>null</code> if the\r
+ * location is not being shown\r
+ */\r
+ public String getWorkspaceLocation() {\r
+ // read command line, which has priority\r
+ IEclipseContext context = getWorkbenchConfigurer().getWorkbench().getService(IEclipseContext.class);\r
+ String location = context != null ? (String) context.get(E4Workbench.FORCED_SHOW_LOCATION) : null;\r
+ if (location != null) {\r
+ return location;\r
+ }\r
+ // read the preference\r
+ if (IDEWorkbenchPlugin.getDefault().getPreferenceStore().getBoolean(IDEInternalPreferences.SHOW_LOCATION)) {\r
+ return Platform.getLocation().toOSString();\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * @return the welcome perspective infos, or <code>null</code> if none or\r
+ * if they should be ignored due to the new intro being present\r
+ */\r
+ public AboutInfo[] getWelcomePerspectiveInfos() {\r
+ if (welcomePerspectiveInfos == null) {\r
+ // support old welcome perspectives if intro plugin is not present\r
+ if (!hasIntro()) {\r
+ Map<String, AboutInfo> m = getNewlyAddedBundleGroups();\r
+ ArrayList<AboutInfo> list = new ArrayList<AboutInfo>(m.size());\r
+ for (Iterator<AboutInfo> i = m.values().iterator(); i.hasNext();) {\r
+ AboutInfo info = i.next();\r
+ if (info != null && info.getWelcomePerspectiveId() != null\r
+ && info.getWelcomePageURL() != null) {\r
+ list.add(info);\r
+ }\r
+ }\r
+ welcomePerspectiveInfos = new AboutInfo[list.size()];\r
+ list.toArray(welcomePerspectiveInfos);\r
+ }\r
+ }\r
+ return welcomePerspectiveInfos;\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ *\r
+ * @see org.eclipse.ui.application.WorkbenchAdvisor#getWorkbenchErrorHandler()\r
+ */\r
+ @Override\r
+ public AbstractStatusHandler getWorkbenchErrorHandler() {\r
+ if (ideWorkbenchErrorHandler == null) {\r
+ ideWorkbenchErrorHandler = new IDEWorkbenchErrorHandler(\r
+ getWorkbenchConfigurer());\r
+ }\r
+ return ideWorkbenchErrorHandler;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see org.eclipse.ui.application.WorkbenchAdvisor#eventLoopIdle(org.eclipse.swt.widgets.Display)\r
+ */\r
+ @Override\r
+ public void eventLoopIdle(Display display) {\r
+ if (delayedEventsProcessor != null)\r
+ delayedEventsProcessor.catchUp(display);\r
+ super.eventLoopIdle(display);\r
+ }\r
+\r
+}\r