001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.ide.application;
011:
012: import java.net.URL;
013: import java.util.ArrayList;
014: import java.util.Iterator;
015: import java.util.List;
016: import java.util.Map;
017:
018: import org.eclipse.core.runtime.IAdaptable;
019: import org.eclipse.core.runtime.IProduct;
020: import org.eclipse.core.runtime.IStatus;
021: import org.eclipse.core.runtime.Platform;
022: import org.eclipse.core.runtime.Status;
023: import org.eclipse.jface.action.IAction;
024: import org.eclipse.jface.action.ToolBarManager;
025: import org.eclipse.jface.dialogs.ErrorDialog;
026: import org.eclipse.jface.dialogs.IDialogConstants;
027: import org.eclipse.jface.dialogs.MessageDialogWithToggle;
028: import org.eclipse.jface.preference.IPreferenceStore;
029: import org.eclipse.jface.resource.JFaceResources;
030: import org.eclipse.osgi.util.NLS;
031: import org.eclipse.swt.SWT;
032: import org.eclipse.swt.dnd.FileTransfer;
033: import org.eclipse.swt.graphics.Color;
034: import org.eclipse.swt.layout.GridLayout;
035: import org.eclipse.swt.widgets.Composite;
036: import org.eclipse.swt.widgets.Control;
037: import org.eclipse.swt.widgets.Display;
038: import org.eclipse.swt.widgets.Label;
039: import org.eclipse.swt.widgets.ToolBar;
040: import org.eclipse.ui.IEditorPart;
041: import org.eclipse.ui.IEditorReference;
042: import org.eclipse.ui.IPageListener;
043: import org.eclipse.ui.IPartListener2;
044: import org.eclipse.ui.IPerspectiveDescriptor;
045: import org.eclipse.ui.IPerspectiveRegistry;
046: import org.eclipse.ui.IPropertyListener;
047: import org.eclipse.ui.IWorkbench;
048: import org.eclipse.ui.IWorkbenchPage;
049: import org.eclipse.ui.IWorkbenchPartConstants;
050: import org.eclipse.ui.IWorkbenchPartReference;
051: import org.eclipse.ui.IWorkbenchWindow;
052: import org.eclipse.ui.PartInitException;
053: import org.eclipse.ui.PerspectiveAdapter;
054: import org.eclipse.ui.WorkbenchException;
055: import org.eclipse.ui.actions.ActionFactory;
056: import org.eclipse.ui.application.ActionBarAdvisor;
057: import org.eclipse.ui.application.IActionBarConfigurer;
058: import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
059: import org.eclipse.ui.application.WorkbenchWindowAdvisor;
060: import org.eclipse.ui.internal.ide.AboutInfo;
061: import org.eclipse.ui.internal.ide.EditorAreaDropAdapter;
062: import org.eclipse.ui.internal.ide.IDEInternalPreferences;
063: import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
064: import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
065: import org.eclipse.ui.internal.ide.WorkbenchActionBuilder;
066: import org.eclipse.ui.internal.ide.dialogs.WelcomeEditorInput;
067: import org.eclipse.ui.part.EditorInputTransfer;
068: import org.eclipse.ui.part.MarkerTransfer;
069: import org.eclipse.ui.part.ResourceTransfer;
070: import org.eclipse.ui.statushandlers.StatusManager;
071: import org.eclipse.update.configurator.ConfiguratorUtils;
072: import org.eclipse.update.configurator.IPlatformConfiguration;
073: import org.osgi.framework.Bundle;
074: import org.osgi.framework.BundleException;
075:
076: /**
077: * Window-level advisor for the IDE.
078: */
079: public class IDEWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
080:
081: private static final String WELCOME_EDITOR_ID = "org.eclipse.ui.internal.ide.dialogs.WelcomeEditor"; //$NON-NLS-1$
082:
083: private IDEWorkbenchAdvisor wbAdvisor;
084: private boolean editorsAndIntrosOpened = false;
085: private IEditorPart lastActiveEditor = null;
086: private IPerspectiveDescriptor lastPerspective = null;
087:
088: private IWorkbenchPage lastActivePage;
089: private String lastEditorTitle = ""; //$NON-NLS-1$
090:
091: private IPropertyListener editorPropertyListener = new IPropertyListener() {
092: public void propertyChanged(Object source, int propId) {
093: if (propId == IWorkbenchPartConstants.PROP_TITLE) {
094: if (lastActiveEditor != null) {
095: String newTitle = lastActiveEditor.getTitle();
096: if (!lastEditorTitle.equals(newTitle)) {
097: recomputeTitle();
098: }
099: }
100: }
101: }
102: };
103:
104: private IAdaptable lastInput;
105:
106: /**
107: * Crates a new IDE workbench window advisor.
108: *
109: * @param wbAdvisor
110: * the workbench advisor
111: * @param configurer
112: * the window configurer
113: */
114: public IDEWorkbenchWindowAdvisor(IDEWorkbenchAdvisor wbAdvisor,
115: IWorkbenchWindowConfigurer configurer) {
116: super (configurer);
117: this .wbAdvisor = wbAdvisor;
118: }
119:
120: /*
121: * (non-Javadoc)
122: *
123: * @see org.eclipse.ui.application.WorkbenchWindowAdvisor#createActionBarAdvisor(org.eclipse.ui.application.IActionBarConfigurer)
124: */
125: public ActionBarAdvisor createActionBarAdvisor(
126: IActionBarConfigurer configurer) {
127: return new WorkbenchActionBuilder(configurer);
128: }
129:
130: /**
131: * Returns the workbench.
132: *
133: * @return the workbench
134: */
135: private IWorkbench getWorkbench() {
136: return getWindowConfigurer().getWorkbenchConfigurer()
137: .getWorkbench();
138: }
139:
140: /*
141: * (non-Javadoc)
142: *
143: * @see org.eclipse.ui.application.WorkbenchAdvisor#preWindowShellClose
144: */
145: public boolean preWindowShellClose() {
146: if (getWorkbench().getWorkbenchWindowCount() > 1) {
147: return true;
148: }
149: // the user has asked to close the last window, while will cause the
150: // workbench to close in due course - prompt the user for confirmation
151: IPreferenceStore store = IDEWorkbenchPlugin.getDefault()
152: .getPreferenceStore();
153: boolean promptOnExit = store
154: .getBoolean(IDEInternalPreferences.EXIT_PROMPT_ON_CLOSE_LAST_WINDOW);
155:
156: if (promptOnExit) {
157: String message;
158:
159: String productName = null;
160: IProduct product = Platform.getProduct();
161: if (product != null) {
162: productName = product.getName();
163: }
164: if (productName == null) {
165: message = IDEWorkbenchMessages.PromptOnExitDialog_message0;
166: } else {
167: message = NLS
168: .bind(
169: IDEWorkbenchMessages.PromptOnExitDialog_message1,
170: productName);
171: }
172:
173: MessageDialogWithToggle dlg = MessageDialogWithToggle
174: .openOkCancelConfirm(
175: getWindowConfigurer().getWindow()
176: .getShell(),
177: IDEWorkbenchMessages.PromptOnExitDialog_shellTitle,
178: message,
179: IDEWorkbenchMessages.PromptOnExitDialog_choice,
180: false, null, null);
181: if (dlg.getReturnCode() != IDialogConstants.OK_ID) {
182: return false;
183: }
184: if (dlg.getToggleState()) {
185: store
186: .setValue(
187: IDEInternalPreferences.EXIT_PROMPT_ON_CLOSE_LAST_WINDOW,
188: false);
189: IDEWorkbenchPlugin.getDefault().savePluginPreferences();
190: }
191: }
192:
193: return true;
194: }
195:
196: /*
197: * (non-Javadoc)
198: *
199: * @see org.eclipse.ui.application.WorkbenchAdvisor#preWindowOpen
200: */
201: public void preWindowOpen() {
202: IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
203:
204: // show the shortcut bar and progress indicator, which are hidden by
205: // default
206: configurer.setShowPerspectiveBar(true);
207: configurer.setShowFastViewBars(true);
208: configurer.setShowProgressIndicator(true);
209:
210: // add the drag and drop support for the editor area
211: configurer.addEditorAreaTransfer(EditorInputTransfer
212: .getInstance());
213: configurer
214: .addEditorAreaTransfer(ResourceTransfer.getInstance());
215: configurer.addEditorAreaTransfer(FileTransfer.getInstance());
216: configurer.addEditorAreaTransfer(MarkerTransfer.getInstance());
217: configurer
218: .configureEditorAreaDropListener(new EditorAreaDropAdapter(
219: configurer.getWindow()));
220:
221: hookTitleUpdateListeners(configurer);
222: }
223:
224: /**
225: * Hooks the listeners needed on the window
226: *
227: * @param configurer
228: */
229: private void hookTitleUpdateListeners(
230: IWorkbenchWindowConfigurer configurer) {
231: // hook up the listeners to update the window title
232: configurer.getWindow().addPageListener(new IPageListener() {
233: public void pageActivated(IWorkbenchPage page) {
234: updateTitle();
235: }
236:
237: public void pageClosed(IWorkbenchPage page) {
238: updateTitle();
239: }
240:
241: public void pageOpened(IWorkbenchPage page) {
242: // do nothing
243: }
244: });
245: configurer.getWindow().addPerspectiveListener(
246: new PerspectiveAdapter() {
247: public void perspectiveActivated(
248: IWorkbenchPage page,
249: IPerspectiveDescriptor perspective) {
250: updateTitle();
251: }
252:
253: public void perspectiveSavedAs(IWorkbenchPage page,
254: IPerspectiveDescriptor oldPerspective,
255: IPerspectiveDescriptor newPerspective) {
256: updateTitle();
257: }
258:
259: public void perspectiveDeactivated(
260: IWorkbenchPage page,
261: IPerspectiveDescriptor perspective) {
262: updateTitle();
263: }
264: });
265: configurer.getWindow().getPartService().addPartListener(
266: new IPartListener2() {
267: public void partActivated(
268: IWorkbenchPartReference ref) {
269: if (ref instanceof IEditorReference) {
270: updateTitle();
271: }
272: }
273:
274: public void partBroughtToTop(
275: IWorkbenchPartReference ref) {
276: if (ref instanceof IEditorReference) {
277: updateTitle();
278: }
279: }
280:
281: public void partClosed(IWorkbenchPartReference ref) {
282: updateTitle();
283: }
284:
285: public void partDeactivated(
286: IWorkbenchPartReference ref) {
287: // do nothing
288: }
289:
290: public void partOpened(IWorkbenchPartReference ref) {
291: // do nothing
292: }
293:
294: public void partHidden(IWorkbenchPartReference ref) {
295: // do nothing
296: }
297:
298: public void partVisible(IWorkbenchPartReference ref) {
299: // do nothing
300: }
301:
302: public void partInputChanged(
303: IWorkbenchPartReference ref) {
304: // do nothing
305: }
306: });
307: }
308:
309: private String computeTitle() {
310: IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
311: IWorkbenchPage currentPage = configurer.getWindow()
312: .getActivePage();
313: IEditorPart activeEditor = null;
314: if (currentPage != null) {
315: activeEditor = currentPage.getActiveEditor();
316: }
317:
318: String title = null;
319: IProduct product = Platform.getProduct();
320: if (product != null) {
321: title = product.getName();
322: }
323: if (title == null) {
324: title = ""; //$NON-NLS-1$
325: }
326:
327: if (currentPage != null) {
328: if (activeEditor != null) {
329: lastEditorTitle = activeEditor.getTitleToolTip();
330: title = NLS
331: .bind(
332: IDEWorkbenchMessages.WorkbenchWindow_shellTitle,
333: lastEditorTitle, title);
334: }
335: IPerspectiveDescriptor persp = currentPage.getPerspective();
336: String label = ""; //$NON-NLS-1$
337: if (persp != null) {
338: label = persp.getLabel();
339: }
340: IAdaptable input = currentPage.getInput();
341: if (input != null
342: && !input.equals(wbAdvisor.getDefaultPageInput())) {
343: label = currentPage.getLabel();
344: }
345: if (label != null && !label.equals("")) { //$NON-NLS-1$
346: title = NLS
347: .bind(
348: IDEWorkbenchMessages.WorkbenchWindow_shellTitle,
349: label, title);
350: }
351: }
352:
353: String workspaceLocation = wbAdvisor.getWorkspaceLocation();
354: if (workspaceLocation != null) {
355: title = NLS.bind(
356: IDEWorkbenchMessages.WorkbenchWindow_shellTitle,
357: title, workspaceLocation);
358: }
359:
360: return title;
361: }
362:
363: private void recomputeTitle() {
364: IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
365: String oldTitle = configurer.getTitle();
366: String newTitle = computeTitle();
367: if (!newTitle.equals(oldTitle)) {
368: configurer.setTitle(newTitle);
369: }
370: }
371:
372: /**
373: * Updates the window title. Format will be: [pageInput -]
374: * [currentPerspective -] [editorInput -] [workspaceLocation -] productName
375: */
376: private void updateTitle() {
377: IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
378: IWorkbenchWindow window = configurer.getWindow();
379: IEditorPart activeEditor = null;
380: IWorkbenchPage currentPage = window.getActivePage();
381: IPerspectiveDescriptor persp = null;
382: IAdaptable input = null;
383:
384: if (currentPage != null) {
385: activeEditor = currentPage.getActiveEditor();
386: persp = currentPage.getPerspective();
387: input = currentPage.getInput();
388: }
389:
390: // Nothing to do if the editor hasn't changed
391: if (activeEditor == lastActiveEditor
392: && currentPage == lastActivePage
393: && persp == lastPerspective && input == lastInput) {
394: return;
395: }
396:
397: if (lastActiveEditor != null) {
398: lastActiveEditor
399: .removePropertyListener(editorPropertyListener);
400: }
401:
402: lastActiveEditor = activeEditor;
403: lastActivePage = currentPage;
404: lastPerspective = persp;
405: lastInput = input;
406:
407: if (activeEditor != null) {
408: activeEditor.addPropertyListener(editorPropertyListener);
409: }
410:
411: recomputeTitle();
412: }
413:
414: /*
415: * (non-Javadoc)
416: *
417: * @see org.eclipse.ui.application.WorkbenchAdvisor#postWindowRestore
418: */
419: public void postWindowRestore() throws WorkbenchException {
420: IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
421: IWorkbenchWindow window = configurer.getWindow();
422:
423: int index = getWorkbench().getWorkbenchWindowCount() - 1;
424:
425: AboutInfo[] welcomePerspectiveInfos = wbAdvisor
426: .getWelcomePerspectiveInfos();
427: if (index >= 0 && welcomePerspectiveInfos != null
428: && index < welcomePerspectiveInfos.length) {
429: // find a page that exist in the window
430: IWorkbenchPage page = window.getActivePage();
431: if (page == null) {
432: IWorkbenchPage[] pages = window.getPages();
433: if (pages != null && pages.length > 0) {
434: page = pages[0];
435: }
436: }
437:
438: // if the window does not contain a page, create one
439: String perspectiveId = welcomePerspectiveInfos[index]
440: .getWelcomePerspectiveId();
441: if (page == null) {
442: IAdaptable root = wbAdvisor.getDefaultPageInput();
443: page = window.openPage(perspectiveId, root);
444: } else {
445: IPerspectiveRegistry reg = getWorkbench()
446: .getPerspectiveRegistry();
447: IPerspectiveDescriptor desc = reg
448: .findPerspectiveWithId(perspectiveId);
449: if (desc != null) {
450: page.setPerspective(desc);
451: }
452: }
453:
454: // set the active page and open the welcome editor
455: window.setActivePage(page);
456: page.openEditor(new WelcomeEditorInput(
457: welcomePerspectiveInfos[index]), WELCOME_EDITOR_ID,
458: true);
459: }
460: }
461:
462: /**
463: * Tries to open the intro, if one exists and otherwise will open the legacy
464: * Welcome pages.
465: *
466: * @see org.eclipse.ui.application.WorkbenchWindowAdvisor#openIntro()
467: */
468: public void openIntro() {
469: if (editorsAndIntrosOpened) {
470: return;
471: }
472:
473: editorsAndIntrosOpened = true;
474:
475: // don't try to open the welcome editors if there is an intro
476: if (wbAdvisor.hasIntro()) {
477: super .openIntro();
478: } else {
479: openWelcomeEditors(getWindowConfigurer().getWindow());
480: // save any preferences changes caused by the above actions
481: IDEWorkbenchPlugin.getDefault().savePluginPreferences();
482: }
483: }
484:
485: /*
486: * Open the welcome editor for the primary feature and for any newly
487: * installed features.
488: */
489: private void openWelcomeEditors(IWorkbenchWindow window) {
490: if (IDEWorkbenchPlugin.getDefault().getPreferenceStore()
491: .getBoolean(IDEInternalPreferences.WELCOME_DIALOG)) {
492: // show the welcome page for the product the first time the
493: // workbench opens
494: IProduct product = Platform.getProduct();
495: if (product == null) {
496: return;
497: }
498:
499: AboutInfo productInfo = new AboutInfo(product);
500: URL url = productInfo.getWelcomePageURL();
501: if (url == null) {
502: return;
503: }
504:
505: IDEWorkbenchPlugin.getDefault().getPreferenceStore()
506: .setValue(IDEInternalPreferences.WELCOME_DIALOG,
507: false);
508: openWelcomeEditor(window, new WelcomeEditorInput(
509: productInfo), null);
510: } else {
511: // Show the welcome page for any newly installed features
512: List welcomeFeatures = new ArrayList();
513: for (Iterator it = wbAdvisor.getNewlyAddedBundleGroups()
514: .entrySet().iterator(); it.hasNext();) {
515: Map.Entry entry = (Map.Entry) it.next();
516: String versionedId = (String) entry.getKey();
517: String featureId = versionedId.substring(0, versionedId
518: .indexOf(':'));
519: AboutInfo info = (AboutInfo) entry.getValue();
520:
521: if (info != null && info.getWelcomePageURL() != null) {
522: welcomeFeatures.add(info);
523: // activate the feature plug-in so it can run some install
524: // code
525: IPlatformConfiguration platformConfiguration = ConfiguratorUtils
526: .getCurrentPlatformConfiguration();
527: IPlatformConfiguration.IFeatureEntry feature = platformConfiguration
528: .findConfiguredFeatureEntry(featureId);
529: if (feature != null) {
530: String pi = feature
531: .getFeaturePluginIdentifier();
532: if (pi != null) {
533: // Start the bundle if there is one
534: Bundle bundle = Platform.getBundle(pi);
535: if (bundle != null) {
536: try {
537: bundle
538: .start(Bundle.START_TRANSIENT);
539: } catch (BundleException exception) {
540: StatusManager
541: .getManager()
542: .handle(
543: new Status(
544: IStatus.ERROR,
545: IDEApplication.PLUGIN_ID,
546: "Failed to load feature", exception));//$NON-NLS-1$
547: }
548: }
549: }
550: }
551: }
552: }
553:
554: int wCount = getWorkbench().getWorkbenchWindowCount();
555: for (int i = 0; i < welcomeFeatures.size(); i++) {
556: AboutInfo newInfo = (AboutInfo) welcomeFeatures.get(i);
557: String id = newInfo.getWelcomePerspectiveId();
558: // Other editors were already opened in postWindowRestore(..)
559: if (id == null || i >= wCount) {
560: openWelcomeEditor(window, new WelcomeEditorInput(
561: newInfo), id);
562: }
563: }
564: }
565: }
566:
567: /**
568: * Open a welcome editor for the given input
569: */
570: private void openWelcomeEditor(IWorkbenchWindow window,
571: WelcomeEditorInput input, String perspectiveId) {
572: if (getWorkbench().getWorkbenchWindowCount() == 0) {
573: // Something is wrong, there should be at least
574: // one workbench window open by now.
575: return;
576: }
577:
578: IWorkbenchWindow win = window;
579: if (perspectiveId != null) {
580: try {
581: win = getWorkbench().openWorkbenchWindow(perspectiveId,
582: wbAdvisor.getDefaultPageInput());
583: if (win == null) {
584: win = window;
585: }
586: } catch (WorkbenchException e) {
587: IDEWorkbenchPlugin
588: .log(
589: "Error opening window with welcome perspective.", e.getStatus()); //$NON-NLS-1$
590: return;
591: }
592: }
593:
594: if (win == null) {
595: win = getWorkbench().getWorkbenchWindows()[0];
596: }
597:
598: IWorkbenchPage page = win.getActivePage();
599: String id = perspectiveId;
600: if (id == null) {
601: id = getWorkbench().getPerspectiveRegistry()
602: .getDefaultPerspective();
603: }
604:
605: if (page == null) {
606: try {
607: page = win
608: .openPage(id, wbAdvisor.getDefaultPageInput());
609: } catch (WorkbenchException e) {
610: ErrorDialog.openError(win.getShell(),
611: IDEWorkbenchMessages.Problems_Opening_Page, e
612: .getMessage(), e.getStatus());
613: }
614: }
615: if (page == null) {
616: return;
617: }
618:
619: if (page.getPerspective() == null) {
620: try {
621: page = getWorkbench().showPerspective(id, win);
622: } catch (WorkbenchException e) {
623: ErrorDialog
624: .openError(
625: win.getShell(),
626: IDEWorkbenchMessages.Workbench_openEditorErrorDialogTitle,
627: IDEWorkbenchMessages.Workbench_openEditorErrorDialogMessage,
628: e.getStatus());
629: return;
630: }
631: }
632:
633: page.setEditorAreaVisible(true);
634:
635: // see if we already have an editor
636: IEditorPart editor = page.findEditor(input);
637: if (editor != null) {
638: page.activate(editor);
639: return;
640: }
641:
642: try {
643: page.openEditor(input, WELCOME_EDITOR_ID);
644: } catch (PartInitException e) {
645: ErrorDialog
646: .openError(
647: win.getShell(),
648: IDEWorkbenchMessages.Workbench_openEditorErrorDialogTitle,
649: IDEWorkbenchMessages.Workbench_openEditorErrorDialogMessage,
650: e.getStatus());
651: }
652: return;
653: }
654:
655: /*
656: * (non-Javadoc)
657: *
658: * @see org.eclipse.ui.application.WorkbenchAdvisor#createEmptyWindowContents(org.eclipse.ui.application.IWorkbenchWindowConfigurer,
659: * org.eclipse.swt.widgets.Composite)
660: */
661: public Control createEmptyWindowContents(Composite parent) {
662: final IWorkbenchWindow window = getWindowConfigurer()
663: .getWindow();
664: Composite composite = new Composite(parent, SWT.NONE);
665: composite.setLayout(new GridLayout(2, false));
666: Display display = composite.getDisplay();
667: Color bgCol = display
668: .getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND);
669: composite.setBackground(bgCol);
670: Label label = new Label(composite, SWT.WRAP);
671: label.setForeground(display
672: .getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND));
673: label.setBackground(bgCol);
674: label.setFont(JFaceResources.getFontRegistry().getBold(
675: JFaceResources.DEFAULT_FONT));
676: String msg = IDEWorkbenchMessages.IDEWorkbenchAdvisor_noPerspective;
677: label.setText(msg);
678: ToolBarManager toolBarManager = new ToolBarManager();
679: // TODO: should obtain the open perspective action from ActionFactory
680: IAction openPerspectiveAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
681: .create(window);
682: toolBarManager.add(openPerspectiveAction);
683: ToolBar toolBar = toolBarManager.createControl(composite);
684: toolBar.setBackground(bgCol);
685: return composite;
686: }
687:
688: }
|