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