Package org.rstudio.studio.client.projects

Source Code of org.rstudio.studio.client.projects.Projects$Binder

/*
* Projects.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;

import org.rstudio.core.client.Debug;
import org.rstudio.core.client.SerializedCommand;
import org.rstudio.core.client.SerializedCommandQueue;
import org.rstudio.core.client.command.CommandBinder;
import org.rstudio.core.client.command.Handler;
import org.rstudio.core.client.files.FileSystemItem;
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.ProgressOperationWithInput;
import org.rstudio.studio.client.application.ApplicationQuit;
import org.rstudio.studio.client.application.Desktop;
import org.rstudio.studio.client.application.events.EventBus;
import org.rstudio.studio.client.common.FileDialogs;
import org.rstudio.studio.client.common.GlobalDisplay;
import org.rstudio.studio.client.common.SimpleRequestCallback;
import org.rstudio.studio.client.common.console.ConsoleProcess;
import org.rstudio.studio.client.common.console.ProcessExitEvent;
import org.rstudio.studio.client.common.vcs.GitServerOperations;
import org.rstudio.studio.client.common.vcs.VCSConstants;
import org.rstudio.studio.client.common.vcs.VcsCloneOptions;
import org.rstudio.studio.client.packrat.model.PackratServerOperations;
import org.rstudio.studio.client.projects.events.OpenProjectErrorEvent;
import org.rstudio.studio.client.projects.events.OpenProjectErrorHandler;
import org.rstudio.studio.client.projects.events.OpenProjectFileEvent;
import org.rstudio.studio.client.projects.events.OpenProjectFileHandler;
import org.rstudio.studio.client.projects.events.SwitchToProjectEvent;
import org.rstudio.studio.client.projects.events.SwitchToProjectHandler;
import org.rstudio.studio.client.projects.model.NewProjectContext;
import org.rstudio.studio.client.projects.model.NewProjectInput;
import org.rstudio.studio.client.projects.model.NewProjectResult;
import org.rstudio.studio.client.projects.model.ProjectsServerOperations;
import org.rstudio.studio.client.projects.model.RProjectOptions;
import org.rstudio.studio.client.projects.ui.newproject.NewProjectWizard;
import org.rstudio.studio.client.projects.ui.prefs.ProjectPreferencesDialog;
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.server.VoidServerRequestCallback;
import org.rstudio.studio.client.workbench.commands.Commands;
import org.rstudio.studio.client.workbench.events.SessionInitEvent;
import org.rstudio.studio.client.workbench.events.SessionInitHandler;
import org.rstudio.studio.client.workbench.model.RemoteFileSystemContext;
import org.rstudio.studio.client.workbench.model.Session;
import org.rstudio.studio.client.workbench.model.SessionInfo;
import org.rstudio.studio.client.workbench.prefs.model.UIPrefs;
import org.rstudio.studio.client.workbench.views.vcs.common.ConsoleProgressDialog;

import com.google.gwt.user.client.Command;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

@Singleton
public class Projects implements OpenProjectFileHandler,
                                 SwitchToProjectHandler,
                                 OpenProjectErrorHandler
{
   public interface Binder extends CommandBinder<Commands, Projects> {}
  
   @Inject
   public Projects(GlobalDisplay globalDisplay,
                   final Session session,
                   Provider<ProjectMRUList> pMRUList,
                   FileDialogs fileDialogs,
                   RemoteFileSystemContext fsContext,
                   ApplicationQuit applicationQuit,
                   ProjectsServerOperations projServer,
                   PackratServerOperations packratServer,
                   GitServerOperations gitServer,
                   EventBus eventBus,
                   Binder binder,
                   final Commands commands,
                   Provider<ProjectPreferencesDialog> pPrefDialog,
                   Provider<UIPrefs> pUIPrefs)
   {
      globalDisplay_ = globalDisplay;
      pMRUList_ = pMRUList;
      applicationQuit_ = applicationQuit;
      projServer_ = projServer;
      packratServer_ = packratServer;
      gitServer_ = gitServer;
      fileDialogs_ = fileDialogs;
      fsContext_ = fsContext;
      session_ = session;
      pPrefDialog_ = pPrefDialog;
      pUIPrefs_ = pUIPrefs;
     
      binder.bind(commands, this);
      
      eventBus.addHandler(OpenProjectErrorEvent.TYPE, this);
      eventBus.addHandler(SwitchToProjectEvent.TYPE, this);
      eventBus.addHandler(OpenProjectFileEvent.TYPE, this);
     
      eventBus.addHandler(SessionInitEvent.TYPE, new SessionInitHandler() {
         public void onSessionInit(SessionInitEvent sie)
         {
            SessionInfo sessionInfo = session.getSessionInfo();
           
            // ensure mru is initialized
            ProjectMRUList mruList = pMRUList_.get();
           
            // enable/disable commands
            String activeProjectFile = sessionInfo.getActiveProjectFile();
            boolean hasProject = activeProjectFile != null;
            commands.closeProject().setEnabled(hasProject);
            commands.projectOptions().setEnabled(hasProject);
           
            // remove version control commands if necessary
            if (!sessionInfo.isVcsEnabled())
            {
               commands.activateVcs().remove();
               commands.vcsCommit().remove();
               commands.vcsShowHistory().remove();
               commands.vcsPull().remove();
               commands.vcsPush().remove();
               commands.vcsCleanup().remove();
            }
            else
            {
               commands.activateVcs().setMenuLabel(
                                    "Show _" + sessionInfo.getVcsName());
              
               // customize for svn if necessary
               if (sessionInfo.getVcsName().equals(VCSConstants.SVN_ID))
               {
                  commands.vcsPush().remove();
                  commands.vcsPull().setButtonLabel("Update");
                  commands.vcsPull().setMenuLabel("_Update");
               }   
              
               // customize for git if necessary
               if (sessionInfo.getVcsName().equals(VCSConstants.GIT_ID))
               {
                  commands.vcsCleanup().remove();
               }
            }
           
            // disable the open project in new window command in web mode
            if (!Desktop.isDesktop())
               commands.openProjectInNewWindow().remove();
           
            // maintain mru
            if (hasProject)
               mruList.add(activeProjectFile);
         }
      });
   }
  
   @Handler
   public void onClearRecentProjects()
   { 
      // Clear the contents of the most rencently used list of projects
      pMRUList_.get().clear();
   }
  
   @Handler
   public void onNewProject()
   {
      // first resolve the quit context (potentially saving edited documents  
      // and determining whether to save the R environment on exit)
      applicationQuit_.prepareForQuit("Save Current Workspace",
         new ApplicationQuit.QuitContext() {
           @Override
           public void onReadyToQuit(final boolean saveChanges)
           {
              projServer_.getNewProjectContext(
                new SimpleRequestCallback<NewProjectContext>() {
                   @Override
                   public void onResponseReceived(NewProjectContext context)
                   {
                      NewProjectWizard wiz = new NewProjectWizard(
                         session_.getSessionInfo(),
                         pUIPrefs_.get(),
                         new NewProjectInput(
                            FileSystemItem.createDir(
                               pUIPrefs_.get().defaultProjectLocation().getValue()),
                            context
                         ),
                        
                         new ProgressOperationWithInput<NewProjectResult>() {

                          @Override
                          public void execute(NewProjectResult newProject,
                                              ProgressIndicator indicator)
                          {
                             indicator.onCompleted();
                             createNewProject(newProject, saveChanges);
                          }
                      });
                      wiz.showModal()
                   }
              });
          
      });
     
     
   }
  

   private void createNewProject(final NewProjectResult newProject,
                                 final boolean saveChanges)
   {
   
     
      // This gets a little crazy. We have several pieces of asynchronous logic
      // that each may or may not need to be executed, depending on the type
      // of project being created and on whether the previous pieces of logic
      // succeed. Plus we have this ProgressIndicator that needs to be fed
      // properly.

      final ProgressIndicator indicator = globalDisplay_.getProgressIndicator(
                                                      "Error Creating Project");
     
      // Here's the command queue that will hold the various operations.
      final SerializedCommandQueue createProjectCmds =
                                                  new SerializedCommandQueue();

      // WARNING: When calling addCommand, BE SURE TO PASS FALSE as the second
      // argument, to delay running of the commands until they are all
      // scheduled.

      // First, attempt to update the default project location pref
      createProjectCmds.addCommand(new SerializedCommand()
      {
         @Override
         public void onExecute(final Command continuation)
         {
            UIPrefs uiPrefs = pUIPrefs_.get();
           
            // update default project location pref if necessary
            if ((newProject.getNewDefaultProjectLocation() != null) ||
                (newProject.getCreateGitRepo() !=
                 uiPrefs.newProjGitInit().getValue()))
            {
               indicator.onProgress("Saving defaults...");

               if (newProject.getNewDefaultProjectLocation() != null)
               {
                  uiPrefs.defaultProjectLocation().setGlobalValue(
                     newProject.getNewDefaultProjectLocation());
               }
              
               if (newProject.getCreateGitRepo() !=
                   uiPrefs.newProjGitInit().getValue())
               {
                  uiPrefs.newProjGitInit().setGlobalValue(
                                          newProject.getCreateGitRepo());
               }
              
               if (newProject.getUsePackrat() !=
                   uiPrefs.newProjUsePackrat().getValue())
               {
                  uiPrefs.newProjUsePackrat().setGlobalValue(
                                          newProject.getUsePackrat());
               }
              
               // call the server -- in all cases continue on with
               // creating the project (swallow errors updating the pref)
               projServer_.setUiPrefs(
                     session_.getSessionInfo().getUiPrefs(),
                     new VoidServerRequestCallback(indicator) {
                        @Override
                        public void onResponseReceived(Void response)
                        {
                           continuation.execute();
                        }

                        @Override
                        public void onError(ServerError error)
                        {
                           super.onError(error);
                           continuation.execute();
                        }
                     });
            }
            else
            {
               continuation.execute();
            }
         }
      }, false);

      // Next, if necessary, clone a repo
      if (newProject.getVcsCloneOptions() != null)
      {
         createProjectCmds.addCommand(new SerializedCommand()
         {
            @Override
            public void onExecute(final Command continuation)
            {
               VcsCloneOptions cloneOptions = newProject.getVcsCloneOptions();
              
               if (cloneOptions.getVcsName().equals((VCSConstants.GIT_ID)))
                  indicator.onProgress("Cloning Git repoistory...");
               else
                  indicator.onProgress("Checking out SVN repository...");
              
               gitServer_.vcsClone(
                     cloneOptions,
                     new ServerRequestCallback<ConsoleProcess>() {
                        @Override
                        public void onResponseReceived(ConsoleProcess proc)
                        {
                           final ConsoleProgressDialog consoleProgressDialog =
                                 new ConsoleProgressDialog(proc, gitServer_);
                           consoleProgressDialog.showModal();
          
                           proc.addProcessExitHandler(new ProcessExitEvent.Handler()
                           {
                              @Override
                              public void onProcessExit(ProcessExitEvent event)
                              {
                                 if (event.getExitCode() == 0)
                                 {
                                    consoleProgressDialog.hide();
                                    continuation.execute();
                                 }
                                 else
                                 {
                                    indicator.onCompleted();
                                 }
                              }
                           });
                        }

                        @Override
                        public void onError(ServerError error)
                        {
                           Debug.logError(error);
                           indicator.onError(error.getUserMessage());
                        }
                     });
            }
         }, false);
      }

      // Next, create the project file
      createProjectCmds.addCommand(new SerializedCommand()
      {
         @Override
         public void onExecute(final Command continuation)
         {
            indicator.onProgress("Creating project...");

            projServer_.createProject(
                  newProject.getProjectFile(),
                  newProject.getNewPackageOptions(),
                  newProject.getNewShinyAppOptions(),
                  new VoidServerRequestCallback(indicator)
                  {
                     @Override
                     public void onSuccess()
                     {
                        continuation.execute();
                     }
                  });
         }
      }, false);
     
      // Next, initialize a git repo if requested
      if (newProject.getCreateGitRepo())
      {
         createProjectCmds.addCommand(new SerializedCommand()
         {
            @Override
            public void onExecute(final Command continuation)
            {
               indicator.onProgress("Initializing git repository...");

               String projDir = FileSystemItem.createFile(
                     newProject.getProjectFile()).getParentPathString();
              
               gitServer_.gitInitRepo(
                     projDir,
                     new VoidServerRequestCallback(indicator)
                     {
                        @Override
                        public void onSuccess()
                        {
                           continuation.execute();
                        }
                       
                        @Override
                        public void onFailure()
                        {
                           continuation.execute();
                        }
                     });
            }
         }, false);
      }
     
      // Generate a new packrat project
      if (newProject.getUsePackrat()) {
         createProjectCmds.addCommand(new SerializedCommand()
         {
           
            @Override
            public void onExecute(final Command continuation) {
              
               indicator.onProgress("Initializing packrat project...");
              
               String projDir = FileSystemItem.createFile(
                  newProject.getProjectFile()
               ).getParentPathString();
              
               packratServer_.packratBootstrap(
                  projDir,
                  false,
                  new VoidServerRequestCallback(indicator) {
                     @Override
                     public void onSuccess()
                     {
                        continuation.execute();
                     }
                  });
            }
         }, false);
      }
     
      if (newProject.getOpenInNewWindow())
      {
         createProjectCmds.addCommand(new SerializedCommand() {

            @Override
            public void onExecute(Command continuation)
            {
               Desktop.getFrame().openProjectInNewWindow(
                                             newProject.getProjectFile());
               continuation.execute();
              
            }
         }, false);
      }

      // If we get here, dismiss the progress indicator
      createProjectCmds.addCommand(new SerializedCommand()
      {
         @Override
         public void onExecute(Command continuation)
         {
            indicator.onCompleted();
           
            if (!newProject.getOpenInNewWindow())
            {
               applicationQuit_.performQuit(
                                 saveChanges,
                                 newProject.getProjectFile());
            }
           
            continuation.execute();
         }
      }, false);

      // Now set it all in motion!
      createProjectCmds.run();
   }


   @Handler
   public void onOpenProject()
   {
      // first resolve the quit context (potentially saving edited documents
      // and determining whether to save the R environment on exit)
      applicationQuit_.prepareForQuit("Switch Projects",
                                      new ApplicationQuit.QuitContext() {
         public void onReadyToQuit(final boolean saveChanges)
         {
            showOpenProjectDialog(
               new ProgressOperationWithInput<FileSystemItem>()
               {
                  @Override
                  public void execute(final FileSystemItem input,
                                      ProgressIndicator indicator)
                  {
                     indicator.onCompleted();
                    
                     if (input == null)
                        return;
                    
                     // perform quit
                     applicationQuit_.performQuit(saveChanges, input.getPath());
                  }  
               });
           
         }
      });
   }
  
   @Handler
   public void onOpenProjectInNewWindow()
   {
      showOpenProjectDialog(
         new ProgressOperationWithInput<FileSystemItem>()
         {
            @Override
            public void execute(final FileSystemItem input,
                                ProgressIndicator indicator)
            {
               indicator.onCompleted();
              
               if (input == null)
                  return;
              
               // call the desktop to open the project (since it is
               // a conventional foreground gui application it has
               // less chance of running afowl of desktop app creation
               // & activation restrictions)
               Desktop.getFrame().openProjectInNewWindow(input.getPath());
            }  
         });
   }
  
  
  
   @Handler
   public void onCloseProject()
   {
      // first resolve the quit context (potentially saving edited documents
      // and determining whether to save the R environment on exit)
      applicationQuit_.prepareForQuit("Close Project",
                                      new ApplicationQuit.QuitContext() {
         public void onReadyToQuit(final boolean saveChanges)
         {
            applicationQuit_.performQuit(saveChanges, NONE);
         }});
   }
  
   @Handler
   public void onProjectOptions()
   {
      showProjectOptions(ProjectPreferencesDialog.GENERAL);
   }

   @Handler
   public void onProjectSweaveOptions()
   {
      showProjectOptions(ProjectPreferencesDialog.SWEAVE);
   }
  
   @Handler
   public void onBuildToolsProjectSetup()
   {  
      // check whether there is a project active
      if (!hasActiveProject())
      {
         globalDisplay_.showMessage(
               MessageDialog.INFO,
               "No Active Project",
               "Build tools can only be configured from within an " +
               "RStudio project.");
       
      }
      else
      {
         showProjectOptions(ProjectPreferencesDialog.BUILD);
      }
   }
  
  
   @Handler
   public void onVersionControlProjectSetup()
   {
      // check whether there is a project active
      if (!hasActiveProject())
      {
         globalDisplay_.showMessage(
               MessageDialog.INFO,
               "No Active Project",
               "Version control features can only be accessed from within an " +
               "RStudio project. Note that if you have an existing directory " +
               "under version control you can associate an RStudio project " +
               "with that directory using the New Project dialog.");
       
      }
      else
      {
         showProjectOptions(ProjectPreferencesDialog.VCS);
      }
   }
  
   @Handler
   public void onPackratBootstrap()
   {
      showProjectOptions(ProjectPreferencesDialog.PACKRAT);
   }
  
   @Handler
   public void onPackratOptions()
   {
      showProjectOptions(ProjectPreferencesDialog.PACKRAT);
   }
  
   private void showProjectOptions(final int initialPane)
   {
      final ProgressIndicator indicator = globalDisplay_.getProgressIndicator(
                                                      "Error Reading Options");
      indicator.onProgress("Reading options...");

      projServer_.readProjectOptions(new SimpleRequestCallback<RProjectOptions>() {

         @Override
         public void onResponseReceived(RProjectOptions options)
         {
            indicator.onCompleted();

            ProjectPreferencesDialog dlg = pPrefDialog_.get();
            dlg.initialize(options);
            dlg.activatePane(initialPane);
            dlg.showModal();
         }});
   }
  
   @Override
   public void onOpenProjectFile(final OpenProjectFileEvent event)
   {
      // project options for current project
      FileSystemItem projFile = event.getFile();
      if (projFile.getPath().equals(
                  session_.getSessionInfo().getActiveProjectFile()))
      {
         onProjectOptions();
         return;
      }
     
      // prompt to confirm
      String projectPath = projFile.getParentPathString();
      globalDisplay_.showYesNoMessage(GlobalDisplay.MSG_QUESTION, 
         "Confirm Open Project",                            
         "Do you want to open the project " + projectPath + "?",                        
          new Operation()
          {
             public void execute()
             {
                 switchToProject(event.getFile().getPath());
             }
          }
          true);  
   }
  

   @Override
   public void onSwitchToProject(final SwitchToProjectEvent event)
   {
      switchToProject(event.getProject());
   }
  
   @Override
   public void onOpenProjectError(OpenProjectErrorEvent event)
   {
      // show error dialog
      String msg = "Project '" + event.getProject() + "' " +
                   "could not be opened: " + event.getMessage();
      globalDisplay_.showErrorMessage("Error Opening Project", msg);
      
      // remove from mru list
      pMRUList_.get().remove(event.getProject());
   }
  
   private boolean hasActiveProject()
   {
      return session_.getSessionInfo().getActiveProjectFile() != null;
   }
  
  
   private void switchToProject(final String projectFilePath)
   {
      applicationQuit_.prepareForQuit("Switch Projects",
                                 new ApplicationQuit.QuitContext() {
         public void onReadyToQuit(final boolean saveChanges)
         {
            applicationQuit_.performQuit(saveChanges, projectFilePath);
         }});
   }
  
   private void showOpenProjectDialog(
                  ProgressOperationWithInput<FileSystemItem> onCompleted)
   {
      // choose project file
      fileDialogs_.openFile(
         "Open Project",
         fsContext_,
         FileSystemItem.createDir(
               pUIPrefs_.get().defaultProjectLocation().getValue()),
         "R Projects (*.Rproj)",
         onCompleted)
   }
  
   private final Provider<ProjectMRUList> pMRUList_;
   private final ApplicationQuit applicationQuit_;
   private final ProjectsServerOperations projServer_;
   private final PackratServerOperations packratServer_;
   private final GitServerOperations gitServer_;
   private final FileDialogs fileDialogs_;
   private final RemoteFileSystemContext fsContext_;
   private final GlobalDisplay globalDisplay_;
   private final Session session_;
   private final Provider<ProjectPreferencesDialog> pPrefDialog_;
   private final Provider<UIPrefs> pUIPrefs_;
  
   public static final String NONE = "none";

  
 
}
TOP

Related Classes of org.rstudio.studio.client.projects.Projects$Binder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.