77fa3a4b2853f019f5b02572f68ba5d4d5b46ab5
[debian/openrocket] / core / src / net / sf / openrocket / gui / customexpression / ExpressionBuilderDialog.java
1 package net.sf.openrocket.gui.customexpression;
2
3 import java.awt.Window;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.awt.event.FocusEvent;
7 import java.awt.event.FocusListener;
8 import java.awt.event.KeyEvent;
9 import java.awt.event.KeyListener;
10
11 import javax.swing.ImageIcon;
12 import javax.swing.JButton;
13 import javax.swing.JCheckBox;
14 import javax.swing.JDialog;
15 import javax.swing.JLabel;
16 import javax.swing.JPanel;
17 import javax.swing.JTextField;
18 import javax.swing.SwingConstants;
19 import javax.swing.SwingUtilities;
20
21 import net.miginfocom.swing.MigLayout;
22 import net.sf.openrocket.document.Simulation;
23 import net.sf.openrocket.gui.util.Icons;
24 import net.sf.openrocket.l10n.Translator;
25 import net.sf.openrocket.logging.LogHelper;
26 import net.sf.openrocket.simulation.CustomExpression;
27 import net.sf.openrocket.startup.Application;
28
29 /**
30  * Dialog box for making a custom expression
31  * @author Richard Graham
32  *
33  */
34
35 public class ExpressionBuilderDialog extends JDialog {
36
37         private static final Translator trans = Application.getTranslator();
38         private static final LogHelper log = Application.getLogger();
39         
40         private static final ImageIcon GreenIcon = Icons.loadImageIcon("pix/spheres/green-16x16.png", "OK");
41         private static final ImageIcon RedIcon = Icons.loadImageIcon("pix/spheres/red-16x16.png", "Bad");
42         
43         private CustomExpression expression;
44         private CustomExpression previousExpressionCopy;
45         
46         private final Window parentWindow;
47         private final Simulation simulation;
48         
49         // Define these check indicators to show if fields are OK
50         private final JLabel nameCheck = new JLabel(RedIcon);
51         private final JLabel expressionCheck = new JLabel(RedIcon);
52         private final JLabel unitCheck = new JLabel(RedIcon);
53         private final JButton okButton = new JButton(trans.get("dlg.but.ok"));
54         private final JTextField expressionField = new JTextField(20);
55         
56         public ExpressionBuilderDialog(Window parent, Simulation simulation){
57                 this(parent, simulation, new CustomExpression(simulation));
58         }
59         
60         public ExpressionBuilderDialog(Window parent, final Simulation simulation, final CustomExpression previousExpression){
61                 
62                 super(parent, trans.get("ExpressionBuilderDialog.title"), JDialog.ModalityType.DOCUMENT_MODAL);
63                 
64                 this.parentWindow = parent;
65                 this.simulation = simulation;
66                 this.previousExpressionCopy = (CustomExpression) previousExpression.clone();
67                 this.expression = previousExpression;
68                                         
69                 //// Name box -- Check input when focus changes and transfer focus to next box on enter key
70                 JLabel nameLabel = new JLabel(trans.get("customExpression.Name"));
71                 final JTextField nameField = new JTextField(20); 
72                 nameField.setText(expression.getName());
73                 nameField.setFocusTraversalKeysEnabled(true);
74                 nameField.addFocusListener(new FocusListener() {
75                         @Override
76                         public void focusGained(FocusEvent e) { }
77
78                         @Override
79                         public void focusLost(FocusEvent e) {
80                                 expression.setName(nameField.getText());
81                                 ExpressionBuilderDialog.this.updateOK();                                
82                         }
83                 });
84                 nameField.addActionListener(new ActionListener() {
85                         @Override
86                         public void actionPerformed(ActionEvent arg0) {
87                                 nameField.transferFocus();
88                         }
89                 });
90                 
91                 //// Expression box -- for this one we check after each keypress using a keyListener. Enter transfers to next field
92                 JLabel expressionLabel = new JLabel(trans.get("customExpression.Expression"));
93                 expressionField.setText(expression.getExpressionString());
94                 expressionField.addKeyListener(new KeyListener() {
95                         @Override
96                         public void keyReleased(KeyEvent arg0) {
97                                 expression.setExpression(  expressionField.getText() );
98                                 ExpressionBuilderDialog.this.updateOK();
99                         }
100
101                         @Override
102                         public void keyPressed(KeyEvent e) {}
103
104                         @Override
105                         public void keyTyped(KeyEvent e) {}
106                 });
107                 expressionField.addActionListener(new ActionListener(){
108                         @Override
109                         public void actionPerformed(ActionEvent e) {
110                                 expressionField.transferFocus();
111                         }
112                 });
113                 
114                 //// Units box -- with action listeners checking input after change in focus or enter press
115                 JLabel unitLabel = new JLabel(trans.get("customExpression.Units"));
116                 final JTextField unitField = new JTextField(5);
117                 unitField.setText(expression.getUnit());
118                 unitField.addFocusListener(new FocusListener(){
119                         @Override
120                         public void focusLost(FocusEvent arg0) { 
121                                 expression.setUnit(unitField.getText()) ;
122                                 ExpressionBuilderDialog.this.updateOK();
123                         }
124                         @Override
125                         public void focusGained(FocusEvent arg0) {}                     
126                 });
127                 unitField.addActionListener(new ActionListener() {
128                         @Override
129                         public void actionPerformed(ActionEvent e) {
130                                 unitField.transferFocus();
131                         }
132                 });
133                 
134                 //// Symbol box
135                 JLabel symbolLabel = new JLabel(trans.get("customExpression.Symbol"));
136                 final JTextField symbolField = new JTextField(5);
137                 symbolField.setText(expression.getSymbol());
138                 symbolField.addFocusListener(new FocusListener(){
139                         @Override
140                         public void focusLost(FocusEvent arg0) { 
141                                 expression.setSymbol(symbolField.getText()) ;
142                                 ExpressionBuilderDialog.this.updateOK();
143                         }
144                         @Override
145                         public void focusGained(FocusEvent arg0) {}                     
146                 });
147                 symbolField.addActionListener(new ActionListener() {
148                         @Override
149                         public void actionPerformed(ActionEvent e) {
150                                 symbolField.transferFocus();
151                         }
152                 });
153                 
154                 
155                 //// Insert variable button
156                 final JButton insertVariableButton = new JButton(trans.get("ExpressionBuilderDialog.InsertVariable"));
157                 insertVariableButton.addActionListener(new ActionListener() {
158                         @Override
159                         public void actionPerformed(ActionEvent e) {
160                                 log.debug("Opening insert variable window");
161                                 Window parentWindow = SwingUtilities.getWindowAncestor(ExpressionBuilderDialog.this);
162                                 new VariableSelector(parentWindow, ExpressionBuilderDialog.this, simulation).setVisible(true);
163                         }
164                 });
165                 
166                 //// Insert operator button
167                 final JButton insertOperatorButton = new JButton(trans.get("ExpressionBuilderDialog.InsertOperator"));
168                 insertOperatorButton.addActionListener(new ActionListener() {
169                         @Override
170                         public void actionPerformed(ActionEvent e) {
171                                 log.debug("Opening insert operator window");
172                                 Window parentWindow = SwingUtilities.getWindowAncestor(ExpressionBuilderDialog.this);
173                                 new OperatorSelector(parentWindow, ExpressionBuilderDialog.this).setVisible(true);
174                         }
175                 });
176                 
177                 //// Copy expression check box
178                 final JCheckBox copyCheckBox = new JCheckBox(trans.get("ExpressionBuilderDialog.CopyToOtherSimulations"));
179                 copyCheckBox.setHorizontalTextPosition(SwingConstants.LEFT);
180                 copyCheckBox.setToolTipText(trans.get("ExpressionBuilderDialog.CopyToOtherSimulations.ttip"));
181                 
182                 //// OK Button
183                 okButton.setEnabled(false);
184                 okButton.addActionListener(new ActionListener() {
185                         @Override
186                         public void actionPerformed(ActionEvent e) {
187                                 // add to this simulation
188                                 expression.addToSimulation();
189                                 if (copyCheckBox.isSelected()){
190                                         expression.copyToOtherSimulations();
191                                 }
192                                 
193                                 // close window
194                                 ExpressionBuilderDialog.this.dispose();
195                         }
196                 });
197
198                 //// Cancel button
199                 final JButton cancelButton = new JButton(trans.get("dlg.but.cancel"));
200                 cancelButton.addActionListener(new ActionListener() {
201                         @Override
202                         public void actionPerformed(ActionEvent e) {
203                                 expression.overwrite(previousExpressionCopy);
204                                 ExpressionBuilderDialog.this.dispose();
205                         }
206                 });
207                         
208                 //// Set to tips
209                 nameCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Name"));
210                 unitCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Symbol"));
211                 expressionCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Expression"));
212                 
213                 //// Do the layout
214                 JPanel mainPanel = new JPanel(new MigLayout());
215                 mainPanel.add(nameLabel);
216                 mainPanel.add(nameField);
217                 mainPanel.add(nameCheck, "wrap, center");
218                 mainPanel.add(symbolLabel);
219                 mainPanel.add(symbolField, "split 4, growx");
220                 mainPanel.add(new JPanel());
221                 mainPanel.add(unitLabel, "right");
222                 mainPanel.add(unitField, "right, growx");
223                 mainPanel.add(unitCheck, "wrap, center");
224                 mainPanel.add(expressionLabel);
225                 mainPanel.add(expressionField);
226                 mainPanel.add(expressionCheck, "wrap, center");
227                 mainPanel.add(insertOperatorButton, "span 2, right, split 2");
228                 mainPanel.add(insertVariableButton, "right, wrap");
229                 mainPanel.add(copyCheckBox, "span 2, right, wrap");
230                 mainPanel.add(cancelButton, "span 2, right, width :50:100");
231                 mainPanel.add(okButton, "right, width :50:100, wrap");
232
233                 this.add(mainPanel);
234                 this.validate();
235                 this.pack();
236                 this.setLocationByPlatform(true);
237                 this.updateOK();
238                 
239         }
240
241         /**
242          * Enable OK button only if all the fields are ok
243          * @param okButton
244          */
245         protected void updateOK() {
246                 
247                 boolean nameOK = expression.checkName();
248                 boolean unitOK = expression.checkUnit();
249                 boolean symbolOK = expression.checkSymbol();
250                 boolean expressionOK = expression.checkExpression();
251                 
252                 if (nameOK)                             { nameCheck.setIcon(GreenIcon);                 } else { nameCheck.setIcon(RedIcon); }
253                 if (unitOK && symbolOK) { unitCheck.setIcon(GreenIcon);                 } else { unitCheck.setIcon(RedIcon); }
254                 if (expressionOK)               { expressionCheck.setIcon(GreenIcon);   } else { expressionCheck.setIcon(RedIcon); }
255                 
256                 okButton.setEnabled( nameOK && unitOK && symbolOK && expressionOK );
257         }
258         
259         /**
260          * Inserts a string into the expression box at the position of the cursor.
261          * String will be padded with spaces either side
262          * Expression box will be focused after this is called.
263          * For strings containing an ( , cursor will be moved to the point after that, otherwise, cursor will move to the end of the inserted string.
264          * @param str
265          */
266         public void pasteIntoExpression(String str) {
267             int pos = expressionField.getCaretPosition();
268             String current = expressionField.getText();
269             expressionField.setText(current.subSequence(0, pos) + " " + str + " " + current.subSequence(pos, current.length()));
270             expressionField.requestFocus();
271             int bracketPos = str.indexOf("(");
272             if (bracketPos != -1){
273                 expressionField.setCaretPosition(pos+2+bracketPos);
274             }
275             else {
276                 expressionField.setCaretPosition(pos+2+str.length());
277             }
278         }
279 }