| /******************************************************************************* |
| * 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.model; |
| |
| import org.eclipse.core.runtime.IRegistryChangeEvent; |
| import org.eclipse.core.runtime.PerformanceStats; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.IToolBarManager; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.ui.IActionBars; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; |
| 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.model.viewer.IntroModelContentProvider; |
| import org.eclipse.ui.internal.intro.impl.model.viewer.IntroModelLabelProvider; |
| 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.IIntroPart; |
| import org.eclipse.ui.intro.config.CustomizableIntroPart; |
| |
| /** |
| * UI Implementation class that represents a Presentation Part. This class is |
| * instantiated from plugin markup and so we need a default constructor, |
| * including in subclasses. It has some base methods, including maintaining a |
| * history of navigation locations. Also, dynamic awarness is honored here. |
| * |
| */ |
| public abstract class AbstractIntroPartImplementation { |
| |
| // CustomizableIntroPart instance. |
| private CustomizableIntroPart introPart = null; |
| |
| // IMemento for restoring state. |
| private IMemento memento; |
| |
| protected History history = new History(); |
| |
| // flag used to enable logging of perf data for full UI creation only once. |
| // Since standbyStateChanged is called several times, flag is used in method |
| // to filter out all subsequent calls. |
| boolean logUIcreationTime = true; |
| |
| // Global actions |
| protected Action backAction = new Action() { |
| |
| { |
| setToolTipText(Messages.Browser_backwardButton_tooltip); |
| setImageDescriptor(ImageUtil |
| .createImageDescriptor("full/elcl16/backward_nav.gif")); //$NON-NLS-1$ |
| setDisabledImageDescriptor(ImageUtil |
| .createImageDescriptor("full/dlcl16/backward_nav.gif")); //$NON-NLS-1$ |
| } |
| |
| @Override |
| public void run() { |
| navigateBackward(); |
| } |
| }; |
| |
| protected Action forwardAction = new Action() { |
| |
| { |
| setToolTipText(Messages.Browser_forwardButton_tooltip); |
| setImageDescriptor(ImageUtil |
| .createImageDescriptor("full/elcl16/forward_nav.gif")); //$NON-NLS-1$ |
| setDisabledImageDescriptor(ImageUtil |
| .createImageDescriptor("full/dlcl16/forward_nav.gif")); //$NON-NLS-1$ |
| } |
| |
| @Override |
| public void run() { |
| navigateForward(); |
| } |
| }; |
| |
| protected Action homeAction = new Action() { |
| |
| { |
| setToolTipText(Messages.Browser_homeButton_tooltip); |
| setImageDescriptor(ImageUtil |
| .createImageDescriptor("full/elcl16/home_nav.gif")); //$NON-NLS-1$ |
| setDisabledImageDescriptor(ImageUtil |
| .createImageDescriptor("full/dlcl16/home_nav.gif")); //$NON-NLS-1$ |
| } |
| |
| @Override |
| public void run() { |
| navigateHome(); |
| } |
| }; |
| |
| protected Action viewIntroModelAction = new Action() { |
| |
| { |
| setToolTipText(Messages.IntroPart_showContentButton_tooltip); |
| setImageDescriptor(ImageUtil |
| .createImageDescriptor("contents_view.gif")); //$NON-NLS-1$ |
| } |
| |
| @Override |
| public void run() { |
| ElementTreeSelectionDialog treeViewer = new ElementTreeSelectionDialog( |
| getIntroPart().getIntroSite().getShell(), |
| new IntroModelLabelProvider(), new IntroModelContentProvider()); |
| treeViewer.setInput(getModel()); |
| treeViewer.open(); |
| } |
| }; |
| |
| /** |
| * Creates the UI based on this implementation class. . |
| * |
| * @param parent |
| */ |
| public abstract void createPartControl(Composite parent); |
| |
| /** |
| * Called when the init method is called in the IIntroPart. Subclasses may |
| * extend, for example to get the passed Memento. When extending, make sure |
| * you include a call to super. |
| * |
| * @param introPart |
| */ |
| public void init(IIntroPart introPart, IMemento memento) { |
| // we know the class type to cast to. |
| this.introPart = (CustomizableIntroPart) introPart; |
| this.memento = memento; |
| } |
| |
| /** |
| * @return |
| */ |
| public IntroModelRoot getModel() { |
| return IntroPlugin.getDefault().getIntroModelRoot(); |
| } |
| |
| /** |
| * @return Returns the introPart. |
| */ |
| public CustomizableIntroPart getIntroPart() { |
| return introPart; |
| } |
| |
| |
| /** |
| * Updates the UI navigation history with either a real URL. |
| * |
| * @param location |
| */ |
| public void updateHistory(String location) { |
| history.updateHistory(location); |
| updateNavigationActionsState(); |
| } |
| |
| /** |
| * Updates the UI navigation history with a page ID. |
| * |
| * @param pageId |
| */ |
| public void updateHistory(AbstractIntroPage page) { |
| history.updateHistory(page); |
| updateNavigationActionsState(); |
| } |
| |
| |
| /** |
| * Subclasses must implement to set the state of the navigation actions in |
| * the toolbar. |
| * |
| */ |
| public abstract void setFocus(); |
| |
| |
| /** |
| * Subclasses must implement to update the intro view actions when history |
| * is updated. |
| * |
| */ |
| protected abstract void updateNavigationActionsState(); |
| |
| |
| |
| public abstract boolean navigateBackward(); |
| |
| public abstract boolean navigateForward(); |
| |
| public abstract boolean navigateHome(); |
| |
| |
| /** |
| * Called when the IntroPart is disposed. Subclasses should override to |
| * dispose of resources. By default, this implementation does nothing. |
| */ |
| public void dispose() { |
| // no-op |
| } |
| |
| |
| /* |
| * Add the Intro Model Viewer as an action to all implementations. |
| */ |
| protected void addToolBarActions() { |
| // Handle menus: |
| IActionBars actionBars = getIntroPart().getIntroSite().getActionBars(); |
| IToolBarManager toolBarManager = actionBars.getToolBarManager(); |
| toolBarManager.add(viewIntroModelAction); |
| toolBarManager.update(true); |
| actionBars.updateActionBars(); |
| } |
| |
| /** |
| * Called when the Intro changes state. This method should not be |
| * subclassed. It adds performance logging calls. Subclasses must implement |
| * doStandbyStateChanged instead. |
| * |
| * @param standby |
| */ |
| public void standbyStateChanged(boolean standby, boolean isStandbyPartNeeded) { |
| PerformanceStats setStandbyStateStats = null; |
| long start = 0; |
| if (Log.logPerformance) { |
| if (logUIcreationTime && PerformanceStats.ENABLED) { |
| PerformanceStats stats = PerformanceStats.getStats( |
| IIntroConstants.PERF_UI_ZOOM, IIntroConstants.INTRO); |
| stats.endRun(); |
| Util |
| .logPerformanceMessage( |
| "(perf stats) time spent in UI code before content is displayed (standbyStateChanged event is fired) ", //$NON-NLS-1$ |
| stats.getRunningTime()); |
| stats.reset(); |
| } |
| |
| // standby time. |
| setStandbyStateStats = PerformanceStats.getStats( |
| IIntroConstants.PERF_SET_STANDBY_STATE, IIntroConstants.INTRO); |
| setStandbyStateStats.startRun(); |
| start = System.currentTimeMillis(); |
| } |
| |
| |
| doStandbyStateChanged(standby, isStandbyPartNeeded); |
| |
| // now log performance |
| if (Log.logPerformance) { |
| if (PerformanceStats.ENABLED) { |
| setStandbyStateStats.endRun(); |
| Util |
| .logPerformanceMessage( |
| "(perf stats) setting standby state (zooming, displaying content) took:", //$NON-NLS-1$ |
| +setStandbyStateStats.getRunningTime()); |
| setStandbyStateStats.reset(); |
| } else |
| Util |
| .logPerformanceTime( |
| "setting standby state (zooming, generating content, setText() ) took:", //$NON-NLS-1$ |
| +start); |
| |
| if (logUIcreationTime) { |
| if (PerformanceStats.ENABLED) { |
| PerformanceStats stats = PerformanceStats.getStats( |
| IIntroConstants.PERF_VIEW_CREATION_TIME, |
| IIntroConstants.INTRO); |
| stats.endRun(); |
| Util |
| .logPerformanceMessage( |
| "END - (perf stats): creating CustomizableIntroPart view took:", //$NON-NLS-1$ |
| +stats.getRunningTime()); |
| stats.reset(); |
| } else |
| Util.logPerformanceTime( |
| "END: creating CustomizableIntroPart view took:", //$NON-NLS-1$ |
| +IntroPlugin.getDefault().gettUICreationStartTime()); |
| |
| |
| // prevent further logging of UI creation time. |
| logUIcreationTime = false; |
| } |
| |
| } |
| } |
| |
| |
| |
| /* |
| * Subclasses must implement the actual logic for the method. |
| */ |
| protected abstract void doStandbyStateChanged(boolean standby, |
| boolean isStandbyPartNeeded); |
| |
| |
| /** |
| * Save the current state of the intro. Currently, we only store information |
| * about the most recently visited intro page. In static case, the last HTML |
| * page is remembered. In dynamic case, the last UI page or HTML page is |
| * remembered. |
| * |
| * Note: This method saves the last visited intro page in a dynamic case. |
| * Subclasses need to extend to get the desired behavior relavent to the |
| * specific implementation. Broswer implementation needs to cache an http |
| * web page, if it happens to be the last page visited. |
| * |
| * @param memento |
| */ |
| public void saveState(IMemento memento) { |
| saveCurrentPage(memento); |
| } |
| |
| |
| /** |
| * This method saves the most recently visited dynamic intro page in the |
| * memento. If a given implementation requires saving alternative |
| * information (e.g., information about the most recently visited static |
| * page) it should override this method. |
| * |
| * @param memento |
| */ |
| protected void saveCurrentPage(IMemento memento) { |
| IntroModelRoot model = getModel(); |
| |
| if (memento == null || model == null) |
| return; |
| String currentPage = model.getCurrentPageId(); |
| if (currentPage != null && currentPage.length() > 0) { |
| memento.putString(IIntroConstants.MEMENTO_CURRENT_PAGE_ATT, |
| currentPage); |
| } |
| } |
| |
| |
| /** |
| * get the last page if it was stored in memento. This page is the last |
| * visited intro page. It can be a intro page id, in the case of dynamic |
| * intro. Or it can be an http in the case of static intro. It can also be |
| * an http in the case of dynamic intro where the last visited page is a |
| * url. |
| */ |
| protected String getCachedCurrentPage() { |
| // Check to see if the start page has been overridden because |
| // content |
| String newContentPage = ExtensionMap.getInstance().getStartPage(); |
| if (newContentPage != null) { |
| return newContentPage; |
| } |
| IMemento memento = getMemento(); |
| if (memento == null) { |
| String startPageId = getModel().getStartPageId(); |
| if (startPageId.length() > 0) { |
| return startPageId; |
| } else { |
| return null; |
| } |
| } |
| return memento.getString(IIntroConstants.MEMENTO_CURRENT_PAGE_ATT); |
| } |
| |
| |
| /** |
| * @return Returns the memento passed on creation. |
| */ |
| public IMemento getMemento() { |
| return memento; |
| } |
| |
| /** |
| * Support dynamic awarness. Clear cached models first, then update UI by |
| * delegating to implementation. |
| * |
| * @see org.eclipse.core.runtime.IRegistryChangeListener#registryChanged(org.eclipse.core.runtime.IRegistryChangeEvent) |
| */ |
| public void registryChanged(IRegistryChangeEvent event) { |
| history.clear(); |
| // give implementation a chance to react to change. |
| handleRegistryChanged(event); |
| } |
| |
| /* |
| * Handle reacting to plugin registry changes. This method will only be |
| * called when regitry changes pertaining to Intro extension points is |
| * detected. |
| */ |
| protected abstract void handleRegistryChanged(IRegistryChangeEvent event); |
| |
| |
| public History getHistory() { |
| return history; |
| } |
| |
| |
| } |