I18 changes
[debian/openrocket] / src / net / sf / openrocket / gui / dialogs / EditMotorConfigurationDialog.java
1 package net.sf.openrocket.gui.dialogs;
2
3 import java.awt.Window;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.awt.event.MouseAdapter;
7 import java.awt.event.MouseEvent;
8 import java.awt.event.WindowAdapter;
9 import java.awt.event.WindowEvent;
10 import java.util.ArrayList;
11 import java.util.Iterator;
12
13 import javax.swing.JButton;
14 import javax.swing.JDialog;
15 import javax.swing.JLabel;
16 import javax.swing.JPanel;
17 import javax.swing.JScrollPane;
18 import javax.swing.JTable;
19 import javax.swing.JTextField;
20 import javax.swing.ListSelectionModel;
21 import javax.swing.event.DocumentEvent;
22 import javax.swing.event.DocumentListener;
23 import javax.swing.table.AbstractTableModel;
24 import javax.swing.table.TableColumn;
25 import javax.swing.table.TableColumnModel;
26
27 import net.miginfocom.swing.MigLayout;
28 import net.sf.openrocket.document.OpenRocketDocument;
29 import net.sf.openrocket.gui.dialogs.motor.MotorChooserDialog;
30 import net.sf.openrocket.gui.main.BasicFrame;
31 import net.sf.openrocket.l10n.Translator;
32 import net.sf.openrocket.motor.Motor;
33 import net.sf.openrocket.rocketcomponent.MotorMount;
34 import net.sf.openrocket.rocketcomponent.Rocket;
35 import net.sf.openrocket.rocketcomponent.RocketComponent;
36 import net.sf.openrocket.startup.Application;
37 import net.sf.openrocket.util.Chars;
38 import net.sf.openrocket.util.GUIUtil;
39
40 public class EditMotorConfigurationDialog extends JDialog {
41         
42         private final Rocket rocket;
43         
44         private final MotorMount[] mounts;
45         
46         private final JTable configurationTable;
47         private final MotorConfigurationTableModel configurationTableModel;
48         
49
50         private final JButton newConfButton, removeConfButton;
51         private final JButton selectMotorButton, removeMotorButton;
52         private final JTextField configurationNameField;
53         
54
55         private String currentID = null;
56         private MotorMount currentMount = null;
57         
58         // Positive when user is modifying configuration name
59         private int configurationNameModification = 0;
60         private static final Translator trans = Application.getTranslator();
61
62         public EditMotorConfigurationDialog(final Rocket rocket, Window parent) {
63                 //// Edit motor configurations
64                 super(parent, trans.get("edtmotorconfdlg.title.Editmotorconf"));
65                 
66                 if (parent != null)
67                         this.setModalityType(ModalityType.DOCUMENT_MODAL);
68                 else
69                         this.setModalityType(ModalityType.APPLICATION_MODAL);
70                 
71                 this.rocket = rocket;
72                 
73                 ArrayList<MotorMount> mountList = new ArrayList<MotorMount>();
74                 Iterator<RocketComponent> iterator = rocket.iterator();
75                 while (iterator.hasNext()) {
76                         RocketComponent c = iterator.next();
77                         if (c instanceof MotorMount) {
78                                 mountList.add((MotorMount) c);
79                         }
80                 }
81                 mounts = mountList.toArray(new MotorMount[0]);
82                 
83
84
85                 JPanel panel = new JPanel(new MigLayout("fill, flowy"));
86                 
87
88                 ////  Motor mount selection
89                 //// <html><b>Motor mounts:</b>
90                 JLabel label = new JLabel(trans.get("edtmotorconfdlg.lbl.Motormounts"));
91                 panel.add(label, "gapbottom para");
92                 
93                 //// <html>Select which components function as motor mounts:
94                 label = new JLabel(trans.get("edtmotorconfdlg.selectcomp"));
95                 panel.add(label, "ay 100%, w 1px, growx");
96                 
97
98                 JTable table = new JTable(new MotorMountTableModel());
99                 table.setTableHeader(null);
100                 table.setShowVerticalLines(false);
101                 table.setRowSelectionAllowed(false);
102                 table.setColumnSelectionAllowed(false);
103                 
104                 TableColumnModel columnModel = table.getColumnModel();
105                 TableColumn col0 = columnModel.getColumn(0);
106                 int w = table.getRowHeight() + 2;
107                 col0.setMinWidth(w);
108                 col0.setPreferredWidth(w);
109                 col0.setMaxWidth(w);
110                 
111                 table.addMouseListener(new GUIUtil.BooleanTableClickListener(table));
112                 
113                 JScrollPane scroll = new JScrollPane(table);
114                 panel.add(scroll, "w 200lp, h 150lp, grow, wrap 20lp");
115                 
116
117
118
119
120                 //// Motor selection
121                 //// <html><b>Motor configurations:</b>
122                 label = new JLabel(trans.get("edtmotorconfdlg.lbl.Motorconfig"));
123                 panel.add(label, "spanx, gapbottom para");
124                 
125                 //// Configuration name:
126                 label = new JLabel(trans.get("edtmotorconfdlg.lbl.Configname"));
127                 //// Leave name empty for default.
128                 String tip = trans.get("edtmotorconfdlg.lbl.Leavenamedefault");
129                 label.setToolTipText(tip);
130                 panel.add(label, "");
131                 
132                 configurationNameField = new JTextField(10);
133                 configurationNameField.setToolTipText(tip);
134                 configurationNameField.getDocument().addDocumentListener(new DocumentListener() {
135                         @Override
136                         public void changedUpdate(DocumentEvent e) {
137                                 update();
138                         }
139                         
140                         @Override
141                         public void insertUpdate(DocumentEvent e) {
142                                 update();
143                         }
144                         
145                         @Override
146                         public void removeUpdate(DocumentEvent e) {
147                                 update();
148                         }
149                         
150                         private void update() {
151                                 if (configurationNameModification != 0)
152                                         return;
153                                 
154                                 String text = configurationNameField.getText();
155                                 if (currentID != null) {
156                                         configurationNameModification++;
157                                         rocket.setMotorConfigurationName(currentID, text);
158                                         int row = configurationTable.getSelectedRow();
159                                         configurationTableModel.fireTableCellUpdated(row, 0);
160                                         updateEnabled();
161                                         configurationNameModification--;
162                                 }
163                         }
164                 });
165                 panel.add(configurationNameField, "cell 2 1, gapright para");
166                 
167                 //// New configuration
168                 newConfButton = new JButton(trans.get("edtmotorconfdlg.but.Newconfiguration"));
169                 newConfButton.addActionListener(new ActionListener() {
170                         @Override
171                         public void actionPerformed(ActionEvent e) {
172                                 String id = rocket.newMotorConfigurationID();
173                                 rocket.getDefaultConfiguration().setMotorConfigurationID(id);
174                                 configurationTableModel.fireTableDataChanged();
175                                 updateEnabled();
176                         }
177                 });
178                 panel.add(newConfButton, "cell 3 1");
179                 
180                 //// Remove configuration
181                 removeConfButton = new JButton(trans.get("edtmotorconfdlg.but.Removeconfiguration"));
182                 removeConfButton.addActionListener(new ActionListener() {
183                         @Override
184                         public void actionPerformed(ActionEvent e) {
185                                 if (currentID == null)
186                                         return;
187                                 rocket.removeMotorConfigurationID(currentID);
188                                 rocket.getDefaultConfiguration().setMotorConfigurationID(null);
189                                 configurationTableModel.fireTableDataChanged();
190                                 updateEnabled();
191                         }
192                 });
193                 panel.add(removeConfButton, "cell 4 1");
194                 
195
196
197
198                 configurationTableModel = new MotorConfigurationTableModel();
199                 configurationTable = new JTable(configurationTableModel);
200                 configurationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
201                 configurationTable.setCellSelectionEnabled(true);
202                 
203                 configurationTable.addMouseListener(new MouseAdapter() {
204                         @Override
205                         public void mouseClicked(MouseEvent e) {
206                                 
207                                 if (e.getClickCount() == 1) {
208                                         
209                                         // Single click updates selection
210                                         updateEnabled();
211                                         
212                                 } else if (e.getClickCount() == 2) {
213                                         
214                                         // Double-click edits motor
215                                         selectMotor();
216                                         
217                                 }
218                                 
219                         }
220                 });
221                 
222
223                 scroll = new JScrollPane(configurationTable);
224                 panel.add(scroll, "cell 1 2, spanx, w 500lp, h 150lp, grow");
225                 
226                 //// Select motor
227                 selectMotorButton = new JButton(trans.get("edtmotorconfdlg.but.Selectmotor"));
228                 selectMotorButton.addActionListener(new ActionListener() {
229                         @Override
230                         public void actionPerformed(ActionEvent e) {
231                                 selectMotor();
232                         }
233                 });
234                 panel.add(selectMotorButton, "spanx, flowx, split 2, ax 50%");
235                 
236                 //// Remove motor button
237                 removeMotorButton = new JButton(trans.get("edtmotorconfdlg.but.removemotor"));
238                 removeMotorButton.addActionListener(new ActionListener() {
239                         @Override
240                         public void actionPerformed(ActionEvent e) {
241                                 removeMotor();
242                         }
243                 });
244                 panel.add(removeMotorButton, "ax 50%");
245                 
246
247
248                 //// Close button
249                 JButton close = new JButton(trans.get("dlg.but.close"));
250                 close.addActionListener(new ActionListener() {
251                         @Override
252                         public void actionPerformed(ActionEvent e) {
253                                 EditMotorConfigurationDialog.this.dispose();
254                         }
255                 });
256                 panel.add(close, "spanx, right");
257                 
258                 this.add(panel);
259                 this.validate();
260                 this.pack();
261                 
262                 updateEnabled();
263                 
264                 this.setLocationByPlatform(true);
265                 GUIUtil.setDisposableDialogOptions(this, close);
266                 
267                 // Undo description
268                 final OpenRocketDocument document = BasicFrame.findDocument(rocket);
269                 if (document != null) {
270                         //// Edit motor configurations
271                         document.startUndo(trans.get("edtmotorconfdlg.title.Editmotorconf"));
272                         this.addWindowListener(new WindowAdapter() {
273                                 @Override
274                                 public void windowClosed(WindowEvent e) {
275                                         document.stopUndo();
276                                 }
277                         });
278                 }
279         }
280         
281         
282
283
284         private void updateEnabled() {
285                 int column = configurationTable.getSelectedColumn();
286                 int row = configurationTable.getSelectedRow();
287                 
288                 if (column < 0 || row < 0) {
289                         currentID = null;
290                         currentMount = null;
291                 } else {
292                         
293                         currentID = findID(row);
294                         if (column == 0) {
295                                 currentMount = null;
296                         } else {
297                                 currentMount = findMount(column);
298                         }
299                         rocket.getDefaultConfiguration().setMotorConfigurationID(currentID);
300                         
301                 }
302                 
303                 if (configurationNameModification == 0) {
304                         // Don't update name field when user is modifying it
305                         configurationNameModification++;
306                         
307                         configurationNameField.setEnabled(currentID != null);
308                         if (currentID == null) {
309                                 configurationNameField.setText("");
310                         } else {
311                                 configurationNameField.setText(rocket.getMotorConfigurationName(currentID));
312                         }
313                         
314                         configurationNameModification--;
315                 }
316                 removeConfButton.setEnabled(currentID != null);
317                 selectMotorButton.setEnabled(currentMount != null && currentID != null);
318                 removeMotorButton.setEnabled(currentMount != null && currentID != null);
319         }
320         
321         
322
323
324         private void selectMotor() {
325                 if (currentID == null || currentMount == null)
326                         return;
327                 
328                 MotorChooserDialog dialog = new MotorChooserDialog(currentMount.getMotor(currentID),
329                                 currentMount.getMotorDelay(currentID), currentMount.getMotorMountDiameter(), this);
330                 dialog.setVisible(true);
331                 Motor m = dialog.getSelectedMotor();
332                 double d = dialog.getSelectedDelay();
333                 
334                 if (m != null) {
335                         currentMount.setMotor(currentID, m);
336                         currentMount.setMotorDelay(currentID, d);
337                 }
338                 
339                 int row = configurationTable.getSelectedRow();
340                 configurationTableModel.fireTableRowsUpdated(row, row);
341                 updateEnabled();
342         }
343         
344         
345         private void removeMotor() {
346                 if (currentID == null || currentMount == null)
347                         return;
348                 
349                 currentMount.setMotor(currentID, null);
350                 
351                 int row = configurationTable.getSelectedRow();
352                 configurationTableModel.fireTableRowsUpdated(row, row);
353                 updateEnabled();
354         }
355         
356         
357         private String findID(int row) {
358                 return rocket.getMotorConfigurationIDs()[row + 1];
359         }
360         
361         
362         private MotorMount findMount(int column) {
363                 MotorMount mount = null;
364                 
365                 int count = column;
366                 for (MotorMount m : mounts) {
367                         if (m.isMotorMount())
368                                 count--;
369                         if (count <= 0) {
370                                 mount = m;
371                                 break;
372                         }
373                 }
374                 
375                 if (mount == null) {
376                         throw new IndexOutOfBoundsException("motor mount not found, column=" + column);
377                 }
378                 return mount;
379         }
380         
381         
382         /**
383          * The table model for selecting whether components are motor mounts or not.
384          */
385         private class MotorMountTableModel extends AbstractTableModel {
386                 
387                 @Override
388                 public int getColumnCount() {
389                         return 2;
390                 }
391                 
392                 @Override
393                 public int getRowCount() {
394                         return mounts.length;
395                 }
396                 
397                 @Override
398                 public Class<?> getColumnClass(int column) {
399                         switch (column) {
400                         case 0:
401                                 return Boolean.class;
402                                 
403                         case 1:
404                                 return String.class;
405                                 
406                         default:
407                                 throw new IndexOutOfBoundsException("column=" + column);
408                         }
409                 }
410                 
411                 @Override
412                 public Object getValueAt(int row, int column) {
413                         switch (column) {
414                         case 0:
415                                 return new Boolean(mounts[row].isMotorMount());
416                                 
417                         case 1:
418                                 return mounts[row].toString();
419                                 
420                         default:
421                                 throw new IndexOutOfBoundsException("column=" + column);
422                         }
423                 }
424                 
425                 @Override
426                 public boolean isCellEditable(int row, int column) {
427                         return column == 0;
428                 }
429                 
430                 @Override
431                 public void setValueAt(Object value, int row, int column) {
432                         if (column != 0 || !(value instanceof Boolean)) {
433                                 throw new IllegalArgumentException("column=" + column + ", value=" + value);
434                         }
435                         
436                         mounts[row].setMotorMount((Boolean) value);
437                         configurationTableModel.fireTableStructureChanged();
438                         updateEnabled();
439                 }
440         }
441         
442         
443
444         /**
445          * The table model for selecting and editing the motor configurations.
446          */
447         private class MotorConfigurationTableModel extends AbstractTableModel {
448                 
449                 @Override
450                 public int getColumnCount() {
451                         int count = 1;
452                         for (MotorMount m : mounts) {
453                                 if (m.isMotorMount())
454                                         count++;
455                         }
456                         return count;
457                 }
458                 
459                 @Override
460                 public int getRowCount() {
461                         return rocket.getMotorConfigurationIDs().length - 1;
462                 }
463                 
464                 @Override
465                 public Object getValueAt(int row, int column) {
466                         
467                         String id = findID(row);
468                         
469                         if (column == 0) {
470                                 return rocket.getMotorConfigurationNameOrDescription(id);
471                         }
472                         
473                         MotorMount mount = findMount(column);
474                         Motor motor = mount.getMotor(id);
475                         if (motor == null)
476                                 return "None";
477                         
478                         String str = motor.getDesignation(mount.getMotorDelay(id));
479                         int count = mount.getMotorCount();
480                         if (count > 1) {
481                                 str = "" + count + Chars.TIMES + " " + str;
482                         }
483                         return str;
484                 }
485                 
486                 
487                 @Override
488                 public String getColumnName(int column) {
489                         if (column == 0) {
490                                 return "Configuration name";
491                         }
492                         
493                         MotorMount mount = findMount(column);
494                         String name = mount.toString();
495                         int count = mount.getMotorCount();
496                         if (count > 1) {
497                                 name = name + " (" + Chars.TIMES + count + ")";
498                         }
499                         return name;
500                 }
501                 
502         }
503         
504 }