/******************************************************************************* * Copyright (c) 2004, 2016 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.internal.intro.impl.presentations; import org.eclipse.core.runtime.IRegistryChangeEvent; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.Separator; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IPropertyListener; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.forms.HyperlinkSettings; import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Hyperlink; import org.eclipse.ui.forms.widgets.ScrolledPageBook; import org.eclipse.ui.internal.intro.impl.IntroPlugin; import org.eclipse.ui.internal.intro.impl.Messages; import org.eclipse.ui.internal.intro.impl.model.AbstractIntroPage; import org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation; import org.eclipse.ui.internal.intro.impl.model.History; import org.eclipse.ui.internal.intro.impl.model.IntroModelRoot; import org.eclipse.ui.internal.intro.impl.model.loader.ContentProviderManager; import org.eclipse.ui.internal.intro.impl.swt.PageForm; import org.eclipse.ui.internal.intro.impl.swt.PageFormWithNavigation; import org.eclipse.ui.internal.intro.impl.swt.PageStyleManager; import org.eclipse.ui.internal.intro.impl.swt.RootPageForm; import org.eclipse.ui.internal.intro.impl.swt.SharedStyleManager; import org.eclipse.ui.internal.intro.impl.util.ImageUtil; import org.eclipse.ui.internal.intro.impl.util.Util; import org.eclipse.ui.intro.config.CustomizableIntroPart; import org.eclipse.ui.intro.config.IIntroContentProvider; import org.eclipse.ui.intro.config.IIntroContentProviderSite; import org.eclipse.ui.intro.config.IntroConfigurer; /** * This is a UI Forms based implementation of an Intro Part Presentation. */ public class FormIntroPartImplementation extends AbstractIntroPartImplementation implements IIntroContentProviderSite, IPropertyListener { private FormToolkit toolkit; private ScrolledPageBook mainPageBook; private PageForm pageForm; private PageFormWithNavigation pageFormWithNav; // cache model instance for reuse. private IntroModelRoot model = getModel(); private SharedStyleManager sharedStyleManager; // static SWT Intro. This is the link shown on the center of a page in a // static SWT intro. private Hyperlink welcomeLink; static { // REVISIT: register all common images here. Even if this part // implementation is created again, the images will remain in plugin // registry. ImageUtil.registerImage(ImageUtil.DEFAULT_ROOT_LINK, "overview_48.png"); //$NON-NLS-1$ ImageUtil.registerImage(ImageUtil.DEFAULT_SMALL_ROOT_LINK, "overview_32.png"); //$NON-NLS-1$ ImageUtil.registerImage(ImageUtil.DEFAULT_FORM_BG, "form_banner.png"); //$NON-NLS-1$ ImageUtil.registerImage(ImageUtil.DEFAULT_LINK, "welcome_item.gif"); //$NON-NLS-1$ } @Override protected void updateNavigationActionsState() { if (getModel().isDynamic()) { forwardAction.setEnabled(history.canNavigateForward()); backAction.setEnabled(history.canNavigateBackward()); return; } // no actions are added in static swt. } public FormIntroPartImplementation() { // Shared style manager sharedStyleManager = new SharedStyleManager(getModel()); } @Override public void createPartControl(Composite container) { if (getModel().isDynamic()) dynamicCreatePartControl(container); else { staticCreatePartControl(container); } } /* * create dynamic UI forms Intro, ie: swt intro. */ private void dynamicCreatePartControl(Composite container) { // Create single toolkit instance, which is disposed of on dispose of // intro part. also define background of all presentation. toolkit = new FormToolkit(container.getDisplay()); // Define presentation title color Color bg = sharedStyleManager.getColor(toolkit, "bg"); //$NON-NLS-1$ if (bg != null) { toolkit.setBackground(bg); } toolkit.getHyperlinkGroup().setHyperlinkUnderlineMode( HyperlinkSettings.UNDERLINE_HOVER); // Define presentation title color and image. Form mainForm = toolkit.createForm(container); Color fg = sharedStyleManager.getColor(toolkit, "title.fg"); //$NON-NLS-1$ if (fg != null) mainForm.setForeground(fg); Image bgImage = sharedStyleManager.getImage("title.image", null, null); //$NON-NLS-1$ if (bgImage != null) { mainForm.setBackgroundImage(bgImage); String repeat = sharedStyleManager .getProperty("title.image.repeat"); //$NON-NLS-1$ if (repeat != null && repeat.equalsIgnoreCase("true")) //$NON-NLS-1$ mainForm.setBackgroundImageTiled(true); } mainPageBook = createMainPageBook(toolkit, mainForm); // Add this presentation as a listener to model. getModel().addPropertyListener(this); addToolBarActions(); } /** * The main page book that holds Intro pages. It has two pages, one that * holds the home page, and one that holds all other pages. If the * presentation is configured to not show the home page with the Home Page * layout, then this page book will only have one page. * * @param toolkit * @param form * @return */ private ScrolledPageBook createMainPageBook(FormToolkit toolkit, Form form) { // get body and create page book in it. Body has GridLayout. Composite body = form.getBody(); body.setLayout(new GridLayout()); // make sure page book expands h and v. ScrolledPageBook pageBook = toolkit.createPageBook(body, SWT.V_SCROLL | SWT.H_SCROLL); pageBook.setLayoutData(new GridData(GridData.FILL_BOTH)); // Create root page in root page layout form, only if needed. if (sharedStyleManager.useCustomHomePagelayout()) { // if we do not have a root page form, create one RootPageForm rootPageForm = new RootPageForm(toolkit, model, form); rootPageForm.createPartControl(pageBook, sharedStyleManager); rootPageForm.setContentProviderSite(this); } // Create the two Page forms . pageForm = new PageForm(toolkit, model, form); pageForm.setContentProviderSite(this); pageForm.createPartControl(pageBook, sharedStyleManager); pageFormWithNav = new PageFormWithNavigation(toolkit, model, form); pageFormWithNav.setContentProviderSite(this); pageFormWithNav.createPartControl(pageBook, sharedStyleManager); // now determine which page to show. Show it and add it to history. // if the cached page is a URL ignore it. We do not want to launch a // browser on startup. String cachedPage = getCachedCurrentPage(); if (cachedPage != null & !History.isURL(cachedPage)) // this will create the page in the page form. model.setCurrentPageId(cachedPage); AbstractIntroPage pageToShow = getModel().getCurrentPage(); // load style manager here to test for navigation. PageStyleManager styleManager = new PageStyleManager(pageToShow, sharedStyleManager.getProperties()); boolean pageHasNavigation = styleManager.showHomePageNavigation(); if (pageToShow != null) { if (pageBook.hasPage(pageToShow.getId())) // we are showing Home Page. pageBook.showPage(pageToShow.getId()); else { if (pageHasNavigation) { // page or Home Page with a page layout and navigation, set // the page id to the static PageFormWithNavigation id. // first create the correct content. pageFormWithNav.showPage(pageToShow, sharedStyleManager); // then show the page pageBook .showPage(PageFormWithNavigation.PAGE_FORM_WITH_NAVIGATION_ID); } else { // page or Home Page with a regular page layout, set the // page id to the static PageForm id. first create the // correct content. pageForm.showPage(pageToShow, sharedStyleManager); // then show the page pageBook.showPage(PageForm.PAGE_FORM_ID); } } updateHistory(pageToShow); } return pageBook; } @Override public void dispose() { if (toolkit != null) toolkit.dispose(); } /** * Handle model property changes. The UI is notified here of a change to the * current page in the model. This happens if an intro URL showPage method * is executed. * * @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object, * int) */ @Override public void propertyChanged(Object source, int propId) { if (propId == IntroModelRoot.CURRENT_PAGE_PROPERTY_ID) { String pageId = getModel().getCurrentPageId(); if (pageId == null || pageId.equals("")) //$NON-NLS-1$ // If page ID was not set properly. exit. return; showPage(getModel().getCurrentPage()); } } @Override protected void addToolBarActions() { // Handle menus: IActionBars actionBars = getIntroPart().getIntroSite().getActionBars(); IToolBarManager toolBarManager = actionBars.getToolBarManager(); actionBars.setGlobalActionHandler(ActionFactory.FORWARD.getId(), forwardAction); actionBars.setGlobalActionHandler(ActionFactory.BACK.getId(), backAction); toolBarManager.add(new Separator(IntroConfigurer.TB_ADDITIONS)); toolBarManager.add(homeAction); toolBarManager.add(backAction); toolBarManager.add(forwardAction); if (IntroPlugin.DEBUG_TOOLBAR) { toolBarManager.add(viewIntroModelAction); } toolBarManager.update(true); actionBars.updateActionBars(); updateNavigationActionsState(); } @Override protected void doStandbyStateChanged(boolean standby, boolean isStandbyPartNeeded) { if (getModel().isDynamic()) dynamicStandbyStateChanged(standby, isStandbyPartNeeded); else staticStandbyStateChanged(standby); } public void dynamicStandbyStateChanged(boolean standby, boolean isStandbyPartNeeded) { // handle action enablement first if (isStandbyPartNeeded | standby) { homeAction.setEnabled(false); forwardAction.setEnabled(false); backAction.setEnabled(false); } else { homeAction.setEnabled(true); updateNavigationActionsState(); } if (isStandbyPartNeeded) // we have a standby part, nothing more to do in presentation. return; // try to show a cached page. AbstractIntroPage pageToShow = null; if (standby) { // we are in standby. Show standby page, in PageForm. pageToShow = getModel().getStandbyPage(); if (pageToShow == null) pageToShow = getModel().getHomePage(); } else // if we are showing a regular intro page, or if the Home Page // has a regular page layout, set the page id to the static PageForm // id. pageToShow = getModel().getCurrentPage(); showPage(pageToShow); } private boolean showPage(AbstractIntroPage pageToShow) { boolean pageisCached = showCachedPage(pageToShow); if (!pageToShow.isDynamic()) { Util.openBrowser((String) pageToShow.getUrl()); return true; } if (!pageisCached) { // page has not been shown before. // load style manager here to test for navigation. PageStyleManager styleManager = new PageStyleManager(pageToShow, sharedStyleManager.getProperties()); boolean pageHasNavigation = styleManager.showHomePageNavigation(); if (pageHasNavigation) { // page or Home Page with a regular page layout, set the // page id to the static PageFormWithNavigation id. first // create the correct content. pageFormWithNav.showPage(pageToShow, sharedStyleManager); // then show the page mainPageBook .showPage(PageFormWithNavigation.PAGE_FORM_WITH_NAVIGATION_ID); } else { // page or Home Page with a regular page layout, set the // page id to the static PageFormWithNavigation id. first // create the correct content. pageForm.showPage(pageToShow, sharedStyleManager); // then show the page mainPageBook.showPage(PageForm.PAGE_FORM_ID); } } return true; } private boolean showCachedPage(AbstractIntroPage page) { String formPageId = null; if (pageForm.hasPage(page.getId())) { pageForm.showPage(page, sharedStyleManager); formPageId = PageForm.PAGE_FORM_ID; } else if (pageFormWithNav.hasPage(page.getId())) { pageFormWithNav.showPage(page, sharedStyleManager); formPageId = PageFormWithNavigation.PAGE_FORM_WITH_NAVIGATION_ID; } else if (mainPageBook.hasPage(page.getId())) formPageId = page.getId(); else return false; mainPageBook.showPage(formPageId); return true; } private void removeCachedPage(AbstractIntroPage page) { if (pageForm.hasPage(page.getId())) pageForm.removePage(page.getId()); else if (pageFormWithNav.hasPage(page.getId())) pageFormWithNav.removePage(page.getId()); else if (mainPageBook.hasPage(page.getId())) mainPageBook.removePage(page.getId()); else return; } /** * Clear page cache for the page that contains this provider. Remove the * form from the correct pagebook that refers to the page we need to * refresh. This will force a call to createContents on all content * providers the next time this page needs to be displayed. * * @see org.eclipse.ui.intro.config.IIntroContentProviderSite#reflow(org.eclipse.ui.intro.config.IIntroContentProvider, * boolean) */ @Override public void reflow(IIntroContentProvider provider, boolean incremental) { AbstractIntroPage page = ContentProviderManager.getInst() .getContentProviderParentPage(provider); if (incremental) { if (pageForm.hasPage(page.getId())) pageForm.reflow(); else if (pageFormWithNav.hasPage(page.getId())) pageFormWithNav.reflow(); else if (mainPageBook.hasPage(page.getId())) mainPageBook.reflow(true); } else { removeCachedPage(page); showPage(model.getCurrentPage()); } } @Override public void setFocus() { if (model.isDynamic()) { if (mainPageBook.getCurrentPage() != null) mainPageBook.getCurrentPage().setFocus(); } } @Override public boolean navigateBackward() { boolean success = false; if (getModel().isDynamic()) { // dynamic case. Uses navigation history. if (history.canNavigateBackward()) { history.navigateHistoryBackward(); if (history.currentLocationIsUrl()) success = Util.openBrowser(history .getCurrentLocationAsUrl()); else { // Set current page, and this will triger regen. CustomizableIntroPart currentIntroPart = (CustomizableIntroPart) IntroPlugin .getIntro(); currentIntroPart.getControl().setRedraw(false); success = getModel().setCurrentPageId( history.getCurrentLocationAsPage().getId()); currentIntroPart.getControl().setRedraw(true); } } } updateNavigationActionsState(); return success; } @Override public boolean navigateForward() { boolean success = false; if (getModel().isDynamic()) { // dynamic case. Uses navigation history. if (history.canNavigateForward()) { history.navigateHistoryForward(); if (history.currentLocationIsUrl()) success = Util.openBrowser(history .getCurrentLocationAsUrl()); else { // Set current page, and this will triger regen. CustomizableIntroPart currentIntroPart = (CustomizableIntroPart) IntroPlugin .getIntro(); currentIntroPart.getControl().setRedraw(false); success = getModel().setCurrentPageId( history.getCurrentLocationAsPage().getId()); currentIntroPart.getControl().setRedraw(true); } } } updateNavigationActionsState(); return success; } @Override public boolean navigateHome() { AbstractIntroPage homePage = getModel().getHomePage(); if (getModel().isDynamic()) { CustomizableIntroPart currentIntroPart = (CustomizableIntroPart) IntroPlugin .getIntro(); currentIntroPart.getControl().setRedraw(false); boolean success = false; success = getModel().setCurrentPageId(homePage.getId()); updateHistory(homePage); currentIntroPart.getControl().setRedraw(true); return success; } // static model. Nothing to do. return false; } @Override protected void handleRegistryChanged(IRegistryChangeEvent event) { if (getModel().isDynamic()) { IntroPlugin.closeIntro(); IntroPlugin.showIntro(false); } } // *********** Static case ****************** /* * create static UI forms Intro. For this, we only launch the url of the * root page. */ private void staticCreatePartControl(Composite parent) { toolkit = new FormToolkit(parent.getDisplay()); toolkit.getHyperlinkGroup().setHyperlinkUnderlineMode( HyperlinkSettings.UNDERLINE_HOVER); // create a page that has only one link. The URL and tooltip will be set // by the standby listener. welcomeLink = createStaticPage(parent); } private Hyperlink createStaticPage(Composite parent) { Form mainForm = toolkit.createForm(parent); Composite body = mainForm.getBody(); GridLayout gl = new GridLayout(); body.setLayout(gl); String label = Messages.StaticHTML_welcome; Hyperlink link = toolkit.createHyperlink(body, label, SWT.WRAP); link.setFont(PageStyleManager.getHeaderFont()); GridData gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL); gd.horizontalAlignment = GridData.CENTER; gd.verticalAlignment = GridData.CENTER; link.setLayoutData(gd); link.addHyperlinkListener(new HyperlinkAdapter() { @Override public void linkActivated(HyperlinkEvent e) { Hyperlink link = (Hyperlink) e.getSource(); Util.openBrowser((String) link.getHref()); return; } }); return link; } public void staticStandbyStateChanged(boolean standby) { AbstractIntroPage homePage = getModel().getHomePage(); AbstractIntroPage standbyPage = getModel().getStandbyPage(); if (standbyPage == null) standbyPage = homePage; if (standby) { welcomeLink.setHref(standbyPage.getUrl()); welcomeLink.setToolTipText(standbyPage.getUrl()); } else { welcomeLink.setHref(homePage.getUrl()); welcomeLink.setToolTipText(homePage.getUrl()); } } }