blob: 970777896c47611e6ab88d52870a93c767eed088 [file] [log] [blame]
/*******************************************************************************
* 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 java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;
import java.util.Properties;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationAdapter;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.internal.intro.impl.FontSelection;
import org.eclipse.ui.internal.intro.impl.IIntroConstants;
import org.eclipse.ui.internal.intro.impl.IntroPlugin;
import org.eclipse.ui.internal.intro.impl.Messages;
import org.eclipse.ui.internal.intro.impl.html.HTMLElement;
import org.eclipse.ui.internal.intro.impl.html.IIntroHTMLConstants;
import org.eclipse.ui.internal.intro.impl.html.IntroHTMLGenerator;
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.IntroContentProvider;
import org.eclipse.ui.internal.intro.impl.model.IntroModelRoot;
import org.eclipse.ui.internal.intro.impl.model.IntroTheme;
import org.eclipse.ui.internal.intro.impl.model.loader.ContentProviderManager;
import org.eclipse.ui.internal.intro.impl.model.loader.IntroContentParser;
import org.eclipse.ui.internal.intro.impl.model.util.ModelUtil;
import org.eclipse.ui.internal.intro.impl.util.ImageUtil;
import org.eclipse.ui.internal.intro.impl.util.Log;
import org.eclipse.ui.internal.intro.impl.util.Util;
import org.eclipse.ui.intro.IIntroManager;
import org.eclipse.ui.intro.IIntroPart;
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.IIntroURL;
import org.eclipse.ui.intro.config.IIntroXHTMLContentProvider;
import org.eclipse.ui.intro.config.IntroConfigurer;
import org.eclipse.ui.intro.config.IntroURLFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class BrowserIntroPartImplementation extends
AbstractIntroPartImplementation implements IPropertyListener,
IIntroContentProviderSite {
private final class ReduceAction extends Action {
{
setToolTipText(Messages.Browser_reduce_tooltip);
setImageDescriptor(ImageUtil
.createImageDescriptor("full/elcl16/reduce_font.gif")); //$NON-NLS-1$
setDisabledImageDescriptor(ImageUtil
.createImageDescriptor("full/dlcl16/reduce_font.gif")); //$NON-NLS-1$
int scalePercent = FontSelection.getScalePercentage();
setEnabled(scalePercent > -40);
}
@Override
public void run() {
int scalePercent = FontSelection.getScalePercentage();
FontSelection.setScalePercentage(scalePercent - 20);
restartIntro();
}
}
private final class MagnifyAction extends Action {
{
setToolTipText(Messages.Browser_magnify_tooltip);
setImageDescriptor(ImageUtil
.createImageDescriptor("full/elcl16/magnify_font.gif")); //$NON-NLS-1$
setDisabledImageDescriptor(ImageUtil
.createImageDescriptor("full/dlcl16/magnify_font.gif")); //$NON-NLS-1$
int scalePercent = FontSelection.getScalePercentage();
setEnabled(scalePercent < 100);
}
@Override
public void run() {
int scalePercent = FontSelection.getScalePercentage();
FontSelection.setScalePercentage(scalePercent + SCALE_INCREMENT);
restartIntro();
}
}
private static final int SCALE_INCREMENT = 20;
// the browser widget that will display the intro content
protected Browser browser = null;
// the HTML generator used to generate dynamic content
private IntroHTMLGenerator htmlGenerator = null;
private String savedContent = null;
private Action openBrowserAction = new Action() {
{
setToolTipText(Messages.IntroPart_openExternal_tooltip);
setImageDescriptor(ImageUtil
.createImageDescriptor("topic.gif")); //$NON-NLS-1$
}
@Override
public void run() {
// Save the html to a file and open it in an external browser
File tempFile;
try {
tempFile = File.createTempFile("intro",".html"); //$NON-NLS-1$//$NON-NLS-2$
tempFile.deleteOnExit();
BufferedWriter out = new BufferedWriter(new
FileWriter(tempFile));
out.write(savedContent);
out.close();
IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
IWebBrowser browser = support.getExternalBrowser();
browser.openURL(tempFile.toURI().toURL());
} catch (IOException e) {
} catch (PartInitException e) {
}
}
};
private void restartIntro() {
IIntroManager manager = PlatformUI.getWorkbench().getIntroManager();
IIntroPart part = manager.getIntro();
if (part != null && part instanceof CustomizableIntroPart) {
IntroModelRoot modelRoot = IntroPlugin.getDefault().getIntroModelRoot();
String currentPageId = modelRoot.getCurrentPageId();
IWorkbenchWindow window = part.getIntroSite().getWorkbenchWindow();
boolean standby = manager.isIntroStandby(part);
PlatformUI.getWorkbench().getIntroManager().closeIntro(part);
IntroPlugin.getDefault().resetVolatileImageRegistry();
part = PlatformUI.getWorkbench().getIntroManager().showIntro(window, standby);
if (part != null && !standby) {
StringBuffer url = new StringBuffer();
url.append("http://org.eclipse.ui.intro/showPage?id="); //$NON-NLS-1$
url.append(currentPageId);
IIntroURL introURL = IntroURLFactory.createIntroURL(url.toString());
if (introURL != null)
introURL.execute();
}
}
}
protected BrowserIntroPartLocationListener urlListener = new BrowserIntroPartLocationListener(
this);
// internal performance test hook
private boolean isFinishedLoading;
private boolean resizeActionsAdded = false;
@Override
protected void updateNavigationActionsState() {
if (getModel().isDynamic()) {
forwardAction.setEnabled(history.canNavigateForward());
backAction.setEnabled(history.canNavigateBackward());
return;
}
// in static html intro, use browser history.
forwardAction.setEnabled(browser.isForwardEnabled());
backAction.setEnabled(browser.isBackEnabled());
}
/**
* create the browser and set it's contents
*/
@Override
public void createPartControl(Composite parent) {
long start = 0;
if (Log.logPerformance)
start = System.currentTimeMillis();
browser = new Browser(parent, SWT.NONE);
// add a location listener on the browser so we can intercept
// LocationEvents. Responsible for intercepting URLs and updating UI
// with history.
browser.addLocationListener(urlListener);
// add a location listener that will clear a flag at the end of any
// navigation to a page. This is used in conjunction with the location
// listener to filter out redundant navigations due to frames.
browser.addProgressListener(new ProgressListener() {
@Override
public void changed(ProgressEvent event) {
// no-op
}
@Override
public void completed(ProgressEvent event) {
urlListener.flagEndOfNavigation();
urlListener.flagEndOfFrameNavigation();
urlListener.flagRemovedTempUrl();
if (!getModel().isDynamic())
updateNavigationActionsState();
}
});
// Enable IE pop-up menu only in debug mode.
browser.addListener(SWT.MenuDetect, event -> {
if (IntroPlugin.getDefault().isDebugging())
event.doit = true;
else
event.doit = false;
});
// if we are logging performance, log actual UI creation time for
// browser.
if (Log.logPerformance)
Util.logPerformanceTime("creating a new Browser() took:", start); //$NON-NLS-1$
addToolBarActions();
if (!getModel().hasValidConfig()) {
browser.setText(Messages.Browser_invalidConfig);
return;
}
// root page is what decides if the model is dynamic or not.
if (getModel().isDynamic())
handleDynamicIntro();
else
handleStaticIntro();
}
private void handleDynamicIntro() {
AbstractIntroPage homePage = getModel().getHomePage();
// check cache state, and populate url page if needed.
String cachedPage = getCachedCurrentPage();
if (cachedPage != null) {
// we have a cached state. handle appropriately
if (History.isURL(cachedPage)) {
// set the URL the browser should display
boolean success = browser.setUrl(cachedPage);
if (!success) {
Log.error("Unable to set the following ULR in browser: " //$NON-NLS-1$
+ cachedPage, null);
return;
}
history.updateHistory(cachedPage);
} else {
// Generate HTML for the cached page, and set it on the browser.
getModel().setCurrentPageId(cachedPage, false);
// generateDynamicContentForPage(getModel().getCurrentPage());
history.updateHistory(getModel().getCurrentPage());
}
} else {
// No cached page. Generate HTML for the home page, and set it
// on the browser.
// generateDynamicContentForPage(homePage);
history.updateHistory(homePage);
}
// INTRO: all setText calls above are commented out because calling
// setText twice causes problems. revisit when swt bug is fixed.
// Add this presentation as a listener to model
// only in dynamic case, for now.
getModel().addPropertyListener(this);
}
/**
* Generate dynamic HTML for the provided page, and set it in the browser
* widget. A cache is used for performance and for having a correct dynamic
* content life cycle. This method also updates the navigation history.
*
* @param page
* the page to generate HTML for
*/
private boolean generateContentForPage(AbstractIntroPage page) {
String content = null;
if (!page.isDynamic()) {
browser.setUrl(page.getUrl());
return true;
}
if (page.isXHTMLPage())
content = generateXHTMLPage(page, this);
else {
HTMLElement html = getHTMLGenerator().generateHTMLforPage(page,
this);
if (html != null) {
IntroModelRoot root = getModel();
if (root!=null) {
IntroTheme theme = root.getTheme();
Map props = theme!=null?theme.getProperties():null;
if (props!=null) {
String value = (String)props.get("standardSupport"); //$NON-NLS-1$
String doctype=null;
if ("html5".equalsIgnoreCase(value)) //$NON-NLS-1$
doctype = "<!DOCTYPE html>\n"; //$NON-NLS-1$
else if ("strict".equalsIgnoreCase(value)) //$NON-NLS-1$
doctype = generateDoctype(true);
else if ("loose".equalsIgnoreCase(value)) //$NON-NLS-1$
doctype = generateDoctype(false);
if (doctype!=null)
content = doctype+html.toString();
}
}
if (content==null)
content = html.toString();
}
}
if (content == null) {
// there was an error generating the html. log an error
Log.error("Error generating HTML content for page", null); //$NON-NLS-1$
return false;
}
// set the browser's HTML.
boolean success = false;
if (browser != null) {
long start = 0;
if (Log.logPerformance)
start = System.currentTimeMillis();
browser.addLocationListener(new LocationAdapter() {
@Override
public void changed(LocationEvent event) {
if (event.top) {
isFinishedLoading = true;
}
}
});
success = browser.setText(content);
if (Log.logPerformance)
Util
.logPerformanceTime("setText() on the browser took:", start); //$NON-NLS-1$
if (!success)
Log.error("Unable to set HTML on the browser", null); //$NON-NLS-1$
}
// print the HTML if we are in debug mode and have tracing turned on
if (IntroPlugin.getDefault().isDebugging()) {
String printHtml = Platform
.getDebugOption("org.eclipse.ui.intro/trace/printHTML"); //$NON-NLS-1$
if (printHtml != null && printHtml.equalsIgnoreCase("true")) { //$NON-NLS-1$
System.out.println(content);
}
if (IntroPlugin.DEBUG_TOOLBAR) {
savedContent = content;
}
}
return success;
}
/**
* Generate an XHTML page as a string.
* <ul>
* <li> Create any dynamic content providers, if there are any. We do this
* by replacing each content provider with a div with the same id. The div
* is the parent of the dynamic content.</li>
* <li>Use xslt to flatten the DOM for the page, and create a string.</li>
* <li>Re-inject the contentProviders into the DOM to recreate the original
* state of the DOM. DOM could not have been cloned since cloning a DOM
* removes the docType.</li>
* </ul>
* Note: Resolving dynamic content is done at the UI level, consistant with
* SWT presentation.
*/
public String generateXHTMLPage(AbstractIntroPage page,
IIntroContentProviderSite site) {
// get/cache all content provider elements in DOM.
Document dom = page.getResolvedDocument();
NodeList nodes = dom.getElementsByTagNameNS("*", //$NON-NLS-1$
IntroContentProvider.TAG_CONTENT_PROVIDER);
// get the array version of the nodelist to work around DOM api design.
Node[] contentProviderElements = ModelUtil.getArray(nodes);
// this modifies the DOM.
resolveDynamicContent(page, site);
String content = IntroContentParser.convertToString(dom);
// this restores the DOM to its original state.
reinjectDynamicContent(dom, contentProviderElements);
return content;
}
private String generateDoctype(boolean strict) {
StringWriter swriter = new StringWriter();
PrintWriter writer = new PrintWriter(swriter);
if (strict) {
writer.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\""); //$NON-NLS-1$
writer.println("\t\t\t\"http://www.w3.org/TR/html4/strict.dtd\">"); //$NON-NLS-1$
}
else {
writer.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\""); //$NON-NLS-1$
writer.println("\t\t\t\"http://www.w3.org/TR/html4/loose.dtd\">"); //$NON-NLS-1$
}
writer.close();
return swriter.toString();
}
/**
* Resolve the dynamic content in the page. Resolving dynamic content will
* alter the original page DOM. Dynamic content tags are removed once
* resolved to have clean xhtml.
*/
private Document resolveDynamicContent(AbstractIntroPage page,
IIntroContentProviderSite site) {
Document dom = page.getResolvedDocument();
// get all content provider elements in DOM.
NodeList contentProviders = dom.getElementsByTagNameNS("*", //$NON-NLS-1$
IntroContentProvider.TAG_CONTENT_PROVIDER);
// get the array version of the nodelist to work around DOM api design.
Node[] nodes = ModelUtil.getArray(contentProviders);
for (int i = 0; i < nodes.length; i++) {
Element contentProviderElement = (Element) nodes[i];
IntroContentProvider provider = new IntroContentProvider(
contentProviderElement, page.getBundle());
provider.setParent(page);
// If we've already loaded the content provider for this element,
// retrieve it, otherwise load the class.
IIntroXHTMLContentProvider providerClass = (IIntroXHTMLContentProvider) ContentProviderManager
.getInst().getContentProvider(provider);
if (providerClass == null)
// content provider never created before, create it.
providerClass = (IIntroXHTMLContentProvider) ContentProviderManager
.getInst().createContentProvider(provider, site);
if (providerClass != null) {
// create a div with the same id as the contentProvider, pass it
// as the parent to create the specialized content, and then
// replace the contentProvider element with this div.
Properties att = new Properties();
att.setProperty(IIntroHTMLConstants.ATTRIBUTE_ID, provider
.getId());
Element contentDiv = ModelUtil.createElement(dom,
ModelUtil.TAG_DIV, att);
providerClass.createContent(provider.getId(), contentDiv);
contentProviderElement.getParentNode().replaceChild(contentDiv,
contentProviderElement);
} else {
// we couldn't load the content provider, so add any alternate
// text content if there is any.
// INTRO: do it. 3.0 intro content style uses text element as
// alt text. We can load XHTML content here.
}
}
return dom;
}
private void reinjectDynamicContent(Document dom,
Node[] contentProviderElements) {
for (int i = 0; i < contentProviderElements.length; i++) {
// for each cached contentProvider, find replacement div in DOM and
// re-subsitute.
Element contentProviderElement = (Element) contentProviderElements[i];
Element contentProviderDiv = ModelUtil.getElementById(dom,
contentProviderElement
.getAttribute(IIntroHTMLConstants.ATTRIBUTE_ID),
ModelUtil.TAG_DIV);
contentProviderDiv.getParentNode().replaceChild(
contentProviderElement, contentProviderDiv);
}
}
/**
* Return the cached IntroHTMLGenerator
*
* @return
*/
private IntroHTMLGenerator getHTMLGenerator() {
if (htmlGenerator == null)
htmlGenerator = new IntroHTMLGenerator();
return htmlGenerator;
}
@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);
if (IntroPlugin.DEBUG_TOOLBAR) {
toolBarManager.add(viewIntroModelAction);
toolBarManager.add(openBrowserAction);
}
toolBarManager.add(new Separator(IntroConfigurer.TB_ADDITIONS));
toolBarManager.add(homeAction);
toolBarManager.add(backAction);
toolBarManager.add(forwardAction);
toolBarManager.update(true);
IntroTheme theme = getModel().getTheme();
boolean createZoomButtons = theme != null && theme.isScalable() && !resizeActionsAdded
&&FontSelection.FONT_RELATIVE.equals(FontSelection.getFontStyle());
if (createZoomButtons) {
toolBarManager.add(new ReduceAction());
toolBarManager.add(new MagnifyAction());
}
actionBars.updateActionBars();
updateNavigationActionsState();
}
public void dynamicStandbyStateChanged(boolean standby,
boolean isStandbyPartNeeded) {
if (isStandbyPartNeeded)
// we have a standby part, nothing more to do in presentation.
return;
if (history.currentLocationIsUrl())
// last page disaplyed was a url. It is already set in the browser
// and stored in history. Nothing more to do.
return;
// presentation is shown here. toggle standby page. No need to update
// history here.
IntroModelRoot model = getModel();
AbstractIntroPage homePage = model.getHomePage();
AbstractIntroPage standbyPage = model.getStandbyPage();
if (standbyPage == null)
standbyPage = homePage;
if (standby) {
generateContentForPage(standbyPage);
} else {
// REVISIT: If cached page is the standby page and we are not
// initially in standby mode, it means standby was forced on
// intro view on close. react.
AbstractIntroPage currentPage = model.getCurrentPage();
if (currentPage == null || standbyPage.getId().equals(currentPage)) {
model.setCurrentPageId(model.getHomePage().getId());
}
generateContentForPage(currentPage);
}
}
/**
* Handle model property changes. Property listeners are only added in the
* dynamic case.
*
* @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$
// page ID was not set properly. exit.
return;
// update the presentation's content based on the model changes
updateContent();
}
}
@Override
public void setFocus() {
browser.setFocus();
}
@Override
public void dispose() {
browser.dispose();
}
/**
* Regenerate the dynamic content for the current page
*/
protected void updateContent() {
generateContentForPage(getModel().getCurrentPage());
}
/**
*
* @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation#reflow()
*/
@Override
public void reflow(IIntroContentProvider provider, boolean incremental) {
updateContent();
}
/**
* Override parent behavior to handle the case when we have a static page.
* This can happen in both the static intro case, or in the dynamic when the
* last visited page is the dynamic browser is an http: page, and not an
* intro page.
*/
@Override
protected void saveCurrentPage(IMemento memento) {
if (memento == null)
return;
// Handle the case where we are on a static page.
// browser.getURL() returns the empty string if there is no current URL
// and returns "about:blank" if we are on a dynamic page
if (browser != null && browser.getUrl() != null
&& browser.getUrl().length() > 0
&& !(browser.getUrl().equals("about:blank")) //$NON-NLS-1$
&& !(browser.getUrl().equals("file:///"))) { //$NON-NLS-1$
String currentURL = browser.getUrl();
if (currentURL != null) {
memento.putString(IIntroConstants.MEMENTO_CURRENT_PAGE_ATT,
currentURL);
}
} else {
super.saveCurrentPage(memento);
}
}
@Override
public boolean navigateBackward() {
boolean success = false;
if (getModel().isDynamic()) {
// dynamic case. Uses navigation history.
if (history.canNavigateBackward()) {
history.navigateHistoryBackward();
// guard against unnecessary History updates.
urlListener.flagStartOfNavigation();
if (history.currentLocationIsUrl()) {
success = browser.setUrl(history.getCurrentLocationAsUrl());
} else {
// we need to regen HTML. We can not use setting current
// page to trigger regen for one case: navigating back from
// a url will not trigger regen since current page would be
// the same.
AbstractIntroPage page = history.getCurrentLocationAsPage();
getModel().setCurrentPageId(page.getId(), false);
success = generateContentForPage(page);
}
} else
success = false;
// update history only in dynamic case.
updateNavigationActionsState();
} else
// static HTML case. use browser real Back.
success = browser.back();
return success;
}
@Override
public boolean navigateForward() {
boolean success = false;
if (getModel().isDynamic()) {
// dynamic case. Uses navigation history.
if (history.canNavigateForward()) {
history.navigateHistoryForward();
// guard against unnecessary History updates.
urlListener.flagStartOfNavigation();
if (history.currentLocationIsUrl()) {
success = browser.setUrl(history.getCurrentLocationAsUrl());
} else {
AbstractIntroPage page = history.getCurrentLocationAsPage();
getModel().setCurrentPageId(page.getId(), false);
success = generateContentForPage(page);
}
} else
success = false;
// update history only in dynamic case.
updateNavigationActionsState();
} else
// static HTML case. use browser real Forward.
success = browser.forward();
return success;
}
@Override
public boolean navigateHome() {
// Home is URL of root page in static case, and root page in
// dynamic.
AbstractIntroPage rootPage = getModel().getHomePage();
boolean success = false;
if (getModel().isDynamic()) {
// special case for when workbench is started with a cached URL. We
// set the url in the browser, but current page is Home Page, and so
// setting the root page will not fire an event. So, force a
// generation
// of root page.
if (history.currentLocationIsUrl())
generateContentForPage(rootPage);
success = getModel().setCurrentPageId(rootPage.getId());
updateHistory(rootPage);
} else {
String location = rootPage.getUrl();
success = browser.setUrl(location);
updateHistory(location);
}
return success;
}
@Override
protected void handleRegistryChanged(IRegistryChangeEvent event) {
if (getModel().isDynamic()) {
// null generator first.
htmlGenerator = null;
// Add this presentation as a listener to model only in dynamic
// case.
getModel().addPropertyListener(this);
getModel().firePropertyChange(
IntroModelRoot.CURRENT_PAGE_PROPERTY_ID);
}
}
@Override
protected void doStandbyStateChanged(boolean standby,
boolean isStandbyPartNeeded) {
// if we have a standby part, regardless if standby state, disable
// actions. Same behavior for static html.
if (isStandbyPartNeeded | standby) {
homeAction.setEnabled(false);
forwardAction.setEnabled(false);
backAction.setEnabled(false);
} else {
homeAction.setEnabled(true);
updateNavigationActionsState();
}
if (getModel().isDynamic())
dynamicStandbyStateChanged(standby, isStandbyPartNeeded);
else
staticStandbyStateChanged(standby);
}
// ***************** Static Intro *****************
private void handleStaticIntro() {
// We have a static case. Set the url on the browser to be the url
// defined in the root page. But first check memento if we can
// restore last visited page.
String url = getCachedCurrentPage();
if (!History.isURL(url))
// no cached state, or invalid state.
url = getModel().getHomePage().getUrl();
if (url == null) {
// We have no content to display. log an error
Log.error("Url is null; no content to display in browser", null); //$NON-NLS-1$
return;
}
// set the URL the browser should display
boolean success = browser.setUrl(url);
if (!success) {
Log.error("Unable to set the following ULR in browser: " + url, //$NON-NLS-1$
null);
return;
}
}
public void staticStandbyStateChanged(boolean standby) {
AbstractIntroPage homePage = getModel().getHomePage();
AbstractIntroPage standbyPage = getModel().getStandbyPage();
if (standbyPage == null)
standbyPage = homePage;
if (standby)
browser.setUrl(standbyPage.getUrl());
else
browser.setUrl(homePage.getUrl());
}
public Browser getBrowser() {
return browser;
}
/*
* Internal performance test hook.
*/
public boolean isFinishedLoading() {
return isFinishedLoading;
}
}