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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.workbench.internal;
\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
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
116 * @author Tuukka Lehtonen
\r
118 public class SimanticsWorkbenchAdvisor extends WorkbenchAdvisor {
\r
120 private static final boolean PROFILE_PLATFORM_STARTUP = false;
\r
122 private static final String SHUT_DOWN_TASK = "Shutting down...";
\r
124 private static final String SHUT_DOWN_PLATFORM_TASK = "Shutting down platform...";
\r
126 private static final String WORKBENCH_PREFERENCE_CATEGORY_ID = "org.eclipse.ui.preferencePages.Workbench"; //$NON-NLS-1$
\r
129 * The dialog setting key to access the known installed features since the
\r
130 * last time the workbench was run.
\r
132 private static final String INSTALLED_FEATURES = "installedFeatures"; //$NON-NLS-1$
\r
135 * Default database ID
\r
137 private static final String DEFAULT_DATABASE_ID = "procore";
\r
140 * The arguments received by the application.
\r
142 protected final IArguments args;
\r
144 protected final boolean restoredPreviousSession = false;
\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
151 protected boolean workbenchWindowsInitialized = false;
\r
154 * Whether or not to save unsaved database changes before exiting the
\r
157 protected boolean saveAtExit = false;
\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
164 private Map<String, AboutInfo> newlyAddedBundleGroups;
\r
167 * Array of <code>AboutInfo</code> for all new installed features that
\r
168 * specify a welcome perspective.
\r
170 private AboutInfo[] welcomePerspectiveInfos = null;
\r
173 * Helper for managing activites in response to workspace changes.
\r
175 private IDEWorkbenchActivityHelper activityHelper = null;
\r
178 * Helper for managing work that is performed when the system is otherwise
\r
181 private IDEIdleHelper idleHelper;
\r
183 private Listener settingsChangeListener;
\r
186 * Support class for monitoring workspace changes and periodically
\r
187 * validating the undo history
\r
189 private WorkspaceUndoMonitor workspaceUndoMonitor;
\r
192 * The IDE workbench error handler.
\r
194 private AbstractStatusHandler ideWorkbenchErrorHandler;
\r
197 * Helper class used to process delayed events.
\r
199 private DelayedEventsProcessor delayedEventsProcessor;
\r
202 * Creates a new workbench advisor instance.
\r
205 public SimanticsWorkbenchAdvisor(IArguments args, DelayedEventsProcessor processor) {
\r
208 this.delayedEventsProcessor = processor;
\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
215 event.type = SWT.None;
\r
218 Display.getDefault().addListener(SWT.Close, closeListener);
\r
221 public IArguments getArguments() {
\r
225 public boolean workbenchInitialized() {
\r
226 return workbenchWindowsInitialized;
\r
229 public boolean restoredPreviousSession() {
\r
230 return restoredPreviousSession;
\r
233 boolean saveAtExit() {
\r
237 void setSaveAtExit(boolean saveAtExit) {
\r
238 this.saveAtExit = saveAtExit;
\r
244 * @see org.eclipse.ui.application.WorkbenchAdvisor#initialize
\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
251 checkWorkspaceDatabaseIndexes();
\r
253 // Start tracking the active perspective to activate contexts based on it.
\r
254 new PerspectiveContextActivator();
\r
255 new PerspectiveBarsActivator();
\r
257 // register workspace adapters
\r
258 IDE.registerAdapters();
\r
260 // register shared images
\r
261 declareWorkbenchImages();
\r
263 // initialize the activity helper
\r
264 activityHelper = IDEWorkbenchActivityHelper.getInstance();
\r
266 // initialize idle handler
\r
267 idleHelper = new IDEIdleHelper(configurer);
\r
269 // initialize the workspace undo monitor
\r
270 workspaceUndoMonitor = WorkspaceUndoMonitor.getInstance();
\r
272 // show Help button in JFace dialogs
\r
273 TrayDialog.setDialogHelpAvailable(true);
\r
275 Policy.setComparator(Collator.getInstance());
\r
278 private void checkWorkspaceDatabaseIndexes() {
\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
286 public WorkbenchWindowAdvisor createWorkbenchWindowAdvisorClass(SimanticsWorkbenchAdvisor advisor, IWorkbenchWindowConfigurer configurer) {
\r
287 return new SimanticsWorkbenchWindowAdvisor(this, configurer);
\r
291 public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
\r
292 // Attach database session watchdog.
\r
293 new SessionWatchdog().attach( Simantics.getSessionContextProvider() );
\r
295 return createWorkbenchWindowAdvisorClass(this, configurer);
\r
299 * For gaining direct access to super.openWindows() in implementations
\r
300 * inheriting this one.
\r
302 public boolean openWindowsSuper() {
\r
303 return super.openWindows();
\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
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
318 * @see platform issue #6353
\r
320 private void fixBindings() {
\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
330 public boolean openWindows() {
\r
331 boolean platformOk = startPlatform();
\r
332 TimeLogger.log("SimanticsWorkbenchAdvisor.startPlatform finished");
\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
343 // Start the database garbage collector after a short while.
\r
344 SessionGarbageCollectorJob.getInstance().scheduleAfterQuietTime();
\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
352 // #6353: Workaround for
\r
359 // Make sure platform shutdown is ran if window opening fails.
\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
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
383 ShowMessage.syncShowError("Invalid Perspective", msg.toString());
\r
388 ILog log = Platform.getLog(Activator.getDefault().getBundle());
\r
393 // Create Simantics Platform Helper.
\r
395 // If Simantics is started from Eclipse IDE or with -fixerrors option,
\r
396 // there is an attempt to fix errors.
\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
404 RecoveryPolicy workspacePolicy = Platform.inDevelopmentMode() ? RecoveryPolicy.FixError : RecoveryPolicy.ThrowError;
\r
405 OntologyRecoveryPolicy ontologyPolicy = Platform.inDevelopmentMode() ? OntologyRecoveryPolicy.Merge : OntologyRecoveryPolicy.ThrowError;
\r
407 if (args.contains(SimanticsArguments.RECOVERY_POLICY_FIX_ERRORS)) {
\r
408 workspacePolicy = RecoveryPolicy.FixError;
\r
409 ontologyPolicy = OntologyRecoveryPolicy.Merge;
\r
412 boolean requireSynchronize = true;
\r
414 if (args.contains(SimanticsArguments.ONTOLOGY_RECOVERY_POLICY_REINSTALL)) {
\r
415 ontologyPolicy = OntologyRecoveryPolicy.ReinstallDatabase;
\r
418 if (args.contains(SimanticsArguments.DO_NOT_SYNCHRONIZE_ONTOLOGIES)) {
\r
419 requireSynchronize = false;
\r
422 if (args.contains(SimanticsArguments.DISABLE_INDEX)) {
\r
423 Indexing.setDefaultDependenciesIndexingEnabled(false);
\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
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
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
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
453 } catch (CancelStartupException e) {
\r
455 } catch (PlatformException e) {
\r
456 boolean hasStackTrace = e.getStackTrace().length > 0;
\r
458 while (ee.getCause() != null) {
\r
459 ee = ee.getCause();
\r
460 hasStackTrace = ee.getStackTrace().length > 0;
\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
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
475 } catch (Exception e) {
\r
476 log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
\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
488 new ShowError("Platform Startup Failed", "Simantics Platform startup failed:\n\n" + e.getMessage(), e, true);
\r
498 * @see org.eclipse.ui.application.WorkbenchAdvisor#preStartup()
\r
501 public void preStartup() {
\r
503 // Suspend background jobs while we startup
\r
504 Job.getJobManager().suspend();
\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
520 * @see org.eclipse.ui.application.WorkbenchAdvisor#postStartup()
\r
523 public void postStartup() {
\r
525 refreshFromLocal();
\r
526 activateProxyService();
\r
527 ((Workbench) PlatformUI.getWorkbench()).registerService(
\r
528 ISelectionConversionService.class,
\r
529 new IDESelectionConversionService());
\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
540 * Activate the proxy service by obtaining it.
\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
548 proxyService = bundle.getBundleContext().getService(ref);
\r
550 if (proxyService == null) {
\r
551 IDEWorkbenchPlugin.log("Proxy service could not be found."); //$NON-NLS-1$
\r
556 * Initialize the listener for settings changes.
\r
558 private void initializeSettingsChangeListener() {
\r
559 settingsChangeListener = new Listener() {
\r
561 boolean currentHighContrast = Display.getCurrent()
\r
562 .getHighContrast();
\r
565 public void handleEvent(org.eclipse.swt.widgets.Event event) {
\r
566 if (Display.getCurrent().getHighContrast() == currentHighContrast)
\r
569 currentHighContrast = !currentHighContrast;
\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
589 * @see org.eclipse.ui.application.WorkbenchAdvisor#postShutdown
\r
592 public void postShutdown() {
\r
593 if (activityHelper != null) {
\r
594 activityHelper.shutdown();
\r
595 activityHelper = null;
\r
597 if (idleHelper != null) {
\r
598 idleHelper.shutdown();
\r
601 if (workspaceUndoMonitor != null) {
\r
602 workspaceUndoMonitor.shutdown();
\r
603 workspaceUndoMonitor = null;
\r
605 if (IDEWorkbenchPlugin.getPluginWorkspace() != null) {
\r
606 disconnectFromWorkspace();
\r
613 * @see org.eclipse.ui.application.WorkbenchAdvisor#preShutdown()
\r
616 public boolean preShutdown() {
\r
617 Display.getCurrent().removeListener(SWT.Settings,
\r
618 settingsChangeListener);
\r
619 return super.preShutdown();
\r
623 * Return true if the intro plugin is present and false otherwise.
\r
627 public boolean hasIntro() {
\r
628 return getWorkbenchConfigurer().getWorkbench().getIntroManager()
\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
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
649 final IContainer root = ResourcesPlugin.getWorkspace().getRoot();
\r
650 Job job = new WorkspaceJob(IDEWorkbenchMessages.Workspace_refreshing) {
\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
662 private static class CancelableProgressMonitorWrapper extends ProgressMonitorWrapper {
\r
663 private double total = 0;
\r
664 private ProgressMonitorJobsDialog dialog;
\r
666 CancelableProgressMonitorWrapper(IProgressMonitor monitor,
\r
667 ProgressMonitorJobsDialog dialog) {
\r
669 this.dialog = dialog;
\r
674 * @see org.eclipse.core.runtime.ProgressMonitorWrapper#internalWorked(double)
\r
676 public void internalWorked(double work) {
\r
677 super.internalWorked(work);
\r
679 updateProgressDetails();
\r
684 * @see org.eclipse.core.runtime.ProgressMonitorWrapper#worked(int)
\r
686 public void worked(int work) {
\r
687 super.worked(work);
\r
689 updateProgressDetails();
\r
692 public void beginTask(String name, int totalWork) {
\r
693 super.beginTask(name, totalWork);
\r
694 subTask(IDEWorkbenchMessages.IDEWorkbenchAdvisor_preHistoryCompaction);
\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
702 if (Math.abs(total - 5.0) < 0.0001 /* history compacting finished */) {
\r
703 subTask(IDEWorkbenchMessages.IDEWorkbenchAdvisor_postHistoryCompaction);
\r
704 dialog.setCancelable(false);
\r
709 private static class CancelableProgressMonitorJobsDialog extends ProgressMonitorJobsDialog {
\r
711 public CancelableProgressMonitorJobsDialog(Shell parent) {
\r
717 * @see org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog#createDetailsButton(org.eclipse.swt.widgets.Composite)
\r
719 protected void createButtonsForButtonBar(Composite parent) {
\r
720 super.createButtonsForButtonBar(parent);
\r
721 registerCancelButtonListener();
\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
734 final IRunnableWithProgress platformShutdownRunnable = new IRunnableWithProgress() {
\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
742 public void run(IProgressMonitor monitor) {
\r
743 SubMonitor progress = SubMonitor.convert(monitor, SHUT_DOWN_PLATFORM_TASK, 100);
\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
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
758 progress.subTask("Thread pools");
\r
759 ThreadUtils.shutdown();
\r
760 progress.worked(5);
\r
762 progress.subTask("Clear index status");
\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
769 progress.worked(5);
\r
771 progress.setWorkRemaining(0);
\r
773 if (monitor != null) {
\r
781 * Disconnect from the workspace and close ProCore sessions.
\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
789 final ProgressMonitorJobsDialog p = new CancelableProgressMonitorJobsDialog(
\r
792 final boolean applyPolicy = ResourcesPlugin.getWorkspace()
\r
793 .getDescription().isApplyFileStatePolicy();
\r
795 final IRunnableWithProgress workspaceShutdownRunnable = new IRunnableWithProgress() {
\r
797 public void run(IProgressMonitor monitor) {
\r
799 status.merge(((Workspace) ResourcesPlugin.getWorkspace()).save(true, true, monitor));
\r
800 } catch (CoreException e) {
\r
801 status.merge(e.getStatus());
\r
806 IRunnableWithProgress shutdownRunnable = new IRunnableWithProgress() {
\r
808 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
\r
810 monitor = new CancelableProgressMonitorWrapper(
\r
813 SubMonitor progress = SubMonitor.convert(monitor, SHUT_DOWN_TASK, 2);
\r
815 workspaceShutdownRunnable.run(progress.newChild(1, SubMonitor.SUPPRESS_NONE));
\r
816 platformShutdownRunnable.run(progress.newChild(1, SubMonitor.SUPPRESS_NONE));
\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
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
846 * @see org.eclipse.ui.application.WorkbenchAdvisor#getDefaultPageInput
\r
849 public IAdaptable getDefaultPageInput() {
\r
850 return ResourcesPlugin.getWorkspace().getRoot();
\r
856 * @see org.eclipse.ui.application.WorkbenchAdvisor
\r
859 public String getInitialWindowPerspectiveId() {
\r
860 int index = PlatformUI.getWorkbench().getWorkbenchWindowCount() - 1;
\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
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
875 if (perspectiveId == null) {
\r
876 IProject project = SimanticsUI.peekProject();
\r
877 if (project != null)
\r
878 perspectiveId = project.getHint(ProjectKeys.DEFAULT_PERSPECTIVE);
\r
881 //System.out.println("Initial perspective: " + perspectiveId);
\r
883 return perspectiveId;
\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
891 * @return map of versioned feature ids -> info object (key type:
\r
892 * <code>String</code>, value type: <code>AboutInfo</code>)
\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
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
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
911 ids.put(versionedFeature, info);
\r
919 * Returns the ordered map of versioned feature ids -> AboutInfo that are
\r
920 * new for this session.
\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
926 public Map<String, AboutInfo> getNewlyAddedBundleGroups() {
\r
927 if (newlyAddedBundleGroups == null) {
\r
928 newlyAddedBundleGroups = createNewBundleGroupsMap();
\r
930 return newlyAddedBundleGroups;
\r
934 * Updates the old features setting and returns a map of new features.
\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
942 // get a map of currently installed bundle groups and store it for next
\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
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
956 return bundleGroups;
\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
964 * @see IWorkbenchConfigurer#declareImage
\r
966 private void declareWorkbenchImages() {
\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
973 final String PATH_DLOCALTOOL = ICONS_PATH + "dlcl16/"; // Disabled //$NON-NLS-1$
\r
977 final String PATH_ETOOL = ICONS_PATH + "etool16/"; // Enabled toolbar //$NON-NLS-1$
\r
980 final String PATH_DTOOL = ICONS_PATH + "dtool16/"; // Disabled toolbar //$NON-NLS-1$
\r
983 final String PATH_OBJECT = ICONS_PATH + "obj16/"; // Model object //$NON-NLS-1$
\r
986 final String PATH_WIZBAN = ICONS_PATH + "wizban/"; // Wizard //$NON-NLS-1$
\r
990 Bundle ideBundle = Platform.getBundle(IDEWorkbenchPlugin.IDE_WORKBENCH);
\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
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
1012 declareWorkbenchImage(ideBundle,
\r
1013 IDEInternalWorkbenchImages.IMG_ETOOL_NEXT_NAV, PATH_ETOOL
\r
1014 + "next_nav.gif", false); //$NON-NLS-1$
\r
1016 declareWorkbenchImage(ideBundle,
\r
1017 IDEInternalWorkbenchImages.IMG_ETOOL_PREVIOUS_NAV, PATH_ETOOL
\r
1018 + "prev_nav.gif", false); //$NON-NLS-1$
\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
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
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
1044 declareWorkbenchImage(ideBundle,
\r
1045 IDEInternalWorkbenchImages.IMG_WIZBAN_RESOURCEWORKINGSET_WIZ,
\r
1046 PATH_WIZBAN + "workset_wiz.png", false); //$NON-NLS-1$
\r
1048 declareWorkbenchImage(ideBundle,
\r
1049 IDEInternalWorkbenchImages.IMG_DLGBAN_SAVEAS_DLG, PATH_WIZBAN
\r
1050 + "saveas_wiz.png", false); //$NON-NLS-1$
\r
1052 declareWorkbenchImage(ideBundle,
\r
1053 IDEInternalWorkbenchImages.IMG_DLGBAN_QUICKFIX_DLG, PATH_WIZBAN
\r
1054 + "quick_fix.png", false); //$NON-NLS-1$
\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
1064 declareWorkbenchImage(ideBundle,
\r
1065 IDEInternalWorkbenchImages.IMG_ELCL_QUICK_FIX_ENABLED,
\r
1066 PATH_ELOCALTOOL + "smartmode_co.gif", true); //$NON-NLS-1$
\r
1068 declareWorkbenchImage(ideBundle,
\r
1069 IDEInternalWorkbenchImages.IMG_DLCL_QUICK_FIX_DISABLED,
\r
1070 PATH_DLOCALTOOL + "smartmode_co.gif", true); //$NON-NLS-1$
\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
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
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
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
1117 declareWorkbenchImage(ideBundle,
\r
1118 IDEInternalWorkbenchImages.IMG_LCL_LINKTO_HELP, PATH_ELOCALTOOL
\r
1119 + "linkto_help.gif", false); //$NON-NLS-1$
\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
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
1140 * Declares an IDE-specific workbench image.
\r
1142 * @param symbolicName
\r
1143 * the symbolic name of the image
\r
1145 * the path of the image file; this path is relative to the base
\r
1146 * of the IDE plug-in
\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
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
1162 * @see org.eclipse.ui.application.WorkbenchAdvisor#getMainPreferencePageId
\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
1171 * @return the workspace location string, or <code>null</code> if the
\r
1172 * location is not being shown
\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
1181 // read the preference
\r
1182 if (IDEWorkbenchPlugin.getDefault().getPreferenceStore().getBoolean(IDEInternalPreferences.SHOW_LOCATION)) {
\r
1183 return Platform.getLocation().toOSString();
\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
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
1205 welcomePerspectiveInfos = new AboutInfo[list.size()];
\r
1206 list.toArray(welcomePerspectiveInfos);
\r
1209 return welcomePerspectiveInfos;
\r
1215 * @see org.eclipse.ui.application.WorkbenchAdvisor#getWorkbenchErrorHandler()
\r
1218 public AbstractStatusHandler getWorkbenchErrorHandler() {
\r
1219 if (ideWorkbenchErrorHandler == null) {
\r
1220 ideWorkbenchErrorHandler = new IDEWorkbenchErrorHandler(
\r
1221 getWorkbenchConfigurer());
\r
1223 return ideWorkbenchErrorHandler;
\r
1227 * @see org.eclipse.ui.application.WorkbenchAdvisor#eventLoopIdle(org.eclipse.swt.widgets.Display)
\r
1230 public void eventLoopIdle(Display display) {
\r
1231 if (delayedEventsProcessor != null)
\r
1232 delayedEventsProcessor.catchUp(display);
\r
1233 super.eventLoopIdle(display);
\r