]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.workbench/src/org/simantics/workbench/internal/SimanticsWorkbenchAdvisor.java
Include acorn db in db.client feature and make it the default db driver
[simantics/platform.git] / bundles / org.simantics.workbench / src / org / simantics / workbench / internal / SimanticsWorkbenchAdvisor.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.workbench.internal;\r
13 \r
14 import java.io.IOException;\r
15 import java.lang.reflect.InvocationTargetException;\r
16 import java.net.URL;\r
17 import java.text.Collator;\r
18 import java.util.ArrayList;\r
19 import java.util.Iterator;\r
20 import java.util.Map;\r
21 import java.util.TreeMap;\r
22 \r
23 import org.eclipse.core.internal.resources.Workspace;\r
24 import org.eclipse.core.net.proxy.IProxyService;\r
25 import org.eclipse.core.resources.IContainer;\r
26 import org.eclipse.core.resources.IResource;\r
27 import org.eclipse.core.resources.ResourcesPlugin;\r
28 import org.eclipse.core.resources.WorkspaceJob;\r
29 import org.eclipse.core.runtime.CoreException;\r
30 import org.eclipse.core.runtime.FileLocator;\r
31 import org.eclipse.core.runtime.IAdaptable;\r
32 import org.eclipse.core.runtime.IBundleGroup;\r
33 import org.eclipse.core.runtime.IBundleGroupProvider;\r
34 import org.eclipse.core.runtime.ILog;\r
35 import org.eclipse.core.runtime.IProgressMonitor;\r
36 import org.eclipse.core.runtime.IStatus;\r
37 import org.eclipse.core.runtime.MultiStatus;\r
38 import org.eclipse.core.runtime.Path;\r
39 import org.eclipse.core.runtime.Platform;\r
40 import org.eclipse.core.runtime.ProgressMonitorWrapper;\r
41 import org.eclipse.core.runtime.Status;\r
42 import org.eclipse.core.runtime.SubMonitor;\r
43 import org.eclipse.core.runtime.jobs.Job;\r
44 import org.eclipse.e4.core.contexts.IEclipseContext;\r
45 import org.eclipse.e4.ui.internal.workbench.E4Workbench;\r
46 import org.eclipse.jface.dialogs.ErrorDialog;\r
47 import org.eclipse.jface.dialogs.IDialogSettings;\r
48 import org.eclipse.jface.dialogs.MessageDialog;\r
49 import org.eclipse.jface.dialogs.TrayDialog;\r
50 import org.eclipse.jface.operation.IRunnableWithProgress;\r
51 import org.eclipse.jface.preference.IPreferenceStore;\r
52 import org.eclipse.jface.resource.ImageDescriptor;\r
53 import org.eclipse.jface.util.Policy;\r
54 import org.eclipse.jface.window.Window;\r
55 import org.eclipse.swt.SWT;\r
56 import org.eclipse.swt.events.SelectionAdapter;\r
57 import org.eclipse.swt.events.SelectionEvent;\r
58 import org.eclipse.swt.widgets.Composite;\r
59 import org.eclipse.swt.widgets.Display;\r
60 import org.eclipse.swt.widgets.Event;\r
61 import org.eclipse.swt.widgets.Listener;\r
62 import org.eclipse.swt.widgets.Shell;\r
63 import org.eclipse.ui.IPerspectiveDescriptor;\r
64 import org.eclipse.ui.IWorkbench;\r
65 import org.eclipse.ui.PlatformUI;\r
66 import org.eclipse.ui.application.IWorkbenchConfigurer;\r
67 import org.eclipse.ui.application.IWorkbenchWindowConfigurer;\r
68 import org.eclipse.ui.application.WorkbenchAdvisor;\r
69 import org.eclipse.ui.application.WorkbenchWindowAdvisor;\r
70 import org.eclipse.ui.ide.IDE;\r
71 import org.eclipse.ui.internal.ISelectionConversionService;\r
72 import org.eclipse.ui.internal.Workbench;\r
73 import org.eclipse.ui.internal.ide.AboutInfo;\r
74 import org.eclipse.ui.internal.ide.IDEInternalPreferences;\r
75 import org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages;\r
76 import org.eclipse.ui.internal.ide.IDESelectionConversionService;\r
77 import org.eclipse.ui.internal.ide.IDEWorkbenchActivityHelper;\r
78 import org.eclipse.ui.internal.ide.IDEWorkbenchErrorHandler;\r
79 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;\r
80 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;\r
81 import org.eclipse.ui.internal.ide.undo.WorkspaceUndoMonitor;\r
82 import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog;\r
83 import org.eclipse.ui.keys.IBindingService;\r
84 import org.eclipse.ui.progress.IProgressService;\r
85 import org.eclipse.ui.statushandlers.AbstractStatusHandler;\r
86 import org.osgi.framework.Bundle;\r
87 import org.osgi.framework.ServiceReference;\r
88 import org.osgi.framework.Version;\r
89 import org.simantics.CancelStartupException;\r
90 import org.simantics.PlatformException;\r
91 import org.simantics.Simantics;\r
92 import org.simantics.SimanticsPlatform;\r
93 import org.simantics.SimanticsPlatform.OntologyRecoveryPolicy;\r
94 import org.simantics.SimanticsPlatform.RecoveryPolicy;\r
95 import org.simantics.application.arguments.IArguments;\r
96 import org.simantics.application.arguments.SimanticsArguments;\r
97 import org.simantics.db.common.Indexing;\r
98 import org.simantics.db.indexing.DatabaseIndexing;\r
99 import org.simantics.db.procore.server.environment.RebootRequiredException;\r
100 import org.simantics.db.procore.server.environment.windows.Product;\r
101 import org.simantics.db.procore.ui.ProCoreUserAgent;\r
102 import org.simantics.internal.TimedSessionCache;\r
103 import org.simantics.project.IProject;\r
104 import org.simantics.project.ProjectKeys;\r
105 import org.simantics.ui.SimanticsUI;\r
106 import org.simantics.ui.jobs.SessionGarbageCollectorJob;\r
107 import org.simantics.ui.workbench.PerspectiveBarsActivator;\r
108 import org.simantics.ui.workbench.PerspectiveContextActivator;\r
109 import org.simantics.utils.logging.TimeLogger;\r
110 import org.simantics.utils.threads.ThreadUtils;\r
111 import org.simantics.utils.ui.dialogs.ShowError;\r
112 import org.simantics.utils.ui.dialogs.ShowMessage;\r
113 \r
114 \r
115 /**\r
116  * @author Tuukka Lehtonen\r
117  */\r
118 public class SimanticsWorkbenchAdvisor extends WorkbenchAdvisor {\r
119 \r
120     private static final boolean PROFILE_PLATFORM_STARTUP = false;\r
121 \r
122     private static final String SHUT_DOWN_TASK = "Shutting down...";\r
123 \r
124     private static final String SHUT_DOWN_PLATFORM_TASK = "Shutting down platform...";\r
125 \r
126     private static final String WORKBENCH_PREFERENCE_CATEGORY_ID = "org.eclipse.ui.preferencePages.Workbench"; //$NON-NLS-1$\r
127 \r
128     /**\r
129      * The dialog setting key to access the known installed features since the\r
130      * last time the workbench was run.\r
131      */\r
132     private static final String INSTALLED_FEATURES = "installedFeatures"; //$NON-NLS-1$\r
133 \r
134     /**\r
135      * Default database ID\r
136      */\r
137     private static final String DEFAULT_DATABASE_ID = "acorn";\r
138     \r
139     /**\r
140      * The arguments received by the application.\r
141      */\r
142     protected final IArguments args;\r
143 \r
144     protected final boolean restoredPreviousSession = false;\r
145 \r
146     /**\r
147      * Only true while opening the initial windows during {@link #openWindows()}.\r
148      * Used by {@link SimanticsWorkbenchWindowAdvisor#postWindowOpen()} to\r
149      * recognize when to skip all one-time initialization.\r
150      */\r
151     protected boolean workbenchWindowsInitialized = false;\r
152 \r
153     /**\r
154      * Whether or not to save unsaved database changes before exiting the\r
155      * workbench.\r
156      */\r
157     protected boolean saveAtExit = false;\r
158 \r
159     /**\r
160      * Ordered map of versioned feature ids -> info that are new for this\r
161      * session; <code>null</code> if uninitialized. Key type:\r
162      * <code>String</code>, Value type: <code>AboutInfo</code>.\r
163      */\r
164     private Map<String, AboutInfo> newlyAddedBundleGroups;\r
165 \r
166     /**\r
167      * Array of <code>AboutInfo</code> for all new installed features that\r
168      * specify a welcome perspective.\r
169      */\r
170     private AboutInfo[] welcomePerspectiveInfos = null;\r
171 \r
172     /**\r
173      * Helper for managing activites in response to workspace changes.\r
174      */\r
175     private IDEWorkbenchActivityHelper activityHelper = null;\r
176 \r
177     /**\r
178      * Helper for managing work that is performed when the system is otherwise\r
179      * idle.\r
180      */\r
181     private IDEIdleHelper idleHelper;\r
182 \r
183     private Listener settingsChangeListener;\r
184 \r
185     /**\r
186      * Support class for monitoring workspace changes and periodically\r
187      * validating the undo history\r
188      */\r
189     private WorkspaceUndoMonitor workspaceUndoMonitor;\r
190 \r
191     /**\r
192      * The IDE workbench error handler.\r
193      */\r
194     private AbstractStatusHandler ideWorkbenchErrorHandler;\r
195 \r
196     /**\r
197      * Helper class used to process delayed events.\r
198      */\r
199     private DelayedEventsProcessor delayedEventsProcessor;\r
200     \r
201     /**\r
202      * Creates a new workbench advisor instance.\r
203      * @param processor\r
204      */\r
205     public SimanticsWorkbenchAdvisor(IArguments args, DelayedEventsProcessor processor) {\r
206         super();\r
207         this.args = args;\r
208         this.delayedEventsProcessor = processor;\r
209 \r
210         Listener closeListener = new Listener() {\r
211             public void handleEvent(Event event) {\r
212                 boolean doExit = SimanticsWorkbenchWindowAdvisor.promptOnExit(null);\r
213                 event.doit = doExit;\r
214                 if (!doExit)\r
215                     event.type = SWT.None;\r
216             }\r
217         };\r
218         Display.getDefault().addListener(SWT.Close, closeListener);\r
219     }\r
220 \r
221     public IArguments getArguments() {\r
222         return args;\r
223     }\r
224 \r
225     public boolean workbenchInitialized() {\r
226         return workbenchWindowsInitialized;\r
227     }\r
228 \r
229     public boolean restoredPreviousSession() {\r
230         return restoredPreviousSession;\r
231     }\r
232 \r
233     boolean saveAtExit() {\r
234         return saveAtExit;\r
235     }\r
236 \r
237     void setSaveAtExit(boolean saveAtExit) {\r
238         this.saveAtExit = saveAtExit;\r
239     }\r
240 \r
241     /*\r
242      * (non-Javadoc)\r
243      *\r
244      * @see org.eclipse.ui.application.WorkbenchAdvisor#initialize\r
245      */\r
246     @Override\r
247     public void initialize(IWorkbenchConfigurer configurer) {\r
248         // By default, we always save and restore the workbench state.\r
249         configurer.setSaveAndRestore(true);\r
250 \r
251         checkWorkspaceDatabaseIndexes();\r
252 \r
253         // Start tracking the active perspective to activate contexts based on it.\r
254         new PerspectiveContextActivator();\r
255         new PerspectiveBarsActivator();\r
256 \r
257         // register workspace adapters\r
258         IDE.registerAdapters();\r
259 \r
260         // register shared images\r
261         declareWorkbenchImages();\r
262 \r
263         // initialize the activity helper\r
264         activityHelper = IDEWorkbenchActivityHelper.getInstance();\r
265 \r
266         // initialize idle handler\r
267         idleHelper = new IDEIdleHelper(configurer);\r
268 \r
269         // initialize the workspace undo monitor\r
270         workspaceUndoMonitor = WorkspaceUndoMonitor.getInstance();\r
271 \r
272         // show Help button in JFace dialogs\r
273         TrayDialog.setDialogHelpAvailable(true);\r
274 \r
275         Policy.setComparator(Collator.getInstance());\r
276     }\r
277 \r
278     private void checkWorkspaceDatabaseIndexes() {\r
279         try {\r
280             DatabaseIndexing.validateIndexes();\r
281         } catch (IOException e) {\r
282             Activator.logError("Problems encountered while checking database indexes, see exception for details.", e);\r
283         }\r
284     }\r
285 \r
286     public WorkbenchWindowAdvisor createWorkbenchWindowAdvisorClass(SimanticsWorkbenchAdvisor advisor, IWorkbenchWindowConfigurer configurer) {\r
287         return new SimanticsWorkbenchWindowAdvisor(this, configurer);\r
288     }\r
289 \r
290     @Override\r
291     public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {\r
292         // Attach database session watchdog.\r
293         new SessionWatchdog().attach( Simantics.getSessionContextProvider() );\r
294 \r
295         return createWorkbenchWindowAdvisorClass(this, configurer);\r
296     }\r
297 \r
298     /**\r
299      * For gaining direct access to super.openWindows() in implementations\r
300      * inheriting this one.\r
301      */\r
302     public boolean openWindowsSuper() {\r
303         return super.openWindows();\r
304     }\r
305 \r
306     /**\r
307      * Sadly we do not know why key bindings are lost and why this helps. But it\r
308      * does. Visiting the <code>Keys</code> preference page and pressing OK uses\r
309      * this the same call and it seems to salvage the bindings that have been in\r
310      * some cases destroyed by <code>BindingToModelProcessor</code>.\r
311      * \r
312      * <p>\r
313      * Related links:\r
314      * https://techblog.ralph-schuster.eu/2013/10/13/eclipsee4-problem-with-key-bindings/comment-page-1/\r
315      * https://www.eclipse.org/forums/index.php/t/550175/\r
316      * https://bugs.eclipse.org/bugs/show_bug.cgi?id=461037\r
317      * \r
318      * @see platform issue #6353\r
319      */\r
320     private void fixBindings() {\r
321         try {\r
322             IBindingService bs = PlatformUI.getWorkbench().getAdapter(IBindingService.class);\r
323             bs.savePreferences(bs.getActiveScheme(), bs.getBindings());\r
324         } catch (IOException e) {\r
325             Activator.logError(getClass().getSimpleName() + ".fixBindings failed", e);\r
326         }\r
327     }\r
328 \r
329     @Override\r
330     public boolean openWindows() {\r
331         boolean platformOk = startPlatform();\r
332         TimeLogger.log("SimanticsWorkbenchAdvisor.startPlatform finished");\r
333 \r
334         if (platformOk) {\r
335             // At this point workbenchConfigurer.getSaveAndRestore()\r
336             // returns false iff something has gone terribly wrong\r
337             // before this. Currently saveAndRestore is always true.\r
338             boolean windowsOpened = super.openWindows();\r
339             TimeLogger.log("Opened windows");\r
340             if (windowsOpened) {\r
341                 workbenchWindowsInitialized = true;\r
342 \r
343                 // Start the database garbage collector after a short while.\r
344                 SessionGarbageCollectorJob.getInstance().scheduleAfterQuietTime();\r
345 \r
346                 // Discard database session undo history at this point to prevent\r
347                 // the user from undoing any initialization operations performed\r
348                 // by the platform startup.\r
349                 SimanticsPlatform.INSTANCE.discardSessionUndoHistory();\r
350                 TimeLogger.log("Discarded session undo history");\r
351 \r
352                 // #6353: Workaround for  \r
353                 fixBindings();\r
354 \r
355                 return true;\r
356             }\r
357         }\r
358 \r
359         // Make sure platform shutdown is ran if window opening fails.\r
360         try {\r
361             platformShutdownRunnable.run(null);\r
362         } catch (InvocationTargetException e) {\r
363             Activator.logError(getClass().getSimpleName() + ".openWindows failed", e);\r
364         } catch (InterruptedException e) {\r
365             Activator.logError(getClass().getSimpleName() + ".openWindows failed", e);\r
366         }\r
367         return false;\r
368     }\r
369 \r
370     protected boolean startPlatform() {\r
371         // Verify selected perspective\r
372         if (args.contains(SimanticsArguments.PERSPECTIVE)) {\r
373             String perspectiveId = args.get(SimanticsArguments.PERSPECTIVE);\r
374             IPerspectiveDescriptor perspective = PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(perspectiveId);\r
375             if (perspective == null) {\r
376                 StringBuilder msg = new StringBuilder();\r
377                 msg.append("Requested perspective not found: '" + perspectiveId + "'\n");\r
378                 msg.append("Valid alternatives are:\n");\r
379                 for (IPerspectiveDescriptor pd : PlatformUI.getWorkbench().getPerspectiveRegistry().getPerspectives()) {\r
380                     msg.append("    " + pd.getId() + "\n");\r
381                 }\r
382 \r
383                 ShowMessage.syncShowError("Invalid Perspective", msg.toString());\r
384                 return false;\r
385             }\r
386         }\r
387 \r
388         ILog log = Platform.getLog(Activator.getDefault().getBundle());\r
389 \r
390         try {\r
391             //\r
392             //\r
393             // Create Simantics Platform Helper.\r
394             //\r
395             // If Simantics is started from Eclipse IDE or with -fixerrors option,\r
396             // there is an attempt to fix errors.\r
397             //\r
398             // On ontology mismatch, there is an attempt to merge new ontology to the\r
399             // existing database. With -reinstall, the database is cleaned and\r
400             // reinstalled.\r
401             //\r
402             //\r
403 \r
404             RecoveryPolicy workspacePolicy = Platform.inDevelopmentMode() ? RecoveryPolicy.FixError : RecoveryPolicy.ThrowError;\r
405             OntologyRecoveryPolicy ontologyPolicy = Platform.inDevelopmentMode() ? OntologyRecoveryPolicy.Merge : OntologyRecoveryPolicy.ThrowError;\r
406 \r
407             if (args.contains(SimanticsArguments.RECOVERY_POLICY_FIX_ERRORS)) {\r
408                 workspacePolicy = RecoveryPolicy.FixError;\r
409                 ontologyPolicy = OntologyRecoveryPolicy.Merge;\r
410             }\r
411 \r
412             boolean requireSynchronize = true;\r
413 \r
414             if (args.contains(SimanticsArguments.ONTOLOGY_RECOVERY_POLICY_REINSTALL)) {\r
415                 ontologyPolicy = OntologyRecoveryPolicy.ReinstallDatabase;\r
416             }\r
417 \r
418             if (args.contains(SimanticsArguments.DO_NOT_SYNCHRONIZE_ONTOLOGIES)) {\r
419                 requireSynchronize = false;\r
420             }\r
421             \r
422             if (args.contains(SimanticsArguments.DISABLE_INDEX)) {\r
423                 Indexing.setDefaultDependenciesIndexingEnabled(false);\r
424             }\r
425 \r
426             if (args.contains(SimanticsArguments.SERVER)) {\r
427                 String serverAddress = args.get(SimanticsArguments.SERVER);\r
428                 throw new PlatformException("Argument not supported: " + SimanticsArguments.SERVER + " " + serverAddress);\r
429             }\r
430 \r
431             // TODO: Default to procore for now;\r
432             String databaseId = DEFAULT_DATABASE_ID;\r
433             if (args.contains(SimanticsArguments.DATABASE_ID)) {\r
434                 databaseId = args.get(SimanticsArguments.DATABASE_ID);\r
435             }\r
436             \r
437             IProgressMonitor mon = null;\r
438             if (PROFILE_PLATFORM_STARTUP)\r
439                 mon = new TimingProgressMonitor();\r
440             IWorkbench wb = PlatformUI.getWorkbench();\r
441             SimanticsPlatform.INSTANCE.startUp(databaseId, mon, workspacePolicy, ontologyPolicy, requireSynchronize, new JFaceUserAgent());\r
442 \r
443             // Make sure that the default perspective comes from the project if\r
444             // the project has set ProjectKeys#DEFAULT_PERSPECTIVE.\r
445             // This might go wrong if project features interact with\r
446             // PerspectiveRegistry while configuring themselves, since that will\r
447             // cause an invocation to #getInitialWindowPerspectiveId() while\r
448             // the project has not yet been properly initialized.\r
449             getWorkbenchConfigurer().getWorkbench().getPerspectiveRegistry().setDefaultPerspective(getInitialWindowPerspectiveId());\r
450             TimeLogger.log("Completed setting default perspective");\r
451 \r
452             return true;\r
453         } catch (CancelStartupException e) {\r
454             return false;\r
455         } catch (PlatformException e) {\r
456             boolean hasStackTrace = e.getStackTrace().length > 0;\r
457             Throwable ee = e;\r
458             while (ee.getCause() != null) {\r
459                 ee = ee.getCause();\r
460                 hasStackTrace = ee.getStackTrace().length > 0;\r
461             }\r
462 \r
463             log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), hasStackTrace ? e : null));\r
464             if (hasStackTrace) {\r
465                 new ShowError("Platform Initialization Failed", "Simantics Platform initialization failed:\n\n" + e.getMessage(), e, true);\r
466             } else {\r
467                 StringBuilder sb = new StringBuilder(256);\r
468                 sb.append(e.getMessage());\r
469                 for (Throwable c=e.getCause(); null != c && null != c.getMessage(); c=c.getCause())\r
470                     sb.append("\ncause: ").append(c.getMessage());\r
471                 new ShowError("Startup Failed", sb.toString(), (Exception) null, true);\r
472             }\r
473 \r
474             return false;\r
475         } catch (Exception e) {\r
476             log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));\r
477 \r
478             Throwable cause = e.getCause();\r
479             if (cause instanceof RebootRequiredException) {\r
480                 RebootRequiredException rre = (RebootRequiredException) cause;\r
481                 StringBuilder msg = new StringBuilder();\r
482                 msg.append("The application must be restarted after installing the following products:\n");\r
483                 for (Product product : rre.products)\r
484                     msg.append("\t" + product + "\n");\r
485                 msg.append("\nThe application will now close.");\r
486                 MessageDialog.openInformation(null, "Restart Required", msg.toString());\r
487             } else {\r
488                 new ShowError("Platform Startup Failed", "Simantics Platform startup failed:\n\n" + e.getMessage(), e, true);\r
489             }\r
490             return false;\r
491         }\r
492 \r
493     }\r
494 \r
495     /*\r
496      * (non-Javadoc)\r
497      *\r
498      * @see org.eclipse.ui.application.WorkbenchAdvisor#preStartup()\r
499      */\r
500     @Override\r
501     public void preStartup() {\r
502 \r
503         // Suspend background jobs while we startup\r
504         Job.getJobManager().suspend();\r
505 \r
506         // Register the build actions\r
507         IProgressService service = PlatformUI.getWorkbench()\r
508         .getProgressService();\r
509         ImageDescriptor newImage = IDEInternalWorkbenchImages\r
510         .getImageDescriptor(IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC);\r
511         service.registerIconForFamily(newImage,\r
512                 ResourcesPlugin.FAMILY_MANUAL_BUILD);\r
513         service.registerIconForFamily(newImage,\r
514                 ResourcesPlugin.FAMILY_AUTO_BUILD);\r
515     }\r
516 \r
517     /*\r
518      * (non-Javadoc)\r
519      *\r
520      * @see org.eclipse.ui.application.WorkbenchAdvisor#postStartup()\r
521      */\r
522     @Override\r
523     public void postStartup() {\r
524         try {\r
525             refreshFromLocal();\r
526             activateProxyService();\r
527             ((Workbench) PlatformUI.getWorkbench()).registerService(\r
528                     ISelectionConversionService.class,\r
529                     new IDESelectionConversionService());\r
530 \r
531             initializeSettingsChangeListener();\r
532             Display.getCurrent().addListener(SWT.Settings,\r
533                     settingsChangeListener);\r
534         } finally {// Resume background jobs after we startup\r
535             Job.getJobManager().resume();\r
536         }\r
537     }\r
538 \r
539     /**\r
540      * Activate the proxy service by obtaining it.\r
541      */\r
542     private void activateProxyService() {\r
543         Bundle bundle = Platform.getBundle("org.eclipse.ui.ide"); //$NON-NLS-1$\r
544         Object proxyService = null;\r
545         if (bundle != null) {\r
546             ServiceReference<?> ref = bundle.getBundleContext().getServiceReference(IProxyService.class.getName());\r
547             if (ref != null)\r
548                 proxyService = bundle.getBundleContext().getService(ref);\r
549         }\r
550         if (proxyService == null) {\r
551             IDEWorkbenchPlugin.log("Proxy service could not be found."); //$NON-NLS-1$\r
552         }\r
553     }\r
554 \r
555     /**\r
556      * Initialize the listener for settings changes.\r
557      */\r
558     private void initializeSettingsChangeListener() {\r
559         settingsChangeListener = new Listener() {\r
560 \r
561             boolean currentHighContrast = Display.getCurrent()\r
562             .getHighContrast();\r
563 \r
564             @Override\r
565             public void handleEvent(org.eclipse.swt.widgets.Event event) {\r
566                 if (Display.getCurrent().getHighContrast() == currentHighContrast)\r
567                     return;\r
568 \r
569                 currentHighContrast = !currentHighContrast;\r
570 \r
571                 // make sure they really want to do this\r
572                 if (new MessageDialog(null,\r
573                         IDEWorkbenchMessages.SystemSettingsChange_title, null,\r
574                         IDEWorkbenchMessages.SystemSettingsChange_message,\r
575                         MessageDialog.QUESTION, new String[] {\r
576                         IDEWorkbenchMessages.SystemSettingsChange_yes,\r
577                         IDEWorkbenchMessages.SystemSettingsChange_no },\r
578                         1).open() == Window.OK) {\r
579                     PlatformUI.getWorkbench().restart();\r
580                 }\r
581             }\r
582         };\r
583 \r
584     }\r
585 \r
586     /*\r
587      * (non-Javadoc)\r
588      *\r
589      * @see org.eclipse.ui.application.WorkbenchAdvisor#postShutdown\r
590      */\r
591     @Override\r
592     public void postShutdown() {\r
593         if (activityHelper != null) {\r
594             activityHelper.shutdown();\r
595             activityHelper = null;\r
596         }\r
597         if (idleHelper != null) {\r
598             idleHelper.shutdown();\r
599             idleHelper = null;\r
600         }\r
601         if (workspaceUndoMonitor != null) {\r
602             workspaceUndoMonitor.shutdown();\r
603             workspaceUndoMonitor = null;\r
604         }\r
605         if (IDEWorkbenchPlugin.getPluginWorkspace() != null) {\r
606             disconnectFromWorkspace();\r
607         }\r
608     }\r
609 \r
610     /*\r
611      * (non-Javadoc)\r
612      *\r
613      * @see org.eclipse.ui.application.WorkbenchAdvisor#preShutdown()\r
614      */\r
615     @Override\r
616     public boolean preShutdown() {\r
617         Display.getCurrent().removeListener(SWT.Settings,\r
618                 settingsChangeListener);\r
619         return super.preShutdown();\r
620     }\r
621 \r
622     /**\r
623      * Return true if the intro plugin is present and false otherwise.\r
624      *\r
625      * @return boolean\r
626      */\r
627     public boolean hasIntro() {\r
628         return getWorkbenchConfigurer().getWorkbench().getIntroManager()\r
629                 .hasIntro();\r
630     }\r
631 \r
632     private void refreshFromLocal() {\r
633         String[] commandLineArgs = Platform.getCommandLineArgs();\r
634         IPreferenceStore store = IDEWorkbenchPlugin.getDefault()\r
635                 .getPreferenceStore();\r
636         boolean refresh = store\r
637                 .getBoolean(IDEInternalPreferences.REFRESH_WORKSPACE_ON_STARTUP);\r
638         if (!refresh) {\r
639             return;\r
640         }\r
641 \r
642         // Do not refresh if it was already done by core on startup.\r
643         for (int i = 0; i < commandLineArgs.length; i++) {\r
644             if (commandLineArgs[i].equalsIgnoreCase("-refresh")) { //$NON-NLS-1$\r
645                 return;\r
646             }\r
647         }\r
648 \r
649         final IContainer root = ResourcesPlugin.getWorkspace().getRoot();\r
650         Job job = new WorkspaceJob(IDEWorkbenchMessages.Workspace_refreshing) {\r
651             @Override\r
652             public IStatus runInWorkspace(IProgressMonitor monitor)\r
653                     throws CoreException {\r
654                 root.refreshLocal(IResource.DEPTH_INFINITE, monitor);\r
655                 return Status.OK_STATUS;\r
656             }\r
657         };\r
658         job.setRule(root);\r
659         job.schedule();\r
660     }\r
661 \r
662     private static class CancelableProgressMonitorWrapper extends ProgressMonitorWrapper {\r
663         private double total = 0;\r
664         private ProgressMonitorJobsDialog dialog;\r
665 \r
666         CancelableProgressMonitorWrapper(IProgressMonitor monitor,\r
667                 ProgressMonitorJobsDialog dialog) {\r
668             super(monitor);\r
669             this.dialog = dialog;\r
670         }\r
671 \r
672         /*\r
673          * (non-Javadoc)\r
674          * @see org.eclipse.core.runtime.ProgressMonitorWrapper#internalWorked(double)\r
675          */\r
676         public void internalWorked(double work) {\r
677             super.internalWorked(work);\r
678             total += work;\r
679             updateProgressDetails();\r
680         }\r
681 \r
682         /*\r
683          * (non-Javadoc)\r
684          * @see org.eclipse.core.runtime.ProgressMonitorWrapper#worked(int)\r
685          */\r
686         public void worked(int work) {\r
687             super.worked(work);\r
688             total += work;\r
689             updateProgressDetails();\r
690         }\r
691 \r
692         public void beginTask(String name, int totalWork) {\r
693             super.beginTask(name, totalWork);\r
694             subTask(IDEWorkbenchMessages.IDEWorkbenchAdvisor_preHistoryCompaction);\r
695         }\r
696 \r
697         private void updateProgressDetails() {\r
698             if (!isCanceled() && Math.abs(total - 4.0) < 0.0001 /* right before history compacting */) {\r
699                 subTask(IDEWorkbenchMessages.IDEWorkbenchAdvisor_cancelHistoryPruning);\r
700                 dialog.setCancelable(true);\r
701             }\r
702             if (Math.abs(total - 5.0) < 0.0001 /* history compacting finished */) {\r
703                 subTask(IDEWorkbenchMessages.IDEWorkbenchAdvisor_postHistoryCompaction);\r
704                 dialog.setCancelable(false);\r
705             }\r
706         }\r
707     }\r
708 \r
709     private static class CancelableProgressMonitorJobsDialog extends ProgressMonitorJobsDialog {\r
710 \r
711         public CancelableProgressMonitorJobsDialog(Shell parent) {\r
712             super(parent);\r
713         }\r
714 \r
715         /*\r
716          * (non-Javadoc)\r
717          * @see org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog#createDetailsButton(org.eclipse.swt.widgets.Composite)\r
718          */\r
719         protected void createButtonsForButtonBar(Composite parent) {\r
720             super.createButtonsForButtonBar(parent);\r
721             registerCancelButtonListener();\r
722         }\r
723 \r
724         public void registerCancelButtonListener() {\r
725             cancel.addSelectionListener(new SelectionAdapter() {\r
726                 public void widgetSelected(SelectionEvent e) {\r
727                     subTaskLabel.setText(""); //$NON-NLS-1$\r
728                 }\r
729             });\r
730         }\r
731     }\r
732 \r
733 \r
734     final IRunnableWithProgress platformShutdownRunnable = new IRunnableWithProgress() {\r
735         /**\r
736          * @param monitor\r
737          *            the progress monitor to use for reporting progress to the\r
738          *            user, or <code>null</code> indicating that no progress\r
739          *            should be reported and the operation cannot be cancelled.\r
740          */\r
741         @Override\r
742         public void run(IProgressMonitor monitor) {\r
743             SubMonitor progress = SubMonitor.convert(monitor, SHUT_DOWN_PLATFORM_TASK, 100);\r
744             try {\r
745                 try {\r
746                     progress.subTask("Platform");\r
747                     SimanticsPlatform.INSTANCE.shutdown(progress.newChild(50));\r
748                 } catch (PlatformException e) {\r
749                     Activator.logError("Problems encountered while shutting down Simantics platform, see exception for details.", e);\r
750                 }\r
751 \r
752                 progress.subTask("Remaining database connections");\r
753                 SimanticsUI.closeSessions();\r
754                 progress.worked(20);\r
755                 TimedSessionCache.close();\r
756                 progress.worked(20);\r
757 \r
758                 progress.subTask("Thread pools");\r
759                 ThreadUtils.shutdown();\r
760                 progress.worked(5);\r
761 \r
762                 progress.subTask("Clear index status");\r
763                 try {\r
764                     // Everything ok, clear index dirty state.\r
765                     DatabaseIndexing.clearAllDirty();\r
766                 } catch (IOException e) {\r
767                     Activator.logError("Problems encountered while refreshing database index states, see exception for details.", e);\r
768                 }\r
769                 progress.worked(5);\r
770 \r
771                 progress.setWorkRemaining(0);\r
772             } finally {\r
773                 if (monitor != null) {\r
774                     monitor.done();\r
775                 }\r
776             }\r
777         }\r
778     };\r
779 \r
780     /**\r
781      * Disconnect from the workspace and close ProCore sessions.\r
782      */\r
783     private void disconnectFromWorkspace() {\r
784         // save the workspace\r
785         final MultiStatus status = new MultiStatus(\r
786                 IDEWorkbenchPlugin.IDE_WORKBENCH, 1,\r
787                 IDEWorkbenchMessages.ProblemSavingWorkbench, null);\r
788 \r
789         final ProgressMonitorJobsDialog p = new CancelableProgressMonitorJobsDialog(\r
790                 null);\r
791 \r
792         final boolean applyPolicy = ResourcesPlugin.getWorkspace()\r
793                 .getDescription().isApplyFileStatePolicy();\r
794 \r
795         final IRunnableWithProgress workspaceShutdownRunnable = new IRunnableWithProgress() {\r
796             @Override\r
797             public void run(IProgressMonitor monitor) {\r
798                 try {\r
799                     status.merge(((Workspace) ResourcesPlugin.getWorkspace()).save(true, true, monitor));\r
800                 } catch (CoreException e) {\r
801                     status.merge(e.getStatus());\r
802                 }\r
803             }\r
804         };\r
805 \r
806         IRunnableWithProgress shutdownRunnable = new IRunnableWithProgress() {\r
807             @Override\r
808             public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {\r
809                 if (applyPolicy)\r
810                     monitor = new CancelableProgressMonitorWrapper(\r
811                             monitor, p);\r
812 \r
813                 SubMonitor progress = SubMonitor.convert(monitor, SHUT_DOWN_TASK, 2);\r
814                 try {\r
815                     workspaceShutdownRunnable.run(progress.newChild(1, SubMonitor.SUPPRESS_NONE));\r
816                     platformShutdownRunnable.run(progress.newChild(1, SubMonitor.SUPPRESS_NONE));\r
817                 } finally {\r
818                     monitor.done();\r
819                 }\r
820             }\r
821         };\r
822 \r
823         try {\r
824             new ProgressMonitorJobsDialog(null).run(true, false, shutdownRunnable);\r
825         } catch (InvocationTargetException e) {\r
826             status.merge(new Status(IStatus.ERROR,\r
827                     IDEWorkbenchPlugin.IDE_WORKBENCH, 1,\r
828                     IDEWorkbenchMessages.InternalError, e.getTargetException()));\r
829         } catch (InterruptedException e) {\r
830             status.merge(new Status(IStatus.ERROR,\r
831                     IDEWorkbenchPlugin.IDE_WORKBENCH, 1,\r
832                     IDEWorkbenchMessages.InternalError, e));\r
833         }\r
834         ErrorDialog.openError(null,\r
835                 IDEWorkbenchMessages.ProblemsSavingWorkspace, null, status,\r
836                 IStatus.ERROR | IStatus.WARNING);\r
837         if (!status.isOK()) {\r
838             IDEWorkbenchPlugin.log(\r
839                     IDEWorkbenchMessages.ProblemsSavingWorkspace, status);\r
840         }\r
841     }\r
842 \r
843     /*\r
844      * (non-Javadoc)\r
845      *\r
846      * @see org.eclipse.ui.application.WorkbenchAdvisor#getDefaultPageInput\r
847      */\r
848     @Override\r
849     public IAdaptable getDefaultPageInput() {\r
850         return ResourcesPlugin.getWorkspace().getRoot();\r
851     }\r
852 \r
853     /*\r
854      * (non-Javadoc)\r
855      *\r
856      * @see org.eclipse.ui.application.WorkbenchAdvisor\r
857      */\r
858     @Override\r
859     public String getInitialWindowPerspectiveId() {\r
860         int index = PlatformUI.getWorkbench().getWorkbenchWindowCount() - 1;\r
861 \r
862         String perspectiveId = null;\r
863         AboutInfo[] welcomeInfos = getWelcomePerspectiveInfos();\r
864         if (index >= 0 && welcomeInfos != null && index < welcomeInfos.length) {\r
865             perspectiveId = welcomeInfos[index].getWelcomePerspectiveId();\r
866         }\r
867 \r
868         if (perspectiveId == null && args.contains(SimanticsArguments.PERSPECTIVE)) {\r
869             String id = args.get(SimanticsArguments.PERSPECTIVE);\r
870             IPerspectiveDescriptor perspective = PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(id);\r
871             if (perspective != null)\r
872                 perspectiveId = id;\r
873         }\r
874 \r
875         if (perspectiveId == null) {\r
876             IProject project = SimanticsUI.peekProject();\r
877             if (project != null)\r
878                 perspectiveId = project.getHint(ProjectKeys.DEFAULT_PERSPECTIVE);\r
879         }\r
880 \r
881         //System.out.println("Initial perspective: " + perspectiveId);\r
882 \r
883         return perspectiveId;\r
884     }\r
885 \r
886     /**\r
887      * Returns the map of versioned feature ids -> info object for all installed\r
888      * features. The format of the versioned feature id (the key of the map) is\r
889      * featureId + ":" + versionId.\r
890      *\r
891      * @return map of versioned feature ids -> info object (key type:\r
892      *         <code>String</code>, value type: <code>AboutInfo</code>)\r
893      * @since 3.0\r
894      */\r
895     private Map<String, AboutInfo> computeBundleGroupMap() {\r
896         // use tree map to get predicable order\r
897         Map<String, AboutInfo> ids = new TreeMap<String, AboutInfo>();\r
898 \r
899         IBundleGroupProvider[] providers = Platform.getBundleGroupProviders();\r
900         for (int i = 0; i < providers.length; ++i) {\r
901             IBundleGroup[] groups = providers[i].getBundleGroups();\r
902             for (int j = 0; j < groups.length; ++j) {\r
903                 IBundleGroup group = groups[j];\r
904                 AboutInfo info = new AboutInfo(group);\r
905 \r
906                 String version = info.getVersionId();\r
907                 version = version == null ? "0.0.0" //$NON-NLS-1$\r
908                         : new Version(version).toString();\r
909                 String versionedFeature = group.getIdentifier() + ":" + version; //$NON-NLS-1$\r
910 \r
911                 ids.put(versionedFeature, info);\r
912             }\r
913         }\r
914 \r
915         return ids;\r
916     }\r
917 \r
918     /**\r
919      * Returns the ordered map of versioned feature ids -> AboutInfo that are\r
920      * new for this session.\r
921      *\r
922      * @return ordered map of versioned feature ids (key type:\r
923      *         <code>String</code>) -> infos (value type:\r
924      *         <code>AboutInfo</code>).\r
925      */\r
926     public Map<String, AboutInfo> getNewlyAddedBundleGroups() {\r
927         if (newlyAddedBundleGroups == null) {\r
928             newlyAddedBundleGroups = createNewBundleGroupsMap();\r
929         }\r
930         return newlyAddedBundleGroups;\r
931     }\r
932 \r
933     /**\r
934      * Updates the old features setting and returns a map of new features.\r
935      */\r
936     private Map<String, AboutInfo> createNewBundleGroupsMap() {\r
937         // retrieve list of installed bundle groups from last session\r
938         IDialogSettings settings = IDEWorkbenchPlugin.getDefault()\r
939                 .getDialogSettings();\r
940         String[] previousFeaturesArray = settings.getArray(INSTALLED_FEATURES);\r
941 \r
942         // get a map of currently installed bundle groups and store it for next\r
943         // session\r
944         Map<String, AboutInfo> bundleGroups = computeBundleGroupMap();\r
945         String[] currentFeaturesArray = new String[bundleGroups.size()];\r
946         bundleGroups.keySet().toArray(currentFeaturesArray);\r
947         settings.put(INSTALLED_FEATURES, currentFeaturesArray);\r
948 \r
949         // remove the previously known from the current set\r
950         if (previousFeaturesArray != null) {\r
951             for (int i = 0; i < previousFeaturesArray.length; ++i) {\r
952                 bundleGroups.remove(previousFeaturesArray[i]);\r
953             }\r
954         }\r
955 \r
956         return bundleGroups;\r
957     }\r
958 \r
959     /**\r
960      * Declares all IDE-specific workbench images. This includes both "shared"\r
961      * images (named in {@link IDE.SharedImages}) and internal images (named in\r
962      * {@link org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages}).\r
963      *\r
964      * @see IWorkbenchConfigurer#declareImage\r
965      */\r
966     private void declareWorkbenchImages() {\r
967 \r
968         final String ICONS_PATH = "$nl$/icons/full/";//$NON-NLS-1$\r
969         final String PATH_ELOCALTOOL = ICONS_PATH + "elcl16/"; // Enabled //$NON-NLS-1$\r
970 \r
971         // toolbar\r
972         // icons.\r
973         final String PATH_DLOCALTOOL = ICONS_PATH + "dlcl16/"; // Disabled //$NON-NLS-1$\r
974         // //$NON-NLS-1$\r
975         // toolbar\r
976         // icons.\r
977         final String PATH_ETOOL = ICONS_PATH + "etool16/"; // Enabled toolbar //$NON-NLS-1$\r
978         // //$NON-NLS-1$\r
979         // icons.\r
980         final String PATH_DTOOL = ICONS_PATH + "dtool16/"; // Disabled toolbar //$NON-NLS-1$\r
981         // //$NON-NLS-1$\r
982         // icons.\r
983         final String PATH_OBJECT = ICONS_PATH + "obj16/"; // Model object //$NON-NLS-1$\r
984         // //$NON-NLS-1$\r
985         // icons\r
986         final String PATH_WIZBAN = ICONS_PATH + "wizban/"; // Wizard //$NON-NLS-1$\r
987         // //$NON-NLS-1$\r
988         // icons\r
989 \r
990         Bundle ideBundle = Platform.getBundle(IDEWorkbenchPlugin.IDE_WORKBENCH);\r
991 \r
992         declareWorkbenchImage(ideBundle,\r
993                 IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC, PATH_ETOOL\r
994                 + "build_exec.gif", false); //$NON-NLS-1$\r
995         declareWorkbenchImage(ideBundle,\r
996                 IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC_HOVER,\r
997                 PATH_ETOOL + "build_exec.gif", false); //$NON-NLS-1$\r
998         declareWorkbenchImage(ideBundle,\r
999                 IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC_DISABLED,\r
1000                 PATH_DTOOL + "build_exec.gif", false); //$NON-NLS-1$\r
1001 \r
1002         declareWorkbenchImage(ideBundle,\r
1003                 IDEInternalWorkbenchImages.IMG_ETOOL_SEARCH_SRC, PATH_ETOOL\r
1004                 + "search_src.gif", false); //$NON-NLS-1$\r
1005         declareWorkbenchImage(ideBundle,\r
1006                 IDEInternalWorkbenchImages.IMG_ETOOL_SEARCH_SRC_HOVER,\r
1007                 PATH_ETOOL + "search_src.gif", false); //$NON-NLS-1$\r
1008         declareWorkbenchImage(ideBundle,\r
1009                 IDEInternalWorkbenchImages.IMG_ETOOL_SEARCH_SRC_DISABLED,\r
1010                 PATH_DTOOL + "search_src.gif", false); //$NON-NLS-1$\r
1011 \r
1012         declareWorkbenchImage(ideBundle,\r
1013                 IDEInternalWorkbenchImages.IMG_ETOOL_NEXT_NAV, PATH_ETOOL\r
1014                 + "next_nav.gif", false); //$NON-NLS-1$\r
1015 \r
1016         declareWorkbenchImage(ideBundle,\r
1017                 IDEInternalWorkbenchImages.IMG_ETOOL_PREVIOUS_NAV, PATH_ETOOL\r
1018                 + "prev_nav.gif", false); //$NON-NLS-1$\r
1019 \r
1020         declareWorkbenchImage(ideBundle,\r
1021                 IDEInternalWorkbenchImages.IMG_WIZBAN_NEWPRJ_WIZ, PATH_WIZBAN\r
1022                 + "newprj_wiz.png", false); //$NON-NLS-1$\r
1023         declareWorkbenchImage(ideBundle,\r
1024                 IDEInternalWorkbenchImages.IMG_WIZBAN_NEWFOLDER_WIZ,\r
1025                 PATH_WIZBAN + "newfolder_wiz.png", false); //$NON-NLS-1$\r
1026         declareWorkbenchImage(ideBundle,\r
1027                 IDEInternalWorkbenchImages.IMG_WIZBAN_NEWFILE_WIZ, PATH_WIZBAN\r
1028                 + "newfile_wiz.png", false); //$NON-NLS-1$\r
1029 \r
1030         declareWorkbenchImage(ideBundle,\r
1031                 IDEInternalWorkbenchImages.IMG_WIZBAN_IMPORTDIR_WIZ,\r
1032                 PATH_WIZBAN + "importdir_wiz.png", false); //$NON-NLS-1$\r
1033         declareWorkbenchImage(ideBundle,\r
1034                 IDEInternalWorkbenchImages.IMG_WIZBAN_IMPORTZIP_WIZ,\r
1035                 PATH_WIZBAN + "importzip_wiz.png", false); //$NON-NLS-1$\r
1036 \r
1037         declareWorkbenchImage(ideBundle,\r
1038                 IDEInternalWorkbenchImages.IMG_WIZBAN_EXPORTDIR_WIZ,\r
1039                 PATH_WIZBAN + "exportdir_wiz.png", false); //$NON-NLS-1$\r
1040         declareWorkbenchImage(ideBundle,\r
1041                 IDEInternalWorkbenchImages.IMG_WIZBAN_EXPORTZIP_WIZ,\r
1042                 PATH_WIZBAN + "exportzip_wiz.png", false); //$NON-NLS-1$\r
1043 \r
1044         declareWorkbenchImage(ideBundle,\r
1045                 IDEInternalWorkbenchImages.IMG_WIZBAN_RESOURCEWORKINGSET_WIZ,\r
1046                 PATH_WIZBAN + "workset_wiz.png", false); //$NON-NLS-1$\r
1047 \r
1048         declareWorkbenchImage(ideBundle,\r
1049                 IDEInternalWorkbenchImages.IMG_DLGBAN_SAVEAS_DLG, PATH_WIZBAN\r
1050                 + "saveas_wiz.png", false); //$NON-NLS-1$\r
1051 \r
1052         declareWorkbenchImage(ideBundle,\r
1053                 IDEInternalWorkbenchImages.IMG_DLGBAN_QUICKFIX_DLG, PATH_WIZBAN\r
1054                 + "quick_fix.png", false); //$NON-NLS-1$\r
1055 \r
1056         declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OBJ_PROJECT,\r
1057                 PATH_OBJECT + "prj_obj.gif", true); //$NON-NLS-1$\r
1058         declareWorkbenchImage(ideBundle,\r
1059                 IDE.SharedImages.IMG_OBJ_PROJECT_CLOSED, PATH_OBJECT\r
1060                 + "cprj_obj.gif", true); //$NON-NLS-1$\r
1061         declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OPEN_MARKER,\r
1062                 PATH_ELOCALTOOL + "gotoobj_tsk.gif", true); //$NON-NLS-1$\r
1063 \r
1064         declareWorkbenchImage(ideBundle,\r
1065                 IDEInternalWorkbenchImages.IMG_ELCL_QUICK_FIX_ENABLED,\r
1066                 PATH_ELOCALTOOL + "smartmode_co.gif", true); //$NON-NLS-1$\r
1067 \r
1068         declareWorkbenchImage(ideBundle,\r
1069                 IDEInternalWorkbenchImages.IMG_DLCL_QUICK_FIX_DISABLED,\r
1070                 PATH_DLOCALTOOL + "smartmode_co.gif", true); //$NON-NLS-1$\r
1071 \r
1072         // task objects\r
1073         // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_HPRIO_TSK,\r
1074         // PATH_OBJECT+"hprio_tsk.gif");\r
1075         // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_MPRIO_TSK,\r
1076         // PATH_OBJECT+"mprio_tsk.gif");\r
1077         // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_LPRIO_TSK,\r
1078         // PATH_OBJECT+"lprio_tsk.gif");\r
1079 \r
1080         declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OBJS_TASK_TSK,\r
1081                 PATH_OBJECT + "taskmrk_tsk.gif", true); //$NON-NLS-1$\r
1082         declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OBJS_BKMRK_TSK,\r
1083                 PATH_OBJECT + "bkmrk_tsk.gif", true); //$NON-NLS-1$\r
1084 \r
1085         declareWorkbenchImage(ideBundle,\r
1086                 IDEInternalWorkbenchImages.IMG_OBJS_COMPLETE_TSK, PATH_OBJECT\r
1087                 + "complete_tsk.gif", true); //$NON-NLS-1$\r
1088         declareWorkbenchImage(ideBundle,\r
1089                 IDEInternalWorkbenchImages.IMG_OBJS_INCOMPLETE_TSK, PATH_OBJECT\r
1090                 + "incomplete_tsk.gif", true); //$NON-NLS-1$\r
1091         declareWorkbenchImage(ideBundle,\r
1092                 IDEInternalWorkbenchImages.IMG_OBJS_WELCOME_ITEM, PATH_OBJECT\r
1093                 + "welcome_item.gif", true); //$NON-NLS-1$\r
1094         declareWorkbenchImage(ideBundle,\r
1095                 IDEInternalWorkbenchImages.IMG_OBJS_WELCOME_BANNER, PATH_OBJECT\r
1096                 + "welcome_banner.gif", true); //$NON-NLS-1$\r
1097         declareWorkbenchImage(ideBundle,\r
1098                 IDEInternalWorkbenchImages.IMG_OBJS_ERROR_PATH, PATH_OBJECT\r
1099                 + "error_tsk.gif", true); //$NON-NLS-1$\r
1100         declareWorkbenchImage(ideBundle,\r
1101                 IDEInternalWorkbenchImages.IMG_OBJS_WARNING_PATH, PATH_OBJECT\r
1102                 + "warn_tsk.gif", true); //$NON-NLS-1$\r
1103         declareWorkbenchImage(ideBundle,\r
1104                 IDEInternalWorkbenchImages.IMG_OBJS_INFO_PATH, PATH_OBJECT\r
1105                 + "info_tsk.gif", true); //$NON-NLS-1$\r
1106 \r
1107         declareWorkbenchImage(ideBundle,\r
1108                 IDEInternalWorkbenchImages.IMG_LCL_FLAT_LAYOUT, PATH_ELOCALTOOL\r
1109                 + "flatLayout.gif", true); //$NON-NLS-1$\r
1110         declareWorkbenchImage(ideBundle,\r
1111                 IDEInternalWorkbenchImages.IMG_LCL_HIERARCHICAL_LAYOUT,\r
1112                 PATH_ELOCALTOOL + "hierarchicalLayout.gif", true); //$NON-NLS-1$\r
1113         declareWorkbenchImage(ideBundle,\r
1114                 IDEInternalWorkbenchImages.IMG_ETOOL_PROBLEM_CATEGORY,\r
1115                 PATH_ETOOL + "problem_category.gif", true); //$NON-NLS-1$\r
1116         /*\r
1117         declareWorkbenchImage(ideBundle,\r
1118                 IDEInternalWorkbenchImages.IMG_LCL_LINKTO_HELP, PATH_ELOCALTOOL\r
1119                         + "linkto_help.gif", false); //$NON-NLS-1$\r
1120          */\r
1121 \r
1122         // synchronization indicator objects\r
1123         // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_WBET_STAT,\r
1124         // PATH_OVERLAY+"wbet_stat.gif");\r
1125         // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_SBET_STAT,\r
1126         // PATH_OVERLAY+"sbet_stat.gif");\r
1127         // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_CONFLICT_STAT,\r
1128         // PATH_OVERLAY+"conflict_stat.gif");\r
1129 \r
1130         // content locality indicator objects\r
1131         // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_NOTLOCAL_STAT,\r
1132         // PATH_STAT+"notlocal_stat.gif");\r
1133         // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_LOCAL_STAT,\r
1134         // PATH_STAT+"local_stat.gif");\r
1135         // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_FILLLOCAL_STAT,\r
1136         // PATH_STAT+"filllocal_stat.gif");\r
1137     }\r
1138 \r
1139     /**\r
1140      * Declares an IDE-specific workbench image.\r
1141      *\r
1142      * @param symbolicName\r
1143      *            the symbolic name of the image\r
1144      * @param path\r
1145      *            the path of the image file; this path is relative to the base\r
1146      *            of the IDE plug-in\r
1147      * @param shared\r
1148      *            <code>true</code> if this is a shared image, and\r
1149      *            <code>false</code> if this is not a shared image\r
1150      * @see IWorkbenchConfigurer#declareImage\r
1151      */\r
1152     private void declareWorkbenchImage(Bundle ideBundle, String symbolicName,\r
1153             String path, boolean shared) {\r
1154         URL url = FileLocator.find(ideBundle, new Path(path), null);\r
1155         ImageDescriptor desc = ImageDescriptor.createFromURL(url);\r
1156         getWorkbenchConfigurer().declareImage(symbolicName, desc, shared);\r
1157     }\r
1158 \r
1159     /*\r
1160      * (non-Javadoc)\r
1161      *\r
1162      * @see org.eclipse.ui.application.WorkbenchAdvisor#getMainPreferencePageId\r
1163      */\r
1164     @Override\r
1165     public String getMainPreferencePageId() {\r
1166         // indicate that we want the Workench preference page to be prominent\r
1167         return WORKBENCH_PREFERENCE_CATEGORY_ID;\r
1168     }\r
1169 \r
1170     /**\r
1171      * @return the workspace location string, or <code>null</code> if the\r
1172      *         location is not being shown\r
1173      */\r
1174     public String getWorkspaceLocation() {\r
1175                 // read command line, which has priority\r
1176                 IEclipseContext context = getWorkbenchConfigurer().getWorkbench().getService(IEclipseContext.class);\r
1177                 String location = context != null ? (String) context.get(E4Workbench.FORCED_SHOW_LOCATION) : null;\r
1178                 if (location != null) {\r
1179                         return location;\r
1180                 }\r
1181                 // read the preference\r
1182                 if (IDEWorkbenchPlugin.getDefault().getPreferenceStore().getBoolean(IDEInternalPreferences.SHOW_LOCATION)) {\r
1183                         return Platform.getLocation().toOSString();\r
1184                 }\r
1185                 return null;\r
1186     }\r
1187 \r
1188     /**\r
1189      * @return the welcome perspective infos, or <code>null</code> if none or\r
1190      *         if they should be ignored due to the new intro being present\r
1191      */\r
1192     public AboutInfo[] getWelcomePerspectiveInfos() {\r
1193         if (welcomePerspectiveInfos == null) {\r
1194             // support old welcome perspectives if intro plugin is not present\r
1195             if (!hasIntro()) {\r
1196                 Map<String, AboutInfo> m = getNewlyAddedBundleGroups();\r
1197                 ArrayList<AboutInfo> list = new ArrayList<AboutInfo>(m.size());\r
1198                 for (Iterator<AboutInfo> i = m.values().iterator(); i.hasNext();) {\r
1199                     AboutInfo info = i.next();\r
1200                     if (info != null && info.getWelcomePerspectiveId() != null\r
1201                             && info.getWelcomePageURL() != null) {\r
1202                         list.add(info);\r
1203                     }\r
1204                 }\r
1205                 welcomePerspectiveInfos = new AboutInfo[list.size()];\r
1206                 list.toArray(welcomePerspectiveInfos);\r
1207             }\r
1208         }\r
1209         return welcomePerspectiveInfos;\r
1210     }\r
1211 \r
1212     /*\r
1213      * (non-Javadoc)\r
1214      *\r
1215      * @see org.eclipse.ui.application.WorkbenchAdvisor#getWorkbenchErrorHandler()\r
1216      */\r
1217     @Override\r
1218     public AbstractStatusHandler getWorkbenchErrorHandler() {\r
1219         if (ideWorkbenchErrorHandler == null) {\r
1220             ideWorkbenchErrorHandler = new IDEWorkbenchErrorHandler(\r
1221                     getWorkbenchConfigurer());\r
1222         }\r
1223         return ideWorkbenchErrorHandler;\r
1224     }\r
1225 \r
1226     /* (non-Javadoc)\r
1227      * @see org.eclipse.ui.application.WorkbenchAdvisor#eventLoopIdle(org.eclipse.swt.widgets.Display)\r
1228      */\r
1229     @Override\r
1230     public void eventLoopIdle(Display display) {\r
1231         if (delayedEventsProcessor != null)\r
1232             delayedEventsProcessor.catchUp(display);\r
1233         super.eventLoopIdle(display);\r
1234     }\r
1235 \r
1236 }\r