/*
* ProjectSourceControlPreferencesPane.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 org.rstudio.core.client.prefs.PreferencesDialogBaseResources;
import org.rstudio.core.client.theme.res.ThemeStyles;
import org.rstudio.core.client.widget.MessageDialog;
import org.rstudio.core.client.widget.Operation;
import org.rstudio.core.client.widget.ProgressIndicator;
import org.rstudio.core.client.widget.SelectWidget;
import org.rstudio.studio.client.common.GlobalDisplay;
import org.rstudio.studio.client.common.HelpLink;
import org.rstudio.studio.client.common.vcs.GitServerOperations;
import org.rstudio.studio.client.common.vcs.VCSConstants;
import org.rstudio.studio.client.common.vcs.VcsHelpLink;
import org.rstudio.studio.client.projects.model.RProjectOptions;
import org.rstudio.studio.client.projects.model.RProjectVcsOptions;
import org.rstudio.studio.client.projects.model.RProjectVcsContext;
import org.rstudio.studio.client.server.ServerError;
import org.rstudio.studio.client.server.ServerRequestCallback;
import org.rstudio.studio.client.server.VoidServerRequestCallback;
import org.rstudio.studio.client.workbench.model.Session;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.inject.Inject;
public class ProjectSourceControlPreferencesPane extends ProjectPreferencesPane
{
@Inject
public ProjectSourceControlPreferencesPane(final Session session,
GlobalDisplay globalDisplay,
GitServerOperations server)
{
session_ = session;
globalDisplay_ = globalDisplay;
server_ = server;
vcsSelect_ = new SelectWidget("Version control system:", new String[]{});
spaced(vcsSelect_);
add(vcsSelect_);
vcsSelect_.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event)
{
updateOriginLabel();
if (vcsSelect_.getValue().equals(VCSConstants.GIT_ID))
{
confirmGitRepo(new Command() {
@Override
public void execute()
{
promptToRestart();
}
});
}
else
{
promptToRestart();
}
}
});
lblOrigin_ = new OriginLabel();
lblOrigin_.addStyleName(RES.styles().vcsOriginLabel());
lblOrigin_.addStyleName(ThemeStyles.INSTANCE.selectableText());
extraSpaced(lblOrigin_);
add(lblOrigin_);
HelpLink vcsHelpLink = new VcsHelpLink();
nudgeRight(vcsHelpLink);
add(vcsHelpLink);
}
@Override
public ImageResource getIcon()
{
return PreferencesDialogBaseResources.INSTANCE.iconSourceControl();
}
@Override
public String getName()
{
return "Git/SVN";
}
@Override
protected void initialize(RProjectOptions options)
{
// save the context
vcsContext_ = options.getVcsContext();
// populate the vcs selections list
String[] vcsSelections = new String[] { NONE };
JsArrayString applicableVcs = vcsContext_.getApplicableVcs();
if (applicableVcs.length() > 0)
{
vcsSelections = new String[applicableVcs.length() + 1];
vcsSelections[0] = NONE;
for (int i=0; i<applicableVcs.length(); i++)
vcsSelections[i+1] = applicableVcs.get(i);
}
vcsSelect_.setChoices(vcsSelections);
// set override or default
RProjectVcsOptions vcsOptions = options.getVcsOptions();
if (vcsOptions.getActiveVcsOverride().length() > 0)
setVcsSelection(vcsOptions.getActiveVcsOverride());
else
setVcsSelection(vcsContext_.getDetectedVcs());
}
@Override
public boolean onApply(RProjectOptions options)
{
RProjectVcsOptions vcsOptions = options.getVcsOptions();
setVcsOptions(vcsOptions);
return false;
}
private void setVcsOptions(RProjectVcsOptions vcsOptions)
{
String vcsSelection = getVcsSelection();
if (!vcsSelection.equals(vcsContext_.getDetectedVcs()))
vcsOptions.setActiveVcsOverride(vcsSelection);
else
vcsOptions.setActiveVcsOverride("");
}
private String getVcsSelection()
{
String value = vcsSelect_.getValue();
if (value.equals(NONE))
return VCSConstants.NO_ID;
else
return value;
}
private void setVcsSelection(String vcs)
{
// set value
if (vcs.equals(VCSConstants.NO_ID))
vcsSelect_.setValue(NONE);
else if (!vcsSelect_.setValue(vcs))
{
vcsSelect_.setValue(NONE);
}
updateOriginLabel();
}
private void updateOriginLabel()
{
String vcs = getVcsSelection();
if (vcs.equals(VCSConstants.GIT_ID))
{
StringBuilder label = new StringBuilder();
label.append("Origin: ");
String originUrl = vcsContext_.getGitRemoteOriginUrl();
if (originUrl.length() == 0)
originUrl = NO_REMOTE_ORIGIN;
lblOrigin_.setOrigin("Origin:", originUrl);
lblOrigin_.setVisible(true);
vcsSelect_.removeStyleName(RES.styles().vcsSelectExtraSpaced());
}
else if (vcs.equals(VCSConstants.SVN_ID))
{
lblOrigin_.setOrigin("Repo:",
vcsContext_.getSvnRepositoryRoot());
lblOrigin_.setVisible(true);
vcsSelect_.removeStyleName(RES.styles().vcsSelectExtraSpaced());
}
else // vcs.equals(VCSConstants.NO_ID)
{
lblOrigin_.setOrigin("", "");
lblOrigin_.setVisible(false);
vcsSelect_.addStyleName(RES.styles().vcsSelectExtraSpaced());
}
}
private void confirmGitRepo(final Command onConfirmed)
{
final ProgressIndicator indicator = getProgressIndicator();
indicator.onProgress("Checking for git repository...");
final String projDir =
session_.getSessionInfo().getActiveProjectDir().getPath();
server_.gitHasRepo(projDir, new ServerRequestCallback<Boolean>() {
@Override
public void onResponseReceived(Boolean result)
{
indicator.onCompleted();
if (result)
{
onConfirmed.execute();
}
else
{
globalDisplay_.showYesNoMessage(
MessageDialog.QUESTION,
"Confirm New Git Repository",
"Do you want to initialize a new git repository " +
"for this project?",
false,
new Operation() {
@Override
public void execute()
{
server_.gitInitRepo(
projDir,
new VoidServerRequestCallback(indicator) {
@Override
public void onSuccess()
{
onConfirmed.execute();
}
@Override
public void onFailure()
{
setVcsSelection(VCSConstants.NO_ID);
}
});
}
},
new Operation() {
@Override
public void execute()
{
setVcsSelection(VCSConstants.NO_ID);
indicator.onCompleted();
}
},
true);
}
}
@Override
public void onError(ServerError error)
{
setVcsSelection(VCSConstants.NO_ID);
indicator.onError(error.getUserMessage());
}
});
}
private class OriginLabel extends Composite
{
public OriginLabel()
{
HorizontalPanel panel = new HorizontalPanel();
lblCaption_ = new Label();
panel.add(lblCaption_);
lblOrigin_ = new Label();
lblOrigin_.addStyleName(RES.styles().vcsOriginUrl());
panel.add(lblOrigin_);
initWidget(panel);
}
public void setOrigin(String caption, String origin)
{
lblCaption_.setText(caption);
lblOrigin_.setText(origin);
if (origin.equals(NO_REMOTE_ORIGIN))
lblOrigin_.addStyleName(RES.styles().vcsNoOriginUrl());
else
lblOrigin_.removeStyleName(RES.styles().vcsNoOriginUrl());
}
private Label lblCaption_;
private Label lblOrigin_;
}
private final Session session_;
private final GlobalDisplay globalDisplay_;
private final GitServerOperations server_;
private SelectWidget vcsSelect_;
private OriginLabel lblOrigin_;
private RProjectVcsContext vcsContext_;
private static final String NONE = "(None)";
private static final String NO_REMOTE_ORIGIN ="None";
private static final ProjectPreferencesDialogResources RES =
ProjectPreferencesDialogResources.INSTANCE;
}