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.statet.r.internal.ui.rhelp; import java.net.URI; import java.net.URISyntaxException; import java.util.Collections; import java.util.List; 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.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.Region; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IPartListener2; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.menus.CommandContributionItem; import org.eclipse.ui.menus.CommandContributionItemParameter; import org.eclipse.ui.part.IShowInTarget; import org.eclipse.ui.part.ShowInContext; import org.eclipse.ui.services.IServiceLocator; import org.eclipse.ui.statushandlers.StatusManager; import de.walware.ecommons.ICommonStatusConstants; import de.walware.ecommons.ltk.ast.AstSelection; import de.walware.ecommons.ltk.ui.ISelectionWithElementInfoListener; import de.walware.ecommons.ltk.ui.LTKInputData; import de.walware.ecommons.ltk.ui.sourceediting.SourceEditor1; import de.walware.ecommons.preferences.PreferencesUtil; import de.walware.ecommons.text.TextUtil; import de.walware.ecommons.ui.SharedUIResources; import de.walware.ecommons.ui.actions.HandlerCollection; import de.walware.ecommons.ui.actions.SimpleContributionItem; import de.walware.ecommons.ui.mpbv.BookmarkCollection; import de.walware.ecommons.ui.mpbv.BrowserBookmark; import de.walware.ecommons.ui.mpbv.BrowserSession; import de.walware.ecommons.ui.mpbv.PageBookBrowserPage; import de.walware.ecommons.ui.mpbv.PageBookBrowserView; import de.walware.ecommons.ui.util.UIAccess; import de.walware.statet.r.core.RCore; import de.walware.statet.r.core.model.IRSourceUnit; import de.walware.statet.r.core.model.RElementName; import de.walware.statet.r.core.model.RModel; import de.walware.statet.r.core.renv.IREnv; import de.walware.statet.r.core.rhelp.IREnvHelp; import de.walware.statet.r.core.rhelp.IRHelpManager; import de.walware.statet.r.core.rhelp.IRHelpPage; import de.walware.statet.r.core.rhelp.IRPkgHelp; import de.walware.statet.r.core.rsource.ast.RAstNode; import de.walware.statet.r.internal.debug.ui.RLaunchingMessages; import de.walware.statet.r.launching.RCodeLaunching; import de.walware.statet.r.ui.RUI; public class RHelpView extends PageBookBrowserView implements ISelectionWithElementInfoListener, IShowInTarget { public class RunCode extends AbstractHandler { private final boolean gotoConsole; public RunCode(final boolean gotoConsole) { this.gotoConsole = gotoConsole; } @Override public void setEnabled(final Object evaluationContext) { setBaseEnabled(getCurrentBrowserPage() != null); } @Override public Object execute(final ExecutionEvent event) throws ExecutionException { final PageBookBrowserPage browserPage = getCurrentBrowserPage(); if (browserPage != null) { final String selectedText = browserPage.getSelectedText(); if (selectedText != null && selectedText.length() > 0) { try { final List<String> lines = TextUtil.toLines(selectedText); RCodeLaunching.runRCodeDirect(lines, this.gotoConsole, null); } catch (final CoreException e) { final IStatus causeStatus = e.getStatus(); final Status status = new Status(causeStatus.getSeverity(), RUI.PLUGIN_ID, ICommonStatusConstants.LAUNCHING, RLaunchingMessages.RSelectionLaunch_error_message, e); StatusManager.getManager().handle(status); final IStatusLineManager manager = getViewSite().getActionBars().getStatusLineManager(); if (manager != null) { if (causeStatus.getSeverity() == IStatus.ERROR) { manager.setErrorMessage(causeStatus.getMessage()); } else { manager.setMessage(causeStatus.getMessage()); } } } } } return null; } } private class LinkEditorHandler extends SimpleContributionItem { public LinkEditorHandler() { super(SharedUIResources.getImages().getDescriptor(SharedUIResources.LOCTOOL_SYNCHRONIZED_IMAGE_ID), null, "Link with Editor", null, STYLE_CHECK); } @Override protected void execute() throws ExecutionException { setLinkingWithEditor(!RHelpView.this.fIsLinkingWithEditor); } } private boolean fIsLinkingWithEditor; private final LinkEditorHandler fLinkingWithEditorHandler = new LinkEditorHandler(); private SourceEditor1 fLinkedEditor; private IPartListener2 partListener; public RHelpView() { super(); } @Override public void dispose() { if (this.partListener != null) { getSite().getPage().removePartListener(this.partListener); this.partListener = null; } if (this.fLinkedEditor != null) { this.fLinkedEditor.removePostSelectionWithElementInfoListener(this); this.fLinkedEditor = null; } super.dispose(); } @Override public void createPartControl(final Composite parent) { super.createPartControl(parent); if (!PlatformUI.getWorkbench().isStarting()) { final Job job = new Job("Initial R Help Page") { //$NON-NLS-1$ { setSystem(true); setUser(false); setPriority(Job.SHORT); } @Override protected IStatus run(final IProgressMonitor monitor) { RCore.getRHelpManager().ensureIsRunning(); final Display display = UIAccess.getDisplay(); if (getCurrentBrowserPage() == null && display != null && !display.isDisposed()) { display.asyncExec(new Runnable() { @Override public void run() { if (getCurrentBrowserPage() == null && UIAccess.isOkToUse(getPageBook())) { newPage(null, true); } } }); } return Status.OK_STATUS; } }; job.schedule(50); } initLinking(); } private void initLinking() { this.partListener = new IPartListener2() { @Override public void partOpened(final IWorkbenchPartReference partRef) { } @Override public void partClosed(final IWorkbenchPartReference partRef) { if (RHelpView.this.fLinkedEditor != null && partRef.getPart(false) == RHelpView.this.fLinkedEditor) { clear(); } } @Override public void partVisible(final IWorkbenchPartReference partRef) { } @Override public void partHidden(final IWorkbenchPartReference partRef) { } @Override public void partInputChanged(final IWorkbenchPartReference partRef) { } @Override public void partActivated(final IWorkbenchPartReference partRef) { final IWorkbenchPart part = partRef.getPart(false); if (part instanceof SourceEditor1) { RHelpView.this.fLinkedEditor = (SourceEditor1) part; RHelpView.this.fLinkedEditor.addPostSelectionWithElementInfoListener(RHelpView.this); } else if (part instanceof IEditorPart) { clear(); } } @Override public void partDeactivated(final IWorkbenchPartReference partRef) { } @Override public void partBroughtToTop(final IWorkbenchPartReference partRef) { } private void clear() { if (RHelpView.this.fLinkedEditor != null) { RHelpView.this.fLinkedEditor.removePostSelectionWithElementInfoListener(RHelpView.this); RHelpView.this.fLinkedEditor = null; } } }; getSite().getPage().addPartListener(this.partListener); } @Override protected void initActions(final IServiceLocator serviceLocator, final HandlerCollection handlers) { super.initActions(serviceLocator, handlers); final IHandlerService handlerService = (IHandlerService) serviceLocator.getService(IHandlerService.class); { final IHandler2 handler = new RunCode(false); handlers.add(RCodeLaunching.SUBMIT_SELECTION_COMMAND_ID, handler); handlerService.activateHandler(RCodeLaunching.SUBMIT_SELECTION_COMMAND_ID, handler); } { final IHandler2 handler = new RunCode(true); handlers.add(RCodeLaunching.SUBMIT_FILEVIACOMMAND_GOTOCONSOLE_COMMAND_ID, handler); handlerService.activateHandler(RCodeLaunching.SUBMIT_FILEVIACOMMAND_GOTOCONSOLE_COMMAND_ID, handler); } } @Override protected void contributeToActionBars(final IServiceLocator serviceLocator, final IActionBars actionBars, final HandlerCollection handlers) { super.contributeToActionBars(serviceLocator, actionBars, handlers); final IToolBarManager toolBarManager = actionBars.getToolBarManager(); toolBarManager.appendToGroup("bookmarks", //$NON-NLS-1$ new CommandContributionItem(new CommandContributionItemParameter(serviceLocator, null, "de.walware.ecommons.ide.commands.OpenSearchDialog", //$NON-NLS-1$ Collections.singletonMap("pageId", "de.walware.statet.r.searchPages.RHelpPage"), //$NON-NLS-1$ //$NON-NLS-2$ null, null, null, null, null, null, CommandContributionItem.STYLE_PUSH, null, false))); toolBarManager.add(this.fLinkingWithEditorHandler); } @Override protected PageBookBrowserPage doCreatePage(final BrowserSession session) { return new RHelpViewPage(this, session); } @Override protected void updateTitle() { final BrowserSession session = getCurrentSession(); if (session == null) { setContentDescription(getNoPageTitle()); } else { setContentDescription(""); //$NON-NLS-1$ } } @Override protected BookmarkCollection initBookmarkCollection() { final BookmarkCollection collection = BookmarkCollection.getCollection(RHelpPreferences.RHELP_QUALIFIER); final List<BrowserBookmark> bookmarks = collection.getBookmarks(); synchronized (collection) { if (bookmarks.isEmpty()) { bookmarks.add(new BrowserBookmark("R Homepage - The R Project for Statistical Computing", //$NON-NLS-1$ "http://www.r-project.org")); //$NON-NLS-1$ bookmarks.add(new BrowserBookmark("CRAN - The Comprehensive R Archive Network", //$NON-NLS-1$ "http://cran.r-project.org/")); //$NON-NLS-1$ bookmarks.add(new BrowserBookmark("RSeek.org - R-project Search Engine", "http://rseek.org/")); //$NON-NLS-1$ //$NON-NLS-2$ } } return collection; } @Override protected BrowserBookmark createBookmark() { final PageBookBrowserPage page = getCurrentBrowserPage(); if (page != null) { String url = page.getCurrentUrl(); try { URI uri = new URI(url); uri = RCore.getRHelpManager().toPortableUrl(uri); url = uri.toString(); } catch (final URISyntaxException e) { // ? } return new BrowserBookmark(page.getCurrentTitle(), url); } return null; } @Override public String getHomePageUrl() { return PreferencesUtil.getInstancePrefs().getPreferenceValue(RHelpPreferences.HOMEPAGE_URL_PREF); } @Override protected void collectContextMenuPreferencePages(final List<String> pageIds) { pageIds.add("de.walware.statet.r.preferencePages.RHelpPage"); //$NON-NLS-1$ pageIds.add("de.walware.statet.r.preferencePages.REnvironmentPage"); //$NON-NLS-1$ } public void setLinkingWithEditor(final boolean enable) { this.fIsLinkingWithEditor = enable; this.fLinkingWithEditorHandler.setChecked(enable); if (enable && this.fLinkedEditor != null) { final ISelection selection = this.fLinkedEditor.getShowInContext().getSelection(); if (selection instanceof LTKInputData) { stateChanged((LTKInputData) selection); } } } @Override public void inputChanged() { } @Override public void stateChanged(final LTKInputData state) { if (!this.fIsLinkingWithEditor) { return; } show(state, false); } private boolean show(final LTKInputData state, final boolean explicite) { if (state.getInputElement().getModelTypeId() == RModel.TYPE_ID || state.getInputElement() instanceof IRSourceUnit) { final AstSelection astSelection = state.getAstSelection(); final ISelection selection = state.getSelection(); if (astSelection != null && selection instanceof ITextSelection) { final ITextSelection textSelection = (ITextSelection) selection; if (!(astSelection.getCovering() instanceof RAstNode) || textSelection.getLength() > 0) { return false; } final RAstNode rNode = (RAstNode) astSelection.getCovering(); RElementName name = null; if (!rNode.hasChildren()) { name = RHelpHover.searchName(rNode, rNode, false); } if (name == null) { name = RHelpHover.searchNameOfFunction(rNode, new Region(textSelection.getOffset(), textSelection.getLength())); } if (name == null) { return false; } final IREnv rEnv = RCore.getREnvManager().getDefault(); if (rEnv == null) { return false; } final IRHelpManager rHelpManager = RCore.getRHelpManager(); final IREnvHelp help = rHelpManager.getHelp(rEnv); if (help != null) { final String url; try { if (name.getType() == RElementName.MAIN_PACKAGE) { final IRPkgHelp packageHelp = help.getRPackage(name.getSegmentName()); if (packageHelp != null) { url = rHelpManager.getPackageHttpUrl(packageHelp, RHelpUIServlet.BROWSE_TARGET); } else { url = null; } } else { final List<IRHelpPage> topics = help.getPagesForTopic(name.getSegmentName()); if (topics.size() == 1) { url = rHelpManager.getPageHttpUrl(topics.get(0), RHelpUIServlet.BROWSE_TARGET); } else if (topics.size() > 1) { url = rHelpManager.toHttpUrl("rhelp:///topic/" + name.getSegmentName(), rEnv, RHelpUIServlet.BROWSE_TARGET); } else { url = null; } } } finally { help.unlock(); } if (url != null) { UIAccess.getDisplay().asyncExec(new Runnable() { @Override public void run() { if ((explicite || RHelpView.this.fLinkedEditor != null && RHelpView.this.fLinkedEditor == RHelpView.this.fLinkedEditor.getSite() .getPage().getActiveEditor()) && getPageBook() != null && !getPageBook().isDisposed()) { final BrowserSession session = getCurrentSession(); if (session == null || !url.equals(session.getUrl())) { openUrl(url, session); } } } }); return true; } } } } return false; } @Override public Object getAdapter(final Class required) { if (IShowInTarget.class.equals(required)) { return this; } return super.getAdapter(required); } @Override public boolean show(final ShowInContext context) { final ISelection selection = context.getSelection(); if (selection instanceof LTKInputData) { return show((LTKInputData) selection, true); } return false; } }