1 /*
2  * DataImportOptionsUiCsvLocale.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 
16 package org.rstudio.studio.client.workbench.views.environment.dataimport;
17 
18 import com.google.gwt.aria.client.Roles;
19 import org.rstudio.core.client.widget.ModalDialog;
20 import org.rstudio.core.client.widget.OperationWithInput;
21 import org.rstudio.studio.client.RStudioGinjector;
22 import org.rstudio.studio.client.common.GlobalDisplay;
23 import org.rstudio.studio.client.common.HelpLink;
24 
25 import com.google.gwt.core.client.GWT;
26 import com.google.gwt.event.dom.client.ChangeEvent;
27 import com.google.gwt.event.dom.client.ChangeHandler;
28 import com.google.gwt.resources.client.CssResource;
29 import com.google.gwt.uibinder.client.UiBinder;
30 import com.google.gwt.uibinder.client.UiField;
31 import com.google.gwt.user.client.ui.CheckBox;
32 import com.google.gwt.user.client.ui.ListBox;
33 import com.google.gwt.user.client.ui.TextBox;
34 import com.google.gwt.user.client.ui.Widget;
35 import com.google.inject.Inject;
36 
37 public class DataImportOptionsUiCsvLocale extends ModalDialog<DataImportOptionsCsvLocale>
38 {
39    interface Binder extends UiBinder<Widget, DataImportOptionsUiCsvLocale> {}
40 
41    public interface DataImportOptionsUiCsvLocaleStyle extends CssResource
42    {
dialog()43       String dialog();
44    }
45 
46    @Inject
initialize(GlobalDisplay globalDisplay)47    private void initialize(GlobalDisplay globalDisplay)
48    {
49       globalDisplay_ = globalDisplay;
50    }
51 
DataImportOptionsUiCsvLocale( OperationWithInput<DataImportOptionsCsvLocale> operation, DataImportOptionsCsvLocale locale)52    public DataImportOptionsUiCsvLocale(
53       OperationWithInput<DataImportOptionsCsvLocale> operation,
54       DataImportOptionsCsvLocale locale)
55    {
56       super("Configure Locale", Roles.getDialogRole(), operation);
57       widget_ = GWT.<Binder> create(Binder.class).createAndBindUi(this);
58       initialLocale_ = locale;
59 
60       RStudioGinjector.INSTANCE.injectMembers(this);
61    }
62 
assignLocale(DataImportOptionsCsvLocale locale)63    private void assignLocale(DataImportOptionsCsvLocale locale)
64    {
65       if (locale == null) return;
66 
67       int fixedEncodings = encoding_.getItemCount();
68       for (int idxEncoding = 0; idxEncoding < fixedEncodings; idxEncoding ++) {
69          if (encoding_.getValue(idxEncoding) == locale.getEncoding()) {
70             encoding_.setSelectedIndex(idxEncoding);
71             break;
72          }
73 
74          if (idxEncoding == fixedEncodings - 1) {
75             addOtherEncodingItem(idxEncoding, locale.getEncoding());
76          }
77       }
78 
79       dateName_.setText(locale.getDateName());
80       dateFormat_.setText(locale.getDateFormat());
81       timeFormat_.setText(locale.getTimeFormat());
82       decimalMark_.setText(locale.getDecimalMark());
83       groupingMark_.setText(locale.getGroupingMark());
84       timeZone_.setText(locale.getTZ());
85       asciify_.setValue(locale.getAsciify());
86    }
87 
88    @Override
onDialogShown()89    protected void onDialogShown()
90    {
91       super.onDialogShown();
92 
93       initializeDefaults();
94       initializeEvents();
95 
96       assignLocale(initialLocale_);
97 
98       setOkButtonCaption("Configure");
99 
100       HelpLink helpLink = new HelpLink(
101          "Locales in readr",
102          "readr_locales",
103          false);
104       addLeftWidget(helpLink);
105    }
106 
107    @Override
createMainWidget()108    protected Widget createMainWidget()
109    {
110       return widget_;
111    }
112 
113    @Override
collectInput()114    protected DataImportOptionsCsvLocale collectInput()
115    {
116       return DataImportOptionsCsvLocale.createLocale(
117         dateName_.getText(),
118         dateFormat_.getText(),
119         timeFormat_.getText(),
120         decimalMark_.getText(),
121         groupingMark_.getText(),
122         timeZone_.getText(),
123         encoding_.getSelectedValue(),
124         asciify_.getValue()
125       );
126    }
127 
initializeDefaults()128    private void initializeDefaults()
129    {
130       // load .rs.iconvcommon()
131       encoding_.addItem("ASCII", "ASCII");
132       encoding_.addItem("UTF-8", "UTF-8");
133       encoding_.addItem("ISO-8859-1", "ISO-8859-1");
134       encoding_.addItem("WINDOWS-1252", "WINDOWS-1252");
135       encoding_.addItem("SHIFT-JIS", "SHIFT-JIS");
136       encoding_.addItem("ISO-2022-JP", "ISO-2022-JP");
137       encoding_.addItem("BIG5", "BIG5");
138       encoding_.addItem("ISO-2022-KR", "ISO-2022-KR");
139       encoding_.addItem("ISO-8859-7", "ISO-8859-7");
140       encoding_.addItem("GB2312", "GB2312");
141       encoding_.addItem("GB18030", "GB18030");
142       encoding_.addItem("ISO-8859-2", "ISO-8859-2");
143 
144       encoding_.addItem(otherLabel, "");
145 
146       encoding_.setSelectedIndex(1);
147    }
148 
addOtherEncodingItem(int selectedIndex, String otherEncoding)149    private void addOtherEncodingItem(int selectedIndex, String otherEncoding) {
150       encoding_.insertItem(otherEncoding, otherEncoding, selectedIndex);
151       encoding_.setSelectedIndex(selectedIndex);
152    }
153 
initializeEvents()154    private void initializeEvents()
155    {
156       ChangeHandler encodingChangeHandler = new ChangeHandler()
157       {
158          @Override
159          public void onChange(ChangeEvent arg0)
160          {
161             if (encoding_.getSelectedItemText() == otherLabel)
162             {
163                globalDisplay_.promptForText(
164                   "Encoding Identifier",
165                   "Please enter an encoding identifier. For a list of valid encodings run iconvlist().",
166                   encoding_.getSelectedValue(),
167                   new OperationWithInput<String>()
168                   {
169                      @Override
170                      public void execute(final String otherEncoding)
171                      {
172                         for (int idxEncoding = 0; idxEncoding < encoding_.getItemCount(); idxEncoding++) {
173                            if (encoding_.getValue(idxEncoding) == otherEncoding) {
174                               encoding_.setSelectedIndex(idxEncoding);
175                               return;
176                            }
177                         }
178 
179                         int selectedIndex = encoding_.getSelectedIndex();
180                         addOtherEncodingItem(selectedIndex - 1, otherEncoding);
181                      }
182                   }
183                );
184             }
185          }
186       };
187 
188       encoding_.addChangeHandler(encodingChangeHandler);
189    }
190 
191    @UiField
192    TextBox dateName_;
193 
194    @UiField
195    ListBox encoding_;
196 
197    @UiField
198    TextBox dateFormat_;
199 
200    @UiField
201    TextBox timeFormat_;
202 
203    @UiField
204    TextBox decimalMark_;
205 
206    @UiField
207    TextBox groupingMark_;
208 
209    @UiField
210    TextBox timeZone_;
211 
212    @UiField
213    CheckBox asciify_;
214 
215    private Widget widget_;
216    private DataImportOptionsCsvLocale initialLocale_;
217    private GlobalDisplay globalDisplay_;
218 
219    private final String otherLabel = "Other...";
220 }
221