Merge branch 'patch/JAL-4345_pae_epas1_doubleclick' into develop
[jalview.git] / src / jalview / gui / RestInputParamEditDialog.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import jalview.jbgui.GRestInputParamEditDialog;
24 import jalview.ws.params.InvalidArgumentException;
25 import jalview.ws.params.OptionI;
26 import jalview.ws.params.ParameterI;
27 import jalview.ws.rest.InputType;
28 import jalview.ws.rest.RestServiceDescription;
29
30 import java.util.ArrayList;
31 import java.util.Hashtable;
32
33 import javax.swing.JOptionPane;
34 import javax.swing.JPanel;
35 import javax.swing.event.ListSelectionEvent;
36
37 import net.miginfocom.swing.MigLayout;
38
39 public class RestInputParamEditDialog extends GRestInputParamEditDialog
40         implements OptsParametersContainerI
41 {
42   Hashtable<String, Class> typeclass = new Hashtable<String, Class>();
43
44   Hashtable<String, ArrayList<JPanel>> typeopts = new Hashtable<String, ArrayList<JPanel>>();
45
46   Hashtable<String, OptsAndParamsPage> opanps = new Hashtable<String, OptsAndParamsPage>();
47
48   private InputType getTypeFor(String name)
49   {
50     try
51     {
52       return (InputType) (typeclass.get(name).getConstructor()
53               .newInstance());
54     } catch (Throwable x)
55     {
56       jalview.bin.Console.errPrintln(
57               "Unexpected exception when instantiating rest input type.");
58       x.printStackTrace();
59     }
60     return null;
61   }
62
63   int reply;
64
65   JalviewDialog frame = new JalviewDialog()
66   {
67
68     @Override
69     protected void raiseClosed()
70     {
71
72     }
73
74     @Override
75     protected void okPressed()
76     {
77       reply = JvOptionPane.OK_OPTION;
78     }
79
80     @Override
81     protected void cancelPressed()
82     {
83       reply = JvOptionPane.CANCEL_OPTION;
84
85     }
86   };
87
88   InputType old, current;
89
90   public RestInputParamEditDialog(
91           RestServiceEditorPane restServiceEditorPane,
92           RestServiceDescription currentservice, InputType toedit)
93   {
94     initFor(restServiceEditorPane, currentservice, toedit);
95     frame.waitForInput();
96     // TODO: warn user if they are about to overwrite an existing parameter
97     // because they have used the same name when editing a different parameter.
98     // TODO: make any press of the return key cause 'OK' to be pressed
99   }
100
101   private void initFor(RestServiceEditorPane restServiceEditorPane,
102           RestServiceDescription currentservice, InputType toedit)
103   {
104     okcancel.add(frame.cancel);
105     okcancel.add(frame.ok);
106     frame.initDialogFrame(dpane, true, true,
107             "Edit parameter for service " + currentservice.getName(), 600,
108             800);
109
110     initTypeLists();
111     reply = JvOptionPane.CANCEL_OPTION;
112     old = toedit;
113     current = null;
114     if (old != null)
115     {
116       setStateFor(old);
117     }
118     updated = updated && reply == JvOptionPane.OK_OPTION;
119     frame.validate();
120   }
121
122   public RestInputParamEditDialog(
123           RestServiceEditorPane restServiceEditorPane,
124           RestServiceDescription currentservice, String string)
125   {
126     initFor(restServiceEditorPane, currentservice, null);
127     tok.setText(string);
128     frame.waitForInput();
129   }
130
131   private void setStateFor(InputType current)
132   {
133     tok.setText(current.token);
134     OptsAndParamsPage opanp = opanps.get(current.getURLtokenPrefix());
135     for (OptionI ops : current.getOptions())
136     {
137       if (ops instanceof ParameterI)
138       {
139         opanp.setParameter((ParameterI) ops);
140       }
141       else
142       {
143         if (ops.getValue() != null && ops.getValue().length() > 0)
144         {
145           opanp.selectOption(ops, ops.getValue());
146         }
147       }
148     }
149     typeList.setSelectedValue(current.getURLtokenPrefix(), true);
150     type_SelectionChangedActionPerformed(null);
151   }
152
153   private void updateCurrentType()
154   {
155     if (typeList.getSelectedValue() != null)
156     {
157       InputType newType = getTypeFor((String) typeList.getSelectedValue());
158       if (newType != null)
159       {
160         newType.token = tok.getText().trim();
161         try
162         {
163           newType.configureFromArgumentI(opanps
164                   .get(newType.getURLtokenPrefix()).getCurrentSettings());
165           current = newType;
166           updated = true;
167         } catch (InvalidArgumentException ex)
168         {
169           jalview.bin.Console.errPrintln(
170                   "IMPLEMENTATION ERROR: Invalid argument for type : "
171                           + typeList.getSelectedValue() + "\n");
172           ex.printStackTrace();
173         }
174       }
175     }
176
177   }
178
179   private void initTypeLists()
180   {
181     ArrayList<String> types = new ArrayList<String>();
182     // populate type list
183     for (Class type : RestServiceDescription.getInputTypes())
184     {
185
186       InputType jtype = null;
187       try
188       {
189         JPanel inopts = new JPanel(new MigLayout());
190         ArrayList<JPanel> opts = new ArrayList<JPanel>(),
191                 prms = new ArrayList<JPanel>();
192         jtype = (InputType) (type.getConstructor().newInstance());
193         typeclass.put(jtype.getURLtokenPrefix(), type);
194         // and populate parameters from this type
195         OptsAndParamsPage opanp = new OptsAndParamsPage(this, true);
196         opanps.put(jtype.getURLtokenPrefix(), opanp);
197         for (OptionI opt : jtype.getOptions())
198         {
199
200           if (opt instanceof ParameterI)
201           {
202             prms.add(opanp.addParameter((ParameterI) opt));
203           }
204           else
205           {
206             opts.add(opanp.addOption(opt));
207           }
208         }
209         // then tag the params at the end of the options.
210         for (JPanel pnl : prms)
211         {
212           opts.add(pnl);
213         }
214         typeopts.put(jtype.getURLtokenPrefix(), opts);
215         types.add(jtype.getURLtokenPrefix());
216       } catch (Throwable x)
217       {
218         jalview.bin.Console.errPrintln(
219                 "Unexpected exception when instantiating rest input type.");
220         x.printStackTrace();
221       }
222     }
223     typeList.setListData(types.toArray());
224
225   }
226
227   @Override
228   protected void type_SelectionChangedActionPerformed(ListSelectionEvent e)
229   {
230     options.removeAll();
231     String typen = (String) typeList.getSelectedValue();
232     if (typeopts.get(typen) != null)
233     {
234       for (JPanel opt : typeopts.get(typen))
235       {
236         opt.setOpaque(true);
237         options.add(opt, "wrap");
238       }
239       options.invalidate();
240       optionsPanel.setVisible(true);
241     }
242     else
243     {
244       optionsPanel.setVisible(false);
245     }
246     dpane.revalidate();
247     updateCurrentType();
248   }
249
250   boolean updated = false;
251
252   public boolean wasUpdated()
253   {
254     return updated;
255   }
256
257   @Override
258   public void refreshParamLayout()
259   {
260     options.invalidate();
261     dpane.revalidate();
262   }
263
264   @Override
265   protected void tokChanged_actionPerformed()
266   {
267     if (tok.getText().trim().length() > 0)
268     {
269       if (current != null)
270       {
271         current.token = tok.getText().trim();
272         updated = true;
273       }
274     }
275   }
276
277   @Override
278   public void argSetModified(Object modifiedElement, boolean b)
279   {
280     updated = updated | b;
281     if (updated)
282     {
283       updateCurrentType();
284     }
285   }
286
287 }