Search in sources :

Example 76 with ScheduledCommand

use of com.google.gwt.core.client.Scheduler.ScheduledCommand in project rstudio by rstudio.

the class ProfilerEditingTarget method onActivate.

public void onActivate() {
    activeProfilerEditingTarger_ = this;
    Scheduler.get().scheduleDeferred(new ScheduledCommand() {

        public void execute() {
            commands_.gotoProfileSource().setEnabled(hasValidPath_);
        }
    });
    final Operation activateOperation = new Operation() {

        @Override
        public void execute() {
            if (!htmlPathInitialized_) {
                htmlPathInitialized_ = true;
                htmlPath_ = getContents().getHtmlPath();
                htmlLocalPath_ = getContents().getHtmlLocalPath();
                isUserSaved_ = getContents().isUserSaved();
                if (htmlPath_ == null) {
                    presenter_.buildHtmlPath(new OperationWithInput<ProfileOperationResponse>() {

                        @Override
                        public void execute(ProfileOperationResponse response) {
                            htmlPath_ = response.getHtmlPath();
                            htmlLocalPath_ = response.getHtmlLocalPath();
                            persistDocumentProperty("htmlPath", htmlPath_);
                            persistDocumentProperty("htmlLocalPath", htmlLocalPath_);
                            view_.showProfilePage(htmlPath_);
                            pSourceWindowManager_.get().maximizeSourcePaneIfNecessary();
                        }
                    }, new Operation() {

                        @Override
                        public void execute() {
                            server_.clearProfile(getPath(), new ServerRequestCallback<JavaScriptObject>() {

                                @Override
                                public void onResponseReceived(JavaScriptObject response) {
                                    commands_.closeSourceDoc().execute();
                                }

                                @Override
                                public void onError(ServerError error) {
                                    Debug.logError(error);
                                    commands_.closeSourceDoc().execute();
                                }
                            });
                        }
                    }, getPath());
                } else {
                    view_.showProfilePage(htmlPath_);
                    Scheduler.get().scheduleDeferred(new ScheduledCommand() {

                        public void execute() {
                            pSourceWindowManager_.get().maximizeSourcePaneIfNecessary();
                        }
                    });
                }
            }
        }
    };
    if (getId() != null && !SourceWindowManager.isMainSourceWindow()) {
        sourceServer_.getSourceDocument(getId(), new ServerRequestCallback<SourceDocument>() {

            @Override
            public void onResponseReceived(SourceDocument document) {
                doc_ = document;
                activateOperation.execute();
            }

            @Override
            public void onError(ServerError error) {
                Debug.logError(error);
            }
        });
    } else {
        activateOperation.execute();
    }
    // This shouldn't happen though.
    if (commandHandlerReg_ != null) {
        Debug.log("Warning: onActivate called twice without intervening onDeactivate");
        commandHandlerReg_.removeHandler();
        commandHandlerReg_ = null;
    }
    commandHandlerReg_ = commandBinder.bind(commands_, this);
}
Also used : ScheduledCommand(com.google.gwt.core.client.Scheduler.ScheduledCommand) JavaScriptObject(com.google.gwt.core.client.JavaScriptObject) ServerError(org.rstudio.studio.client.server.ServerError) SourceDocument(org.rstudio.studio.client.workbench.views.source.model.SourceDocument) ServerRequestCallback(org.rstudio.studio.client.server.ServerRequestCallback) ProfileOperationResponse(org.rstudio.studio.client.workbench.views.source.editors.profiler.model.ProfileOperationResponse) Operation(org.rstudio.core.client.widget.Operation)

Example 77 with ScheduledCommand

use of com.google.gwt.core.client.Scheduler.ScheduledCommand in project rstudio by rstudio.

the class TabOverflowPopupPanel method show.

@Override
public void show() {
    super.show();
    Scheduler.get().scheduleDeferred(new ScheduledCommand() {

        public void execute() {
            search_.focus();
        }
    });
}
Also used : ScheduledCommand(com.google.gwt.core.client.Scheduler.ScheduledCommand)

Example 78 with ScheduledCommand

use of com.google.gwt.core.client.Scheduler.ScheduledCommand in project rstudio by rstudio.

the class SavePlotAsHandler method webSavePlotAs.

private void webSavePlotAs(final FileSystemItem targetPath, final boolean overwrite, final boolean viewAfterSave, final Operation onCompleted) {
    globalDisplay_.openProgressWindow("_blank", "Converting Plot...", new OperationWithInput<WindowEx>() {

        public void execute(final WindowEx window) {
            savePlotAs(targetPath, overwrite, viewAfterSave, onCompleted, new PlotSaveAsUIHandler() {

                @Override
                public void onSuccess() {
                    // redirect window to view file
                    final String url = server_.getFileUrl(targetPath);
                    Scheduler.get().scheduleDeferred(new ScheduledCommand() {

                        @Override
                        public void execute() {
                            window.replaceLocationHref(url);
                        }
                    });
                }

                @Override
                public void onError(ServerError error) {
                    window.close();
                    globalDisplay_.showErrorMessage("Error Saving Plot", error.getUserMessage());
                }

                @Override
                public void onOverwritePrompt() {
                    window.close();
                }
            });
        }
    });
}
Also used : ScheduledCommand(com.google.gwt.core.client.Scheduler.ScheduledCommand) ServerError(org.rstudio.studio.client.server.ServerError) WindowEx(org.rstudio.core.client.dom.WindowEx)

Example 79 with ScheduledCommand

use of com.google.gwt.core.client.Scheduler.ScheduledCommand in project rstudio by rstudio.

the class AceEditorWidget method removeMarkersOnCursorLine.

public void removeMarkersOnCursorLine() {
    // Defer this so other event handling can update anchors etc.
    Scheduler.get().scheduleDeferred(new ScheduledCommand() {

        @Override
        public void execute() {
            int cursorRow = editor_.getCursorPosition().getRow();
            JsArray<AceAnnotation> newAnnotations = JsArray.createArray().cast();
            for (int i = 0; i < annotations_.size(); i++) {
                AnchoredAceAnnotation annotation = annotations_.get(i);
                int markerId = annotation.getMarkerId();
                Marker marker = editor_.getSession().getMarker(markerId);
                // a previous action.
                if (marker == null)
                    continue;
                Range range = marker.getRange();
                int rowStart = range.getStart().getRow();
                int rowEnd = range.getEnd().getRow();
                if (cursorRow >= rowStart && cursorRow <= rowEnd)
                    editor_.getSession().removeMarker(markerId);
                else
                    newAnnotations.push(annotation.asAceAnnotation());
            }
            editor_.getSession().setAnnotations(newAnnotations);
            editor_.getRenderer().renderMarkers();
        }
    });
}
Also used : JsArray(com.google.gwt.core.client.JsArray) ScheduledCommand(com.google.gwt.core.client.Scheduler.ScheduledCommand) Marker(org.rstudio.studio.client.workbench.views.source.editors.text.ace.Marker) Range(org.rstudio.studio.client.workbench.views.source.editors.text.ace.Range) AnchoredRange(org.rstudio.studio.client.workbench.views.source.editors.text.ace.AnchoredRange)

Example 80 with ScheduledCommand

use of com.google.gwt.core.client.Scheduler.ScheduledCommand in project rstudio by rstudio.

the class ImagePreviewer method onPreviewImageLineWidget.

private static void onPreviewImageLineWidget(final DocDisplay display, final DocUpdateSentinel sentinel, final String href, final String attributes, final Position position, final Range tokenRange) {
    // if we already have a line widget for this row, bail
    LineWidget lineWidget = display.getLineWidgetForRow(position.getRow());
    if (lineWidget != null)
        return;
    // shared mutable state that we hide in this closure
    final Mutable<PinnedLineWidget> plw = new Mutable<PinnedLineWidget>();
    final Mutable<ChunkOutputWidget> cow = new Mutable<ChunkOutputWidget>();
    final Mutable<HandlerRegistration> docChangedHandler = new Mutable<HandlerRegistration>();
    final Mutable<HandlerRegistration> renderHandler = new Mutable<HandlerRegistration>();
    // command that ensures state is cleaned up when widget hidden
    final Command onDetach = new Command() {

        private void detach() {
            // detach chunk output widget
            cow.set(null);
            // detach pinned line widget
            if (plw.get() != null)
                plw.get().detach();
            plw.set(null);
            // detach render handler
            if (renderHandler.get() != null)
                renderHandler.get().removeHandler();
            renderHandler.set(null);
            // detach doc changed handler
            if (docChangedHandler.get() != null)
                docChangedHandler.get().removeHandler();
            docChangedHandler.set(null);
        }

        @Override
        public void execute() {
            // if the associated chunk output widget has been cleaned up,
            // make a last-ditch detach effort anyhow
            ChunkOutputWidget widget = cow.get();
            if (widget == null) {
                detach();
                return;
            }
            // fade out and then detach
            FadeOutAnimation anim = new FadeOutAnimation(widget, new Command() {

                @Override
                public void execute() {
                    detach();
                }
            });
            anim.run(400);
        }
    };
    // construct placeholder for image
    final SimplePanel container = new SimplePanel();
    container.addStyleName(RES.styles().container());
    final Label noImageLabel = new Label("(No image at path " + href + ")");
    // resize command (used by various routines that need to respond
    // to width / height change events)
    final CommandWithArg<Integer> onResize = new CommandWithArg<Integer>() {

        private int state_ = -1;

        @Override
        public void execute(Integer height) {
            // defend against missing chunk output widget (can happen if a widget
            // is closed / dismissed before image finishes loading)
            ChunkOutputWidget widget = cow.get();
            if (widget == null)
                return;
            // don't resize if the chunk widget if we were already collapsed
            int state = widget.getExpansionState();
            if (state == state_ && state == ChunkOutputWidget.COLLAPSED)
                return;
            state_ = state;
            widget.getFrame().setHeight(height + "px");
            LineWidget lw = plw.get().getLineWidget();
            lw.setPixelHeight(height);
            display.onLineWidgetChanged(lw);
        }
    };
    // construct our image
    String srcPath = imgSrcPathFromHref(sentinel, href);
    final Image image = new Image(srcPath);
    image.addStyleName(RES.styles().image());
    // parse and inject attributes
    Map<String, String> parsedAttributes = HTMLAttributesParser.parseAttributes(attributes);
    final Element imgEl = image.getElement();
    for (Map.Entry<String, String> entry : parsedAttributes.entrySet()) {
        String key = entry.getKey();
        String val = entry.getValue();
        if (StringUtil.isNullOrEmpty(key) || StringUtil.isNullOrEmpty(val))
            continue;
        imgEl.setAttribute(key, val);
    }
    // add load handlers to image
    DOM.sinkEvents(imgEl, Event.ONLOAD | Event.ONERROR);
    DOM.setEventListener(imgEl, new EventListener() {

        @Override
        public void onBrowserEvent(Event event) {
            if (DOM.eventGetType(event) == Event.ONLOAD) {
                final ImageElementEx imgEl = image.getElement().cast();
                int minWidth = Math.min(imgEl.naturalWidth(), 100);
                int maxWidth = Math.min(imgEl.naturalWidth(), 650);
                Style style = imgEl.getStyle();
                boolean hasWidth = imgEl.hasAttribute("width") || style.getProperty("width") != null;
                if (!hasWidth) {
                    style.setProperty("width", "100%");
                    style.setProperty("minWidth", minWidth + "px");
                    style.setProperty("maxWidth", maxWidth + "px");
                }
                // attach to container
                container.setWidget(image);
                // update widget
                int height = image.getOffsetHeight() + 10;
                onResize.execute(height);
            } else if (DOM.eventGetType(event) == Event.ONERROR) {
                container.setWidget(noImageLabel);
                onResize.execute(50);
            }
        }
    });
    // handle editor resize events
    final Timer renderTimer = new Timer() {

        @Override
        public void run() {
            int height = image.getOffsetHeight() + 30;
            onResize.execute(height);
        }
    };
    // initialize render handler
    renderHandler.set(display.addRenderFinishedHandler(new RenderFinishedEvent.Handler() {

        private int width_;

        @Override
        public void onRenderFinished(RenderFinishedEvent event) {
            int width = display.getBounds().getWidth();
            if (width == width_)
                return;
            width_ = width;
            renderTimer.schedule(100);
        }
    }));
    // initialize doc changed handler
    docChangedHandler.set(display.addDocumentChangedHandler(new DocumentChangedEvent.Handler() {

        private String href_ = href;

        private String attributes_ = StringUtil.notNull(attributes);

        private final Timer refreshImageTimer = new Timer() {

            @Override
            public void run() {
                // if the discovered href isn't an image link, just bail
                if (!ImagePreviewer.isImageHref(href_))
                    return;
                // set new src location (load handler will replace label as needed)
                container.setWidget(new SimplePanel());
                noImageLabel.setText("(No image at path " + href_ + ")");
                image.getElement().setAttribute("src", imgSrcPathFromHref(sentinel, href_));
                // parse and inject attributes
                Map<String, String> parsedAttributes = HTMLAttributesParser.parseAttributes(attributes_);
                final Element imgEl = image.getElement();
                for (Map.Entry<String, String> entry : parsedAttributes.entrySet()) {
                    String key = entry.getKey();
                    String val = entry.getValue();
                    if (StringUtil.isNullOrEmpty(key) || StringUtil.isNullOrEmpty(val))
                        continue;
                    imgEl.setAttribute(key, val);
                }
            }
        };

        private void onDocumentChangedImpl(DocumentChangedEvent event) {
            int row = plw.get().getRow();
            Range range = event.getEvent().getRange();
            if (range.getStart().getRow() <= row && row <= range.getEnd().getRow()) {
                String line = display.getLine(row);
                if (ImagePreviewer.isStandaloneMarkdownLink(line)) {
                    // check to see if the URL text has been updated
                    Token hrefToken = null;
                    JsArray<Token> tokens = display.getTokens(row);
                    for (Token token : JsUtil.asIterable(tokens)) {
                        if (token.hasType("href")) {
                            hrefToken = token;
                            break;
                        }
                    }
                    if (hrefToken == null)
                        return;
                    String attributes = "";
                    int startBraceIdx = line.indexOf("){");
                    int endBraceIdx = line.lastIndexOf("}");
                    if (startBraceIdx != -1 && endBraceIdx != -1 && endBraceIdx > startBraceIdx) {
                        attributes = line.substring(startBraceIdx + 2, endBraceIdx).trim();
                    }
                    // (avoid flickering + re-requests of same URL)
                    if (hrefToken.getValue().equals(href_) && attributes.equals(attributes_))
                        return;
                    // cache href and schedule refresh of image
                    href_ = hrefToken.getValue();
                    attributes_ = attributes;
                    refreshImageTimer.schedule(700);
                } else {
                    onDetach.execute();
                }
            }
        }

        @Override
        public void onDocumentChanged(final DocumentChangedEvent event) {
            // ignore 'removeLines' events as they won't mutate the actual
            // line containing the markdown link
            String action = event.getEvent().getAction();
            if (action.equals("removeLines"))
                return;
            Scheduler.get().scheduleDeferred(new ScheduledCommand() {

                @Override
                public void execute() {
                    onDocumentChangedImpl(event);
                }
            });
        }
    }));
    ChunkOutputHost host = new ChunkOutputHost() {

        @Override
        public void onOutputRemoved(final ChunkOutputWidget widget) {
            onDetach.execute();
        }

        @Override
        public void onOutputHeightChanged(ChunkOutputWidget widget, int height, boolean ensureVisible) {
            onResize.execute(height);
        }
    };
    cow.set(new ChunkOutputWidget(sentinel.getId(), "md-image-preview-" + StringUtil.makeRandomId(8), RmdChunkOptions.create(), ChunkOutputWidget.EXPANDED, // can close
    false, host, ChunkOutputSize.Bare));
    ChunkOutputWidget outputWidget = cow.get();
    outputWidget.setRootWidget(container);
    outputWidget.hideSatellitePopup();
    outputWidget.getElement().getStyle().setMarginTop(4, Unit.PX);
    plw.set(new PinnedLineWidget(LINE_WIDGET_TYPE, display, outputWidget, position.getRow(), null, null));
}
Also used : FadeOutAnimation(org.rstudio.core.client.layout.FadeOutAnimation) ChunkOutputHost(org.rstudio.studio.client.workbench.views.source.editors.text.rmd.ChunkOutputHost) Element(com.google.gwt.dom.client.Element) Label(com.google.gwt.user.client.ui.Label) ImageElementEx(org.rstudio.core.client.dom.ImageElementEx) RenderFinishedEvent(org.rstudio.studio.client.workbench.views.source.editors.text.events.RenderFinishedEvent) Token(org.rstudio.studio.client.workbench.views.source.editors.text.ace.Token) CommandWithArg(org.rstudio.core.client.CommandWithArg) Image(com.google.gwt.user.client.ui.Image) ScheduledCommand(com.google.gwt.core.client.Scheduler.ScheduledCommand) Style(com.google.gwt.dom.client.Style) LineWidget(org.rstudio.studio.client.workbench.views.source.editors.text.ace.LineWidget) DocumentChangedEvent(org.rstudio.studio.client.workbench.views.source.editors.text.events.DocumentChangedEvent) EventListener(com.google.gwt.user.client.EventListener) HandlerRegistration(com.google.gwt.event.shared.HandlerRegistration) SimplePanel(com.google.gwt.user.client.ui.SimplePanel) Range(org.rstudio.studio.client.workbench.views.source.editors.text.ace.Range) Mutable(org.rstudio.core.client.Mutable) Timer(com.google.gwt.user.client.Timer) Command(com.google.gwt.user.client.Command) ScheduledCommand(com.google.gwt.core.client.Scheduler.ScheduledCommand) Event(com.google.gwt.user.client.Event) DocumentChangedEvent(org.rstudio.studio.client.workbench.views.source.editors.text.events.DocumentChangedEvent) RenderFinishedEvent(org.rstudio.studio.client.workbench.views.source.editors.text.events.RenderFinishedEvent) Map(java.util.Map)

Aggregations

ScheduledCommand (com.google.gwt.core.client.Scheduler.ScheduledCommand)105 Position (org.rstudio.studio.client.workbench.views.source.editors.text.ace.Position)7 Element (com.google.gwt.dom.client.Element)6 Range (org.rstudio.studio.client.workbench.views.source.editors.text.ace.Range)6 JsArray (com.google.gwt.core.client.JsArray)5 Command (com.google.gwt.user.client.Command)5 ServerError (org.rstudio.studio.client.server.ServerError)5 JsArrayString (com.google.gwt.core.client.JsArrayString)4 ArrayList (java.util.ArrayList)4 Test (org.junit.Test)4 FileSystemItem (org.rstudio.core.client.files.FileSystemItem)4 RepeatingCommand (com.google.gwt.core.client.Scheduler.RepeatingCommand)3 ClickEvent (com.google.gwt.event.dom.client.ClickEvent)3 Event (com.google.gwt.user.client.Event)3 NativePreviewHandler (com.google.gwt.user.client.Event.NativePreviewHandler)3 Timer (com.google.gwt.user.client.Timer)3 WindowEx (org.rstudio.core.client.dom.WindowEx)3 SourcePosition (org.rstudio.studio.client.workbench.views.source.model.SourcePosition)3 ErrorDialog (com.google.gerrit.client.ErrorDialog)2 OnEditEnabler (com.google.gerrit.client.ui.OnEditEnabler)2