]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.workbench/src/org/simantics/workbench/internal/SimanticsWorkbenchWindowAdvisor.java
Initial version of SCL tab contributions
[simantics/platform.git] / bundles / org.simantics.workbench / src / org / simantics / workbench / internal / SimanticsWorkbenchWindowAdvisor.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.net.URL;\r
15 import java.util.ArrayList;\r
16 import java.util.Iterator;\r
17 import java.util.List;\r
18 import java.util.Map;\r
19 import java.util.concurrent.atomic.AtomicBoolean;\r
20 \r
21 import org.eclipse.core.runtime.IAdaptable;\r
22 import org.eclipse.core.runtime.IProduct;\r
23 import org.eclipse.core.runtime.IStatus;\r
24 import org.eclipse.core.runtime.Platform;\r
25 import org.eclipse.core.runtime.Status;\r
26 import org.eclipse.jface.action.ToolBarManager;\r
27 import org.eclipse.jface.dialogs.ErrorDialog;\r
28 import org.eclipse.jface.dialogs.IDialogConstants;\r
29 import org.eclipse.jface.dialogs.MessageDialogWithToggle;\r
30 import org.eclipse.jface.preference.IPreferenceStore;\r
31 import org.eclipse.jface.resource.JFaceResources;\r
32 import org.eclipse.jface.util.IPropertyChangeListener;\r
33 import org.eclipse.jface.util.PropertyChangeEvent;\r
34 import org.eclipse.osgi.util.NLS;\r
35 import org.eclipse.swt.SWT;\r
36 import org.eclipse.swt.dnd.FileTransfer;\r
37 import org.eclipse.swt.graphics.Color;\r
38 import org.eclipse.swt.layout.GridLayout;\r
39 import org.eclipse.swt.widgets.Composite;\r
40 import org.eclipse.swt.widgets.Control;\r
41 import org.eclipse.swt.widgets.Display;\r
42 import org.eclipse.swt.widgets.Label;\r
43 import org.eclipse.swt.widgets.Shell;\r
44 import org.eclipse.swt.widgets.ToolBar;\r
45 import org.eclipse.ui.IEditorPart;\r
46 import org.eclipse.ui.IEditorReference;\r
47 import org.eclipse.ui.IPageListener;\r
48 import org.eclipse.ui.IPartListener2;\r
49 import org.eclipse.ui.IPerspectiveDescriptor;\r
50 import org.eclipse.ui.IPerspectiveRegistry;\r
51 import org.eclipse.ui.IPropertyListener;\r
52 import org.eclipse.ui.IWorkbench;\r
53 import org.eclipse.ui.IWorkbenchPage;\r
54 import org.eclipse.ui.IWorkbenchPartConstants;\r
55 import org.eclipse.ui.IWorkbenchPartReference;\r
56 import org.eclipse.ui.IWorkbenchWindow;\r
57 import org.eclipse.ui.PartInitException;\r
58 import org.eclipse.ui.PerspectiveAdapter;\r
59 import org.eclipse.ui.PlatformUI;\r
60 import org.eclipse.ui.WorkbenchException;\r
61 import org.eclipse.ui.actions.ActionFactory;\r
62 import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;\r
63 import org.eclipse.ui.application.ActionBarAdvisor;\r
64 import org.eclipse.ui.application.IActionBarConfigurer;\r
65 import org.eclipse.ui.application.IWorkbenchWindowConfigurer;\r
66 import org.eclipse.ui.application.WorkbenchWindowAdvisor;\r
67 import org.eclipse.ui.internal.ide.AboutInfo;\r
68 import org.eclipse.ui.internal.ide.EditorAreaDropAdapter;\r
69 import org.eclipse.ui.internal.ide.IDEInternalPreferences;\r
70 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;\r
71 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;\r
72 import org.eclipse.ui.internal.ide.dialogs.WelcomeEditorInput;\r
73 import org.eclipse.ui.part.EditorInputTransfer;\r
74 import org.eclipse.ui.part.MarkerTransfer;\r
75 import org.eclipse.ui.part.ResourceTransfer;\r
76 import org.eclipse.ui.statushandlers.StatusManager;\r
77 import org.osgi.framework.Bundle;\r
78 import org.osgi.framework.BundleContext;\r
79 import org.osgi.framework.BundleException;\r
80 import org.osgi.framework.ServiceReference;\r
81 import org.simantics.db.management.ISessionContextChangedListener;\r
82 import org.simantics.db.management.ISessionContextProvider;\r
83 import org.simantics.db.management.SessionContextChangedEvent;\r
84 import org.simantics.ui.SimanticsUI;\r
85 import org.simantics.ui.workbench.WorkbenchShutdownService;\r
86 \r
87 \r
88 /**\r
89  * System properties used to configure how this class works:\r
90  * <ul>\r
91  * <li><code>org.simantics.workbench.application.showProgressIndicator=true|false (default=true)</code> - Used to initialize IWorkbenchWindowConfigurer.setShowProgressIndicator</li>\r
92  * <li><code>org.simantics.workbench.application.showFastViewBars=true|false (default=true)</code> - Used to initialize IWorkbenchWindowConfigurer.setShowFastViewBars</li>\r
93  * <li><code>org.simantics.workbench.application.showPerspectiveBar=true|false (default=true)</code> - Used to initialize IWorkbenchWindowConfigurer.setShowPerspectiveBar</li>\r
94  * <li><code>org.simantics.workbench.application.excludePerspectiveFromTitle=true|false (default=false)</code> - Used to exclude perspective name in {@link #computeTitle()}</li>\r
95  * </ul>\r
96  * \r
97  * @author Tuukka Lehtonen\r
98  */\r
99 public class SimanticsWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {\r
100 \r
101     private static final String WELCOME_EDITOR_ID = "org.eclipse.ui.internal.ide.dialogs.WelcomeEditor"; //$NON-NLS-1$\r
102 \r
103     protected SimanticsWorkbenchAdvisor wbAdvisor;\r
104     protected boolean editorsAndIntrosOpened = false;\r
105     protected IEditorPart lastActiveEditor = null;\r
106     protected IPerspectiveDescriptor lastPerspective = null;\r
107 \r
108     protected IWorkbenchPage lastActivePage;\r
109     protected String lastEditorTitle = ""; //$NON-NLS-1$\r
110 \r
111     private final IPropertyListener editorPropertyListener = new IPropertyListener() {\r
112         @Override\r
113         public void propertyChanged(Object source, int propId) {\r
114             if (propId == IWorkbenchPartConstants.PROP_TITLE) {\r
115                 if (lastActiveEditor != null) {\r
116                     String newTitle = lastActiveEditor.getTitle();\r
117                     if (!lastEditorTitle.equals(newTitle)) {\r
118                         recomputeTitle();\r
119                     }\r
120                 }\r
121             }\r
122         }\r
123     };\r
124 \r
125     private IAdaptable lastInput;\r
126     private IWorkbenchAction openPerspectiveAction;\r
127 \r
128     /**\r
129      * The property change listener.\r
130      * @since 3.6.1\r
131      */\r
132     private IPropertyChangeListener propertyChangeListener;\r
133 \r
134     /**\r
135      * Return the style bits for the shortcut bar.\r
136      * \r
137      * @return style bitmask\r
138      */\r
139     protected int perspectiveBarStyle() {\r
140         return SWT.FLAT | SWT.WRAP | SWT.RIGHT | SWT.HORIZONTAL;\r
141     }\r
142 \r
143     /**\r
144      * Crates a new IDE workbench window advisor.\r
145      * \r
146      * @param wbAdvisor the workbench advisor\r
147      * @param configurer the window configurer\r
148      */\r
149     public SimanticsWorkbenchWindowAdvisor(SimanticsWorkbenchAdvisor wbAdvisor, IWorkbenchWindowConfigurer configurer) {\r
150         super(configurer);\r
151         this.wbAdvisor = wbAdvisor;\r
152     }\r
153 \r
154     /* (non-Javadoc)\r
155      * @see org.eclipse.ui.application.WorkbenchWindowAdvisor#createActionBarAdvisor(org.eclipse.ui.application.IActionBarConfigurer)\r
156      */\r
157     @Override\r
158     public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) {\r
159         return new SimanticsWorkbenchActionBarAdvisor(configurer);\r
160     }\r
161 \r
162     /**\r
163      * Returns the workbench.\r
164      * \r
165      * @return the workbench\r
166      */\r
167     private IWorkbench getWorkbench() {\r
168         return getWindowConfigurer().getWorkbenchConfigurer().getWorkbench();\r
169     }\r
170 \r
171     private volatile boolean allWindowShellsClosed = false;\r
172 \r
173     /*\r
174      * (non-Javadoc)\r
175      * \r
176      * @see org.eclipse.ui.application.WorkbenchAdvisor#preWindowShellClose\r
177      */\r
178     @Override\r
179     public boolean preWindowShellClose() {\r
180         if (getWorkbench().getWorkbenchWindowCount() > 1) {\r
181             return true;\r
182         }\r
183 \r
184         // WORKAROUND for a workbench problem which causes Eclipse to invoke this method twice:\r
185         // Always return false after true has been returned.\r
186         // Eclipse/SWT or something seems to have a bug of some sort that causes it to receive\r
187         // See https://www.simantics.org/redmine/issues/3848.\r
188         if (allWindowShellsClosed)\r
189             return false;\r
190 \r
191         // the user has asked to close the last window, while will cause the\r
192         // workbench to close in due course - prompt the user for confirmation\r
193         IPreferenceStore store = IDEWorkbenchPlugin.getDefault()\r
194         .getPreferenceStore();\r
195         boolean promptOnExit = store\r
196         .getBoolean(IDEInternalPreferences.EXIT_PROMPT_ON_CLOSE_LAST_WINDOW);\r
197 \r
198         if (promptOnExit) {\r
199             String message;\r
200 \r
201             String productName = null;\r
202             IProduct product = Platform.getProduct();\r
203             if (product != null) {\r
204                 productName = product.getName();\r
205             }\r
206             if (productName == null) {\r
207                 message = IDEWorkbenchMessages.PromptOnExitDialog_message0;\r
208             } else {\r
209                 message = NLS.bind(IDEWorkbenchMessages.PromptOnExitDialog_message1, productName);\r
210             }\r
211 \r
212             MessageDialogWithToggle dlg = MessageDialogWithToggle\r
213             .openOkCancelConfirm(getWindowConfigurer().getWindow()\r
214                     .getShell(), IDEWorkbenchMessages.PromptOnExitDialog_shellTitle,\r
215                     message, IDEWorkbenchMessages.PromptOnExitDialog_choice,\r
216                     false, null, null);\r
217             if (dlg.getReturnCode() != IDialogConstants.OK_ID) {\r
218                 return false;\r
219             }\r
220             if (dlg.getToggleState()) {\r
221                 store\r
222                 .setValue(\r
223                         IDEInternalPreferences.EXIT_PROMPT_ON_CLOSE_LAST_WINDOW,\r
224                         false);\r
225                 IDEWorkbenchPlugin.getDefault().savePluginPreferences();\r
226             }\r
227         }\r
228 \r
229         // Make sure that it's OK to close even if there are unsaved changes.\r
230         AtomicBoolean saveAtExit = new AtomicBoolean(false);\r
231         if (!ApplicationUtil.allowShutdown(saveAtExit))\r
232             return false;\r
233         wbAdvisor.setSaveAtExit(saveAtExit.get());\r
234 \r
235         BundleContext context = Activator.getDefault().getBundle().getBundleContext();\r
236         ServiceReference<?> ref = context.getServiceReference(WorkbenchShutdownService.class.getName());\r
237         WorkbenchShutdownService shutdown = (WorkbenchShutdownService)context.getService(ref);\r
238         shutdown.doShutdown();\r
239         context.ungetService(ref);\r
240 \r
241         allWindowShellsClosed = true;\r
242 \r
243         return true;\r
244     }\r
245 \r
246     /**\r
247      * Asks the user whether the workbench should really be closed. Only asks if\r
248      * the preference is enabled.\r
249      * \r
250      * @param parentShell\r
251      *            the parent shell to use for the confirmation dialog\r
252      * @return <code>true</code> if OK to exit, <code>false</code> if the user\r
253      *         canceled\r
254      * @since 3.6\r
255      */\r
256     static boolean promptOnExit(Shell parentShell) {\r
257         IPreferenceStore store = IDEWorkbenchPlugin.getDefault()\r
258                 .getPreferenceStore();\r
259         boolean promptOnExit = store\r
260                 .getBoolean(IDEInternalPreferences.EXIT_PROMPT_ON_CLOSE_LAST_WINDOW);\r
261 \r
262         if (promptOnExit) {\r
263             if (parentShell == null) {\r
264                 IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();\r
265                 if (workbenchWindow != null) {\r
266                     parentShell = workbenchWindow.getShell();\r
267                 }\r
268             }\r
269             if (parentShell != null) {\r
270                 parentShell.setMinimized(false);\r
271                 parentShell.forceActive();\r
272             }\r
273 \r
274             String message;\r
275 \r
276             String productName = null;\r
277             IProduct product = Platform.getProduct();\r
278             if (product != null) {\r
279                 productName = product.getName();\r
280             }\r
281             if (productName == null) {\r
282                 message = IDEWorkbenchMessages.PromptOnExitDialog_message0;\r
283             } else {\r
284                 message = NLS.bind(\r
285                         IDEWorkbenchMessages.PromptOnExitDialog_message1,\r
286                         productName);\r
287             }\r
288 \r
289             MessageDialogWithToggle dlg = MessageDialogWithToggle\r
290                     .openOkCancelConfirm(parentShell,\r
291                             IDEWorkbenchMessages.PromptOnExitDialog_shellTitle,\r
292                             message,\r
293                             IDEWorkbenchMessages.PromptOnExitDialog_choice,\r
294                             false, null, null);\r
295             if (dlg.getReturnCode() != IDialogConstants.OK_ID) {\r
296                 return false;\r
297             }\r
298             if (dlg.getToggleState()) {\r
299                 store\r
300                 .setValue(\r
301                         IDEInternalPreferences.EXIT_PROMPT_ON_CLOSE_LAST_WINDOW,\r
302                         false);\r
303                 IDEWorkbenchPlugin.getDefault().savePluginPreferences();\r
304             }\r
305         }\r
306 \r
307         return true;\r
308     }\r
309 \r
310     /* (non-Javadoc)\r
311      * @see org.eclipse.ui.application.WorkbenchAdvisor#preWindowOpen\r
312      */\r
313     @Override\r
314     public void preWindowOpen() {\r
315         IWorkbenchWindowConfigurer configurer = getWindowConfigurer();\r
316 \r
317         boolean showProgressIndicator = !"false".equals(System.getProperty("org.simantics.workbench.application.showProgressIndicator", "true").toLowerCase());\r
318         boolean showPerspectiveBar    = !"false".equals(System.getProperty("org.simantics.workbench.application.showPerspectiveBar", "true").toLowerCase());\r
319 \r
320         // show the shortcut bar and progress indicator, which are hidden by default\r
321         configurer.setShowProgressIndicator(showProgressIndicator);\r
322         configurer.setShowPerspectiveBar(showPerspectiveBar);\r
323 \r
324         // add the drag and drop support for the editor area\r
325         configurer.addEditorAreaTransfer(EditorInputTransfer.getInstance());\r
326         configurer.addEditorAreaTransfer(ResourceTransfer.getInstance());\r
327         configurer.addEditorAreaTransfer(FileTransfer.getInstance());\r
328         configurer.addEditorAreaTransfer(MarkerTransfer.getInstance());\r
329         configurer.configureEditorAreaDropListener(new EditorAreaDropAdapter(\r
330                 configurer.getWindow()));\r
331 \r
332         hookTitleUpdateListeners(configurer);\r
333     }\r
334 \r
335     /**\r
336      * Hooks the listeners needed on the window\r
337      * @param configurer\r
338      */\r
339     private void hookTitleUpdateListeners(IWorkbenchWindowConfigurer configurer) {\r
340         // hook up the listeners to update the window title\r
341         configurer.getWindow().addPageListener(new IPageListener() {\r
342             @Override\r
343             public void pageActivated(IWorkbenchPage page) {\r
344                 updateTitle(false);\r
345             }\r
346 \r
347             @Override\r
348             public void pageClosed(IWorkbenchPage page) {\r
349                 updateTitle(false);\r
350             }\r
351 \r
352             @Override\r
353             public void pageOpened(IWorkbenchPage page) {\r
354                 // do nothing\r
355             }\r
356         });\r
357         configurer.getWindow().addPerspectiveListener(\r
358                 new PerspectiveAdapter() {\r
359                     @Override\r
360                     public void perspectiveActivated(IWorkbenchPage page,\r
361                             IPerspectiveDescriptor perspective) {\r
362                         updateTitle(false);\r
363                     }\r
364                     @Override\r
365                     public void perspectiveSavedAs(IWorkbenchPage page,IPerspectiveDescriptor oldPerspective,IPerspectiveDescriptor newPerspective){\r
366                         updateTitle(false);\r
367                     }\r
368                     @Override\r
369                     public void perspectiveDeactivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {\r
370                         updateTitle(false);\r
371                     }\r
372                 });\r
373         configurer.getWindow().getPartService().addPartListener(\r
374                 new IPartListener2() {\r
375                     @Override\r
376                     public void partActivated(IWorkbenchPartReference ref) {\r
377                         if (ref instanceof IEditorReference) {\r
378                             updateTitle(false);\r
379                         }\r
380                     }\r
381 \r
382                     @Override\r
383                     public void partBroughtToTop(IWorkbenchPartReference ref) {\r
384                         if (ref instanceof IEditorReference) {\r
385                             updateTitle(false);\r
386                         }\r
387                     }\r
388 \r
389                     @Override\r
390                     public void partClosed(IWorkbenchPartReference ref) {\r
391                         updateTitle(false);\r
392                     }\r
393 \r
394                     @Override\r
395                     public void partDeactivated(IWorkbenchPartReference ref) {\r
396                         // do nothing\r
397                     }\r
398 \r
399                     @Override\r
400                     public void partOpened(IWorkbenchPartReference ref) {\r
401                         // do nothing\r
402                     }\r
403 \r
404                     @Override\r
405                     public void partHidden(IWorkbenchPartReference ref) {\r
406                         if (ref.getPart(false) == lastActiveEditor\r
407                                 && lastActiveEditor != null) {\r
408                             updateTitle(true);\r
409                         }\r
410                     }\r
411 \r
412                     @Override\r
413                     public void partVisible(IWorkbenchPartReference ref) {\r
414                         if (ref.getPart(false) == lastActiveEditor\r
415                                 && lastActiveEditor != null) {\r
416                             updateTitle(false);\r
417                         }\r
418                     }\r
419 \r
420                     @Override\r
421                     public void partInputChanged(IWorkbenchPartReference ref) {\r
422                         // do nothing\r
423                     }\r
424                 });\r
425 \r
426         // Update the title when the active UI database session is changed.\r
427         ISessionContextProvider provider = SimanticsUI.getSessionContextProvider(configurer.getWindow());\r
428         provider.addContextChangedListener(new ISessionContextChangedListener() {\r
429             @Override\r
430             public void sessionContextChanged(SessionContextChangedEvent event) {\r
431                 IWorkbenchWindowConfigurer configurer = getWindowConfigurer();\r
432                 IWorkbenchWindow window = configurer.getWindow();\r
433                 if (window == null)\r
434                     return;\r
435                 Shell shell = window.getShell();\r
436                 if (shell == null || shell.isDisposed())\r
437                     return;\r
438                 shell.getDisplay().asyncExec(new Runnable() {\r
439                     @Override\r
440                     public void run() {\r
441                         updateTitle(true);\r
442                     }\r
443                 });\r
444             }\r
445         });\r
446 \r
447         // Listen for changes of the workspace name.\r
448         propertyChangeListener = new IPropertyChangeListener() {\r
449             public void propertyChange(PropertyChangeEvent event) {\r
450                 String property = event.getProperty();\r
451                 if (IDEInternalPreferences.WORKSPACE_NAME.equals(property)\r
452                         || IDEInternalPreferences.SHOW_LOCATION.equals(property)) {\r
453                     // Make sure the title is actually updated by\r
454                     // setting last active page.\r
455                     lastActivePage = null;\r
456                     updateTitle(false);\r
457                 }\r
458             }\r
459         };\r
460         IDEWorkbenchPlugin.getDefault().getPreferenceStore()\r
461                 .addPropertyChangeListener(propertyChangeListener);\r
462     }\r
463 \r
464     protected String computeTitle() {\r
465         IWorkbenchWindowConfigurer configurer = getWindowConfigurer();\r
466         IWorkbenchPage currentPage = configurer.getWindow().getActivePage();\r
467         IEditorPart activeEditor = null;\r
468         if (currentPage != null) {\r
469             activeEditor = lastActiveEditor;\r
470         }\r
471 \r
472         String title = null;\r
473         IProduct product = Platform.getProduct();\r
474         if (product != null) {\r
475             title = product.getName();\r
476         }\r
477         if (title == null) {\r
478             title = ""; //$NON-NLS-1$\r
479         }\r
480 \r
481 //        ISessionContext ctx = SimanticsUI.getSessionContext(configurer.getWindow());\r
482 //        if (ctx != null) {\r
483 //            ServerAddress addr = ctx.getAddress();\r
484 //            if (addr != null) {\r
485 //                title += " - Connected to " + addr.getAddress().getHostName();//InetAddressUtils.toHostString(addr);\r
486 //            }\r
487 //            Session session = ctx.getSession();\r
488 //            if (session != null) {\r
489 //                SessionUserSupport sessionUser = session.getService(SessionUserSupport.class);\r
490 //                final Resource user = sessionUser.getUser();\r
491 //                if (user != null) {\r
492 //                    String userName;\r
493 //                    try {\r
494 //                        userName = session.syncRequest(new Read<String>() {\r
495 //                            @Override\r
496 //                            public String perform(ReadGraph graph) throws DatabaseException {\r
497 //                                try {\r
498 //                                    return graph.adapt(user, String.class);\r
499 //                                } catch (AdaptionException e) {\r
500 //                                    return NameUtils.getSafeName(graph, user);\r
501 //                                }\r
502 //                            }\r
503 //                        });\r
504 //                    } catch (DatabaseException e) {\r
505 //                        e.printStackTrace();\r
506 //                        userName = "ERROR";\r
507 //                    }\r
508 //\r
509 //                    title += " - " + userName;\r
510 //                }\r
511 //            }\r
512 //\r
513 //        } else {\r
514 //            //title += " - Disconnected";\r
515 //        }\r
516 \r
517         if (currentPage != null) {\r
518             if (activeEditor != null) {\r
519                 lastEditorTitle = activeEditor.getTitleToolTip();\r
520                 title = NLS.bind(IDEWorkbenchMessages.WorkbenchWindow_shellTitle, lastEditorTitle, title);\r
521             }\r
522 \r
523             boolean excludePerspectiveFromTitle = "true".equals(System.getProperty("org.simantics.workbench.application.excludePerspectiveFromTitle", "false").toLowerCase());\r
524             if (!excludePerspectiveFromTitle) {\r
525                 IPerspectiveDescriptor persp = currentPage.getPerspective();\r
526                 String label = ""; //$NON-NLS-1$\r
527                 if (persp != null) {\r
528                     label = persp.getLabel();\r
529                 }\r
530                 IAdaptable input = currentPage.getInput();\r
531                 if (input != null && !input.equals(wbAdvisor.getDefaultPageInput())) {\r
532                     label = currentPage.getLabel();\r
533                 }\r
534                 if (label != null && !label.equals("")) { //$NON-NLS-1$\r
535                     title = NLS.bind(IDEWorkbenchMessages.WorkbenchWindow_shellTitle, label, title);\r
536                 }\r
537             }\r
538         }\r
539 \r
540         String workspaceLocation = wbAdvisor.getWorkspaceLocation();\r
541         if (workspaceLocation != null) {\r
542             title = NLS.bind(IDEWorkbenchMessages.WorkbenchWindow_shellTitle, title, workspaceLocation);\r
543         }\r
544 \r
545         // Bug 284447: Prepend workspace name to the title\r
546         String workspaceName = IDEWorkbenchPlugin.getDefault()\r
547         .getPreferenceStore().getString(\r
548                 IDEInternalPreferences.WORKSPACE_NAME);\r
549         if (workspaceName != null && workspaceName.length() > 0) {\r
550             title = NLS.bind(IDEWorkbenchMessages.WorkbenchWindow_shellTitle,\r
551                     workspaceName, title);\r
552         }\r
553 \r
554         return title;\r
555     }\r
556 \r
557     private void recomputeTitle() {\r
558         IWorkbenchWindowConfigurer configurer = getWindowConfigurer();\r
559         String oldTitle = configurer.getTitle();\r
560         String newTitle = computeTitle();\r
561         if (!newTitle.equals(oldTitle)) {\r
562             configurer.setTitle(newTitle);\r
563         }\r
564     }\r
565 \r
566     /**\r
567      * Updates the window title. Format will be:\r
568      * [pageInput -] [currentPerspective -] [editorInput -] [workspaceLocation -] productName\r
569      */\r
570     private void updateTitle(boolean force) {\r
571         IWorkbenchWindowConfigurer configurer = getWindowConfigurer();\r
572         IWorkbenchWindow window = configurer.getWindow();\r
573         IEditorPart activeEditor = null;\r
574         IWorkbenchPage currentPage = window.getActivePage();\r
575         IPerspectiveDescriptor persp = null;\r
576         IAdaptable input = null;\r
577 \r
578         if (currentPage != null) {\r
579             activeEditor = currentPage.getActiveEditor();\r
580             persp = currentPage.getPerspective();\r
581             input = currentPage.getInput();\r
582         }\r
583 \r
584         // Nothing to do if the editor hasn't changed or change is not forced.\r
585         if (!force && activeEditor == lastActiveEditor && currentPage == lastActivePage\r
586                 && persp == lastPerspective && input == lastInput) {\r
587             return;\r
588         }\r
589 \r
590         if (lastActiveEditor != null) {\r
591             lastActiveEditor.removePropertyListener(editorPropertyListener );\r
592         }\r
593 \r
594         lastActiveEditor = activeEditor;\r
595         lastActivePage = currentPage;\r
596         lastPerspective = persp;\r
597         lastInput = input;\r
598 \r
599         if (activeEditor != null) {\r
600             activeEditor.addPropertyListener(editorPropertyListener);\r
601         }\r
602 \r
603         recomputeTitle();\r
604     }\r
605 \r
606     /* (non-Javadoc)\r
607      * @see org.eclipse.ui.application.WorkbenchAdvisor#postWindowRestore\r
608      */\r
609     @Override\r
610     public void postWindowRestore()\r
611     throws WorkbenchException {\r
612         IWorkbenchWindowConfigurer configurer = getWindowConfigurer();\r
613         IWorkbenchWindow window = configurer.getWindow();\r
614 \r
615         int index = getWorkbench().getWorkbenchWindowCount() - 1;\r
616 \r
617         AboutInfo[] welcomePerspectiveInfos = wbAdvisor.getWelcomePerspectiveInfos();\r
618         if (index >= 0 && welcomePerspectiveInfos != null\r
619                 && index < welcomePerspectiveInfos.length) {\r
620             // find a page that exist in the window\r
621             IWorkbenchPage page = window.getActivePage();\r
622             if (page == null) {\r
623                 IWorkbenchPage[] pages = window.getPages();\r
624                 if (pages != null && pages.length > 0) {\r
625                     page = pages[0];\r
626                 }\r
627             }\r
628 \r
629             // if the window does not contain a page, create one\r
630             String perspectiveId = welcomePerspectiveInfos[index].getWelcomePerspectiveId();\r
631             if (page == null) {\r
632                 IAdaptable root = wbAdvisor.getDefaultPageInput();\r
633                 page = window.openPage(perspectiveId, root);\r
634             } else {\r
635                 IPerspectiveRegistry reg = getWorkbench()\r
636                         .getPerspectiveRegistry();\r
637                 IPerspectiveDescriptor desc = reg\r
638                         .findPerspectiveWithId(perspectiveId);\r
639                 if (desc != null) {\r
640                     page.setPerspective(desc);\r
641                 }\r
642             }\r
643 \r
644             // set the active page and open the welcome editor\r
645             window.setActivePage(page);\r
646             page.openEditor(new WelcomeEditorInput(\r
647                     welcomePerspectiveInfos[index]), WELCOME_EDITOR_ID, true);\r
648         }\r
649     }\r
650 \r
651     /**\r
652      * Tries to open the intro, if one exists and otherwise will open the legacy\r
653      * Welcome pages.\r
654      * \r
655      * @see org.eclipse.ui.application.WorkbenchWindowAdvisor#openIntro()\r
656      */\r
657     @Override\r
658     public void openIntro() {\r
659         if (editorsAndIntrosOpened ) {\r
660             return;\r
661         }\r
662 \r
663         editorsAndIntrosOpened = true;\r
664 \r
665         // don't try to open the welcome editors if there is an intro\r
666         if (wbAdvisor.hasIntro()) {\r
667             super.openIntro();\r
668         } else {\r
669             openWelcomeEditors(getWindowConfigurer().getWindow());\r
670             // save any preferences changes caused by the above actions\r
671             IDEWorkbenchPlugin.getDefault().savePluginPreferences();\r
672         }\r
673     }\r
674 \r
675     /*\r
676      * Open the welcome editor for the primary feature and for any newly\r
677      * installed features.\r
678      */\r
679     private void openWelcomeEditors(IWorkbenchWindow window) {\r
680         if (IDEWorkbenchPlugin.getDefault().getPreferenceStore().getBoolean(\r
681                 IDEInternalPreferences.WELCOME_DIALOG)) {\r
682             // show the welcome page for the product the first time the\r
683             // workbench opens\r
684             IProduct product = Platform.getProduct();\r
685             if (product == null) {\r
686                 return;\r
687             }\r
688 \r
689             AboutInfo productInfo = new AboutInfo(product);\r
690             URL url = productInfo.getWelcomePageURL();\r
691             if (url == null) {\r
692                 return;\r
693             }\r
694 \r
695             IDEWorkbenchPlugin.getDefault().getPreferenceStore().setValue(\r
696                     IDEInternalPreferences.WELCOME_DIALOG, false);\r
697             openWelcomeEditor(window, new WelcomeEditorInput(productInfo), null);\r
698         } else {\r
699             // Show the welcome page for any newly installed features\r
700             List<AboutInfo> welcomeFeatures = new ArrayList<AboutInfo>();\r
701             for (Iterator<?> it = wbAdvisor.getNewlyAddedBundleGroups().entrySet()\r
702                     .iterator(); it.hasNext();) {\r
703                 Map.Entry<?,?> entry = (Map.Entry<?,?>) it.next();\r
704                 AboutInfo info = (AboutInfo) entry.getValue();\r
705 \r
706                 if (info != null && info.getWelcomePageURL() != null) {\r
707                     welcomeFeatures.add(info);\r
708                     // activate the feature plug-in so it can run some install\r
709                     // code\r
710                     String pi = info.getBrandingBundleId();\r
711                     if (pi != null) {\r
712                         // Start the bundle if there is one\r
713                         Bundle bundle = Platform.getBundle(pi);\r
714                         if (bundle != null) {\r
715                             try {\r
716                                 bundle.start(Bundle.START_TRANSIENT);\r
717                             } catch (BundleException exception) {\r
718                                 StatusManager\r
719                                 .getManager()\r
720                                 .handle(\r
721                                         new Status(\r
722                                                 IStatus.ERROR,\r
723                                                 Activator.PLUGIN_ID,\r
724                                                 "Failed to load feature", exception));//$NON-NLS-1$\r
725                             }\r
726                         }\r
727                     }\r
728                 }\r
729             }\r
730 \r
731             int wCount = getWorkbench().getWorkbenchWindowCount();\r
732             for (int i = 0; i < welcomeFeatures.size(); i++) {\r
733                 AboutInfo newInfo = (AboutInfo) welcomeFeatures.get(i);\r
734                 String id = newInfo.getWelcomePerspectiveId();\r
735                 // Other editors were already opened in postWindowRestore(..)\r
736                 if (id == null || i >= wCount) {\r
737                     openWelcomeEditor(window, new WelcomeEditorInput(newInfo),\r
738                             id);\r
739                 }\r
740             }\r
741         }\r
742     }\r
743 \r
744     /**\r
745      * Open a welcome editor for the given input\r
746      */\r
747     private void openWelcomeEditor(IWorkbenchWindow window,\r
748             WelcomeEditorInput input, String perspectiveId) {\r
749         if (getWorkbench().getWorkbenchWindowCount() == 0) {\r
750             // Something is wrong, there should be at least\r
751             // one workbench window open by now.\r
752             return;\r
753         }\r
754 \r
755         IWorkbenchWindow win = window;\r
756         if (perspectiveId != null) {\r
757             try {\r
758                 win = getWorkbench().openWorkbenchWindow(perspectiveId,\r
759                         wbAdvisor.getDefaultPageInput());\r
760                 if (win == null) {\r
761                     win = window;\r
762                 }\r
763             } catch (WorkbenchException e) {\r
764                 IDEWorkbenchPlugin\r
765                 .log(\r
766                         "Error opening window with welcome perspective.", e.getStatus()); //$NON-NLS-1$\r
767                 return;\r
768             }\r
769         }\r
770 \r
771         if (win == null) {\r
772             win = getWorkbench().getWorkbenchWindows()[0];\r
773         }\r
774 \r
775         IWorkbenchPage page = win.getActivePage();\r
776         String id = perspectiveId;\r
777         if (id == null) {\r
778             id = getWorkbench().getPerspectiveRegistry()\r
779             .getDefaultPerspective();\r
780         }\r
781 \r
782         if (page == null) {\r
783             try {\r
784                 page = win.openPage(id, wbAdvisor.getDefaultPageInput());\r
785             } catch (WorkbenchException e) {\r
786                 ErrorDialog.openError(win.getShell(),\r
787                         IDEWorkbenchMessages.Problems_Opening_Page, e\r
788                         .getMessage(), e.getStatus());\r
789             }\r
790         }\r
791         if (page == null) {\r
792             return;\r
793         }\r
794 \r
795         if (page.getPerspective() == null) {\r
796             try {\r
797                 page = getWorkbench().showPerspective(id, win);\r
798             } catch (WorkbenchException e) {\r
799                 ErrorDialog\r
800                 .openError(\r
801                         win.getShell(),\r
802                         IDEWorkbenchMessages.Workbench_openEditorErrorDialogTitle,\r
803                         IDEWorkbenchMessages.Workbench_openEditorErrorDialogMessage,\r
804                         e.getStatus());\r
805                 return;\r
806             }\r
807         }\r
808 \r
809         page.setEditorAreaVisible(true);\r
810 \r
811         // see if we already have an editor\r
812         IEditorPart editor = page.findEditor(input);\r
813         if (editor != null) {\r
814             page.activate(editor);\r
815             return;\r
816         }\r
817 \r
818         try {\r
819             page.openEditor(input, WELCOME_EDITOR_ID);\r
820         } catch (PartInitException e) {\r
821             ErrorDialog\r
822             .openError(\r
823                     win.getShell(),\r
824                     IDEWorkbenchMessages.Workbench_openEditorErrorDialogTitle,\r
825                     IDEWorkbenchMessages.Workbench_openEditorErrorDialogMessage,\r
826                     e.getStatus());\r
827         }\r
828         return;\r
829     }\r
830 \r
831     /* (non-Javadoc)\r
832      * @see org.eclipse.ui.application.WorkbenchAdvisor#createEmptyWindowContents(org.eclipse.ui.application.IWorkbenchWindowConfigurer, org.eclipse.swt.widgets.Composite)\r
833      */\r
834     @Override\r
835     public Control createEmptyWindowContents(Composite parent) {\r
836         final IWorkbenchWindow window = getWindowConfigurer().getWindow();\r
837         Composite composite = new Composite(parent, SWT.NONE);\r
838         composite.setLayout(new GridLayout(2, false));\r
839         Display display = composite.getDisplay();\r
840         Color bgCol = display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND);\r
841         composite.setBackground(bgCol);\r
842         Label label = new Label(composite, SWT.WRAP);\r
843         label.setForeground(display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND));\r
844         label.setBackground(bgCol);\r
845         label.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));\r
846         String msg = IDEWorkbenchMessages.IDEWorkbenchAdvisor_noPerspective;\r
847         label.setText(msg);\r
848         ToolBarManager toolBarManager = new ToolBarManager();\r
849         openPerspectiveAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG.create(window);\r
850         toolBarManager.add(openPerspectiveAction);\r
851         ToolBar toolBar = toolBarManager.createControl(composite);\r
852         toolBar.setBackground(bgCol);\r
853         return composite;\r
854     }\r
855 \r
856     @Override\r
857     public void dispose() {\r
858         if (propertyChangeListener != null) {\r
859             IDEWorkbenchPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(propertyChangeListener);\r
860             propertyChangeListener = null;\r
861         }\r
862 \r
863         if (openPerspectiveAction!=null) {\r
864             openPerspectiveAction.dispose();\r
865             openPerspectiveAction = null;\r
866         }\r
867         super.dispose();\r
868     }\r
869 \r
870 }\r