blob: 3bd213d4f58d47a929011518142f0b005267f8ad [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2017 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* 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(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());
}
}
}