Java tutorial
/*=============================================================================# # Copyright (c) 2009-2015 Stephan Wahlbrink (WalWare.de) 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: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.ecommons.ui.mpbv; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.IHandler2; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IPropertyListener; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.menus.CommandContributionItemParameter; import org.eclipse.ui.part.IPage; import org.eclipse.ui.part.IPageBookViewPage; import org.eclipse.ui.part.MessagePage; import org.eclipse.ui.part.PageBook; import org.eclipse.ui.part.PageBookView; import org.eclipse.ui.part.PageSwitcher; import org.eclipse.ui.services.IServiceLocator; import de.walware.ecommons.collections.ConstArrayList; import de.walware.ecommons.ui.SharedUIResources; import de.walware.ecommons.ui.actions.HandlerCollection; import de.walware.ecommons.ui.actions.HandlerContributionItem; import de.walware.ecommons.ui.actions.SimpleContributionItem; import de.walware.ecommons.ui.util.StatusLineMessageManager; public abstract class ManagedPageBookView<S extends ISession> extends PageBookView { protected static final String PAGE_CONTROL_MENU_ID = "page_control"; //$NON-NLS-1$ private class SessionHandler implements IWorkbenchPart { private final S fSession; public SessionHandler(final S session) { fSession = session; } ManagedPageBookView<S> getView() { return ManagedPageBookView.this; } @Override public IWorkbenchPartSite getSite() { return ManagedPageBookView.this.getSite(); } public S getSession() { return fSession; } @Override public String getTitle() { return ""; //$NON-NLS-1$ } @Override public Image getTitleImage() { return null; } @Override public String getTitleToolTip() { return ""; //$NON-NLS-1$ } @Override public void addPropertyListener(final IPropertyListener listener) { } @Override public void removePropertyListener(final IPropertyListener listener) { } @Override public void createPartControl(final Composite parent) { } @Override public void setFocus() { } @Override public void dispose() { } @Override public Object getAdapter(final Class adapter) { return null; } @Override public int hashCode() { return fSession.hashCode(); } @Override public boolean equals(final Object obj) { return ((obj instanceof ManagedPageBookView<?>.SessionHandler) && (fSession == ((SessionHandler) obj).fSession)); } } private class NewPageHandler extends AbstractHandler { public NewPageHandler() { } @Override public void setEnabled(final Object evaluationContext) { } @Override public Object execute(final ExecutionEvent event) throws ExecutionException { newPage(null, true); return null; } } private class CloseCurrentPageHandler extends AbstractHandler { public CloseCurrentPageHandler() { } @Override public void setEnabled(final Object evaluationContext) { setBaseEnabled(!fSessionList.isEmpty()); } @Override public Object execute(final ExecutionEvent event) throws ExecutionException { final S session = getCurrentSession(); if (session != null) { closePage(session); } return null; } } public class CloseAllPagesHandler extends AbstractHandler { @Override public void setEnabled(final Object evaluationContext) { setBaseEnabled(!fSessionList.isEmpty()); } @Override public Object execute(final ExecutionEvent event) throws ExecutionException { fSessionHistory.clear(); final List<S> sessions = getSessions(); for (final S session : sessions) { closePage(session); } return null; } } private final List<S> fSessionList = new ArrayList<S>(); private final Map<S, SessionHandler> fSessionMap = new HashMap<S, SessionHandler>(); private Comparator<S> fSessionComparator; private final List<S> fSessionHistory = new LinkedList<S>(); private SessionHandler fActiveSession; private final HandlerCollection fViewHandlers = new HandlerCollection(); private StatusLineMessageManager statusManager; public ManagedPageBookView() { } protected void setSessionComparator(final Comparator<S> comparator) { fSessionComparator = comparator; } @Override protected boolean isImportant(final IWorkbenchPart part) { return ((part instanceof ManagedPageBookView<?>.SessionHandler) && ((ManagedPageBookView<?>.SessionHandler) part).getView() == this); } @Override protected IWorkbenchPart getBootstrapPart() { return null; } @Override public void createPartControl(final Composite parent) { super.createPartControl(parent); final IViewSite site = getViewSite(); this.statusManager = new StatusLineMessageManager(site.getActionBars().getStatusLineManager()); initActions(site, fViewHandlers); initPageSwitcher(); contributeToActionBars(site, site.getActionBars(), fViewHandlers); updateState(); } @Override protected IPage createDefaultPage(final PageBook book) { final MessagePage page = new MessagePage(); page.createControl(getPageBook()); initPage(page); return page; } @Override protected PageRec doCreatePage(final IWorkbenchPart part) { final SessionHandler sessionHandler = (SessionHandler) part; final S session = sessionHandler.getSession(); final IPageBookViewPage page = doCreatePage(session); if (page != null) { initPage(page); page.createControl(getPageBook()); final PageRec pageRecord = new PageRec(part, page); return pageRecord; } return null; } protected /* abstract */ IPageBookViewPage doCreatePage(final S session) { throw new UnsupportedOperationException(); } @Override protected void showPageRec(final PageRec pageRec) { if ((fActiveSession != null) ? (pageRec.part != fActiveSession) : (pageRec.part != null)) { onPageHiding((IPageBookViewPage) getCurrentPage(), (fActiveSession != null) ? fActiveSession.getSession() : null); fActiveSession = null; super.showPageRec(pageRec); fActiveSession = (SessionHandler) pageRec.part; final S session; if (fActiveSession != null) { session = fActiveSession.getSession(); fSessionHistory.remove(session); fSessionHistory.add(0, session); } else { session = null; } onPageShowing((IPageBookViewPage) pageRec.page, session); } updateTitle(); } protected void updateTitle() { final S session = getCurrentSession(); if (session == null) { setContentDescription(getNoPageTitle()); } else { setContentDescription(session.getLabel()); } } protected String getNoPageTitle() { return "No page at this time."; } @Override public void partClosed(final IWorkbenchPart part) { if (part instanceof ManagedPageBookView<?>.SessionHandler) { final SessionHandler sessionHandler = (SessionHandler) part; final S session = sessionHandler.getSession(); fSessionList.remove(session); fSessionHistory.remove(session); if (fActiveSession == part) { if (!fSessionHistory.isEmpty()) { showPage(fSessionHistory.get(0)); } else if (!fSessionList.isEmpty()) { showPage(fSessionList.get(fSessionList.size() - 1)); } } super.partClosed(part); } } @Override protected void doDestroyPage(final IWorkbenchPart part, final PageRec pageRecord) { final SessionHandler sessionHandler = (SessionHandler) part; final S session = sessionHandler.getSession(); pageRecord.page.dispose(); pageRecord.dispose(); fSessionMap.remove(session); if (sessionHandler == fActiveSession) { fActiveSession = null; } } private void initPageSwitcher() { new PageSwitcher(this) { @Override public Object[] getPages() { return fSessionList.toArray(); } @Override public String getName(final Object page) { return ((S) page).getLabel(); } @Override public ImageDescriptor getImageDescriptor(final Object page) { return ((S) page).getImageDescriptor(); } @Override public int getCurrentPageIndex() { return fSessionList.indexOf(fActiveSession); } @Override public void activatePage(final Object page) { showPage((S) page); } }; } protected boolean getPageControlByUser() { return true; } protected void initActions(final IServiceLocator serviceLocator, final HandlerCollection handlers) { final IHandlerService handlerService = (IHandlerService) serviceLocator.getService(IHandlerService.class); if (getPageControlByUser()) { final IHandler2 newPageHandler = createNewPageHandler(); if (newPageHandler != null) { handlers.add(SharedUIResources.NEW_PAGE_COMMAND_ID, newPageHandler); handlerService.activateHandler(SharedUIResources.NEW_PAGE_COMMAND_ID, newPageHandler); } final IHandler2 closePageHandler = new CloseCurrentPageHandler(); handlers.add(SharedUIResources.CLOSE_PAGE_COMMAND_ID, closePageHandler); handlerService.activateHandler(SharedUIResources.CLOSE_PAGE_COMMAND_ID, closePageHandler); final IHandler2 closeAllPagesHandler = new CloseAllPagesHandler(); handlers.add(SharedUIResources.CLOSE_ALL_PAGES_COMMAND_ID, closeAllPagesHandler); handlerService.activateHandler(SharedUIResources.CLOSE_ALL_PAGES_COMMAND_ID, closeAllPagesHandler); } } protected IHandler2 createNewPageHandler() { return new NewPageHandler(); } protected void contributeToActionBars(final IServiceLocator serviceLocator, final IActionBars actionBars, final HandlerCollection handlers) { final IToolBarManager toolBarManager = actionBars.getToolBarManager(); toolBarManager.add(new Separator(SharedUIResources.ADDITIONS_MENU_ID)); toolBarManager.add(new Separator(PAGE_CONTROL_MENU_ID)); { final IHandler2 handler = handlers.get(SharedUIResources.NEW_PAGE_COMMAND_ID); if (handler != null) { toolBarManager.appendToGroup(PAGE_CONTROL_MENU_ID, new HandlerContributionItem( new CommandContributionItemParameter(serviceLocator, null, SharedUIResources.NEW_PAGE_COMMAND_ID, HandlerContributionItem.STYLE_PUSH), handler)); } } toolBarManager.appendToGroup(PAGE_CONTROL_MENU_ID, new SimpleContributionItem( SharedUIResources.getImages().getDescriptor(SharedUIResources.LOCTOOL_CHANGE_PAGE_IMAGE_ID), null, "Pages", null, SimpleContributionItem.STYLE_PULLDOWN) { { setId("page_control.change_page"); //$NON-NLS-1$ } @Override protected void dropDownMenuAboutToShow(final IMenuManager manager) { manager.add(new ShowPageDropdownContribution<S>(ManagedPageBookView.this)); } @Override protected void execute() throws ExecutionException { if (fSessionHistory.size() >= 2) { showPage(fSessionHistory.get(1)); } } }); { final IHandler2 handler = handlers.get(SharedUIResources.CLOSE_PAGE_COMMAND_ID); if (handler != null) { toolBarManager.appendToGroup(PAGE_CONTROL_MENU_ID, new HandlerContributionItem(new CommandContributionItemParameter(serviceLocator, null, SharedUIResources.CLOSE_PAGE_COMMAND_ID, HandlerContributionItem.STYLE_PUSH), handler)); } } { final IHandler2 handler = handlers.get(SharedUIResources.CLOSE_ALL_PAGES_COMMAND_ID); if (handler != null) { toolBarManager.appendToGroup(PAGE_CONTROL_MENU_ID, new HandlerContributionItem(new CommandContributionItemParameter(serviceLocator, null, SharedUIResources.CLOSE_ALL_PAGES_COMMAND_ID, HandlerContributionItem.STYLE_PUSH), handler)); } } } @Override public void dispose() { super.dispose(); fViewHandlers.dispose(); } public IPage newPage(S session, final boolean show) { session = checkNewSession(session); if (session == null || fSessionList.contains(session)) { return null; } final SessionHandler sessionHandler = new SessionHandler(session); if (fSessionComparator != null) { final int idx = Collections.binarySearch(fSessionList, session, fSessionComparator); fSessionList.add((idx >= 0) ? idx : -(idx + 1), session); } else { fSessionList.add(session); } fSessionMap.put(session, sessionHandler); if (show) { partActivated(sessionHandler); final PageRec pageRec = getPageRec(sessionHandler); if (pageRec != null) { return pageRec.page; } else { fSessionMap.remove(sessionHandler); fSessionList.remove(session); return null; } } else { return null; } } protected S checkNewSession(final S session) { return session; } public IPage getPage(final S session) { final SessionHandler sessionHandler = fSessionMap.get(session); if (sessionHandler != null) { final PageRec pageRec = getPageRec(sessionHandler); if (pageRec != null) { return pageRec.page; } } return null; } public void showPage(final S session) { final SessionHandler sessionHandler = fSessionMap.get(session); if (sessionHandler != null) { partActivated(sessionHandler); } } public void closePage(final S session) { final SessionHandler sessionHandler = fSessionMap.get(session); if (sessionHandler != null) { partClosed(sessionHandler); } } public final List<S> getSessions() { return new ConstArrayList<S>(fSessionList); } public final S getCurrentSession() { final SessionHandler sessionHandler = fActiveSession; if (sessionHandler != null) { return sessionHandler.getSession(); } return null; } protected void onPageHiding(final IPageBookViewPage page, final S session) { updateState(); } protected void onPageShowing(final IPageBookViewPage page, final S session) { updateState(); } protected StatusLineMessageManager getStatusManager() { return this.statusManager; } protected void updateState() { fViewHandlers.update(null); } }