/* * ChunkContextToolbar.java * * Copyright (C) 2009-16 by RStudio, Inc. * * Unless you have received this program directly from RStudio pursuant * to the terms of a commercial license agreement with RStudio, then * this program is licensed to you under the terms of version 3 of the * GNU Affero General Public License. This program is distributed WITHOUT * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. * */ package org.rstudio.studio.client.workbench.views.source.editors.text.rmd; import org.rstudio.core.client.BrowseCap; import org.rstudio.core.client.command.AppCommand; import org.rstudio.core.client.resources.ImageResource2x; import org.rstudio.core.client.widget.ToolbarPopupMenu; import org.rstudio.studio.client.RStudioGinjector; import org.rstudio.studio.client.workbench.commands.Commands; import com.google.gwt.core.client.GWT; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.EventListener; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.MenuItem; import com.google.gwt.user.client.ui.PopupPanel.PositionCallback; import com.google.gwt.user.client.ui.Widget; public class ChunkContextToolbar extends Composite { private static ChunkContextToolbarUiBinder uiBinder = GWT .create(ChunkContextToolbarUiBinder.class); interface ChunkContextToolbarUiBinder extends UiBinder<Widget, ChunkContextToolbar> { } public interface Host { void runPreviousChunks(); void runChunk(); void showOptions(int x, int y); void interruptChunk(); void dequeueChunk(); void switchChunk(String chunkType); } public final static ChunkContextResources RES = GWT.create(ChunkContextResources.class); public ChunkContextToolbar(Host host, boolean dark, boolean runPrevious, String engine) { host_ = host; state_ = STATE_RESTING; initWidget(uiBinder.createAndBindUi(this)); initOptions(dark); initRunPrevious(dark); setRunPrevious(runPrevious); initRun(); } // Public methods ---------------------------------------------------------- public void setState(int state) { switch(state) { case STATE_RESTING: run_.setResource(new ImageResource2x(RES.runChunk2x())); break; case STATE_QUEUED: run_.setResource(new ImageResource2x(RES.runChunkPending2x())); break; case STATE_EXECUTING: run_.setResource(new ImageResource2x(RES.interruptChunk2x())); break; } state_ = state; } public void setRunPrevious(boolean visible) { runPrevious_.setVisible(visible); } public void setEngine(String engine) { chunkTypeLabel_.setText(engine); } // Private methods --------------------------------------------------------- private void initOptions(boolean dark) { options_.setResource(new ImageResource2x( dark ? RES.chunkOptionsDark2x() : RES.chunkOptionsLight2x())); DOM.sinkEvents(options_.getElement(), Event.ONCLICK); DOM.setEventListener(options_.getElement(), new EventListener() { @Override public void onBrowserEvent(Event event) { if (DOM.eventGetType(event) == Event.ONCLICK) { host_.showOptions(event.getClientX(), event.getClientY()); } } }); } private void initRun() { setState(state_); run_.setTitle(RStudioGinjector.INSTANCE.getCommands() .executeCurrentChunk().getMenuLabel(false)); DOM.sinkEvents(run_.getElement(), Event.ONCLICK); DOM.setEventListener(run_.getElement(), new EventListener() { @Override public void onBrowserEvent(Event event) { if (DOM.eventGetType(event) == Event.ONCLICK) { switch(state_) { case STATE_RESTING: host_.runChunk(); break; case STATE_QUEUED: host_.dequeueChunk(); break; case STATE_EXECUTING: host_.interruptChunk(); break; } } } }); } private void initRunPrevious(boolean dark) { runPrevious_.setTitle(RStudioGinjector.INSTANCE.getCommands() .executePreviousChunks().getMenuLabel(false)); runPrevious_.setResource(new ImageResource2x( dark ? RES.runPreviousChunksDark2x() : RES.runPreviousChunksLight2x())); DOM.sinkEvents(runPrevious_.getElement(), Event.ONCLICK); DOM.setEventListener(runPrevious_.getElement(), new EventListener() { @Override public void onBrowserEvent(Event event) { if (DOM.eventGetType(event) == Event.ONCLICK) { host_.runPreviousChunks(); } } }); } private MenuItem createMenuItemForType(final AppCommand command, final String chunkType) { SafeHtml menuHTML = new SafeHtmlBuilder().appendHtmlConstant( command.getMenuHTML(false)).toSafeHtml(); MenuItem menuItem = new MenuItem( menuHTML, new Command() { public void execute() { host_.switchChunk(chunkType); } }); return menuItem; } @SuppressWarnings("unused") private void initChangeChunkEngine(String engine) { chunkTypeLabel_.setText(engine); DOM.sinkEvents(chunkTypePanel_.getElement(), Event.ONCLICK); DOM.setEventListener(chunkTypePanel_.getElement(), new EventListener() { @Override public void onBrowserEvent(Event event) { if (DOM.eventGetType(event) == Event.ONCLICK) { Commands commands = RStudioGinjector.INSTANCE.getCommands(); String engineLabel = chunkTypeLabel_.getText(); final ToolbarPopupMenu switchChunksMenu = new ToolbarPopupMenu(); if (engineLabel != "r") { switchChunksMenu.addItem(createMenuItemForType( commands.switchToChunkR(), "r")); switchChunksMenu.addSeparator(); } if (!BrowseCap.isWindowsDesktop() && engineLabel != "bash") { switchChunksMenu.addItem(createMenuItemForType( commands.switchToChunkBash(), "bash")); } if (engineLabel != "python") { switchChunksMenu.addItem(createMenuItemForType( commands.switchToChunkPython(), "python")); } if (engineLabel != "rcpp") { switchChunksMenu.addItem(createMenuItemForType( commands.switchToChunkRCPP(), "rcpp")); } if (engineLabel != "sql") { switchChunksMenu.addItem(createMenuItemForType( commands.switchToChunkSQL(), "sql")); } if (engineLabel != "stan") { switchChunksMenu.addItem(createMenuItemForType( commands.switchToChunkStan(), "stan")); } switchChunksMenu.setPopupPositionAndShow(new PositionCallback() { @Override public void setPosition(int offsetWidth, int offsetHeight) { switchChunksMenu.setPopupPosition( chunkTypePanel_.getAbsoluteLeft() + chunkTypePanel_.getOffsetWidth() - offsetWidth + 15, chunkTypePanel_.getAbsoluteTop() + chunkTypePanel_.getOffsetHeight()); } }); } } }); } @UiField Image options_; @UiField Image runPrevious_; @UiField Image run_; @UiField Label chunkTypeLabel_; @UiField HTMLPanel chunkTypePanel_; private final Host host_; private int state_; public final static int STATE_QUEUED = 0; public final static int STATE_EXECUTING = 1; public final static int STATE_RESTING = 2; public final static String LINE_WIDGET_TYPE = "ChunkToolbar"; }