1 /*
2  * SpellingLanguageSelectWidget.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.common.spelling.ui;
16 
17 import org.rstudio.core.client.widget.HelpButton;
18 import org.rstudio.core.client.widget.ProgressIndicator;
19 import org.rstudio.core.client.widget.SelectWidget;
20 import org.rstudio.studio.client.RStudioGinjector;
21 import org.rstudio.studio.client.common.spelling.SpellingService;
22 import org.rstudio.studio.client.common.spelling.model.SpellingLanguage;
23 import org.rstudio.studio.client.server.ServerError;
24 import org.rstudio.studio.client.server.ServerRequestCallback;
25 import org.rstudio.studio.client.workbench.prefs.model.SpellingPrefsContext;
26 
27 import com.google.gwt.core.client.JsArray;
28 import com.google.gwt.dom.client.Style.Unit;
29 import com.google.gwt.event.dom.client.ChangeEvent;
30 import com.google.gwt.event.dom.client.ChangeHandler;
31 import com.google.gwt.json.client.JSONString;
32 import com.google.gwt.user.client.ui.ListBox;
33 
34 public class SpellingLanguageSelectWidget extends SelectWidget
35 {
SpellingLanguageSelectWidget(SpellingService spellingService)36    public SpellingLanguageSelectWidget(SpellingService spellingService)
37    {
38       this(spellingService, false);
39    }
40 
SpellingLanguageSelectWidget(SpellingService spellingService, boolean includeDefaultOption)41    public SpellingLanguageSelectWidget(SpellingService spellingService,
42                                        boolean includeDefaultOption)
43    {
44       super("Main dictionary language:",
45             new String[0],
46             new String[0],
47             false,
48             true,
49             false);
50 
51       includeDefaultOption_ = includeDefaultOption;
52       languageOffset_ = includeDefaultOption_ ? 1 : 0;
53 
54       getLabel().getElement().getStyle().setMarginBottom(4, Unit.PX);
55 
56       HelpButton.addHelpButton(this, "spelling_dictionaries", "Help on spelling dictionaries", 0);
57 
58       getListBox().addChangeHandler(new ChangeHandler() {
59 
60          @Override
61          public void onChange(ChangeEvent event)
62          {
63             int selectedIndex = getListBox().getSelectedIndex();
64             if (selectedIndex == installIndex_)
65             {
66                setSelectedLanguage(currentLangId_);
67                String progress = allLanguagesInstalled_ ?
68                                     "Downloading dictionaries..." :
69                                     "Downloading additional languages...";
70 
71                // show progress
72                progressIndicator_.onProgress(progress);
73 
74                // save current selection for restoring
75                final String currentLang = getSelectedLanguage();
76 
77                spellingService.installAllDictionaries(
78                   new ServerRequestCallback<SpellingPrefsContext> () {
79 
80                      @Override
81                      public void onResponseReceived(SpellingPrefsContext context)
82                      {
83                         progressIndicator_.onCompleted();
84                         setLanguages(context.getAllLanguagesInstalled(),
85                                      context.getAvailableLanguages());
86                         setSelectedLanguage(currentLang);
87                      }
88 
89                      @Override
90                      public void onError(ServerError error)
91                      {
92                         JSONString userMessage = error.getClientInfo().isString();
93                         if (userMessage != null)
94                         {
95                            progressIndicator_.onCompleted();
96                            RStudioGinjector.INSTANCE.getGlobalDisplay().showErrorMessage(
97                               "Error Downloading Dictionaries", userMessage.stringValue());
98                         }
99                         else
100                         {
101                            progressIndicator_.onError(error.getUserMessage());
102                         }
103                      }
104 
105                });
106 
107             }
108             else
109             {
110                currentLangId_ = getSelectedLanguage();
111             }
112          }
113 
114       });
115    }
116 
setProgressIndicator(ProgressIndicator progressIndicator)117    public void setProgressIndicator(ProgressIndicator progressIndicator)
118    {
119       progressIndicator_ = progressIndicator;
120    }
121 
setLanguages(boolean allLanguagesInstalled, JsArray<SpellingLanguage> languages)122    public void setLanguages(boolean allLanguagesInstalled,
123                             JsArray<SpellingLanguage> languages)
124    {
125       languages_ = languages;
126       installIndex_ = languages.length() + languageOffset_;
127       allLanguagesInstalled_ = allLanguagesInstalled;
128       String[] choices =  new String[languages.length()+1 + languageOffset_];
129       String[] values = new String[languages.length()+1 + languageOffset_];
130       if (includeDefaultOption_)
131       {
132          choices[0] = "(Default)";
133          values[0] = "";
134       }
135       for (int i=0; i<languages.length(); i++)
136       {
137          SpellingLanguage language = languages.get(i);
138          choices[i + languageOffset_] = language.getName();
139          values[i + languageOffset_] = language.getId();
140       }
141       if (allLanguagesInstalled)
142          choices[installIndex_] = "Update Dictionaries...";
143       else
144          choices[installIndex_] = "Install More Languages...";
145       values[installIndex_] = "";
146 
147       setChoices(choices, values);
148    }
149 
setSelectedLanguage(String langId)150    public void setSelectedLanguage(String langId)
151    {
152       if (includeDefaultOption_ && langId.isEmpty())
153       {
154          getListBox().setSelectedIndex(0);
155          currentLangId_ = "";
156       }
157       else
158       {
159          for (int i=0; i<languages_.length(); i++)
160          {
161             if (langId == languages_.get(i).getId())
162             {
163                currentLangId_ = langId;
164                getListBox().setSelectedIndex(i + languageOffset_);
165                return;
166             }
167          }
168 
169          // if we couldn't find this lang id then reset
170          getListBox().setSelectedIndex(0);
171          currentLangId_ = getListBox().getValue(0);
172       }
173    }
174 
getSelectedLanguage()175    public String getSelectedLanguage()
176    {
177       ListBox listBox = getListBox();
178       return listBox.getValue(listBox.getSelectedIndex());
179    }
180 
181    private final boolean includeDefaultOption_;
182    private final int languageOffset_;
183    private String currentLangId_ = null;
184    private int installIndex_ = -1;
185    private boolean allLanguagesInstalled_ = false;
186    private JsArray<SpellingLanguage> languages_;
187    private ProgressIndicator progressIndicator_;
188 
189 }
190