1 /* 2 * PythonInterpreterSelectionDialog.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.python; 16 17 import java.util.HashMap; 18 import java.util.Map; 19 20 import org.rstudio.core.client.StringUtil; 21 import org.rstudio.core.client.js.JsUtil; 22 import org.rstudio.core.client.theme.DialogTabLayoutPanel; 23 import org.rstudio.core.client.theme.VerticalTabPanel; 24 import org.rstudio.core.client.widget.ModalDialog; 25 import org.rstudio.core.client.widget.OperationWithInput; 26 import org.rstudio.core.client.widget.ThemedButton; 27 import org.rstudio.core.client.widget.WidgetListBox; 28 import org.rstudio.studio.client.workbench.prefs.views.PythonInterpreter; 29 30 import com.google.gwt.aria.client.Roles; 31 import com.google.gwt.core.client.JsArray; 32 import com.google.gwt.event.dom.client.ChangeEvent; 33 import com.google.gwt.event.dom.client.DoubleClickEvent; 34 import com.google.gwt.user.client.ui.Widget; 35 36 public class PythonInterpreterSelectionDialog extends ModalDialog<PythonInterpreter> 37 { 38 private static final String LABEL_SYSTEM = "System"; 39 private static final String LABEL_VIRTUAL = "Virtual Environments"; 40 private static final String LABEL_CONDA = "Conda Environments"; 41 PythonInterpreterSelectionDialog(final JsArray<PythonInterpreter> interpreters, final OperationWithInput<PythonInterpreter> operation)42 public PythonInterpreterSelectionDialog(final JsArray<PythonInterpreter> interpreters, 43 final OperationWithInput<PythonInterpreter> operation) 44 { 45 super("Python Interpreters", Roles.getDialogRole(), operation); 46 setOkButtonCaption("Select"); 47 48 // initialize widget list boxes 49 widgets_ = new HashMap<>(); 50 for (String label : new String[] { LABEL_SYSTEM, LABEL_VIRTUAL, LABEL_CONDA }) 51 { 52 WidgetListBox<PythonInterpreterListEntryUi> listBox = new WidgetListBox<>(); 53 listBox.setSize("598px", "468px"); 54 listBox.setAriaLabel(label); 55 56 listBox.setEmptyText("(None available)"); 57 58 // allow double-click to select the requested interpreter 59 listBox.addDoubleClickHandler((DoubleClickEvent event) -> 60 { 61 if (listBox.getSelectedItem() != null) 62 { 63 selectedItem_ = listBox.getSelectedItem(); 64 clickOkButton(); 65 } 66 }); 67 68 listBox.addChangeHandler((ChangeEvent event) -> 69 { 70 selectedItem_ = listBox.getSelectedItem(); 71 }); 72 73 widgets_.put(label, listBox); 74 } 75 76 // add interpreters to their appropriate buckets 77 for (PythonInterpreter interpreter : JsUtil.asIterable(interpreters)) 78 { 79 if (interpreter == null || !interpreter.isValid()) 80 continue; 81 82 String type = interpreter.getType(); 83 if (type == null) 84 continue; 85 86 String version = interpreter.getVersion(); 87 if (version == null || version.startsWith("2")) 88 continue; 89 90 if (StringUtil.equals(type, "system")) 91 { 92 widgets_.get(LABEL_SYSTEM).addItem(new PythonInterpreterListEntryUi(interpreter)); 93 } 94 else if (StringUtil.equals(type, "virtualenv")) 95 { 96 widgets_.get(LABEL_VIRTUAL).addItem(new PythonInterpreterListEntryUi(interpreter)); 97 } 98 else if (StringUtil.equals(type, "conda")) 99 { 100 widgets_.get(LABEL_CONDA).addItem(new PythonInterpreterListEntryUi(interpreter)); 101 } 102 } 103 104 // initialize tab panel 105 tabPanel_ = new DialogTabLayoutPanel("General"); 106 tabPanel_.setSize("620px", "520px"); 107 for (Map.Entry<String, WidgetListBox<PythonInterpreterListEntryUi>> entry : widgets_.entrySet()) 108 { 109 VerticalTabPanel panel = new VerticalTabPanel(entry.getKey()); 110 panel.add(entry.getValue()); 111 tabPanel_.add(panel, entry.getKey(), panel.getBasePanelId()); 112 } 113 114 tabPanel_.selectTab(0); 115 } 116 117 @Override collectInput()118 protected PythonInterpreter collectInput() 119 { 120 if (selectedItem_ == null) 121 return null; 122 123 return selectedItem_.getInterpreter(); 124 } 125 126 @Override createMainWidget()127 protected Widget createMainWidget() 128 { 129 return tabPanel_; 130 } 131 132 final DialogTabLayoutPanel tabPanel_; 133 final Map<String, WidgetListBox<PythonInterpreterListEntryUi>> widgets_; 134 135 PythonInterpreterListEntryUi selectedItem_; 136 ThemedButton useDefaultBtn_; 137 } 138