Xcos: remove block default values
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / block / actions / EditBlockFormatAction.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - DIGITEO - ClĂ©ment DAVID
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.xcos.block.actions;
14
15 import java.awt.Color;
16 import java.awt.Dimension;
17 import java.awt.Font;
18 import java.awt.Frame;
19 import java.awt.GraphicsEnvironment;
20 import java.awt.Toolkit;
21 import java.awt.event.ActionEvent;
22 import java.awt.event.ActionListener;
23 import java.awt.event.KeyEvent;
24
25 import javax.swing.SpinnerModel;
26 import javax.swing.event.ChangeEvent;
27 import javax.swing.event.ChangeListener;
28
29 import org.scilab.modules.graph.ScilabComponent;
30 import org.scilab.modules.graph.ScilabGraph;
31 import org.scilab.modules.graph.actions.base.DefaultAction;
32 import org.scilab.modules.graph.utils.StyleMap;
33 import org.scilab.modules.gui.menuitem.MenuItem;
34 import org.scilab.modules.xcos.graph.XcosDiagram;
35 import org.scilab.modules.xcos.utils.XcosMessages;
36
37 import com.mxgraph.model.mxCell;
38 import com.mxgraph.util.mxConstants;
39 import com.mxgraph.util.mxUtils;
40
41 /**
42  * Customize the block representation.
43  */
44 public class EditBlockFormatAction extends DefaultAction {
45         /**
46          * Name of the action
47          */
48         public static final String NAME = XcosMessages.EDIT + XcosMessages.DOTS;
49         /**
50          * Icon of the action
51          */
52         public static final String SMALL_ICON = "";
53         /**
54          * Mnemonic key for the action
55          */
56         public static final int MNEMONIC_KEY = KeyEvent.VK_F2;
57         /**
58          * Accelerator key for the action
59          */
60         public static final int ACCELERATOR_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
61
62         /**
63          * The default color used on non initialized border color.
64          */
65         private static final Color DEFAULT_BORDERCOLOR = new Color(0, 0, 0, 0);
66         /**
67          * The default color used on non initialized filled color.
68          */
69         private static final Color DEFAULT_FILLCOLOR = new Color(255, 255, 255, 0);
70         
71         /**
72          * Default constructor
73          * @param scilabGraph the current graph
74          */
75         public EditBlockFormatAction(ScilabGraph scilabGraph) {
76                 super(scilabGraph);
77         }
78
79         /**
80          * Menu added to the menubar
81          * @param scilabGraph associated diagram
82          * @return the menu
83          */
84         public static MenuItem createMenu(ScilabGraph scilabGraph) {
85                 return createMenu(scilabGraph, EditBlockFormatAction.class);
86         }
87         
88         /**
89          * Create a new dialog for editing this cell
90          * @param c the current component 
91          * @param name the window name
92          * @param selectedCell the selected cell
93          */
94         public static void showDialog(ScilabComponent c, String name, mxCell selectedCell) {
95                 /*
96                  * Looking for the parent window
97                  */
98                 final Frame window = javax.swing.JOptionPane.getFrameForComponent(c);
99                 
100                 /*
101                  * Create and show the dialog
102                  */
103                 EditFormatDialog dialog = createDialog(selectedCell, window);
104                 dialog.setName(name);
105                 dialog.setVisible(true);
106         }
107
108         /**
109          * Create the dialog and set the default values
110          * @param selectedCell the current selected cell
111          * @param window the current windows
112          * @return the instantiated dialog
113          */
114         private static EditFormatDialog createDialog(mxCell selectedCell,
115                         final Frame window) {
116                 String working;
117                 Color border;
118                 Color fill;
119                 String font;
120                 int fontSize;
121                 int fontStyle;
122                 Color textColor;
123                 String text;
124                 
125                 StyleMap style = new StyleMap(selectedCell.getStyle());
126                 
127                 working = style.get(mxConstants.STYLE_STROKECOLOR);
128                 if (working == null) {
129                         border = DEFAULT_BORDERCOLOR;
130                 } else {
131                         border = mxUtils.parseColor(working);
132                 }
133                 
134                 working = style.get(mxConstants.STYLE_FILLCOLOR);
135                 if (working == null) {
136                         fill = DEFAULT_FILLCOLOR;
137                 } else {
138                         fill = mxUtils.parseColor(working);
139                 }
140                 
141                 working = style.get(mxConstants.STYLE_FONTFAMILY);
142                 if (working == null) {
143                         font = mxConstants.DEFAULT_FONTFAMILY;
144                 } else {
145                         font = working;
146                 }
147                 
148                 working = style.get(mxConstants.STYLE_FONTSIZE);
149                 if (working == null) {
150                         fontSize = mxConstants.DEFAULT_FONTSIZE;
151                 } else {
152                         fontSize = Integer.parseInt(working);
153                 }
154
155                 working = style.get(mxConstants.STYLE_FONTSTYLE);
156                 if (working == null) {
157                         fontStyle = 0;
158                 } else {
159                         fontStyle = Integer.parseInt(working);
160                 }
161                 
162                 working = style.get(mxConstants.STYLE_FONTCOLOR);
163                 if (working == null) {
164                         textColor = Color.BLACK;
165                 } else {
166                         textColor = mxUtils.parseColor(working);
167                 }
168                 
169                 Object current = selectedCell.getValue();
170                 if (current == null) {
171                         text = "";
172                 } else {
173                         text = mxUtils.getBodyMarkup(current.toString(), false);
174                 }
175                 
176                 EditFormatDialog dialog = new EditFormatDialog(window);
177                 dialog.setValues(border, fill, font, fontSize, fontStyle, textColor, text);
178                 dialog.setCell(selectedCell);
179                 return dialog;
180         }
181         
182         /**
183          * Update the cell value from the dialog ones.
184          * 
185          * @param dialog the current dialog
186          * @param borderColor the selected border color
187          * @param backgroundColor the selected background color
188          * @param fontName the selected font name
189          * @param fontSize the selected font size
190          * @param textColor the selected color
191          * @param text the typed text
192          */
193         private static void updateFromDialog(EditFormatDialog dialog, Color borderColor, Color backgroundColor, 
194                                 String fontName, int fontSize, Color textColor, String text) {
195                 mxCell cell = dialog.getCell();
196                 
197                 StyleMap style = new StyleMap(cell.getStyle());
198                 
199                 if (!borderColor.equals(DEFAULT_BORDERCOLOR)) {
200                         style.put(mxConstants.STYLE_STROKECOLOR, mxUtils.hexString(borderColor));
201                 }
202                 
203                 if (!backgroundColor.equals(DEFAULT_FILLCOLOR)) {
204                         style.put(mxConstants.STYLE_FILLCOLOR, mxUtils.hexString(backgroundColor));
205                 }
206                 
207                 if (!fontName.equals(mxConstants.DEFAULT_FONTFAMILY)) {
208                         style.put(mxConstants.STYLE_FONTFAMILY, fontName);
209                 }
210                 
211                 if (!fontName.equals(mxConstants.DEFAULT_FONTFAMILY)) {
212                         style.put(mxConstants.STYLE_FONTFAMILY, fontName);
213                 }
214                 
215                 if (fontSize != mxConstants.DEFAULT_FONTSIZE) {
216                         style.put(mxConstants.STYLE_FONTSIZE, Integer.toString(fontSize));
217                 }
218                 
219                 if (!textColor.equals(DEFAULT_BORDERCOLOR)) {
220                         style.put(mxConstants.STYLE_FONTCOLOR, mxUtils.hexString(textColor));
221                 }
222                 
223                 cell.setStyle(style.toString());
224                 cell.setValue(text);
225         }
226         
227         /**
228          * Open a dialog to set the parameters
229          * @param e the current event
230          * @see org.scilab.modules.graph.actions.base.DefaultAction#actionPerformed(java.awt.event.ActionEvent)
231          */
232         @Override
233         public void actionPerformed(ActionEvent e) {
234                 XcosDiagram graph = (XcosDiagram) getGraph(null);
235                 Object[] selectedCells = graph.getSelectionCells();
236                 
237                 EditBlockFormatAction.showDialog((ScilabComponent) graph
238                                 .getAsComponent(), NAME, (mxCell) selectedCells[0]);
239                 
240                 graph.getView().clear(selectedCells[0], true, true);
241                 graph.updateCellSize(selectedCells[0]);
242                 graph.refresh();
243         }
244         
245         /**
246          * Dialog used to edit the current cell.
247          * 
248          * This class perform UI instantiation and thus doesn't pass checkstyle
249          * metrics.
250          */
251         // CSOFF: ClassDataAbstractionCoupling
252         // CSOFF: ClassFanOutComplexity
253         private static final class EditFormatDialog extends javax.swing.JDialog  {
254                 private static final int TEXT_AREA_ROWS = 5;
255                 private static final int TEXT_AREA_COLUMNS = 20;
256                 
257                 /**
258                  * The default model used to set a font size. 
259                  */
260                 private static final SpinnerModel FONTSIZE_MODEL = new javax.swing.SpinnerNumberModel(10, 0, 100, 1);
261                 /**
262                  * The default border size used to separate buttons
263                  */
264                 private static final int BORDER_SIZE = 10;
265                 
266             private javax.swing.JColorChooser backgroundColorChooser;
267             private javax.swing.JColorChooser borderColorChooser;
268             private javax.swing.JColorChooser textColorChooser;
269             private javax.swing.JComboBox fontNameComboBox;
270             private javax.swing.JLabel fontNameLabel;
271             private javax.swing.JSpinner fontSizeSpinner;
272             private javax.swing.JLabel fontSizeLabel;
273             private javax.swing.JCheckBox fontStyleBold;
274             private javax.swing.JCheckBox fontStyleItalic;
275             private javax.swing.JLabel fontStyleLabel;
276             
277             private javax.swing.JPanel jPanel2;
278             private javax.swing.JScrollPane jScrollPane1;
279             private javax.swing.JTabbedPane mainTab;
280             private javax.swing.JTextArea textArea;
281             private javax.swing.JPanel textFormat;
282             
283             private javax.swing.JButton cancelButton;
284             private javax.swing.JButton okButton;
285             private javax.swing.JPanel buttonPane;
286             
287             private mxCell cell;
288                 
289             private final transient ChangeListener defaultChangeListener = new ChangeListener() {
290                 /**
291                  * Update the text area font
292                  * @param e the event parameters
293                  * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
294                  */
295                         @Override
296                         public void stateChanged(ChangeEvent e) {
297                                 updateFont();
298                         }
299                 };
300                 
301                 private final transient ActionListener defaultActionListener = new ActionListener() {
302                 /**
303                  * Update the text area font
304                  * @param e the event parameters
305                  * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
306                  */
307                         @Override
308                         public void actionPerformed(ActionEvent e) {
309                                 updateFont();
310                         }
311                 };
312             
313                 /**
314                  * Construct the dialog
315                  * 
316                  * @param f the current graph frame
317                  */
318                 public EditFormatDialog(Frame f) {
319                         super(f, true);
320                         setDefaultCloseOperation(DISPOSE_ON_CLOSE);
321                         setLocationRelativeTo(f);
322                         
323                         initComponents();
324                 }
325
326                 /**
327                  * Initialize the dialog parameters
328                  * 
329                  * @param borderColor the default border color
330                  * @param backgroundColor the default background color
331                  * @param fontName The default font name
332                  * @param fontSize the default font size
333                  * @param fontStyle the current font style
334                  * @param textColor the current text color
335                  * @param text the current text
336                  */
337                 public void setValues(Color borderColor, Color backgroundColor, 
338                                 String fontName, int fontSize, int fontStyle, Color textColor, 
339                                 String text) {
340                         borderColorChooser.setColor(borderColor);
341                         backgroundColorChooser.setColor(backgroundColor);
342                         textColorChooser.setColor(textColor);
343                         
344                         fontNameComboBox.getModel().setSelectedItem(fontName);
345                         fontSizeSpinner.getModel().setValue(fontSize);
346                         
347                         fontStyleBold.setSelected((fontStyle & mxConstants.FONT_BOLD) != 0);
348                         fontStyleItalic.setSelected((fontStyle & mxConstants.FONT_ITALIC) != 0);
349                         
350                         textArea.setText(text);
351                 }
352                 
353                 /**
354                  * Set the currently selected cell
355                  * @param selectedCell the current cell
356                  */
357                 public void setCell(mxCell selectedCell) {
358                         cell = selectedCell;
359                 }
360                 
361                 /** 
362                  * @return the currently selected cell
363                  */
364                 public mxCell getCell() {
365                         return cell;
366                 }
367
368                 /**
369                  * @return the current dialog
370                  */
371                 public EditFormatDialog getDialog() {
372                         return this;
373                 }
374                 
375                 /**
376                  * Initialize the dialog.
377                  * 
378                  * This code is UI initialization and thus doesn't pass checkstyle
379                  * metrics.
380                  */
381                 // CSOFF: JavaNCSS
382                 // CSOFF: LineLength
383                 // CSOFF: MethodLength
384                 private void initComponents() {
385                         
386                 mainTab = new javax.swing.JTabbedPane();
387                 borderColorChooser = new javax.swing.JColorChooser();
388                 backgroundColorChooser = new javax.swing.JColorChooser();
389                 textColorChooser = new javax.swing.JColorChooser();
390                 textFormat = new javax.swing.JPanel();
391                 jPanel2 = new javax.swing.JPanel();
392                 fontSizeLabel = new javax.swing.JLabel();
393                 fontSizeSpinner = new javax.swing.JSpinner();
394                 fontNameLabel = new javax.swing.JLabel();
395                 fontNameComboBox = new javax.swing.JComboBox();
396                 fontStyleBold = new javax.swing.JCheckBox();
397                 fontStyleItalic = new javax.swing.JCheckBox();
398                 fontStyleLabel = new javax.swing.JLabel();
399                 
400                 jScrollPane1 = new javax.swing.JScrollPane();
401                 textArea = new javax.swing.JTextArea();
402                 
403                 textArea.setColumns(TEXT_AREA_COLUMNS);
404                 textArea.setRows(TEXT_AREA_ROWS);
405                 textArea.setLineWrap(true);
406                 textArea.setWrapStyleWord(true);
407                 
408                 cancelButton = new javax.swing.JButton(XcosMessages.CANCEL);
409                 okButton = new javax.swing.JButton(XcosMessages.OK);
410                 buttonPane = new javax.swing.JPanel();
411
412                 mainTab.addTab(XcosMessages.BORDER_COLOR, borderColorChooser);
413                 mainTab.addTab(XcosMessages.FILL_COLOR, backgroundColorChooser);
414                 mainTab.addTab(XcosMessages.TEXT_COLOR, textColorChooser);
415
416                 textFormat.setLayout(new java.awt.BorderLayout());
417
418                 fontSizeLabel.setText(XcosMessages.FONT_SIZE);
419
420                 fontSizeSpinner.setModel(FONTSIZE_MODEL);
421                 fontSizeSpinner.addChangeListener(defaultChangeListener);
422
423                 fontNameLabel.setText(XcosMessages.FONT_NAME);
424
425                         fontNameComboBox.setModel(new javax.swing.DefaultComboBoxModel(
426                                         GraphicsEnvironment.getLocalGraphicsEnvironment()
427                                                         .getAvailableFontFamilyNames()));
428                         
429                 fontNameComboBox.addActionListener(defaultActionListener);
430                 
431                 fontStyleLabel.setText(XcosMessages.FONT_STYLE);
432                 
433                 fontStyleBold.setText(XcosMessages.BOLD);
434                 fontStyleBold.addChangeListener(defaultChangeListener);
435                 
436                 fontStyleItalic.setText(XcosMessages.ITALIC);
437                 fontStyleItalic.addChangeListener(defaultChangeListener);
438                 
439                 javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
440                 jPanel2.setLayout(jPanel2Layout);
441                 jPanel2Layout.setHorizontalGroup(
442                     jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
443                     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
444                         .addContainerGap()
445                         .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
446                             .addComponent(fontNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
447                             .addComponent(fontSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
448                             .addComponent(fontStyleLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
449                         .addGap(BORDER_SIZE)
450                         .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
451                             .addComponent(fontNameComboBox, 0, javax.swing.GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
452                             .addComponent(fontSizeSpinner, 0, javax.swing.GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
453                             .addGroup(jPanel2Layout.createSequentialGroup()
454                                 .addComponent(fontStyleBold)
455                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
456                                 .addComponent(fontStyleItalic)))
457                         .addContainerGap())
458                 );
459                 jPanel2Layout.setVerticalGroup(
460                     jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
461                     .addGroup(jPanel2Layout.createSequentialGroup()
462                         .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
463                             .addComponent(fontSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
464                             .addComponent(fontSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
465                         .addGap(BORDER_SIZE)
466                         .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
467                             .addComponent(fontNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
468                             .addComponent(fontNameComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
469                         .addGap(BORDER_SIZE)
470                         .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
471                             .addComponent(fontStyleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
472                             .addComponent(fontStyleBold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
473                             .addComponent(fontStyleItalic, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
474                         .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
475                 );
476
477                 textFormat.add(jPanel2, java.awt.BorderLayout.PAGE_END);
478
479                 jScrollPane1.setViewportView(textArea);
480                 jScrollPane1.setBackground(Color.WHITE);
481
482                 textFormat.add(jScrollPane1, java.awt.BorderLayout.CENTER);
483
484                 mainTab.addTab(XcosMessages.TEXT_SETTINGS, textFormat);
485
486                 mainTab.addChangeListener(defaultChangeListener);
487                 
488                         cancelButton.addActionListener(new ActionListener() {
489                                 /**
490                                  * On cancel close the window
491                                  * 
492                                  * @param e
493                                  *            the current event parameter
494                                  * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
495                                  */
496                                 @Override
497                                 public void actionPerformed(ActionEvent e) {
498                                         getDialog().dispose();
499                                 }
500                         });
501
502                         okButton.addActionListener(new ActionListener() {
503                                 /**
504                                  * On OK, set the current parameter on the cell
505                                  * 
506                                  * @param e
507                                  *            the current parameters
508                                  * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
509                                  */
510                                 @Override
511                                 public void actionPerformed(ActionEvent e) {
512                                         EditBlockFormatAction.updateFromDialog(getDialog(),
513                                                         borderColorChooser.getColor(),
514                                                         backgroundColorChooser.getColor(),
515                                                         (String) fontNameComboBox.getSelectedItem(),
516                                                         (Integer) fontSizeSpinner.getValue(), 
517                                                         textColorChooser.getColor(),
518                                                         textArea.getText());
519                                         getDialog().dispose();
520                                 }
521                         });
522                         
523                 getRootPane().setDefaultButton(okButton);
524                 
525                 buttonPane.setLayout(new javax.swing.BoxLayout(buttonPane, javax.swing.BoxLayout.LINE_AXIS));
526                         buttonPane.setBorder(javax.swing.BorderFactory.createEmptyBorder(
527                                         BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
528                 buttonPane.add(javax.swing.Box.createHorizontalGlue());
529                 buttonPane.add(cancelButton);
530                         buttonPane.add(javax.swing.Box.createRigidArea(new Dimension(
531                                         BORDER_SIZE, 0)));
532                 buttonPane.add(okButton);
533
534                 java.awt.Container contentPane = getContentPane();
535                 contentPane.add(mainTab, java.awt.BorderLayout.CENTER);
536                 contentPane.add(buttonPane, java.awt.BorderLayout.PAGE_END);
537                 
538                 pack();
539                 }
540                 // CSON: JavaNCSS
541                 // CSON: LineLength
542                 // CSON: MethodLength
543
544                 /**
545                  * Update the text area from the font
546                  */
547                 protected void updateFont() {
548                         int style = 0;
549                         if (fontStyleBold.isSelected()) {
550                                 style |= Font.BOLD;
551                         }
552                         if (fontStyleItalic.isSelected()) {
553                                 style |= Font.ITALIC;
554                         }
555                         
556                         Font f = new Font((String) fontNameComboBox.getSelectedItem(), style,
557                                         (Integer) fontSizeSpinner.getValue());
558                         textArea.setFont(f);
559                         textArea.setBackground(backgroundColorChooser.getColor());
560                         textArea.setForeground(textColorChooser.getColor());
561                         
562                         // Repaint the parent scroll pane to force a full redraw call. 
563                         jScrollPane1.repaint();
564                 }
565         }
566         // CSON: ClassDataAbstractionCoupling
567         // CSON: ClassFanOutComplexity
568 }