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