1 /*
2  * PreferencesDialog.java
3  *
4  * Copyright (C) 2021 by RStudio, PBC
5  *
6  * Unless you have received this program directly from RStudio pursuant
7  * to the terms of a commercial license agreement with RStudio, then
8  * this program is licensed to you under the terms of version 3 of the
9  * GNU Affero General Public License. This program is distributed WITHOUT
10  * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12  * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13  *
14  */
15 package org.rstudio.studio.client.workbench.prefs.views;
16 
17 import com.google.gwt.core.client.GWT;
18 import com.google.inject.Inject;
19 
20 import java.util.ArrayList;
21 import java.util.List;
22 
23 import org.rstudio.core.client.ElementIds;
24 import org.rstudio.core.client.prefs.PreferencesDialogBase;
25 import org.rstudio.core.client.prefs.PreferencesDialogPaneBase;
26 import org.rstudio.core.client.prefs.RestartRequirement;
27 import org.rstudio.core.client.widget.Operation;
28 import org.rstudio.core.client.widget.ProgressIndicator;
29 import org.rstudio.studio.client.RStudioGinjector;
30 import org.rstudio.studio.client.application.ApplicationQuit;
31 import org.rstudio.studio.client.common.GlobalDisplay;
32 import org.rstudio.studio.client.common.SimpleRequestCallback;
33 import org.rstudio.studio.client.server.ServerError;
34 import org.rstudio.studio.client.server.Void;
35 import org.rstudio.studio.client.workbench.model.Session;
36 import org.rstudio.studio.client.workbench.model.WorkbenchServerOperations;
37 import org.rstudio.studio.client.workbench.prefs.events.UserPrefsChangedEvent;
38 import org.rstudio.studio.client.workbench.prefs.model.UserPrefs;
39 import org.rstudio.studio.client.workbench.prefs.model.UserState;
40 
41 public class PreferencesDialog extends PreferencesDialogBase<UserPrefs>
42 {
43    /**
44     * Implementation note, when adding a new PreferencesPane, also add a
45     * command for directly showing that pane from the Command Palette. See
46     * WorkbenchScreen.onShowCodeOptions() for an example.
47     */
48    @Inject
PreferencesDialog(WorkbenchServerOperations server, Session session, PreferencesDialogResources res, GeneralPreferencesPane general, EditingPreferencesPane source, ConsolePreferencesPane console, RMarkdownPreferencesPane rmarkdown, CompilePdfPreferencesPane compilePdf, AppearancePreferencesPane appearance, PaneLayoutPreferencesPane paneLayout, PackagesPreferencesPane packages, SourceControlPreferencesPane sourceControl, SpellingPreferencesPane spelling, PublishingPreferencesPane publishing, TerminalPreferencesPane terminal, AccessibilityPreferencesPane accessibility, PythonPreferencesPane python, ApplicationQuit quit, GlobalDisplay globalDisplay, UserPrefs userPrefs, UserState userState)49    public PreferencesDialog(WorkbenchServerOperations server,
50                             Session session,
51                             PreferencesDialogResources res,
52                             GeneralPreferencesPane general,
53                             EditingPreferencesPane source,
54                             ConsolePreferencesPane console,
55                             RMarkdownPreferencesPane rmarkdown,
56                             CompilePdfPreferencesPane compilePdf,
57                             AppearancePreferencesPane appearance,
58                             PaneLayoutPreferencesPane paneLayout,
59                             PackagesPreferencesPane packages,
60                             SourceControlPreferencesPane sourceControl,
61                             SpellingPreferencesPane spelling,
62                             PublishingPreferencesPane publishing,
63                             TerminalPreferencesPane terminal,
64                             AccessibilityPreferencesPane accessibility,
65                             PythonPreferencesPane python,
66                             ApplicationQuit quit,
67                             GlobalDisplay globalDisplay,
68                             UserPrefs userPrefs,
69                             UserState userState)
70    {
71       super("Options",
72             res.styles().panelContainer(),
73             res.styles().panelContainerNoChooser(),
74             true,
75             panes(
76                   general,
77                   source,
78                   console,
79                   appearance,
80                   paneLayout,
81                   packages,
82                   rmarkdown,
83                   python,
84                   compilePdf,
85                   spelling,
86                   sourceControl,
87                   publishing,
88                   terminal,
89                   accessibility));
90 
91       session_ = session;
92       server_ = server;
93       state_ = userState;
94       quit_ = quit;
95       globalDisplay_ = globalDisplay;
96 
97       if (!session.getSessionInfo().getAllowVcs())
98          hidePane(SourceControlPreferencesPane.class);
99 
100       if (!session.getSessionInfo().getAllowPublish())
101          hidePane(PublishingPreferencesPane.class);
102 
103       else if (!session.getSessionInfo().getAllowExternalPublish() &&
104                !userState.enableRsconnectPublishUi().getValue())
105       {
106          hidePane(PublishingPreferencesPane.class);
107       }
108 
109       if (!session.getSessionInfo().getAllowShell())
110       {
111          hidePane(TerminalPreferencesPane.class);
112       }
113 
114       ElementIds.assignElementId(this, ElementIds.DIALOG_GLOBAL_PREFS);
115    }
116 
117    @Override
createEmptyPrefs()118    protected UserPrefs createEmptyPrefs()
119    {
120       return RStudioGinjector.INSTANCE.getUserPrefs();
121    }
122 
123    @Override
doSaveChanges(final UserPrefs rPrefs, final Operation onCompleted, final ProgressIndicator progressIndicator, final RestartRequirement restartRequirement)124    protected void doSaveChanges(final UserPrefs rPrefs,
125                                 final Operation onCompleted,
126                                 final ProgressIndicator progressIndicator,
127                                 final RestartRequirement restartRequirement)
128    {
129       // save changes
130       server_.setUserPrefs(
131          rPrefs.getUserLayer(),
132          new SimpleRequestCallback<Void>() {
133 
134             @Override
135             public void onResponseReceived(Void response)
136             {
137                // write accompanying state changes
138                state_.writeState();
139 
140                progressIndicator.onCompleted();
141 
142                if (onCompleted != null)
143                   onCompleted.execute();
144 
145                handleRestart(
146                      globalDisplay_,
147                      quit_,
148                      session_,
149                      restartRequirement);
150             }
151 
152             @Override
153             public void onError(ServerError error)
154             {
155                progressIndicator.onError(error.getUserMessage());
156             }
157          });
158 
159       // broadcast UI pref changes to satellites
160       RStudioGinjector.INSTANCE.getSatelliteManager().dispatchCrossWindowEvent(
161                      new UserPrefsChangedEvent(session_.getSessionInfo().getUserPrefLayer()));
162    }
163 
ensureStylesInjected()164    public static void ensureStylesInjected()
165    {
166       GWT.<PreferencesDialogResources>create(PreferencesDialogResources.class).styles().ensureInjected();
167    }
168 
169    @SafeVarargs
panes( PreferencesDialogPaneBase<UserPrefs>.... paneList)170    private static final List<PreferencesDialogPaneBase<UserPrefs>> panes(
171       PreferencesDialogPaneBase<UserPrefs>... paneList)
172    {
173       List<PreferencesDialogPaneBase<UserPrefs>> allPanes = new ArrayList<>();
174       for (PreferencesDialogPaneBase<UserPrefs> pane : paneList)
175          allPanes.add(pane);
176       return allPanes;
177    }
178 
179 
180    private final WorkbenchServerOperations server_;
181    private final Session session_;
182    private final UserState state_;
183    private final ApplicationQuit quit_;
184    private final GlobalDisplay globalDisplay_;
185 }
186