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