/*
* ViewerPane.java
*
* Copyright (C) 2009-12 by RStudio, Inc.
*
* 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.viewer;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import org.rstudio.core.client.CommandWithArg;
import org.rstudio.core.client.Size;
import org.rstudio.core.client.StringUtil;
import org.rstudio.core.client.URIUtils;
import org.rstudio.core.client.resources.ImageResource2x;
import org.rstudio.core.client.widget.RStudioThemedFrame;
import org.rstudio.core.client.widget.Toolbar;
import org.rstudio.core.client.widget.ToolbarButton;
import org.rstudio.core.client.widget.ToolbarPopupMenu;
import org.rstudio.studio.client.application.events.EventBus;
import org.rstudio.studio.client.common.AutoGlassPanel;
import org.rstudio.studio.client.common.GlobalDisplay;
import org.rstudio.studio.client.common.icons.StandardIcons;
import org.rstudio.studio.client.rmarkdown.model.RmdPreviewParams;
import org.rstudio.studio.client.rsconnect.RSConnect;
import org.rstudio.studio.client.rsconnect.model.PublishHtmlSource;
import org.rstudio.studio.client.rsconnect.ui.RSConnectPublishButton;
import org.rstudio.studio.client.server.ServerError;
import org.rstudio.studio.client.server.ServerRequestCallback;
import org.rstudio.studio.client.shiny.model.ShinyApplicationParams;
import org.rstudio.studio.client.workbench.commands.Commands;
import org.rstudio.studio.client.workbench.ui.WorkbenchPane;
import org.rstudio.studio.client.workbench.views.viewer.events.ViewerNavigatedEvent;
import org.rstudio.studio.client.workbench.views.viewer.model.ViewerServerOperations;
public class ViewerPane extends WorkbenchPane implements ViewerPresenter.Display
{
@Inject
public ViewerPane(Commands commands, GlobalDisplay globalDisplay, EventBus events,
ViewerServerOperations server)
{
super("Viewer");
commands_ = commands;
globalDisplay_ = globalDisplay;
events_ = events;
server_ = server;
ensureWidget();
}
@Override
protected Toolbar createMainToolbar()
{
toolbar_ = new Toolbar();
// add html widget buttons
toolbar_.addLeftWidget(commands_.viewerBack().createToolbarButton());
toolbar_.addLeftWidget(commands_.viewerForward().createToolbarButton());
toolbar_.addLeftSeparator();
toolbar_.addLeftWidget(commands_.viewerZoom().createToolbarButton());
// export commands
exportButtonSeparator_ = toolbar_.addLeftSeparator();
ToolbarPopupMenu exportMenu = new ToolbarPopupMenu();
exportMenu.addItem(commands_.viewerSaveAsImage().createMenuItem(false));
exportMenu.addItem(commands_.viewerCopyToClipboard().createMenuItem(false));
exportMenu.addSeparator();
exportMenu.addItem(commands_.viewerSaveAsWebPage().createMenuItem(false));
exportButton_ = new ToolbarButton(
"Export", new ImageResource2x(StandardIcons.INSTANCE.export_menu2x()),
exportMenu);
toolbar_.addLeftWidget(exportButton_);
exportButton_.setVisible(false);
exportButtonSeparator_.setVisible(false);
toolbar_.addLeftSeparator();
toolbar_.addLeftWidget(commands_.viewerClear().createToolbarButton());
toolbar_.addLeftSeparator();
toolbar_.addLeftWidget(commands_.viewerClearAll().createToolbarButton());
toolbar_.addLeftSeparator();
toolbar_.addLeftWidget(commands_.viewerPopout().createToolbarButton());
toolbar_.addLeftSeparator();
toolbar_.addLeftWidget(commands_.viewerStop().createToolbarButton());
// add publish button
publishButton_ = new RSConnectPublishButton(
RSConnect.CONTENT_TYPE_DOCUMENT, true, null);
toolbar_.addRightWidget(publishButton_);
toolbar_.addRightSeparator();
toolbar_.addRightWidget(commands_.viewerRefresh().createToolbarButton());
// create an HTML generator
publishButton_.setPublishHtmlSource(new PublishHtmlSource()
{
@Override
public void generatePublishHtml(
final CommandWithArg<String> onCompleted)
{
server_.viewerCreateRPubsHtml(
getTitle(), "", new ServerRequestCallback<String>()
{
@Override
public void onResponseReceived(String htmlFile)
{
onCompleted.execute(htmlFile);
}
@Override
public void onError(ServerError error)
{
globalDisplay_.showErrorMessage("Could Not Publish",
error.getMessage());
}
});
}
@Override
public String getTitle()
{
String title = frame_.getTitle();
if (StringUtil.isNullOrEmpty(title))
title = "Viewer Content";
return title;
}
});
return toolbar_;
}
@Override
protected Widget createMainWidget()
{
frame_ = new RStudioThemedFrame();
frame_.setSize("100%", "100%");
frame_.addStyleName("ace_editor_theme");
navigate(ABOUT_BLANK, false);
return new AutoGlassPanel(frame_);
}
@Override
public void navigate(String url)
{
navigate(url, false);
rmdPreviewParams_ = null;
if (url.equals(ABOUT_BLANK))
{
publishButton_.setContentType(RSConnect.CONTENT_TYPE_NONE);
}
else
{
publishButton_.setContentType(RSConnect.CONTENT_TYPE_HTML);
}
}
@Override
public void previewRmd(RmdPreviewParams params)
{
navigate(params.getOutputUrl(), true);
publishButton_.setManuallyHidden(false);
publishButton_.setRmdPreview(params);
rmdPreviewParams_ = params;
toolbar_.invalidateSeparators();
}
@Override
public void previewShiny(ShinyApplicationParams params)
{
navigate(params.getUrl(), true);
publishButton_.setManuallyHidden(false);
publishButton_.setShinyPreview(params);
toolbar_.invalidateSeparators();
};
@Override
public void setExportEnabled(boolean exportEnabled)
{
exportButton_.setVisible(exportEnabled);
exportButtonSeparator_.setVisible(exportEnabled);
publishButton_.setManuallyHidden(!exportEnabled);
toolbar_.invalidateSeparators();
}
@Override
public String getUrl()
{
return frame_.getUrl();
}
@Override
public String getTitle()
{
return frame_.getTitle();
}
@Override
public void popout()
{
if (rmdPreviewParams_ != null &&
!rmdPreviewParams_.isShinyDocument())
{
globalDisplay_.showHtmlFile(rmdPreviewParams_.getOutputFile());
}
else if (unmodifiedUrl_ != null)
{
globalDisplay_.openWindow(unmodifiedUrl_);
}
}
@Override
public void refresh()
{
String url = frame_.getUrl();
if (url != null)
frame_.setUrl(url);
}
@Override
public Size getViewerFrameSize()
{
return new Size(frame_.getOffsetWidth(), frame_.getOffsetHeight());
}
@Override
public void onResize()
{
super.onResize();
int width = getOffsetWidth();
if (width == 0)
return;
publishButton_.setShowCaption(width > 500);
}
private void navigate(String url, boolean useRawURL)
{
// save the unmodified URL for pop-out
unmodifiedUrl_ = url;
// append the viewer_pane query parameter
if ((unmodifiedUrl_ != null) &&
!unmodifiedUrl_.equals(ABOUT_BLANK) &&
!useRawURL)
{
String viewerUrl = URIUtils.addQueryParam(unmodifiedUrl_,
"viewer_pane",
"1");
frame_.setUrl(viewerUrl);
}
else
{
frame_.setUrl(unmodifiedUrl_);
}
events_.fireEvent(new ViewerNavigatedEvent(url, frame_));
}
private RStudioThemedFrame frame_;
private String unmodifiedUrl_;
private RmdPreviewParams rmdPreviewParams_;
private final Commands commands_;
private final GlobalDisplay globalDisplay_;
private final EventBus events_;
private final ViewerServerOperations server_;
private Toolbar toolbar_;
private RSConnectPublishButton publishButton_;
private ToolbarButton exportButton_;
private Widget exportButtonSeparator_;
public static final String ABOUT_BLANK = "about:blank";
}