001: /*******************************************************************************
002: * Copyright (c) 2004, 2006 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.intro.impl.presentations;
011:
012: import org.eclipse.core.runtime.IRegistryChangeEvent;
013: import org.eclipse.jface.action.IToolBarManager;
014: import org.eclipse.jface.action.Separator;
015: import org.eclipse.swt.SWT;
016: import org.eclipse.swt.graphics.Color;
017: import org.eclipse.swt.graphics.Image;
018: import org.eclipse.swt.layout.GridData;
019: import org.eclipse.swt.layout.GridLayout;
020: import org.eclipse.swt.widgets.Composite;
021: import org.eclipse.ui.IActionBars;
022: import org.eclipse.ui.IPropertyListener;
023: import org.eclipse.ui.actions.ActionFactory;
024: import org.eclipse.ui.forms.HyperlinkSettings;
025: import org.eclipse.ui.forms.events.HyperlinkAdapter;
026: import org.eclipse.ui.forms.events.HyperlinkEvent;
027: import org.eclipse.ui.forms.widgets.Form;
028: import org.eclipse.ui.forms.widgets.FormToolkit;
029: import org.eclipse.ui.forms.widgets.Hyperlink;
030: import org.eclipse.ui.forms.widgets.ScrolledPageBook;
031: import org.eclipse.ui.internal.intro.impl.IntroPlugin;
032: import org.eclipse.ui.internal.intro.impl.Messages;
033: import org.eclipse.ui.internal.intro.impl.model.AbstractIntroPage;
034: import org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation;
035: import org.eclipse.ui.internal.intro.impl.model.History;
036: import org.eclipse.ui.internal.intro.impl.model.IntroHomePage;
037: import org.eclipse.ui.internal.intro.impl.model.IntroModelRoot;
038: import org.eclipse.ui.internal.intro.impl.model.loader.ContentProviderManager;
039: import org.eclipse.ui.internal.intro.impl.swt.PageForm;
040: import org.eclipse.ui.internal.intro.impl.swt.PageFormWithNavigation;
041: import org.eclipse.ui.internal.intro.impl.swt.PageStyleManager;
042: import org.eclipse.ui.internal.intro.impl.swt.RootPageForm;
043: import org.eclipse.ui.internal.intro.impl.swt.SharedStyleManager;
044: import org.eclipse.ui.internal.intro.impl.util.ImageUtil;
045: import org.eclipse.ui.internal.intro.impl.util.Util;
046: import org.eclipse.ui.intro.config.CustomizableIntroPart;
047: import org.eclipse.ui.intro.config.IIntroContentProvider;
048: import org.eclipse.ui.intro.config.IIntroContentProviderSite;
049: import org.eclipse.ui.intro.config.IntroConfigurer;
050:
051: /**
052: * This is a UI Forms based implementation of an Intro Part Presentation.
053: */
054: public class FormIntroPartImplementation extends
055: AbstractIntroPartImplementation implements
056: IIntroContentProviderSite, IPropertyListener {
057:
058: private FormToolkit toolkit;
059: private ScrolledPageBook mainPageBook;
060: private PageForm pageForm;
061: private PageFormWithNavigation pageFormWithNav;
062: // cache model instance for reuse.
063: private IntroModelRoot model = getModel();
064: private SharedStyleManager sharedStyleManager;
065:
066: // static SWT Intro. This is the link shown on the center of a page in a
067: // static SWT intro.
068: private Hyperlink welcomeLink;
069:
070: static {
071: // REVISIT: register all common images here. Even if this part
072: // implementation is created again, the images will remain in plugin
073: // registry.
074: ImageUtil.registerImage(ImageUtil.DEFAULT_ROOT_LINK,
075: "overview_48.gif"); //$NON-NLS-1$
076: ImageUtil.registerImage(ImageUtil.DEFAULT_SMALL_ROOT_LINK,
077: "overview_32.gif"); //$NON-NLS-1$
078: ImageUtil.registerImage(ImageUtil.DEFAULT_FORM_BG,
079: "form_banner.gif"); //$NON-NLS-1$
080: ImageUtil.registerImage(ImageUtil.DEFAULT_LINK,
081: "welcome_item.gif"); //$NON-NLS-1$
082: }
083:
084: protected void updateNavigationActionsState() {
085: if (getModel().isDynamic()) {
086: forwardAction.setEnabled(history.canNavigateForward());
087: backAction.setEnabled(history.canNavigateBackward());
088: return;
089: }
090: // no actions are added in static swt.
091: }
092:
093: public FormIntroPartImplementation() {
094: // Shared style manager
095: sharedStyleManager = new SharedStyleManager(getModel());
096: }
097:
098: public void createPartControl(Composite container) {
099: if (getModel().isDynamic())
100: dynamicCreatePartControl(container);
101: else {
102: staticCreatePartControl(container);
103: }
104: }
105:
106: /*
107: * create dynamic UI forms Intro, ie: swt intro.
108: */
109: private void dynamicCreatePartControl(Composite container) {
110: // Create single toolkit instance, which is disposed of on dispose of
111: // intro part. also define background of all presentation.
112: toolkit = new FormToolkit(container.getDisplay());
113: // Define presentation title color
114: Color bg = sharedStyleManager.getColor(toolkit, "bg"); //$NON-NLS-1$
115: if (bg != null) {
116: toolkit.setBackground(bg);
117: }
118: toolkit.getHyperlinkGroup().setHyperlinkUnderlineMode(
119: HyperlinkSettings.UNDERLINE_HOVER);
120:
121: // Define presentation title color and image.
122: Form mainForm = toolkit.createForm(container);
123: Color fg = sharedStyleManager.getColor(toolkit, "title.fg"); //$NON-NLS-1$
124: if (fg != null)
125: mainForm.setForeground(fg);
126: Image bgImage = sharedStyleManager.getImage(
127: "title.image", null, null); //$NON-NLS-1$
128: if (bgImage != null) {
129: mainForm.setBackgroundImage(bgImage);
130: String repeat = sharedStyleManager
131: .getProperty("title.image.repeat"); //$NON-NLS-1$
132: if (repeat != null && repeat.equalsIgnoreCase("true")) //$NON-NLS-1$
133:
134: mainForm.setBackgroundImageTiled(true);
135: }
136:
137: mainPageBook = createMainPageBook(toolkit, mainForm);
138: // Add this presentation as a listener to model.
139: getModel().addPropertyListener(this );
140:
141: addToolBarActions();
142: }
143:
144: /**
145: * The main page book that holds Intro pages. It has two pages, one that
146: * holds the home page, and one that holds all other pages. If the
147: * presentation is configured to not show the home page with the Home Page
148: * layout, then this page book will only have one page.
149: *
150: * @param toolkit
151: * @param form
152: * @return
153: */
154: private ScrolledPageBook createMainPageBook(FormToolkit toolkit,
155: Form form) {
156: // get body and create page book in it. Body has GridLayout.
157: Composite body = form.getBody();
158: body.setLayout(new GridLayout());
159: // make sure page book expands h and v.
160: ScrolledPageBook pageBook = toolkit.createPageBook(body,
161: SWT.V_SCROLL | SWT.H_SCROLL);
162: pageBook.setLayoutData(new GridData(GridData.FILL_BOTH));
163:
164: // Create root page in root page layout form, only if needed.
165: if (sharedStyleManager.useCustomHomePagelayout()) {
166: // if we do not have a root page form, create one
167: RootPageForm rootPageForm = new RootPageForm(toolkit,
168: model, form);
169: rootPageForm
170: .createPartControl(pageBook, sharedStyleManager);
171: rootPageForm.setContentProviderSite(this );
172: }
173:
174: // Create the two Page forms .
175: pageForm = new PageForm(toolkit, model, form);
176: pageForm.setContentProviderSite(this );
177: pageForm.createPartControl(pageBook, sharedStyleManager);
178:
179: pageFormWithNav = new PageFormWithNavigation(toolkit, model,
180: form);
181: pageFormWithNav.setContentProviderSite(this );
182: pageFormWithNav.createPartControl(pageBook, sharedStyleManager);
183:
184: // now determine which page to show. Show it and add it to history.
185: // if the cached page is a URL ignore it. We do not want to launch a
186: // browser on startup.
187: String cachedPage = getCachedCurrentPage();
188: if (cachedPage != null & !History.isURL(cachedPage))
189: // this will create the page in the page form.
190: model.setCurrentPageId(cachedPage);
191:
192: AbstractIntroPage pageToShow = getModel().getCurrentPage();
193: // load style manager here to test for navigation.
194: PageStyleManager styleManager = new PageStyleManager(
195: pageToShow, sharedStyleManager.getProperties());
196: boolean pageHasNavigation = styleManager
197: .showHomePageNavigation();
198: if (pageToShow != null) {
199: if (pageBook.hasPage(pageToShow.getId()))
200: // we are showing Home Page.
201: pageBook.showPage(pageToShow.getId());
202: else {
203: if (pageHasNavigation) {
204: // page or Home Page with a page layout and navigation, set
205: // the page id to the static PageFormWithNavigation id.
206: // first create the correct content.
207: pageFormWithNav.showPage(pageToShow,
208: sharedStyleManager);
209: // then show the page
210: pageBook
211: .showPage(PageFormWithNavigation.PAGE_FORM_WITH_NAVIGATION_ID);
212: } else {
213: // page or Home Page with a regular page layout, set the
214: // page id to the static PageForm id. first create the
215: // correct content.
216: pageForm.showPage(pageToShow, sharedStyleManager);
217: // then show the page
218: pageBook.showPage(PageForm.PAGE_FORM_ID);
219: }
220: }
221: updateHistory(pageToShow);
222: }
223:
224: return pageBook;
225: }
226:
227: public void dispose() {
228: if (toolkit != null)
229: toolkit.dispose();
230: }
231:
232: /**
233: * Handle model property changes. The UI is notified here of a change to the
234: * current page in the model. This happens if an intro URL showPage method
235: * is executed.
236: *
237: * @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object,
238: * int)
239: */
240: public void propertyChanged(Object source, int propId) {
241: if (propId == IntroModelRoot.CURRENT_PAGE_PROPERTY_ID) {
242: String pageId = getModel().getCurrentPageId();
243: if (pageId == null || pageId.equals("")) //$NON-NLS-1$
244: // If page ID was not set properly. exit.
245: return;
246:
247: showPage(getModel().getCurrentPage());
248: }
249: }
250:
251: protected void addToolBarActions() {
252: // Handle menus:
253: IActionBars actionBars = getIntroPart().getIntroSite()
254: .getActionBars();
255: IToolBarManager toolBarManager = actionBars.getToolBarManager();
256: actionBars.setGlobalActionHandler(
257: ActionFactory.FORWARD.getId(), forwardAction);
258: actionBars.setGlobalActionHandler(ActionFactory.BACK.getId(),
259: backAction);
260: toolBarManager.add(new Separator(IntroConfigurer.TB_ADDITIONS));
261: toolBarManager.add(homeAction);
262: toolBarManager.add(backAction);
263: toolBarManager.add(forwardAction);
264: toolBarManager.update(true);
265: actionBars.updateActionBars();
266: updateNavigationActionsState();
267: }
268:
269: protected void doStandbyStateChanged(boolean standby,
270: boolean isStandbyPartNeeded) {
271: if (getModel().isDynamic())
272: dynamicStandbyStateChanged(standby, isStandbyPartNeeded);
273: else
274: staticStandbyStateChanged(standby);
275: }
276:
277: public void dynamicStandbyStateChanged(boolean standby,
278: boolean isStandbyPartNeeded) {
279: // handle action enablement first
280: if (isStandbyPartNeeded | standby) {
281: homeAction.setEnabled(false);
282: forwardAction.setEnabled(false);
283: backAction.setEnabled(false);
284: } else {
285: homeAction.setEnabled(true);
286: updateNavigationActionsState();
287: }
288:
289: if (isStandbyPartNeeded)
290: // we have a standby part, nothing more to do in presentation.
291: return;
292:
293: // try to show a cached page.
294: AbstractIntroPage pageToShow = null;
295: if (standby) {
296: // we are in standby. Show standby page, in PageForm.
297: pageToShow = getModel().getStandbyPage();
298: if (pageToShow == null)
299: pageToShow = getModel().getHomePage();
300: } else
301: // if we are showing a regular intro page, or if the Home Page
302: // has a regular page layout, set the page id to the static PageForm
303: // id.
304: pageToShow = getModel().getCurrentPage();
305:
306: showPage(pageToShow);
307: }
308:
309: private boolean showPage(AbstractIntroPage pageToShow) {
310: boolean pageisCached = showCachedPage(pageToShow);
311:
312: if (!pageisCached) {
313: // page has not been shown before.
314: // load style manager here to test for navigation.
315: PageStyleManager styleManager = new PageStyleManager(
316: pageToShow, sharedStyleManager.getProperties());
317: boolean pageHasNavigation = styleManager
318: .showHomePageNavigation();
319: if (pageHasNavigation) {
320: // page or Home Page with a regular page layout, set the
321: // page id to the static PageFormWithNavigation id. first
322: // create the correct content.
323: pageFormWithNav
324: .showPage(pageToShow, sharedStyleManager);
325: // then show the page
326: mainPageBook
327: .showPage(PageFormWithNavigation.PAGE_FORM_WITH_NAVIGATION_ID);
328: } else {
329: // page or Home Page with a regular page layout, set the
330: // page id to the static PageFormWithNavigation id. first
331: // create the correct content.
332: pageForm.showPage(pageToShow, sharedStyleManager);
333: // then show the page
334: mainPageBook.showPage(PageForm.PAGE_FORM_ID);
335: }
336: }
337:
338: return true;
339: }
340:
341: private boolean showCachedPage(AbstractIntroPage page) {
342: String formPageId = null;
343: if (pageForm.hasPage(page.getId())) {
344: pageForm.showPage(page, sharedStyleManager);
345: formPageId = PageForm.PAGE_FORM_ID;
346: } else if (pageFormWithNav.hasPage(page.getId())) {
347: pageFormWithNav.showPage(page, sharedStyleManager);
348: formPageId = PageFormWithNavigation.PAGE_FORM_WITH_NAVIGATION_ID;
349: } else if (mainPageBook.hasPage(page.getId()))
350: formPageId = page.getId();
351: else
352: return false;
353:
354: mainPageBook.showPage(formPageId);
355: return true;
356: }
357:
358: private void removeCachedPage(AbstractIntroPage page) {
359: if (pageForm.hasPage(page.getId()))
360: pageForm.removePage(page.getId());
361: else if (pageFormWithNav.hasPage(page.getId()))
362: pageFormWithNav.removePage(page.getId());
363: else if (mainPageBook.hasPage(page.getId()))
364: mainPageBook.removePage(page.getId());
365: else
366: return;
367: }
368:
369: /**
370: * Clear page cache for the page that contains this provider. Remove the
371: * form from the correct pagebook that refers to the page we need to
372: * refresh. This will force a call to createContents on all content
373: * providers the next time this page needs to be displayed.
374: *
375: * @see org.eclipse.ui.intro.config.IIntroContentProviderSite#reflow(org.eclipse.ui.intro.config.IIntroContentProvider,
376: * boolean)
377: */
378: public void reflow(IIntroContentProvider provider,
379: boolean incremental) {
380: AbstractIntroPage page = ContentProviderManager.getInst()
381: .getContentProviderParentPage(provider);
382: if (incremental) {
383: if (pageForm.hasPage(page.getId()))
384: pageForm.reflow();
385: else if (pageFormWithNav.hasPage(page.getId()))
386: pageFormWithNav.reflow();
387: else if (mainPageBook.hasPage(page.getId()))
388: mainPageBook.reflow(true);
389: } else {
390: removeCachedPage(page);
391: showPage(model.getCurrentPage());
392: }
393: }
394:
395: public void setFocus() {
396: if (model.isDynamic()) {
397: if (mainPageBook.getCurrentPage() != null)
398: mainPageBook.getCurrentPage().setFocus();
399: }
400: }
401:
402: /*
403: * (non-Javadoc)
404: *
405: * @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation#navigateBackward()
406: */
407: public boolean navigateBackward() {
408: boolean success = false;
409: if (getModel().isDynamic()) {
410: // dynamic case. Uses navigation history.
411: if (history.canNavigateBackward()) {
412: history.navigateHistoryBackward();
413: if (history.currentLocationIsUrl())
414: success = Util.openBrowser(history
415: .getCurrentLocationAsUrl());
416: else {
417: // Set current page, and this will triger regen.
418: CustomizableIntroPart currentIntroPart = (CustomizableIntroPart) IntroPlugin
419: .getIntro();
420: currentIntroPart.getControl().setRedraw(false);
421: success = getModel().setCurrentPageId(
422: history.getCurrentLocationAsPage().getId());
423: currentIntroPart.getControl().setRedraw(true);
424: }
425: }
426: }
427:
428: updateNavigationActionsState();
429: return success;
430: }
431:
432: /*
433: * (non-Javadoc)
434: *
435: * @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation#navigateForward()
436: */
437: public boolean navigateForward() {
438: boolean success = false;
439:
440: if (getModel().isDynamic()) {
441: // dynamic case. Uses navigation history.
442: if (history.canNavigateForward()) {
443: history.navigateHistoryForward();
444: if (history.currentLocationIsUrl())
445: success = Util.openBrowser(history
446: .getCurrentLocationAsUrl());
447: else {
448: // Set current page, and this will triger regen.
449: CustomizableIntroPart currentIntroPart = (CustomizableIntroPart) IntroPlugin
450: .getIntro();
451: currentIntroPart.getControl().setRedraw(false);
452: success = getModel().setCurrentPageId(
453: history.getCurrentLocationAsPage().getId());
454: currentIntroPart.getControl().setRedraw(true);
455: }
456: }
457: }
458: updateNavigationActionsState();
459: return success;
460: }
461:
462: public boolean navigateHome() {
463: IntroHomePage rootPage = getModel().getHomePage();
464: if (getModel().isDynamic()) {
465: CustomizableIntroPart currentIntroPart = (CustomizableIntroPart) IntroPlugin
466: .getIntro();
467: currentIntroPart.getControl().setRedraw(false);
468: boolean success = false;
469: success = getModel().setCurrentPageId(rootPage.getId());
470: updateHistory(rootPage);
471: currentIntroPart.getControl().setRedraw(true);
472: return success;
473: }
474: // static model. Nothing to do.
475: return false;
476: }
477:
478: /*
479: * (non-Javadoc)
480: *
481: * @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation#handleRegistryChanged(org.eclipse.core.runtime.IRegistryChangeEvent)
482: */
483: protected void handleRegistryChanged(IRegistryChangeEvent event) {
484: if (getModel().isDynamic()) {
485: IntroPlugin.closeIntro();
486: IntroPlugin.showIntro(false);
487: }
488: }
489:
490: // *********** Static case ******************
491: /*
492: * create static UI forms Intro. For this, we only launch the url of the
493: * root page.
494: */
495: private void staticCreatePartControl(Composite parent) {
496: toolkit = new FormToolkit(parent.getDisplay());
497: toolkit.getHyperlinkGroup().setHyperlinkUnderlineMode(
498: HyperlinkSettings.UNDERLINE_HOVER);
499:
500: // create a page that has only one link. The URL and tooltip will be set
501: // by the standby listener.
502: welcomeLink = createStaticPage(parent);
503: }
504:
505: private Hyperlink createStaticPage(Composite parent) {
506: Form mainForm = toolkit.createForm(parent);
507: Composite body = mainForm.getBody();
508:
509: GridLayout gl = new GridLayout();
510: body.setLayout(gl);
511: String label = Messages.StaticHTML_welcome;
512: Hyperlink link = toolkit.createHyperlink(body, label, SWT.WRAP);
513: link.setFont(PageStyleManager.getHeaderFont());
514: GridData gd = new GridData(GridData.GRAB_HORIZONTAL
515: | GridData.GRAB_VERTICAL);
516: gd.horizontalAlignment = GridData.CENTER;
517: gd.verticalAlignment = GridData.CENTER;
518: link.setLayoutData(gd);
519: link.addHyperlinkListener(new HyperlinkAdapter() {
520:
521: public void linkActivated(HyperlinkEvent e) {
522: Hyperlink link = (Hyperlink) e.getSource();
523: Util.openBrowser((String) link.getHref());
524: return;
525: }
526: });
527:
528: return link;
529: }
530:
531: public void staticStandbyStateChanged(boolean standby) {
532: IntroHomePage homePage = getModel().getHomePage();
533: IntroHomePage standbyPage = getModel().getStandbyPage();
534: if (standbyPage == null)
535: standbyPage = homePage;
536:
537: if (standby) {
538: welcomeLink.setHref(standbyPage.getUrl());
539: welcomeLink.setToolTipText(standbyPage.getUrl());
540: } else {
541: welcomeLink.setHref(homePage.getUrl());
542: welcomeLink.setToolTipText(homePage.getUrl());
543: }
544: }
545:
546: }
|