/* * ProjectTemplateWidget.java * * Copyright (C) 2009-16 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.model; import java.util.ArrayList; import java.util.List; import org.rstudio.core.client.Debug; import org.rstudio.core.client.StringUtil; import org.rstudio.core.client.js.JsObject; import org.rstudio.core.client.widget.FileChooserTextBox; import org.rstudio.core.client.widget.SelectWidget; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsArrayString; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Grid; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; public class ProjectTemplateWidget extends Composite { private interface Collector { public void collectInput(JsObject receiver); } private static class ProjectTemplateWidgetItem extends Composite { public ProjectTemplateWidgetItem(Widget widget, Collector collector) { collector_ = collector; initWidget(widget); } public void collectInput(JsObject receiver) { if (collector_ != null) collector_.collectInput(receiver); } private final Collector collector_; } public ProjectTemplateWidget(ProjectTemplateDescription description) { widgets_ = new ArrayList<ProjectTemplateWidgetItem>(); // initialize widgets JsArray<ProjectTemplateWidgetDescription> descriptions = description.getWidgetDescription(); int n = descriptions.length(); for (int i = 0; i < n; i++) widgets_.add(createWidget(descriptions.get(i))); // initialize panel VerticalPanel leftPanel = new VerticalPanel(); VerticalPanel rightPanel = new VerticalPanel(); for (int i = 0; i < n; i++) { String position = StringUtil.notNull(descriptions.get(i).getPosition()); Widget widget = widgets_.get(i); if ("right".equals(position.toLowerCase())) rightPanel.add(widget); else leftPanel.add(widget); } int nLeft = leftPanel.getWidgetCount(); int nRight = rightPanel.getWidgetCount(); Widget primaryWidget; if (nLeft == 0 && nRight == 0) primaryWidget = new FlowPanel(); else if (nRight == 0) primaryWidget = leftPanel; else if (nLeft == 0) primaryWidget = rightPanel; else { // both sides have widgets -- populate appropriately HorizontalPanel panel = new HorizontalPanel(); panel.add(leftPanel); panel.add(rightPanel); primaryWidget = panel; } primaryWidget.setWidth("100%"); initWidget(primaryWidget); } public JsObject collectInput() { JsObject object = JsObject.createJsObject(); for (ProjectTemplateWidgetItem widget : widgets_) widget.collectInput(object); return object; } private ProjectTemplateWidgetItem createWidget(ProjectTemplateWidgetDescription description) { String type = description.getType().toLowerCase(); if (type.equals(TYPE_CHECKBOX_INPUT)) return checkBoxInput(description); else if (type.equals(TYPE_SELECT_INPUT)) return selectBoxInput(description); else if (type.equals(TYPE_TEXT_INPUT)) return textInput(description); else if (type.equals(TYPE_FILE_INPUT)) return fileInput(description); Debug.log("Unexpected widget type '" + type + "'"); return new ProjectTemplateWidgetItem(new FlowPanel(), null); } private ProjectTemplateWidgetItem checkBoxInput(final ProjectTemplateWidgetDescription description) { final CheckBox widget = new CheckBox(description.getLabel()); // set default value String defaultValue = description.getDefault(); if (!StringUtil.isNullOrEmpty(defaultValue)) widget.setValue(isTruthy(defaultValue)); return new ProjectTemplateWidgetItem(widget, new Collector() { @Override public void collectInput(JsObject receiver) { boolean value = widget.getValue(); receiver.setBoolean(description.getParameter(), value); } }); } private ProjectTemplateWidgetItem selectBoxInput(final ProjectTemplateWidgetDescription description) { String[] fields = readSelectBoxFields(description); String label = ensureEndsWithColon(description.getLabel()); final SelectWidget widget = new SelectWidget(label, fields); String defaultValue = description.getDefault(); if (!StringUtil.isNullOrEmpty(defaultValue)) widget.setValue(defaultValue); return new ProjectTemplateWidgetItem(widget, new Collector() { @Override public void collectInput(JsObject receiver) { String value = widget.getValue(); receiver.setString(description.getParameter(), value); } }); } private ProjectTemplateWidgetItem textInput(final ProjectTemplateWidgetDescription description) { final TextBox primaryWidget = new TextBox(); primaryWidget.setWidth("180px"); String defaultValue = description.getDefault(); if (!StringUtil.isNullOrEmpty(defaultValue)) primaryWidget.setText(defaultValue); Grid grid = new Grid(1, 2); primaryWidget.getElement().setAttribute("spellcheck", "false"); grid.setWidget(0, 0, new Label(ensureEndsWithColon(description.getLabel()))); grid.setWidget(0, 1, primaryWidget); return new ProjectTemplateWidgetItem(grid, new Collector() { @Override public void collectInput(JsObject receiver) { String value = primaryWidget.getValue(); receiver.setString(description.getParameter(), value); } }); } private ProjectTemplateWidgetItem fileInput(final ProjectTemplateWidgetDescription description) { final FileChooserTextBox widget = new FileChooserTextBox(description.getLabel(), null); String defaultValue = description.getDefault(); if (!StringUtil.isNullOrEmpty(defaultValue)) widget.setText(defaultValue); return new ProjectTemplateWidgetItem(widget, new Collector() { @Override public void collectInput(JsObject receiver) { String value = widget.getText(); receiver.setString(description.getParameter(), value); } }); } private String[] readSelectBoxFields(ProjectTemplateWidgetDescription description) { JsArrayString jsFields = description.getFields(); int n = jsFields.length(); String[] fields = new String[n]; for (int i = 0; i < n; i++) fields[i] = jsFields.get(i); return fields; } private String ensureEndsWithColon(String string) { return string.endsWith(":") ? string : string + ":"; } private boolean isTruthy(String value) { String lower = value.toLowerCase(); return lower.equals("true") || lower.equals("yes") || lower.equals("on") || lower.equals("1"); } private final List<ProjectTemplateWidgetItem> widgets_; public static final String TYPE_CHECKBOX_INPUT = "checkboxinput"; public static final String TYPE_SELECT_INPUT = "selectinput"; public static final String TYPE_FILE_INPUT = "fileinput"; public static final String TYPE_TEXT_INPUT = "textinput"; }