/*
* ProjectPreferencesDialog.java
*
* Copyright (C) 2009-12 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.projects.ui.prefs;
import java.util.ArrayList;
import org.rstudio.core.client.StringUtil;
import org.rstudio.core.client.js.JsUtil;
import org.rstudio.core.client.prefs.PreferencesDialogBase;
import org.rstudio.core.client.widget.Operation;
import org.rstudio.core.client.widget.ProgressIndicator;
import org.rstudio.studio.client.application.events.EventBus;
import org.rstudio.studio.client.packrat.PackratUtil;
import org.rstudio.studio.client.projects.model.ProjectsServerOperations;
import org.rstudio.studio.client.projects.model.RProjectConfig;
import org.rstudio.studio.client.projects.model.RProjectOptions;
import org.rstudio.studio.client.projects.model.RProjectPackratOptions;
import org.rstudio.studio.client.projects.ui.prefs.buildtools.ProjectBuildToolsPreferencesPane;
import org.rstudio.studio.client.server.ServerError;
import org.rstudio.studio.client.server.ServerRequestCallback;
import org.rstudio.studio.client.server.Void;
import org.rstudio.studio.client.workbench.model.Session;
import org.rstudio.studio.client.workbench.prefs.model.UIPrefs;
import org.rstudio.studio.client.workbench.views.console.events.SendToConsoleEvent;
import com.google.gwt.core.client.JsArrayString;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class ProjectPreferencesDialog extends PreferencesDialogBase<RProjectOptions>
{
public static final int GENERAL = 0;
public static final int EDITING = 1;
public static final int SWEAVE = 2;
public static final int BUILD = 3;
public static final int VCS = 4;
public static final int PACKRAT = 5;
public static final int SHARING = 6;
@Inject
public ProjectPreferencesDialog(ProjectsServerOperations server,
Provider<UIPrefs> pUIPrefs,
Provider<EventBus> pEventBus,
Provider<PackratUtil> pPackratUtil,
Provider<Session> session,
ProjectGeneralPreferencesPane general,
ProjectEditingPreferencesPane editing,
ProjectCompilePdfPreferencesPane compilePdf,
ProjectSourceControlPreferencesPane source,
ProjectBuildToolsPreferencesPane build,
ProjectPackratPreferencesPane packrat,
ProjectSharingPreferencesPane sharing)
{
super("Project Options",
RES.styles().panelContainer(),
false,
new ProjectPreferencesPane[] {general, editing, compilePdf, build,
source, packrat, sharing});
session_ = session;
server_ = server;
pUIPrefs_ = pUIPrefs;
pEventBus_ = pEventBus;
pPackratUtil_ = pPackratUtil;
}
@Override
public void initialize(RProjectOptions options)
{
super.initialize(options);
initialPackratOptions_ = options.getPackratOptions();
if (!session_.get().getSessionInfo().getAllowVcs())
hidePane(VCS);
if (!options.getPackratContext().isAvailable())
hidePane(PACKRAT);
if (!session_.get().getSessionInfo().projectSupportsSharing())
hidePane(SHARING);
}
@Override
protected RProjectOptions createEmptyPrefs()
{
return RProjectOptions.createEmpty();
}
@Override
protected void doSaveChanges(final RProjectOptions options,
final Operation onCompleted,
final ProgressIndicator indicator,
final boolean reload)
{
server_.writeProjectOptions(
options,
new ServerRequestCallback<Void>() {
@Override
public void onResponseReceived(Void response)
{
indicator.onCompleted();
// update project ui prefs
RProjectConfig config = options.getConfig();
UIPrefs uiPrefs = pUIPrefs_.get();
uiPrefs.useSpacesForTab().setProjectValue(
config.getUseSpacesForTab());
uiPrefs.numSpacesForTab().setProjectValue(
config.getNumSpacesForTab());
uiPrefs.autoAppendNewline().setProjectValue(
config.getAutoAppendNewline());
uiPrefs.stripTrailingWhitespace().setProjectValue(
config.getStripTrailingWhitespace());
uiPrefs.defaultEncoding().setProjectValue(
config.getEncoding());
uiPrefs.defaultSweaveEngine().setProjectValue(
config.getDefaultSweaveEngine());
uiPrefs.defaultLatexProgram().setProjectValue(
config.getDefaultLatexProgram());
uiPrefs.rootDocument().setProjectValue(
config.getRootDocument());
uiPrefs.useRoxygen().setProjectValue(
config.hasPackageRoxygenize());
// convert packrat option changes to console actions
emitPackratConsoleActions(options.getPackratOptions());
if (onCompleted != null)
onCompleted.execute();
if (reload)
reload();
}
@Override
public void onError(ServerError error)
{
indicator.onError(error.getUserMessage());
}
});
}
private void emitPackratConsoleActions(RProjectPackratOptions options)
{
String packratFunction = null;
String packratArgs = null;
// case: enabling packrat
if (options.getUsePackrat() && !initialPackratOptions_.getUsePackrat())
{
packratFunction = "init";
String optionArgs = packratArgs(options);
if (optionArgs.length() > 0)
packratArgs = "options = list(" + optionArgs + ")";
}
// case: disabling packart
else if (!options.getUsePackrat() && initialPackratOptions_.getUsePackrat())
{
packratFunction = "disable";
}
// case: changing packrat options
else
{
packratArgs = packratArgs(options);
if (!StringUtil.isNullOrEmpty(packratArgs))
packratFunction = "set_opts";
}
if (packratFunction != null)
{
// build the call
StringBuilder b = new StringBuilder();
b.append("packrat::");
b.append(packratFunction);
b.append("(");
String projectArg = pPackratUtil_.get().packratProjectArg();
if (projectArg.length() > 0)
{
b.append(projectArg);
if (packratArgs != null)
b.append(", ");
}
if (packratArgs != null)
b.append(packratArgs);
b.append(")");
pEventBus_.get().fireEvent(new SendToConsoleEvent(b.toString(),
true,
true));
}
}
private boolean equals(JsArrayString lhsJson, JsArrayString rhsJson)
{
String[] lhs = JsUtil.toStringArray(lhsJson);
String[] rhs = JsUtil.toStringArray(rhsJson);
if (lhs.length != rhs.length) return false;
for (int i = 0; i < lhs.length; ++i)
{
if (!lhs[i].equals(rhs[i]))
{
return false;
}
}
return true;
}
private String packratArgs(RProjectPackratOptions options)
{
ArrayList<String> opts = new ArrayList<String>();
if (options.getAutoSnapshot() != initialPackratOptions_.getAutoSnapshot())
opts.add(packratBoolArg("auto.snapshot", options.getAutoSnapshot()));
if (options.getVcsIgnoreLib() != initialPackratOptions_.getVcsIgnoreLib())
opts.add(packratBoolArg("vcs.ignore.lib", options.getVcsIgnoreLib()));
if (options.getVcsIgnoreSrc() != initialPackratOptions_.getVcsIgnoreSrc())
opts.add(packratBoolArg("vcs.ignore.src", options.getVcsIgnoreSrc()));
if (options.getUseCache() != initialPackratOptions_.getUseCache())
opts.add(packratBoolArg("use.cache", options.getUseCache()));
if (!equals(options.getExternalPackages(),
initialPackratOptions_.getExternalPackages()))
opts.add(packratVectorArg("external.packages",
options.getExternalPackages()));
if (!equals(options.getLocalRepos(),
initialPackratOptions_.getLocalRepos()))
opts.add(packratVectorArg("local.repos",
options.getLocalRepos()));
return StringUtil.joinStrings(opts, ", ");
}
private String packratBoolArg(String name, boolean value)
{
return name + " = " + (value ? "TRUE" : "FALSE");
}
private String packratVectorArg(String name, JsArrayString valueJson)
{
String[] value = JsUtil.toStringArray(valueJson);
String result = name + " = ";
if (value.length < 1) return result + "\"\"";
result += "c(";
for (int i = 0; i < value.length - 1; ++i)
{
result += StringUtil.ensureSurroundedWith(
value[i].replaceAll("\"", "\\\\\""), '"');
result += ", ";
}
result += StringUtil.ensureSurroundedWith(
value[value.length - 1].replaceAll("\"", "\\\\\""), '"');
result += ")";
return result;
}
private final Provider<Session> session_;
private final ProjectsServerOperations server_;
private final Provider<UIPrefs> pUIPrefs_;
private final Provider<EventBus> pEventBus_;
private final Provider<PackratUtil> pPackratUtil_;
private RProjectPackratOptions initialPackratOptions_ = null;
private static final ProjectPreferencesDialogResources RES =
ProjectPreferencesDialogResources.INSTANCE;
}