| /*=============================================================================# |
| # Copyright (c) 2009, 2020 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.internal.redocs.wikitext.r.ui.editors; |
| |
| import static org.eclipse.ui.IWorkbenchCommandConstants.NAVIGATE_EXPAND_ALL; |
| |
| import static org.eclipse.statet.ecommons.ui.actions.UIActions.ADDITIONS_GROUP_ID; |
| import static org.eclipse.statet.ecommons.ui.actions.UIActions.VIEW_EXPAND_GROUP_ID; |
| import static org.eclipse.statet.ecommons.ui.actions.UIActions.VIEW_FILTER_GROUP_ID; |
| |
| import java.util.Collections; |
| import java.util.Map; |
| |
| import org.eclipse.core.commands.AbstractHandler; |
| import org.eclipse.core.commands.ExecutionEvent; |
| import org.eclipse.core.commands.IHandler2; |
| import org.eclipse.jface.action.IMenuListener2; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.IToolBarManager; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.ui.IActionBars; |
| import org.eclipse.ui.handlers.IHandlerService; |
| import org.eclipse.ui.menus.CommandContributionItem; |
| import org.eclipse.ui.menus.CommandContributionItemParameter; |
| import org.eclipse.ui.part.IPageSite; |
| import org.eclipse.ui.services.IServiceLocator; |
| |
| import org.eclipse.statet.ecommons.ui.actions.HandlerCollection; |
| import org.eclipse.statet.ecommons.ui.actions.HandlerContributionItem; |
| import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils; |
| import org.eclipse.statet.ecommons.ui.util.UIAccess; |
| import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils; |
| |
| import org.eclipse.statet.base.ui.IStatetUIMenuIds; |
| import org.eclipse.statet.docmlet.base.ui.DocmlBaseUIResources; |
| import org.eclipse.statet.docmlet.wikitext.core.model.IWikidocModelInfo; |
| import org.eclipse.statet.docmlet.wikitext.core.model.IWikitextSourceElement; |
| import org.eclipse.statet.docmlet.wikitext.core.model.WikitextModel; |
| import org.eclipse.statet.internal.redocs.wikitext.r.RedocsWikitextRPlugin; |
| import org.eclipse.statet.internal.redocs.wikitext.r.ui.sourceediting.DocROutlineContentProvider; |
| import org.eclipse.statet.ltk.model.core.elements.IEmbeddedForeignElement; |
| import org.eclipse.statet.ltk.model.core.elements.IModelElement; |
| import org.eclipse.statet.ltk.model.core.elements.IModelElement.Filter; |
| import org.eclipse.statet.ltk.model.core.elements.ISourceStructElement; |
| import org.eclipse.statet.ltk.model.core.elements.ISourceUnitModelInfo; |
| import org.eclipse.statet.ltk.ui.sourceediting.OutlineContentProvider; |
| import org.eclipse.statet.ltk.ui.sourceediting.SourceEditor1; |
| import org.eclipse.statet.ltk.ui.sourceediting.SourceEditor2OutlinePage; |
| import org.eclipse.statet.ltk.ui.util.ViewerDragSupport; |
| import org.eclipse.statet.ltk.ui.util.ViewerDropSupport; |
| import org.eclipse.statet.r.core.model.RModel; |
| import org.eclipse.statet.r.launching.RCodeLaunching; |
| import org.eclipse.statet.redocs.r.ui.RedocsRUIResources; |
| import org.eclipse.statet.redocs.wikitext.r.ui.WikitextRweaveLabelProvider; |
| |
| |
| public class WikidocRweaveOutlinePage extends SourceEditor2OutlinePage { |
| |
| |
| private static final String EXPAND_ELEMENTS_COMMAND_ID= "org.eclipse.statet.workbench.commands.ExpandElements"; //$NON-NLS-1$ |
| |
| |
| private static boolean isRChunk(final IModelElement element) { |
| if (element instanceof IEmbeddedForeignElement) { |
| final ISourceStructElement foreignElement= ((IEmbeddedForeignElement) element).getForeignElement(); |
| if (foreignElement != null && foreignElement.getModelTypeId() == RModel.R_TYPE_ID) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| |
| private static Map<String, String> H2_PARAMETERS= Collections.singletonMap("type", "h2"); //$NON-NLS-1$ //$NON-NLS-2$ |
| private static Map<String, String> H3_PARAMETERS= Collections.singletonMap("type", "h3"); //$NON-NLS-1$ //$NON-NLS-2$ |
| private static Map<String, String> H4_PARAMETERS= Collections.singletonMap("type", "h4"); //$NON-NLS-1$ //$NON-NLS-2$ |
| private static Map<String, String> RCHUNK_PARAMETERS= Collections.singletonMap("type", "rchunks"); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| |
| private class FilterRChunks extends AbstractToggleHandler { |
| |
| public FilterRChunks() { |
| super("filter.r_chunks.enabled", false, null, 0); //$NON-NLS-1$ |
| } |
| |
| @Override |
| protected void apply(final boolean on) { |
| final TreeViewer viewer= getViewer(); |
| WikidocRweaveOutlinePage.this.filter.hideRChunks= on; |
| if (UIAccess.isOkToUse(viewer)) { |
| viewer.refresh(false); |
| } |
| } |
| |
| } |
| |
| public class ExpandElementsContributionItem extends HandlerContributionItem { |
| |
| private final IHandler2 expandElementsHandler; |
| |
| public ExpandElementsContributionItem( |
| final IServiceLocator serviceLocator, final HandlerCollection handlers) { |
| super(new CommandContributionItemParameter(serviceLocator, |
| ".ExpandElements", NAVIGATE_EXPAND_ALL, null, //$NON-NLS-1$ |
| null, null, null, |
| "Expand All", "E", null, |
| HandlerContributionItem.STYLE_PULLDOWN, null, false ), |
| handlers.get(NAVIGATE_EXPAND_ALL) ); |
| this.expandElementsHandler= handlers.get(EXPAND_ELEMENTS_COMMAND_ID); |
| } |
| |
| |
| @Override |
| protected void initDropDownMenu(final MenuManager menuManager) { |
| menuManager.addMenuListener(new IMenuListener2() { |
| @Override |
| public void menuAboutToShow(final IMenuManager manager) { |
| final TreeViewer viewer= getViewer(); |
| if (viewer == null) { |
| return; |
| } |
| |
| final IWikidocModelInfo modelInfo= getCurrentInputModel(); |
| final DocmlBaseUIResources baseResources= DocmlBaseUIResources.INSTANCE; |
| final RedocsRUIResources redocsResources= RedocsRUIResources.INSTANCE; |
| if (modelInfo.getMinSectionLevel() > 0) { |
| if (modelInfo.getMinSectionLevel() < 2 |
| && modelInfo.getMaxSectionLevel() >= 2) { |
| manager.add(new HandlerContributionItem(new CommandContributionItemParameter( |
| getSite(), null, EXPAND_ELEMENTS_COMMAND_ID, H2_PARAMETERS, |
| baseResources.getImageDescriptor(DocmlBaseUIResources.OBJ_HEADING2_IMAGE_ID), null, null, |
| "Show all H2 sections", "C", null, |
| HandlerContributionItem.STYLE_PUSH, null, false ), |
| ExpandElementsContributionItem.this.expandElementsHandler )); |
| } |
| if (modelInfo.getMinSectionLevel() < 3 |
| && modelInfo.getMaxSectionLevel() >= 3) { |
| manager.add(new HandlerContributionItem(new CommandContributionItemParameter( |
| getSite(), null, EXPAND_ELEMENTS_COMMAND_ID, H3_PARAMETERS, |
| baseResources.getImageDescriptor(DocmlBaseUIResources.OBJ_HEADING3_IMAGE_ID), null, null, |
| "Show all H3 sections", "S", null, |
| HandlerContributionItem.STYLE_PUSH, null, false ), |
| ExpandElementsContributionItem.this.expandElementsHandler )); |
| } |
| if (modelInfo.getMinSectionLevel() < 4 |
| && modelInfo.getMaxSectionLevel() >= 4) { |
| manager.add(new HandlerContributionItem(new CommandContributionItemParameter( |
| getSite(), null, EXPAND_ELEMENTS_COMMAND_ID, H4_PARAMETERS, |
| baseResources.getImageDescriptor(DocmlBaseUIResources.OBJ_HEADING4_IMAGE_ID), null, null, |
| "Show all H4 sections", "u", null, |
| HandlerContributionItem.STYLE_PUSH, null, false ), |
| ExpandElementsContributionItem.this.expandElementsHandler )); |
| manager.add(new Separator()); |
| } |
| } |
| if (!WikidocRweaveOutlinePage.this.filter.hideRChunks) { |
| manager.add(new HandlerContributionItem(new CommandContributionItemParameter( |
| getSite(), null, EXPAND_ELEMENTS_COMMAND_ID, RCHUNK_PARAMETERS, |
| redocsResources.getImageDescriptor(RedocsRUIResources.OBJ_RCHUNK_IMAGE_ID), null, null, |
| "Show all R Chunks", "R", null, |
| HandlerContributionItem.STYLE_PUSH, null, false ), |
| ExpandElementsContributionItem.this.expandElementsHandler )); |
| } |
| } |
| @Override |
| public void menuAboutToHide(final IMenuManager manager) { |
| ExpandElementsContributionItem.this.display.asyncExec(new Runnable() { |
| @Override |
| public void run() { |
| menuManager.dispose(); |
| } |
| }); |
| } |
| }); |
| } |
| |
| } |
| |
| public class ExpandElementsHandler extends AbstractHandler { |
| |
| public ExpandElementsHandler() { |
| } |
| |
| @Override |
| public Object execute(final ExecutionEvent event) { |
| final TreeViewer viewer= getViewer(); |
| final String type= event.getParameter("type"); |
| if (UIAccess.isOkToUse(viewer) && type != null) { |
| final ISourceUnitModelInfo modelInfo= getModelInfo(viewer.getInput()); |
| if (modelInfo == null) { |
| return null; |
| } |
| final Filter contentFilter= getContentFilter(); |
| final Filter expandFilter; |
| if (type.equals("rchunks")) { |
| expandFilter= new Filter() { |
| @Override |
| public boolean include(final IModelElement element) { |
| if (contentFilter.include(element)) { |
| if ((element.getElementType() & IModelElement.MASK_C1) == IWikitextSourceElement.C1_EMBEDDED |
| && isRChunk(element)) { |
| ViewerUtils.expandToLevel(viewer, element, 0); |
| return false; |
| } |
| ((ISourceStructElement) element).hasSourceChildren(this); |
| return false; |
| } |
| return false; |
| } |
| }; |
| } |
| else { |
| final int sectionLevel; |
| if (type.equals("h2")) { //$NON-NLS-1$ |
| sectionLevel= 2; |
| } |
| else if (type.equals("h3")) { //$NON-NLS-1$ |
| sectionLevel= 3; |
| } |
| else if (type.equals("h4")) { //$NON-NLS-1$ |
| sectionLevel= 4; |
| } |
| else if (type.equals("h5")) { //$NON-NLS-1$ |
| sectionLevel= 5; |
| } |
| else if (type.equals("h6")) { //$NON-NLS-1$ |
| sectionLevel= 6; |
| } |
| else { |
| sectionLevel= 0; |
| } |
| if (sectionLevel < 1 || sectionLevel > 6) { |
| return null; |
| } |
| expandFilter= new Filter() { |
| private boolean childExpand; |
| @Override |
| public boolean include(final IModelElement element) { |
| if (contentFilter.include(element) |
| && (element.getElementType() & IModelElement.MASK_C2) == IWikitextSourceElement.C2_SECTIONING) { |
| final int currentLevel= (element.getElementType() & 0xf); |
| if (currentLevel < 1 || currentLevel > sectionLevel) { |
| return false; // nothing to do |
| } |
| if (currentLevel < sectionLevel) { |
| this.childExpand= false; |
| ((ISourceStructElement) element).hasSourceChildren(this); |
| if (this.childExpand) { |
| return false; // done |
| } |
| } |
| // expand |
| ViewerUtils.expandToLevel(viewer, element, 0); |
| this.childExpand= true; |
| return false; |
| } |
| return false; |
| } |
| }; |
| } |
| modelInfo.getSourceElement().hasSourceChildren(expandFilter); |
| } |
| return null; |
| } |
| } |
| |
| |
| private class ContentFilter implements IModelElement.Filter { |
| |
| private boolean hideRChunks; |
| |
| @Override |
| public boolean include(final IModelElement element) { |
| switch ((element.getElementType() & IModelElement.MASK_C1)) { |
| case IWikitextSourceElement.C1_EMBEDDED: |
| if (isRChunk(element)) { |
| return !this.hideRChunks; |
| } |
| } |
| return true; |
| } |
| |
| } |
| |
| |
| private final ContentFilter filter= new ContentFilter(); |
| |
| |
| public WikidocRweaveOutlinePage(final SourceEditor1 editor) { |
| super(editor, WikitextModel.WIKIDOC_TYPE_ID, WikidocRweaveRefactoringFactory.getInstance(), |
| "org.eclipse.statet.docmlet.menus.WikidocOutlineViewContextMenu"); //$NON-NLS-1$ |
| } |
| |
| |
| @Override |
| protected IDialogSettings getDialogSettings() { |
| return DialogUtils.getDialogSettings(RedocsWikitextRPlugin.getInstance(), "WikidocRweaveOutlineView"); //$NON-NLS-1$ |
| } |
| |
| @Override |
| protected OutlineContentProvider createContentProvider() { |
| return new DocROutlineContentProvider(new OutlineContent()); |
| } |
| |
| @Override |
| protected IModelElement.Filter getContentFilter() { |
| return this.filter; |
| } |
| |
| @Override |
| protected void configureViewer(final TreeViewer viewer) { |
| super.configureViewer(viewer); |
| |
| viewer.setLabelProvider(new WikitextRweaveLabelProvider(0)); |
| |
| final ViewerDropSupport drop= new ViewerDropSupport(viewer, this, |
| getRefactoringFactory() ); |
| drop.init(); |
| final ViewerDragSupport drag= new ViewerDragSupport(viewer); |
| drag.init(); |
| } |
| |
| @Override |
| protected void initActions(final IServiceLocator serviceLocator, |
| final HandlerCollection handlers) { |
| super.initActions(serviceLocator, handlers); |
| |
| final IHandlerService handlerService= serviceLocator.getService(IHandlerService.class); |
| |
| handlers.add(".FilterRChunks", new FilterRChunks()); //$NON-NLS-1$ |
| |
| { final IHandler2 handler= new ExpandElementsHandler(); |
| handlers.add(EXPAND_ELEMENTS_COMMAND_ID, handler); |
| // handlerService.activateHandler(EXPAND_ELEMENTS_COMMAND_ID, handler); //$NON-NLS-1$ |
| } |
| } |
| |
| @Override |
| protected void contributeToActionBars(final IServiceLocator serviceLocator, |
| final IActionBars actionBars, final HandlerCollection handlers) { |
| super.contributeToActionBars(serviceLocator, actionBars, handlers); |
| |
| final IToolBarManager toolBarManager= actionBars.getToolBarManager(); |
| final RedocsRUIResources redocsResources= RedocsRUIResources.INSTANCE; |
| |
| toolBarManager.appendToGroup(VIEW_EXPAND_GROUP_ID, |
| new ExpandElementsContributionItem(serviceLocator, handlers)); |
| |
| // toolBarManager.appendToGroup(ECommonsUI.VIEW_SORT_MENU_ID, |
| // new AlphaSortAction()); |
| toolBarManager.appendToGroup(VIEW_FILTER_GROUP_ID, |
| new HandlerContributionItem(new CommandContributionItemParameter(serviceLocator, |
| null, HandlerContributionItem.NO_COMMAND_ID, null, |
| redocsResources.getImageDescriptor(RedocsRUIResources.LOCTOOL_FILTERCHUNKS_IMAGE_ID), null, null, |
| "Hide R Chunks", "R", null, |
| HandlerContributionItem.STYLE_CHECK, null, false ), |
| handlers.get(".FilterRChunks") ) ); //$NON-NLS-1$ |
| // toolBarManager.appendToGroup(ECommonsUI.VIEW_FILTER_MENU_ID, |
| // new FilterLocalDefinitions()); |
| } |
| |
| @Override |
| protected void contextMenuAboutToShow(final IMenuManager m) { |
| super.contextMenuAboutToShow(m); |
| final IPageSite site= getSite(); |
| |
| if (m.find(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID) == null) { |
| m.insertBefore(ADDITIONS_GROUP_ID, |
| new Separator(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID) ); |
| } |
| |
| m.appendToGroup(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID, |
| new CommandContributionItem(new CommandContributionItemParameter( |
| site, null, RCodeLaunching.SUBMIT_SELECTION_COMMAND_ID, null, |
| null, null, null, |
| null, "R", null, //$NON-NLS-1$ |
| CommandContributionItem.STYLE_PUSH, null, false) )); |
| m.appendToGroup(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID, |
| new CommandContributionItem(new CommandContributionItemParameter( |
| site, null, RCodeLaunching.SUBMIT_UPTO_SELECTION_COMMAND_ID, null, |
| null, null, null, |
| null, "U", null, //$NON-NLS-1$ |
| CommandContributionItem.STYLE_PUSH, null, false) )); |
| |
| m.add(new Separator(IStatetUIMenuIds.GROUP_ADD_MORE_ID)); |
| } |
| |
| protected IWikidocModelInfo getCurrentInputModel() { |
| final TreeViewer viewer= getViewer(); |
| if (viewer == null) { |
| return null; |
| } |
| return (IWikidocModelInfo) getModelInfo(viewer.getInput()); |
| } |
| |
| } |