private void renderNotebookv2WithDialog(final DocUpdateSentinel sourceDoc) { // default format String format = sourceDoc.getProperty(NOTEBOOK_FORMAT); if (StringUtil.isNullOrEmpty(format)) { format = prefs_.compileNotebookv2Options().getValue().getFormat(); if (StringUtil.isNullOrEmpty(format)) format = CompileNotebookv2Options.FORMAT_DEFAULT; } CompileNotebookv2OptionsDialog dialog = new CompileNotebookv2OptionsDialog( format, new OperationWithInput<CompileNotebookv2Options>() { @Override public void execute(CompileNotebookv2Options input) { renderNotebookv2(sourceDoc, input.getFormat()); // save options for this document HashMap<String, String> changedProperties = new HashMap<String, String>(); changedProperties.put(NOTEBOOK_FORMAT, input.getFormat()); sourceDoc.modifyProperties(changedProperties, null); // save global prefs CompileNotebookv2Prefs prefs = CompileNotebookv2Prefs.create(input.getFormat()); if (!CompileNotebookv2Prefs.areEqual( prefs, prefs_.compileNotebookv2Options().getValue())) { prefs_.compileNotebookv2Options().setGlobalValue(prefs); prefs_.writeUIPrefs(); } } }); dialog.showModal(); }
private boolean recomputeVisibility() { // if all publishing is disabled, hide ourselves if (!session_.getSessionInfo().getAllowPublish() || !pUiPrefs_.get().showPublishUi().getGlobalValue()) return false; // if both internal and external publishing is disabled, hide ourselves if (!session_.getSessionInfo().getAllowExternalPublish() && !pUiPrefs_.get().enableRStudioConnect().getGlobalValue()) return false; // if we're bound to a command's visibility/enabled state, check that if (boundCommand_ != null && (!boundCommand_.isVisible() || !boundCommand_.isEnabled())) return false; // if we have no content type, hide ourselves if (contentType_ == RSConnect.CONTENT_TYPE_NONE) return false; // if we do have a content type, ensure that we have actual content // bound to it if ((contentType_ == RSConnect.CONTENT_TYPE_HTML || contentType_ == RSConnect.CONTENT_TYPE_PLOT || contentType_ == RSConnect.CONTENT_TYPE_PRES) && publishHtmlSource_ == null) return false; if ((contentType_ == RSConnect.CONTENT_TYPE_APP || contentType_ == RSConnect.CONTENT_TYPE_APP_SINGLE) && StringUtil.isNullOrEmpty(contentPath_)) return false; if (manuallyHidden_) return false; // looks like we should be visible return true; }
public void setRmd(String rmd, boolean isStatic) { docPreview_ = new RenderedDocPreview(rmd, "", isStatic); setContentPath(rmd, ""); SessionInfo sessionInfo = session_.getSessionInfo(); String buildType = sessionInfo.getBuildToolsType(); boolean setType = false; if (buildType.equals(SessionInfo.BUILD_TOOLS_WEBSITE)) { // if this is an Rmd with a content path if (contentType_ == RSConnect.CONTENT_TYPE_DOCUMENT && !StringUtil.isNullOrEmpty(contentPath_)) { // ...and if the content path is within the website dir, String websiteDir = sessionInfo.getBuildTargetDir(); if (contentPath_.startsWith(websiteDir)) { setType = true; setContentType(RSConnect.CONTENT_TYPE_WEBSITE); } } } // if we haven't set the type yet, apply it if (!setType) setContentType(RSConnect.CONTENT_TYPE_DOCUMENT); applyVisiblity(); }
public void onSendToConsole(final SendToConsoleEvent event) { final InputEditorDisplay display = view_.getInputEditorDisplay(); // get anything already at the console final String previousInput = StringUtil.notNull(display.getText()); // define code block we execute at finish Command finishSendToConsole = new Command() { @Override public void execute() { if (event.shouldExecute()) { processCommandEntry(); if (previousInput.length() > 0) display.setText(previousInput); } if (!event.shouldExecute() || event.shouldFocus()) { display.setFocus(true); display.collapseSelection(false); } } }; // do standrd finish if we aren't animating if (!event.shouldAnimate()) { display.clear(); display.setText(event.getCode()); finishSendToConsole.execute(); } else { inputAnimator_.enque(event.getCode(), finishSendToConsole); } }
public String processCommandEntry() { // parse out the command text String promptText = prompt_.getElement().getInnerText(); String commandText = input_.getCode(); input_.setText(""); // Force render to avoid subtle command movement in the console, caused // by the prompt disappearing before the input line does input_.forceImmediateRender(); prompt_.setHTML(""); SpanElement pendingPrompt = Document.get().createSpanElement(); pendingPrompt.setInnerText(promptText); pendingPrompt.setClassName(styles_.prompt() + " " + KEYWORD_CLASS_NAME); if (!suppressPendingInput_ && !input_.isPasswordMode()) { SpanElement pendingInput = Document.get().createSpanElement(); pendingInput.setInnerText(StringUtil.notNull(commandText).split("\n")[0] + "\n"); pendingInput.setClassName(styles_.command() + " " + KEYWORD_CLASS_NAME); pendingInput_.getElement().appendChild(pendingPrompt); pendingInput_.getElement().appendChild(pendingInput); pendingInput_.setVisible(true); } ensureInputVisible(); return commandText; }
public void setCode(String code, boolean preserveCursorPosition) { // Calling setCode("", false) while the editor contains multiple lines of // content causes bug 2928: Flickering console when typing. Empirically, // first setting code to a single line of content and then clearing it, // seems to correct this problem. if (StringUtil.isNullOrEmpty(code)) doSetCode(" ", preserveCursorPosition); doSetCode(code, preserveCursorPosition); }
@Override public void onRPubsPublishStatus(RPubsUploadStatusEvent event) { // make sure it applies to our context RPubsUploadStatusEvent.Status status = event.getStatus(); if (StringUtil.isNullOrEmpty(status.getError())) { populateDeployments(true); } }
public void setText(String label) { if (!StringUtil.isNullOrEmpty(label)) { label_.setInnerText(label); label_.getStyle().setDisplay(Display.BLOCK); removeStyleName(styles_.noLabel()); } else { label_.getStyle().setDisplay(Display.NONE); addStyleName(styles_.noLabel()); } }
public void consolePrompt(String prompt, boolean showInput) { if (prompt != null) prompt = VirtualConsole.consolify(prompt); prompt_.getElement().setInnerText(prompt); // input_.clear() ; ensureInputVisible(); // Deal gracefully with multi-line prompts int promptLines = StringUtil.notNull(prompt).split("\\n").length; input_.asWidget().getElement().getStyle().setPaddingTop((promptLines - 1) * 15, Unit.PX); input_.setPasswordMode(!showInput); }
private String makeCommand(ImportFileSettings input) { HashMap<String, ImportFileSettings> commandDefaults_ = new HashMap<String, ImportFileSettings>(); commandDefaults_.put("read.table", new ImportFileSettings(null, null, false, "", ".", "\"'")); commandDefaults_.put("read.csv", new ImportFileSettings(null, null, true, ",", ".", "\"")); commandDefaults_.put("read.delim", new ImportFileSettings(null, null, true, "\t", ".", "\"")); commandDefaults_.put("read.csv2", new ImportFileSettings(null, null, true, ";", ",", "\"")); commandDefaults_.put("read.delim2", new ImportFileSettings(null, null, true, "\t", ",", "\"")); String command = "read.table"; ImportFileSettings settings = commandDefaults_.get("read.table"); int score = settings.calculateSimilarity(input); for (String cmd : new String[] {"read.csv", "read.delim"}) { ImportFileSettings theseSettings = commandDefaults_.get(cmd); int thisScore = theseSettings.calculateSimilarity(input); if (thisScore > score) { score = thisScore; command = cmd; settings = theseSettings; } } StringBuilder code = new StringBuilder(command); code.append("("); code.append(StringUtil.textToRLiteral(input.getFile().getPath())); if (input.isHeader() != settings.isHeader()) code.append(", header=" + (input.isHeader() ? "T" : "F")); if (!input.getSep().equals(settings.getSep())) code.append(", sep=" + StringUtil.textToRLiteral(input.getSep())); if (!input.getDec().equals(settings.getDec())) code.append(", dec=" + StringUtil.textToRLiteral(input.getDec())); if (!input.getQuote().equals(settings.getQuote())) code.append(", quote=" + StringUtil.textToRLiteral(input.getQuote())); code.append(")"); return code.toString(); }
public static int parseDisableModes(String disableModes) { int mode = KeyboardShortcut.MODE_NONE; if (StringUtil.isNullOrEmpty(disableModes)) return mode; String[] splat = disableModes.split(","); for (String item : splat) { if (item.equals("default")) mode |= KeyboardShortcut.MODE_DEFAULT; else if (item.equals("vim")) mode |= KeyboardShortcut.MODE_VIM; else if (item.equals("emacs")) mode |= KeyboardShortcut.MODE_EMACS; else assert false : "Unrecognized 'disableModes' value '" + item + "'"; } return mode; }
private String createPrefix() { StringBuilder builder = new StringBuilder(); String title = txtTitle_.getValue().trim(); if (title.length() > 0) { builder.append("### ").append(SafeHtmlUtils.htmlEscape(title)).append("\n"); } String author = txtAuthor_.getValue().trim(); if (author.length() > 0) { builder.append(SafeHtmlUtils.htmlEscape(author)).append(" --- "); } builder.append("*"); builder.append(StringUtil.formatDate(new Date())); builder.append("*"); return builder.toString(); }
@Override public void onRmdRenderCompleted(RmdRenderCompletedEvent event) { // ensure we got a result--note that even a cancelled render generates an // event, but with an empty output file if (rmdRenderPending_ && event.getResult() != null && !StringUtil.isNullOrEmpty(event.getResult().getOutputFile())) { RenderedDocPreview docPreview = new RenderedDocPreview(event.getResult()); events_.fireEvent( RSConnectActionEvent.DeployDocEvent( docPreview, event.getResult().isWebsite() ? RSConnect.CONTENT_TYPE_WEBSITE : RSConnect.CONTENT_TYPE_DOCUMENT, publishAfterRmdRender_)); } publishAfterRmdRender_ = null; rmdRenderPending_ = false; anyRmdRenderPending_ = false; }
@Override public void onRSConnectDeploymentStarted(RSConnectDeploymentStartedEvent event) { switchToConsoleAfterDeploy_ = !view_.isEffectivelyVisible(); view_.ensureVisible(true); // show the filename in the deployment tab, unless we're deploying an // HTML file for which we know the title--this may very well be a // temporary file String title = event.getPath(); if (title == null) title = ""; if ((title.isEmpty() || title.toLowerCase().endsWith(".htm") || title.toLowerCase().endsWith(".html") && !StringUtil.isNullOrEmpty(event.getTitle()))) { title = event.getTitle(); } view_.compileStarted(title); setIsBusy(true); }
public boolean hasDocOutput() { return originatingEvent_ != null && originatingEvent_.getFromPreview() != null && !StringUtil.isNullOrEmpty(originatingEvent_.getFromPreview().getOutputFile()); }
public String getText() { return StringUtil.notNull(label_.getInnerText()); }
public void endDrag(final Event evt, int action) { if (curState_ == STATE_NONE) return; // remove the properties used to position for dragging if (dragElement_ != null) { dragElement_.getStyle().clearLeft(); dragElement_.getStyle().clearPosition(); dragElement_.getStyle().clearZIndex(); dragElement_.getStyle().clearDisplay(); dragElement_.getStyle().clearOpacity(); // insert this tab where the placeholder landed if we're not // cancelling if (action == ACTION_COMMIT) { dragTabsHost_.removeChild(dragElement_); dragTabsHost_.insertAfter(dragElement_, dragPlaceholder_); } } // remove the placeholder if (dragPlaceholder_ != null) { dragTabsHost_.removeChild(dragPlaceholder_); dragPlaceholder_ = null; } if (dragElement_ != null && action == ACTION_EXTERNAL) { // if we own the dragged tab, change to external drag state dragElement_.getStyle().setOpacity(0.4); curState_ = STATE_EXTERNAL; } else { // otherwise, we're back to pristine curState_ = STATE_NONE; events_.fireEvent(new DocTabDragStateChangedEvent(DocTabDragStateChangedEvent.STATE_NONE)); } if (dragElement_ != null && action == ACTION_COMMIT) { // let observer know we moved; adjust the destination position one to // the left if we're right of the start position to account for the // position of the tab prior to movement if (startPos_ != null && startPos_ != destPos_) { TabReorderEvent event = new TabReorderEvent(startPos_, destPos_); fireEvent(event); } } // this is the case when we adopt someone else's doc if (dragElement_ == null && evt != null && action == ACTION_COMMIT) { // pull the document ID and source window out String data = evt.getDataTransfer().getData(getDataTransferFormat()); if (StringUtil.isNullOrEmpty(data)) return; // the data format is docID|windowID; windowID can be omitted if // the main window is the origin String pieces[] = data.split("\\|"); if (pieces.length < 1) return; events_.fireEvent( new DocWindowChangedEvent( pieces[0], pieces.length > 1 ? pieces[1] : "", initDragParams_, destPos_)); } // this is the case when our own drag ends; if it ended outside our // window and outside all satellites, treat it as a tab tear-off if (dragElement_ != null && evt != null && action == ACTION_CANCEL) { // if this is the last tab in satellite, we don't want to tear // it out boolean isLastSatelliteTab = docTabs_.size() == 1 && Satellite.isCurrentWindowSatellite(); // did the user drag the tab outside this doc? if (!isLastSatelliteTab && DomUtils.elementFromPoint(evt.getClientX(), evt.getClientY()) == null) { // did it end in any RStudio satellite window? String targetWindowName; Satellite satellite = RStudioGinjector.INSTANCE.getSatellite(); if (Satellite.isCurrentWindowSatellite()) { // this is a satellite, ask the main window targetWindowName = satellite.getWindowAtPoint(evt.getScreenX(), evt.getScreenY()); } else { // this is the main window, query our own satellites targetWindowName = RStudioGinjector.INSTANCE .getSatelliteManager() .getWindowAtPoint(evt.getScreenX(), evt.getScreenY()); } if (targetWindowName == null) { // it was dragged over nothing RStudio owns--pop it out events_.fireEvent( new PopoutDocInitiatedEvent( initDragParams_.getDocId(), new Point(evt.getScreenX(), evt.getScreenY()))); } } } if (curState_ != STATE_EXTERNAL) { // if we're in an end state, clear the drag element dragElement_ = null; } }
public final boolean isVcsEnabled() { return !StringUtil.isNullOrEmpty(getVcsName()); }
private void onPublishRecordClick(final RSConnectDeploymentRecord previous) { switch (contentType_) { case RSConnect.CONTENT_TYPE_HTML: case RSConnect.CONTENT_TYPE_PRES: if (publishHtmlSource_ == null) { display_.showErrorMessage( "Content Publish Failed", "No HTML could be generated for the content."); return; } publishHtmlSource_.generatePublishHtml( new CommandWithArg<String>() { @Override public void execute(String arg) { events_.fireEvent( RSConnectActionEvent.DeployHtmlEvent( contentType_, contentPath_, arg, publishHtmlSource_.getTitle(), previous)); } }); break; case RSConnect.CONTENT_TYPE_PLOT: // for plots, we need to generate the hosting HTML prior to publishing if (publishHtmlSource_ != null) { publishHtmlSource_.generatePublishHtml( new CommandWithArg<String>() { @Override public void execute(String htmlFile) { events_.fireEvent(RSConnectActionEvent.DeployPlotEvent(htmlFile, previous)); } }); } break; case RSConnect.CONTENT_TYPE_APP: case RSConnect.CONTENT_TYPE_APP_SINGLE: // Shiny application events_.fireEvent( RSConnectActionEvent.DeployAppEvent(contentPath_, contentType_, previous)); break; case RSConnect.CONTENT_TYPE_DOCUMENT: if (docPreview_ == null || (docPreview_.isStatic() && StringUtil.isNullOrEmpty(docPreview_.getOutputFile()) && docPreview_.getSourceFile() != null)) { // if the doc has been saved but not been rendered, go render it and // come back when we're finished renderThenPublish(contentPath_, previous); } else { // All R Markdown variants (single/multiple and static/Shiny) if (docPreview_.getSourceFile() == null) { display_.showErrorMessage( "Unsaved Document", "Unsaved documents cannot be published. Save the document " + "before publishing it."); break; } events_.fireEvent( RSConnectActionEvent.DeployDocEvent( docPreview_, RSConnect.CONTENT_TYPE_DOCUMENT, previous)); } break; case RSConnect.CONTENT_TYPE_WEBSITE: events_.fireEvent( RSConnectActionEvent.DeployDocEvent( docPreview_, RSConnect.CONTENT_TYPE_WEBSITE, previous)); break; default: // should never happen display_.showErrorMessage( "Can't Publish " + RSConnect.contentTypeDesc(contentType_), "The content type '" + RSConnect.contentTypeDesc(contentType_) + "' is not currently supported for publishing."); } }
private void executeFunctionForObject(String function, String objectName) { String editCode = function + "(" + StringUtil.toRSymbolName(objectName) + ")"; SendToConsoleEvent event = new SendToConsoleEvent(editCode, true); eventBus_.fireEvent(event); }
public String getPromptText() { return StringUtil.notNull(prompt_.getText()); }
public boolean isPromptEmpty() { return StringUtil.isNullOrEmpty(prompt_.getText()); }
// rebuilds the popup menu--this can happen when the menu is invoked; it can // also happen when the button is created if we're aggressively checking // publish status private void rebuildPopupMenu(final ToolbarPopupMenu.DynamicPopupMenuCallback callback) { final ToolbarPopupMenu menu = publishMenu_; // prevent reentrancy if (populating_) { if (callback != null) callback.onPopupMenu(menu); return; } // handle case where we don't have a content path (i.e. plots) if (contentPath_ == null) { setPreviousDeployments(null); if (callback != null) callback.onPopupMenu(menu); return; } // avoid populating if we've already set the deployments for this path // (unless we're forcefully repopulating) if (populatedPath_ != null && populatedPath_.equals(contentPath_)) { if (callback != null) callback.onPopupMenu(menu); return; } String contentPath = contentPath_; boolean parent = false; // if this is a Shiny application and an .R file is being invoked, check // for deployments of its parent path (single-file apps have // CONTENT_TYPE_APP_SINGLE and their own deployment records) if (contentType_ == RSConnect.CONTENT_TYPE_APP && StringUtil.getExtension(contentPath_).equalsIgnoreCase("r")) parent = true; // if this is a document in a website, use the parent path if (contentType_ == RSConnect.CONTENT_TYPE_WEBSITE) parent = true; // apply parent path if needed if (parent) { FileSystemItem fsiContent = FileSystemItem.createFile(contentPath_); contentPath = fsiContent.getParentPathString(); } populating_ = true; server_.getRSConnectDeployments( contentPath, outputPath_ == null ? "" : outputPath_, new ServerRequestCallback<JsArray<RSConnectDeploymentRecord>>() { @Override public void onResponseReceived(JsArray<RSConnectDeploymentRecord> recs) { populatedPath_ = contentPath_; populating_ = false; // if publishing a website but not content, filter deployments // that are static (as we can't update them) if (contentType_ == RSConnect.CONTENT_TYPE_WEBSITE && (docPreview_ == null || StringUtil.isNullOrEmpty(docPreview_.getOutputFile()))) { JsArray<RSConnectDeploymentRecord> codeRecs = JsArray.createArray().cast(); for (int i = 0; i < recs.length(); i++) { if (!recs.get(i).getAsStatic()) codeRecs.push(recs.get(i)); } recs = codeRecs; } setPreviousDeployments(recs); if (callback != null) callback.onPopupMenu(menu); } @Override public void onError(ServerError error) { populating_ = false; if (callback != null) callback.onPopupMenu(menu); } }); }
private boolean output(String text, String className, boolean addToTop) { if (text.indexOf('\f') >= 0) clearOutput(); Node node; boolean isOutput = StringUtil.isNullOrEmpty(className) || className.equals(styles_.output()); if (isOutput && !addToTop && trailingOutput_ != null) { // Short-circuit the case where we're appending output to the // bottom, and there's already some output there. We need to // treat this differently in case the new output uses control // characters to pound over parts of the previous output. int oldLineCount = DomUtils.countLines(trailingOutput_, true); trailingOutputConsole_.submit(text); trailingOutput_.setNodeValue(ensureNewLine(trailingOutputConsole_.toString())); int newLineCount = DomUtils.countLines(trailingOutput_, true); lines_ += newLineCount - oldLineCount; } else { Element outEl = output_.getElement(); text = VirtualConsole.consolify(text); if (isOutput) { VirtualConsole console = new VirtualConsole(); console.submit(text); String consoleSnapshot = console.toString(); // We use ensureNewLine to make sure that even if output // doesn't end with \n, a prompt will appear on its own line. // However, if we call ensureNewLine indiscriminantly (i.e. // on an output that's going to be followed by another output) // we can end up inserting newlines where they don't belong. // // It's safe to add a newline when we're appending output to // the end of the console, because if the next append is also // output, we'll use the contents of VirtualConsole and the // newline we add here will be plowed over. // // If we're prepending output to the top of the console, then // it's safe to add a newline if the next chunk (which is already // there) is something besides output. if (!addToTop || (!outEl.hasChildNodes() || outEl.getFirstChild().getNodeType() != Node.TEXT_NODE)) { consoleSnapshot = ensureNewLine(consoleSnapshot); } node = Document.get().createTextNode(consoleSnapshot); if (!addToTop) { trailingOutput_ = (Text) node; trailingOutputConsole_ = console; } } else { SpanElement span = Document.get().createSpanElement(); span.setClassName(className); span.setInnerText(text); node = span; if (!addToTop) { trailingOutput_ = null; trailingOutputConsole_ = null; } } if (addToTop) outEl.insertFirst(node); else outEl.appendChild(node); lines_ += DomUtils.countLines(node, true); } return !trimExcess(); }