* Bug #15284 fixed: Port names are not set to the corresponding I/O block labels.
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / actions / EditFormatAction.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010-2011 - DIGITEO - Clement DAVID
4  * Copyright (C) 2011-2015 - Scilab Enterprises - Clement DAVID
5  * Copyright (C) 2017-2018 - ESI Group - Clement DAVID
6  *
7  * Copyright (C) 2012 - 2016 - Scilab Enterprises
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  */
17
18 package org.scilab.modules.xcos.actions;
19
20 import java.awt.Color;
21 import java.awt.Dimension;
22 import java.awt.Font;
23 import java.awt.Frame;
24 import java.awt.GraphicsEnvironment;
25 import java.awt.Toolkit;
26 import java.awt.event.ActionEvent;
27 import java.awt.event.ActionListener;
28 import java.awt.event.KeyEvent;
29 import java.io.File;
30 import java.net.MalformedURLException;
31 import java.net.URI;
32 import java.net.URISyntaxException;
33 import java.net.URL;
34
35 import javax.swing.BorderFactory;
36 import javax.swing.SpinnerModel;
37 import javax.swing.event.ChangeEvent;
38 import javax.swing.event.ChangeListener;
39
40 import org.scilab.modules.graph.ScilabComponent;
41 import org.scilab.modules.graph.ScilabGraph;
42 import org.scilab.modules.graph.actions.base.DefaultAction;
43 import org.scilab.modules.graph.utils.StyleMap;
44 import org.scilab.modules.gui.menuitem.MenuItem;
45 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
46 import org.scilab.modules.xcos.block.TextBlock;
47 import org.scilab.modules.xcos.graph.XcosDiagram;
48 import org.scilab.modules.xcos.utils.XcosMessages;
49
50 import com.mxgraph.model.mxCell;
51 import com.mxgraph.model.mxGraphModel;
52 import com.mxgraph.model.mxICell;
53 import com.mxgraph.util.mxConstants;
54 import com.mxgraph.util.mxEvent;
55 import com.mxgraph.util.mxEventObject;
56 import com.mxgraph.util.mxUtils;
57 import java.util.List;
58 import org.scilab.modules.xcos.JavaController;
59 import org.scilab.modules.xcos.Kind;
60 import org.scilab.modules.xcos.ObjectProperties;
61 import org.scilab.modules.xcos.VectorOfDouble;
62 import org.scilab.modules.xcos.Xcos;
63 import org.scilab.modules.xcos.block.SuperBlock;
64 import org.scilab.modules.xcos.block.io.ContextUpdate;
65 import org.scilab.modules.xcos.graph.model.XcosCell;
66 import org.scilab.modules.xcos.graph.model.XcosGraphModel;
67
68 /**
69  * Customize the block representation.
70  */
71 @SuppressWarnings(value = { "serial" })
72 public final class EditFormatAction extends DefaultAction {
73     /**
74      * Name of the action
75      */
76     public static final String NAME = XcosMessages.EDIT + XcosMessages.DOTS;
77     /**
78      * Icon of the action
79      */
80     public static final String SMALL_ICON = "select-by-color";
81     /**
82      * Mnemonic key for the action
83      */
84     public static final int MNEMONIC_KEY = KeyEvent.VK_F2;
85     /**
86      * Accelerator key for the action
87      */
88     public static final int ACCELERATOR_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
89
90     /**
91      * The default color used on non initialized border color.
92      */
93     private static final Color DEFAULT_BORDERCOLOR = Color.BLACK;
94     /**
95      * The default color used on non initialized filled color.
96      */
97     private static final Color DEFAULT_FILLCOLOR = Color.WHITE;
98
99     /**
100      * Default constructor
101      *
102      * @param scilabGraph
103      *            the current graph
104      */
105     public EditFormatAction(ScilabGraph scilabGraph) {
106         super(scilabGraph);
107     }
108
109     /**
110      * Menu added to the menubar
111      *
112      * @param scilabGraph
113      *            associated diagram
114      * @return the menu
115      */
116     public static MenuItem createMenu(ScilabGraph scilabGraph) {
117         return createMenu(scilabGraph, EditFormatAction.class);
118     }
119
120     /**
121      * Create a new dialog for editing this cell
122      *
123      * @param c
124      *            the current component
125      * @param name
126      *            the window name
127      * @param selectedCell
128      *            the selected cell
129      * @param graph
130      *            the current graph
131      */
132     public static void showDialog(ScilabComponent c, String name, mxCell selectedCell, XcosDiagram graph) {
133         /*
134          * Looking for the parent window
135          */
136         final Frame window = javax.swing.JOptionPane.getFrameForComponent(c);
137
138         /*
139          * Create and show the dialog
140          */
141         EditFormatDialog dialog = createDialog(selectedCell, graph, window);
142         dialog.setName(name);
143         dialog.setVisible(true);
144     }
145
146     /**
147      * Create the dialog and set the default values
148      *
149      * @param cell
150      *            the current selected cell
151      * @param graph
152      *            the current graph
153      * @param window
154      *            the current windows
155      * @return the instantiated dialog
156      */
157     // CSOFF: NPathComplexity
158     // CSOFF: JavaNCSS
159     private static EditFormatDialog createDialog(final mxCell cell, final XcosDiagram graph, final Frame window) {
160         String working;
161         Color border;
162         Color fill;
163         String font;
164         int fontSize;
165         int fontStyle;
166         Color textColor;
167         String description;
168         String text;
169         String image = null;
170
171         final mxGraphModel model = (mxGraphModel) graph.getModel();
172         final StyleMap cellStyle = new StyleMap(cell.getStyle());
173
174         final mxCell identifier;
175         final StyleMap identifierStyle;
176         if (cell instanceof TextBlock) {
177             identifier = cell;
178             identifierStyle = cellStyle;
179         } else {
180             identifier = graph.getOrCreateCellIdentifier(cell);
181             identifierStyle = new StyleMap(identifier.getStyle());
182         }
183
184         /*
185          * Stroke color
186          */
187         working = cellStyle.get(mxConstants.STYLE_STROKECOLOR);
188         if (working == null) {
189             border = DEFAULT_BORDERCOLOR;
190         } else {
191             border = mxUtils.parseColor(working);
192         }
193
194         /*
195          * Fill color
196          */
197         working = cellStyle.get(mxConstants.STYLE_FILLCOLOR);
198         if (working == null) {
199             fill = DEFAULT_FILLCOLOR;
200         } else {
201             fill = mxUtils.parseColor(working);
202         }
203
204         /*
205          * Font
206          */
207         working = identifierStyle.get(mxConstants.STYLE_FONTFAMILY);
208         if (working == null) {
209             font = mxConstants.DEFAULT_FONTFAMILY;
210         } else {
211             font = working;
212         }
213
214         /*
215          * Font size
216          */
217         working = identifierStyle.get(mxConstants.STYLE_FONTSIZE);
218         if (working == null) {
219             fontSize = mxConstants.DEFAULT_FONTSIZE;
220         } else {
221             fontSize = Integer.parseInt(working);
222         }
223
224         /*
225          * Font modifier
226          */
227         working = identifierStyle.get(mxConstants.STYLE_FONTSTYLE);
228         if (working == null) {
229             fontStyle = 0;
230         } else {
231             fontStyle = Integer.parseInt(working);
232         }
233
234         /*
235          * Font color
236          */
237         working = identifierStyle.get(mxConstants.STYLE_FONTCOLOR);
238         if (working == null) {
239             textColor = Color.BLACK;
240         } else {
241             textColor = mxUtils.parseColor(working);
242         }
243
244         /*
245          * Image
246          */
247         working = cellStyle.get(mxConstants.STYLE_IMAGE);
248         if (working != null) {
249             image = working;
250         }
251
252         /*
253          * Description
254          */
255         final Object currentValue = model.getValue(cell);
256         if (currentValue == null) {
257             description = "";
258         } else {
259             description = currentValue.toString();
260         }
261
262         /*
263          * Text
264          */
265         final Object current = model.getValue(identifier);
266         if (current == null) {
267             text = "";
268         } else {
269             text = mxUtils.getBodyMarkup(current.toString(), false);
270         }
271
272         EditFormatDialog dialog = new EditFormatDialog(window);
273         dialog.setValues(border, fill, font, fontSize, fontStyle, textColor, description, text, image);
274         dialog.setGraph(graph);
275         dialog.setCell(cell);
276         return dialog;
277     }
278
279     // CSON: JavaNCSS
280     // CSON: NPathComplexity
281
282     /**
283      * Update the cell value from the dialog ones.
284      *
285      * @param dialog
286      *            the current dialog
287      * @param borderColor
288      *            the selected border color
289      * @param backgroundColor
290      *            the selected background color
291      * @param fontName
292      *            the selected font name
293      * @param fontSize
294      *            the selected font size
295      * @param isBold
296      *            is the text bold ?
297      * @param isItalic
298      *            is the text italic ?
299      * @param textColor
300      *            the selected color
301      * @param oneliner
302      *            the one-line description text
303      * @param text
304      *            the typed text
305      * @param image
306      *            the image URL
307      */
308     // CSOFF: NPathComplexity
309     private static void updateFromDialog(EditFormatDialog dialog, Color borderColor, Color backgroundColor, String fontName, int fontSize, Color textColor,
310                                          boolean isBold, boolean isItalic, String oneliner, String text, String image) {
311         final XcosDiagram graph = dialog.getGraph();
312         final mxGraphModel model = (mxGraphModel) graph.getModel();
313
314         final mxCell cell = dialog.getCell();
315         final StyleMap cellStyle = new StyleMap(cell.getStyle());
316
317         final mxCell identifier;
318         final StyleMap identifierStyle;
319         if (cell instanceof TextBlock) {
320             identifier = cell;
321             identifierStyle = cellStyle;
322         } else {
323             identifier = graph.getOrCreateCellIdentifier(cell);
324             identifierStyle = new StyleMap(identifier.getStyle());
325         }
326
327         if (!borderColor.equals(DEFAULT_BORDERCOLOR)) {
328             cellStyle.put(mxConstants.STYLE_STROKECOLOR, mxUtils.hexString(borderColor));
329         } else {
330             cellStyle.remove(mxConstants.STYLE_STROKECOLOR);
331         }
332
333         if (!backgroundColor.equals(DEFAULT_FILLCOLOR)) {
334             cellStyle.put(mxConstants.STYLE_FILLCOLOR, mxUtils.hexString(backgroundColor));
335         } else {
336             cellStyle.remove(mxConstants.STYLE_FILLCOLOR);
337         }
338
339         if (!fontName.equals(mxConstants.DEFAULT_FONTFAMILY)) {
340             identifierStyle.put(mxConstants.STYLE_FONTFAMILY, fontName);
341         } else {
342             identifierStyle.remove(mxConstants.STYLE_FONTFAMILY);
343         }
344
345         applyFontStyle(isBold, isItalic, identifierStyle);
346
347         if (fontSize != mxConstants.DEFAULT_FONTSIZE) {
348             identifierStyle.put(mxConstants.STYLE_FONTSIZE, Integer.toString(fontSize));
349         } else {
350             identifierStyle.remove(mxConstants.DEFAULT_FONTSIZE);
351         }
352
353         if (!textColor.equals(DEFAULT_BORDERCOLOR)) {
354             identifierStyle.put(mxConstants.STYLE_FONTCOLOR, mxUtils.hexString(textColor));
355         } else {
356             identifierStyle.remove(mxConstants.STYLE_FONTCOLOR);
357         }
358
359         applyImage(image, cellStyle);
360
361         model.setStyle(cell, cellStyle.toString());
362         if (cell != identifier) {
363             model.setStyle(identifier, identifierStyle.toString());
364         }
365
366         // convert to a C / Scilab compatible variable name
367         StringBuilder str = new StringBuilder(oneliner.length());
368         for (char c : oneliner.toCharArray()) {
369             if (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ( c == '_')) {
370                 str.append(c);
371             }
372             if (c == ' ') {
373                 str.append('_');
374             }
375         }
376         if (str.length() > 0 && '0' <= str.charAt(0) && str.charAt(0) <= '9') {
377             str.insert(0, '_');
378         }
379         oneliner = str.toString();
380
381         //
382         // Update the cell value and cell identifier value (related annotation)
383         //
384
385         graph.cellLabelChanged(cell, oneliner, false);
386         graph.fireEvent(new mxEventObject(mxEvent.LABEL_CHANGED, "cell", cell, "value", text, "parent", cell.getParent()));
387
388         graph.cellLabelChanged(identifier, text, false);
389         graph.fireEvent(new mxEventObject(mxEvent.LABEL_CHANGED, "cell", identifier, "value", text, "parent", cell));
390
391         //
392         // Update the corresponding port if the block is an I/O block
393         //
394         if (cell instanceof ContextUpdate) {
395             JavaController controller = new JavaController();
396
397             VectorOfDouble ipar = new VectorOfDouble();
398             controller.getObjectProperty(((ContextUpdate) cell).getUID(), Kind.BLOCK, ObjectProperties.IPAR, ipar);
399             int portNumber = (int) (ipar.size() > 0 ? ipar.get(0) : 1);
400
401             XcosCell parent = (XcosCell) graph.getDefaultParent();
402             XcosDiagram parentGraph = Xcos.findParent(controller, parent.getUID(), parent.getKind());
403             if (parentGraph != null) {
404                 String[] jgraphxID = {""};
405                 controller.getObjectProperty(parent.getUID(), parent.getKind(), ObjectProperties.UID, jgraphxID);
406
407                 XcosGraphModel parentModel = (XcosGraphModel) parentGraph.getModel();
408                 Object superBlock = parentModel.getCell(jgraphxID[0]);
409                 if (superBlock instanceof SuperBlock) {
410                     List<mxICell> ports = ContextUpdate.IOBlocks.getPorts((SuperBlock) superBlock, (Class<? extends ContextUpdate>) cell.getClass());
411
412                     if (ports.size() >= portNumber) {
413                         mxICell port = ports.get(portNumber - 1);
414                         parentGraph.cellLabelChanged(port, oneliner, false);
415                         parentGraph.fireEvent(new mxEventObject(mxEvent.LABEL_CHANGED, "cell", port, "value", text, "parent", superBlock));
416                     }
417                 }
418
419             }
420
421         }
422     }
423
424     // CSON: NPathComplexity
425
426     /**
427      * Reset to the default values
428      *
429      * @param dialog
430      *            the dialog to reset
431      */
432     private static void reset(EditFormatDialog dialog) {
433         final XcosDiagram graph = dialog.getGraph();
434         final mxGraphModel model = (mxGraphModel) graph.getModel();
435
436         final mxCell cell = dialog.getCell();
437         final StyleMap cellStyle = new StyleMap(cell.getStyle());
438
439         final mxCell identifier;
440         if (cell instanceof TextBlock) {
441             identifier = cell;
442         } else {
443             identifier = graph.getCellIdentifier(cell);
444             if (identifier != null) {
445                 model.remove(identifier);
446             }
447         }
448
449         cellStyle.clear();
450
451         dialog.setValues(DEFAULT_BORDERCOLOR, DEFAULT_FILLCOLOR, mxConstants.DEFAULT_FONTFAMILY, mxConstants.DEFAULT_FONTSIZE, 0, DEFAULT_BORDERCOLOR, "", "", null);
452
453         dialog.updateFont();
454     }
455
456     /**
457      * Apply image to the identifier style
458      *
459      * @param image
460      *            the image path
461      * @param cellStyle
462      *            the cell style
463      */
464     private static void applyImage(String image, final StyleMap cellStyle) {
465         if (image != null && !image.isEmpty()) {
466             String path;
467             try {
468                 URL url = new URL(image);
469                 path = url.toExternalForm();
470             } catch (MalformedURLException e) {
471                 path = image;
472             }
473
474             cellStyle.put(mxConstants.STYLE_IMAGE, path);
475         } else {
476             cellStyle.remove(mxConstants.STYLE_IMAGE);
477         }
478     }
479
480     /**
481      * Apply font style to the identifier style
482      *
483      * @param isBold
484      *            true if the font is bold
485      * @param isItalic
486      *            true is the font is italic
487      * @param identifierStyle
488      *            the identifier style
489      */
490     private static void applyFontStyle(boolean isBold, boolean isItalic, final StyleMap identifierStyle) {
491         int fontStyle = 0;
492         if (isBold) {
493             fontStyle |= mxConstants.FONT_BOLD;
494         }
495         if (isItalic) {
496             fontStyle |= mxConstants.FONT_ITALIC;
497         }
498
499         if (fontStyle != 0) {
500             identifierStyle.put(mxConstants.STYLE_FONTSTYLE, Integer.toString(fontStyle));
501         } else {
502             identifierStyle.remove(mxConstants.STYLE_FONTSTYLE);
503         }
504     }
505
506     /**
507      * Open a dialog to set the parameters
508      *
509      * @param e
510      *            the current event
511      * @see org.scilab.modules.graph.actions.base.DefaultAction#actionPerformed(java.awt.event.ActionEvent)
512      */
513     @Override
514     public void actionPerformed(ActionEvent e) {
515         XcosDiagram graph = (XcosDiagram) getGraph(null);
516         final Object selectedCell = graph.getSelectionCell();
517
518         if (selectedCell == null) {
519             return;
520         }
521
522         EditFormatAction.showDialog((ScilabComponent) graph.getAsComponent(), NAME, (mxCell) selectedCell, graph);
523
524         graph.getView().clear(selectedCell, true, true);
525         graph.refresh();
526     }
527
528     /**
529      * Dialog used to edit the current cell.
530      *
531      * This class perform UI instantiation and thus doesn't pass checkstyle
532      * metrics.
533      */
534     // CSOFF: ClassDataAbstractionCoupling
535     // CSOFF: ClassFanOutComplexity
536     private static final class EditFormatDialog extends javax.swing.JDialog {
537         private static final int TEXT_AREA_ROWS = 5;
538         private static final int TEXT_AREA_COLUMNS = 20;
539
540         /**
541          * The default model used to set a font size.
542          */
543         private static final SpinnerModel FONTSIZE_MODEL = new javax.swing.SpinnerNumberModel(10, 0, 100, 1);
544         /**
545          * The default border size used to separate buttons
546          */
547         private static final int BORDER_SIZE = 10;
548
549         private javax.swing.JColorChooser backgroundColorChooser;
550         private javax.swing.JColorChooser borderColorChooser;
551         private javax.swing.JColorChooser textColorChooser;
552         private javax.swing.JComboBox fontNameComboBox;
553         private javax.swing.JLabel fontNameLabel;
554         private javax.swing.JSpinner fontSizeSpinner;
555         private javax.swing.JLabel fontSizeLabel;
556         private javax.swing.JCheckBox fontStyleBold;
557         private javax.swing.JCheckBox fontStyleItalic;
558         private javax.swing.JLabel fontStyleLabel;
559         private javax.swing.JPanel backgroundPane;
560
561         private javax.swing.JLabel imagePathLabel;
562         private javax.swing.JTextField imagePath;
563         private javax.swing.JButton imageFileChooserBtn;
564
565         private javax.swing.JPanel jPanel2;
566         private javax.swing.JScrollPane jScrollPane1;
567         private javax.swing.JTabbedPane mainTab;
568         private javax.swing.JTextField labelArea;
569         private javax.swing.JTextPane textArea;
570         private javax.swing.JPanel textFormat;
571
572         private javax.swing.JButton cancelButton;
573         private javax.swing.JButton okButton;
574         private javax.swing.JButton resetButton;
575         private javax.swing.JPanel buttonPane;
576
577         private XcosDiagram graph;
578         private mxCell cell;
579
580         private final transient ChangeListener defaultChangeListener = new ChangeListener() {
581             /**
582              * Update the text area font
583              *
584              * @param e
585              *            the event parameters
586              * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
587              */
588             @Override
589             public void stateChanged(ChangeEvent e) {
590                 updateFont();
591             }
592         };
593
594         private final transient ActionListener defaultActionListener = new ActionListener() {
595             /**
596              * Update the text area font
597              *
598              * @param e
599              *            the event parameters
600              * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
601              */
602             @Override
603             public void actionPerformed(ActionEvent e) {
604                 updateFont();
605             }
606         };
607
608         /**
609          * Construct the dialog
610          *
611          * @param f
612          *            the current graph frame
613          */
614         public EditFormatDialog(Frame f) {
615             super(f, true);
616             setDefaultCloseOperation(DISPOSE_ON_CLOSE);
617             setLocationRelativeTo(f);
618             ScilabSwingUtilities.closeOnEscape(this);
619
620             initComponents();
621         }
622
623         /**
624          * Initialize the dialog parameters
625          *
626          * @param borderColor
627          *            the default border color
628          * @param backgroundColor
629          *            the default background color
630          * @param fontName
631          *            The default font name
632          * @param fontSize
633          *            the default font size
634          * @param fontStyle
635          *            the current font style
636          * @param textColor
637          *            the current text color
638          * @param text
639          *            the current text
640          * @param image
641          *            the current URL of the image (may be null, absolute or
642          *            relative)
643          */
644         public void setValues(Color borderColor, Color backgroundColor, String fontName, int fontSize, int fontStyle, Color textColor, String description, String text, String image) {
645             borderColorChooser.setColor(borderColor);
646             backgroundColorChooser.setColor(backgroundColor);
647             textColorChooser.setColor(textColor);
648
649             fontNameComboBox.getModel().setSelectedItem(fontName);
650             fontSizeSpinner.getModel().setValue(fontSize);
651
652             fontStyleBold.setSelected((fontStyle & mxConstants.FONT_BOLD) != 0);
653             fontStyleItalic.setSelected((fontStyle & mxConstants.FONT_ITALIC) != 0);
654
655             labelArea.setText(description);
656             textArea.setText(text);
657             if (image != null) {
658                 imagePath.setText(image);
659             }
660         }
661
662         /**
663          * @param graph
664          *            the current graph to set
665          */
666         public void setGraph(XcosDiagram graph) {
667             this.graph = graph;
668         }
669
670         /**
671          * @return the current graph
672          */
673         public XcosDiagram getGraph() {
674             return graph;
675         }
676
677         /**
678          * Set the currently selected cell
679          *
680          * @param selectedCell
681          *            the current cell
682          */
683         public void setCell(mxCell selectedCell) {
684             cell = selectedCell;
685
686             // enable/disable the fill color pane
687             if (selectedCell.isVertex()) {
688                 mainTab.addTab(XcosMessages.FILL_COLOR, backgroundPane);
689             } else {
690                 mainTab.remove(backgroundPane);
691             }
692
693             pack();
694         }
695
696         /**
697          * @return the currently selected cell
698          */
699         public mxCell getCell() {
700             return cell;
701         }
702
703         /**
704          * @return the current dialog
705          */
706         public EditFormatDialog getDialog() {
707             return this;
708         }
709
710         /**
711          * Initialize the dialog.
712          *
713          * This code is UI initialization and thus doesn't pass checkstyle
714          * metrics.
715          */
716         // CSOFF: JavaNCSS
717         // CSOFF: LineLength
718         // CSOFF: MethodLength
719         private void initComponents() {
720
721             mainTab = new javax.swing.JTabbedPane();
722             borderColorChooser = new javax.swing.JColorChooser();
723             backgroundColorChooser = new javax.swing.JColorChooser();
724             textColorChooser = new javax.swing.JColorChooser();
725             textFormat = new javax.swing.JPanel();
726             jPanel2 = new javax.swing.JPanel();
727             fontSizeLabel = new javax.swing.JLabel();
728             fontSizeSpinner = new javax.swing.JSpinner();
729             fontNameLabel = new javax.swing.JLabel();
730             fontNameComboBox = new javax.swing.JComboBox();
731             fontStyleBold = new javax.swing.JCheckBox();
732             fontStyleItalic = new javax.swing.JCheckBox();
733             fontStyleLabel = new javax.swing.JLabel();
734             imageFileChooserBtn = new javax.swing.JButton(XcosMessages.DOTS);
735             imagePathLabel = new javax.swing.JLabel();
736             imagePath = new javax.swing.JTextField(TEXT_AREA_COLUMNS);
737             backgroundPane = new javax.swing.JPanel();
738
739             labelArea = new javax.swing.JTextField();
740             labelArea.setToolTipText(XcosMessages.ONELINE_DESCRIPTION_TOOLTIP);
741
742             jScrollPane1 = new javax.swing.JScrollPane();
743             textArea = new javax.swing.JTextPane();
744             textArea.setToolTipText(XcosMessages.MULTILINE_DESCRIPTION_TOOLTIP);
745
746             textArea.setContentType("text/html");
747
748             cancelButton = new javax.swing.JButton(XcosMessages.CANCEL);
749             okButton = new javax.swing.JButton(XcosMessages.OK);
750             okButton.setMnemonic(KeyEvent.VK_ENTER);
751             resetButton = new javax.swing.JButton(XcosMessages.RESET);
752             buttonPane = new javax.swing.JPanel();
753
754             backgroundPane.setLayout(new java.awt.BorderLayout());
755             textFormat.setLayout(new java.awt.BorderLayout());
756
757             fontSizeLabel.setText(XcosMessages.FONT_SIZE);
758
759             fontSizeSpinner.setModel(FONTSIZE_MODEL);
760             fontSizeSpinner.addChangeListener(defaultChangeListener);
761
762             fontNameLabel.setText(XcosMessages.FONT_NAME);
763
764             fontNameComboBox.setModel(new javax.swing.DefaultComboBoxModel(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames()));
765
766             fontNameComboBox.addActionListener(defaultActionListener);
767
768             fontStyleLabel.setText(XcosMessages.FONT_STYLE);
769
770             fontStyleBold.setText(XcosMessages.BOLD);
771             fontStyleBold.addChangeListener(defaultChangeListener);
772
773             fontStyleItalic.setText(XcosMessages.ITALIC);
774             fontStyleItalic.addChangeListener(defaultChangeListener);
775
776             imagePathLabel.setText(XcosMessages.IMAGE_PATH);
777
778             javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
779             jPanel2.setLayout(jPanel2Layout);
780             jPanel2Layout.setHorizontalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
781                                              .addGroup(
782                                                  javax.swing.GroupLayout.Alignment.TRAILING,
783                                                  jPanel2Layout
784                                                  .createSequentialGroup()
785                                                  .addContainerGap()
786                                                  .addGroup(
787                                                          jPanel2Layout
788                                                          .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
789                                                          .addComponent(fontNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
790                                                                  Short.MAX_VALUE)
791                                                          .addComponent(fontSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE,
792                                                                  Short.MAX_VALUE)
793                                                          .addComponent(fontStyleLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
794                                                                  Short.MAX_VALUE))
795                                                  .addGap(BORDER_SIZE)
796                                                  .addGroup(
797                                                          jPanel2Layout
798                                                          .createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
799                                                          .addComponent(fontNameComboBox, 0, javax.swing.GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
800                                                          .addComponent(fontSizeSpinner, 0, javax.swing.GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
801                                                          .addGroup(
802                                                                  jPanel2Layout.createSequentialGroup().addComponent(fontStyleBold)
803                                                                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
804                                                                  .addComponent(fontStyleItalic))).addContainerGap()));
805             jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
806                                                jPanel2Layout
807                                                .createSequentialGroup()
808                                                .addGroup(
809                                                    jPanel2Layout
810                                                    .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
811                                                    .addComponent(fontSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE,
812                                                            javax.swing.GroupLayout.PREFERRED_SIZE)
813                                                    .addComponent(fontSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
814                                                            javax.swing.GroupLayout.PREFERRED_SIZE))
815                                                .addGap(BORDER_SIZE)
816                                                .addGroup(
817                                                    jPanel2Layout
818                                                    .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
819                                                    .addComponent(fontNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE,
820                                                            javax.swing.GroupLayout.PREFERRED_SIZE)
821                                                    .addComponent(fontNameComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
822                                                            javax.swing.GroupLayout.PREFERRED_SIZE))
823                                                .addGap(BORDER_SIZE)
824                                                .addGroup(
825                                                    jPanel2Layout
826                                                    .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
827                                                    .addComponent(fontStyleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE,
828                                                            javax.swing.GroupLayout.PREFERRED_SIZE)
829                                                    .addComponent(fontStyleBold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
830                                                            javax.swing.GroupLayout.PREFERRED_SIZE)
831                                                    .addComponent(fontStyleItalic, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
832                                                            javax.swing.GroupLayout.PREFERRED_SIZE))
833                                                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
834
835             textFormat.add(jPanel2, java.awt.BorderLayout.PAGE_END);
836
837             jScrollPane1.setViewportView(textArea);
838             jScrollPane1.setBackground(Color.WHITE);
839
840             textFormat.add(labelArea, java.awt.BorderLayout.PAGE_START);
841             textFormat.add(jScrollPane1, java.awt.BorderLayout.CENTER);
842
843             backgroundPane.add(backgroundColorChooser, java.awt.BorderLayout.CENTER);
844             javax.swing.JPanel filePane = new javax.swing.JPanel();
845             filePane.setBorder(BorderFactory.createEtchedBorder());
846             filePane.add(imagePathLabel);
847             filePane.add(imagePath);
848             filePane.add(imageFileChooserBtn);
849             backgroundPane.add(filePane, java.awt.BorderLayout.SOUTH);
850
851             mainTab.addTab(XcosMessages.TEXT_SETTINGS, textFormat);
852             mainTab.addTab(XcosMessages.BORDER_COLOR, borderColorChooser);
853             mainTab.addTab(XcosMessages.TEXT_COLOR, textColorChooser);
854             // backgroundColorChooser is added on the setCell method only if the
855             // cell is a vertex
856             // mainTab.addTab(XcosMessages.FILL_COLOR, backgroundColorChooser);
857
858             mainTab.addChangeListener(defaultChangeListener);
859
860             cancelButton.addActionListener(new ActionListener() {
861                 /**
862                  * On cancel close the window
863                  *
864                  * @param e
865                  *            the current event parameter
866                  * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
867                  */
868                 @Override
869                 public void actionPerformed(ActionEvent e) {
870                     getDialog().dispose();
871                 }
872             });
873
874             okButton.addActionListener(new ActionListener() {
875                 /**
876                  * On OK, set the current parameter on the cell
877                  *
878                  * @param e
879                  *            the current parameters
880                  * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
881                  */
882                 @Override
883                 public void actionPerformed(ActionEvent e) {
884                     graph.getModel().beginUpdate();
885                     EditFormatAction.updateFromDialog(getDialog(), borderColorChooser.getColor(), backgroundColorChooser.getColor(),
886                                                       (String) fontNameComboBox.getSelectedItem(), (Integer) fontSizeSpinner.getValue(), textColorChooser.getColor(),
887                                                       fontStyleBold.isSelected(), fontStyleItalic.isSelected(), labelArea.getText(), mxUtils.getBodyMarkup(textArea.getText(), false), imagePath.getText());
888                     graph.getModel().endUpdate();
889                     getDialog().dispose();
890                 }
891             });
892
893             resetButton.addActionListener(new ActionListener() {
894
895                 @Override
896                 public void actionPerformed(ActionEvent e) {
897                     graph.getModel().beginUpdate();
898                     EditFormatAction.reset(getDialog());
899                     graph.getModel().endUpdate();
900                 }
901             });
902
903             imageFileChooserBtn.addActionListener(new ActionListener() {
904                 /**
905                  * On file chooser open the file chooser with image filter.
906                  *
907                  * @param e
908                  *            the event
909                  * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
910                  */
911                 @Override
912                 public void actionPerformed(ActionEvent e) {
913                     javax.swing.JFileChooser chooser = new javax.swing.JFileChooser();
914                     javax.swing.filechooser.FileNameExtensionFilter filter = new javax.swing.filechooser.FileNameExtensionFilter("Images", "jpg", "png", "svg",
915                             "gif");
916                     chooser.setFileFilter(filter);
917
918                     final String current = imagePath.getText();
919                     final File savedFile = getGraph().getSavedFile();
920                     if (current != null && !current.isEmpty()) {
921                         try {
922                             // try to handle an absolute URL
923                             final URI uri = new URI(current);
924                             chooser.setSelectedFile(new File(uri));
925                         } catch (URISyntaxException e1) {
926                             // this is a relative path
927                             if (savedFile != null) {
928                                 final File parent = savedFile.getParentFile();
929                                 chooser.setSelectedFile(new File(parent, current));
930                             }
931                         }
932                     } else {
933                         if (savedFile != null) {
934                             chooser.setCurrentDirectory(savedFile.getParentFile());
935                         }
936                     }
937
938                     int returnVal = chooser.showOpenDialog(mainTab);
939                     if (returnVal == javax.swing.JFileChooser.APPROVE_OPTION) {
940                         if (savedFile != null) {
941                             final String relativeChild = savedFile.getParentFile().toURI().relativize(chooser.getSelectedFile().toURI()).toASCIIString();
942                             imagePath.setText(relativeChild);
943                         } else {
944                             final String uri = chooser.getSelectedFile().toURI().toASCIIString();
945                             imagePath.setText(uri);
946                         }
947                     }
948                 }
949             });
950
951             getRootPane().setDefaultButton(okButton);
952             labelArea.requestFocusInWindow();
953
954             buttonPane.setLayout(new javax.swing.BoxLayout(buttonPane, javax.swing.BoxLayout.LINE_AXIS));
955             buttonPane.setBorder(javax.swing.BorderFactory.createEmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
956             buttonPane.add(javax.swing.Box.createHorizontalGlue());
957             buttonPane.add(okButton);
958             buttonPane.add(javax.swing.Box.createRigidArea(new Dimension(BORDER_SIZE, 0)));
959             buttonPane.add(cancelButton);
960             buttonPane.add(javax.swing.Box.createRigidArea(new Dimension(BORDER_SIZE, 0)));
961             buttonPane.add(javax.swing.Box.createRigidArea(new Dimension(BORDER_SIZE, 0)));
962             buttonPane.add(resetButton);
963
964             java.awt.Container contentPane = getContentPane();
965             contentPane.add(mainTab, java.awt.BorderLayout.CENTER);
966             contentPane.add(buttonPane, java.awt.BorderLayout.PAGE_END);
967         }
968
969         // CSON: JavaNCSS
970         // CSON: LineLength
971         // CSON: MethodLength
972
973         /**
974          * Update the text area from the font
975          */
976         protected void updateFont() {
977             int style = 0;
978             if (fontStyleBold.isSelected()) {
979                 style |= Font.BOLD;
980             }
981             if (fontStyleItalic.isSelected()) {
982                 style |= Font.ITALIC;
983             }
984
985             Font f = new Font((String) fontNameComboBox.getSelectedItem(), style, (Integer) fontSizeSpinner.getValue());
986             textArea.setFont(f);
987             textArea.setBackground(backgroundColorChooser.getColor());
988             textArea.setForeground(textColorChooser.getColor());
989
990             // Repaint the parent scroll pane to force a full redraw call.
991             jScrollPane1.repaint();
992         }
993     }
994     // CSON: ClassDataAbstractionCoupling
995     // CSON: ClassFanOutComplexity
996 }