1    package com.instantbank.lettertemplate.editor.applet;
2    
3    import java.awt.FlowLayout;
4    import java.awt.Event;
5    
6    import java.awt.event.ActionListener;
7    import java.awt.event.ActionEvent;
8    import java.awt.event.FocusListener;
9    import java.awt.event.FocusEvent;
10   import java.awt.event.MouseListener;
11   import java.awt.event.MouseAdapter;
12   import java.awt.event.MouseEvent;
13   import java.awt.event.KeyEvent;
14   
15   import java.io.ByteArrayOutputStream;
16   import java.io.ByteArrayInputStream;
17   
18   import java.util.Hashtable;
19   import java.util.ArrayList;
20   import java.util.Date;
21   import java.util.Locale;
22   
23   import java.text.DecimalFormat;
24   import java.text.NumberFormat;
25   
26   import java.net.URL;
27   import java.net.MalformedURLException;
28   
29   import javax.swing.JApplet;
30   import javax.swing.JTree;
31   import javax.swing.UIManager;
32   import javax.swing.SwingUtilities;
33   import javax.swing.JSplitPane;
34   import javax.swing.JToolBar;
35   import javax.swing.JTabbedPane;
36   import javax.swing.ImageIcon;
37   import javax.swing.AbstractAction;
38   import javax.swing.JTextPane;
39   import javax.swing.Action;
40   import javax.swing.KeyStroke;
41   import javax.swing.ToolTipManager;
42   
43   import javax.swing.text.DefaultStyledDocument;
44   import javax.swing.text.MutableAttributeSet;
45   import javax.swing.text.SimpleAttributeSet;
46   import javax.swing.text.StyleConstants;
47   import javax.swing.text.StyleContext;
48   import javax.swing.text.BadLocationException;
49   import javax.swing.text.Keymap;
50   import javax.swing.text.AttributeSet;
51   
52   import javax.swing.text.rtf.RTFEditorKit;
53   
54   import javax.swing.tree.DefaultMutableTreeNode;
55   import javax.swing.tree.DefaultTreeCellRenderer;
56   import javax.swing.tree.TreeSelectionModel;
57   import javax.swing.tree.TreePath;
58   
59   import javax.swing.event.ChangeListener;
60   import javax.swing.event.ChangeEvent;
61   import javax.swing.event.CaretListener;
62   import javax.swing.event.CaretEvent;
63   
64   import javax.swing.border.LineBorder;
65   
66   
67   //--------------- imports for the CategoryNameTemplateDialog internal class ---
68   import java.awt.Frame;
69   import java.awt.Dimension;
70   import javax.swing.JDialog;
71   import javax.swing.JComboBox;
72   import javax.swing.JLabel;
73   import javax.swing.JTextField;
74   import javax.swing.SwingConstants;
75   import javax.swing.JButton;
76   import java.awt.GridBagLayout;
77   import java.awt.GridBagConstraints;
78   import java.awt.Insets;
79   import javax.swing.JPanel;
80   import java.awt.Color;
81   import java.awt.GridLayout;
82   import java.awt.BorderLayout;
83   import java.awt.event.*;
84   import javax.swing.BorderFactory;
85   import javax.swing.JOptionPane;
86   import javax.swing.JList;
87   import javax.swing.event.ListSelectionEvent;
88   import javax.swing.event.ListSelectionListener;
89   import javax.swing.ListSelectionModel;
90   import javax.swing.JScrollPane;
91   import javax.swing.border.EtchedBorder;
92   import javax.swing.border.TitledBorder;
93   import javax.swing.event.DocumentListener;
94   
95   import javax.swing.event.DocumentEvent;
96   import java.awt.GridLayout;
97   
98   import com.instantbank.lettertemplate.editor.util.LetterOp;
99   import com.instantbank.lettertemplate.editor.web.VariablesManager;
100  import com.instantbank.component.lettertemplate.util.LetterComponent;
101  import com.instantbank.component.lettertemplate.util.Template;
102  import com.instantbank.common.uiutils.LabelCombo;
103  import com.instantbank.common.uiutils.LabelComboCombo;
104  import com.instantbank.common.uiutils.LabelText;
105  import com.instantbank.common.uiutils.MessageFrame;
106  import com.instantbank.common.uiutils.MiscDecoration;
107  import com.instantbank.common.uiutils.SmallButton;
108  import com.instantbank.common.uiutils.SmallToggleButton;
109  import com.instantbank.common.uiutils.GetLineFromListDialog;
110  import com.instantbank.common.uiutils.DeltaDialog;
111  import com.instantbank.common.uiutils.DoubleDocument;
112  import com.instantbank.common.utilcomponents.CodeDescription;
113  import com.instantbank.common.utilcomponents.LetterTemplateGlobals;
114  import com.instantbank.common.utilcomponents.UtilOnJdk;
115  
116  //---------end of imports for the CategoryNameTemplateDialog internal class ---
117  
118  /**
119   *  Applet for letters template edition. Some of the code has been adapted from
120   *  the Swing book by Robinson and Vorobiev (Manning Ed).
121   *
122   * @author InstantBank (Rodrigo Lopez)
123   * @created September 2002
124   */
125  public class TemplateEditor extends JApplet {
126    /**
127     *  Background color for main widgets in the user interface.
128     */
129    static final Color backColor = Color.white;
130  
131    /**
132     *  Color for components' tabs: header, body, closing
133     */
134    static final Color tabColor = new Color(204, 220, 233);
135    //light blue
136  
137    /**
138     *  Name of the attribute used to remember the points of insertion of images
139     *  in the text.
140     */
141    public static final String ICONBYTES = "IconBytes";
142  
143    /**
144     *  The manager of loan variables information.
145     */
146    public VariablesManager varManager = null;
147  
148    /**
149     *  Name of the attribute used to remember the code and points of insertion of
150     *  loan variables in the text.
151     */
152    public static final String VARCODE = "VarCode";
153  
154    /**
155     *  Name of the attribute that records the format of a variable.
156     */
157    public static final String VARFORMAT = "VarFormat";
158  
159    /**
160     * Name of the attribute that records the date offset of a variable.
161     */
162    public static final String DATEDELTA = "DateDelta";
163  
164    /**
165     *  Color for visual repesentation of variables
166     */
167    public static final Color varColor = new Color(255, 130, 100);
168    /**
169     *  Character to be inserted with an image.
170     */
171    public static final String imgChar = new String(new char[]{'\u00FE'});
172  
173    /**
174     *  Character to be inserted with a variable.
175     */
176    public static final String varChar = new String(new char[]{'\u00FF'});
177  
178    /**
179     *  Label and Text displaying the print type of the template.
180     */
181    protected LabelText lbtPrintType;
182  
183    /**
184     *  Label and Text displaying the name of the template.
185     */
186    protected LabelText lbtTemplate;
187  
188    /**
189     *  Label and Text displaying the category of the template.
190     */
191    protected LabelText lbtCategory;
192  
193    /**
194     *  Label and Text displaying the name of the header.
195     */
196    protected LabelText lbtHeader;
197  
198    /**
199     *  Label and Text displaying the name of the body.
200     */
201    protected LabelText lbtBody;
202  
203    /**
204     *  Label and Text displaying the name of the closing.
205     */
206    protected LabelText lbtClosing;
207  
208    /**
209     *  Array of LabelText containing the controls associated with Template,
210     *  Header, Body, Closing, Category (in this order), grouped for fast access.
211     */
212    protected LabelText[] basicControls = new LabelText[5];
213  
214    /**
215     *  Widget for font display (family name and size).
216     */
217    protected LabelComboCombo lbccFont;
218  
219    /**
220     *  Widget for format display.
221     */
222    protected LabelCombo lbcFormat;
223  
224    /**
225     *  Upper panel containing controls displaying information related to template
226     *  name, template type, font, header, body and closing.
227     */
228    protected JPanel pnlControl = new JPanel();
229  
230    /**
231     *  Panel containing the right hand side of the user interface.
232     */
233    protected JPanel pnlRight = new JPanel();
234  
235    /**
236     *  Editor user interface, excluding variables tree.
237     */
238    protected EditorStuff edtStuff;
239  
240    /**
241     *  Editor having the focus.
242     */
243    protected ComponentEditor selectedTed;
244  
245    /**
246     *  JScrollPane for variables tree.
247     */
248    protected JScrollPane jsTree;
249  
250    /**
251     *  Variables tree.
252     */
253    protected JTree jtrVariables;
254  
255    /**
256     *  The known printType names.
257     */
258    protected String[] printTypes = {"", "laser", "typewriter"};
259  
260    /**
261     *  The code of the current print type : LASER, TYPEWRITTER
262     */
263    private int printType;
264  
265    /**
266     *  Local document clipboard. Replaces the system clipboard in order to do
267     *  copy/cut/paste including images and other attributes.
268     */
269    public DefaultStyledDocument docClipboard;
270  
271    /**
272     *  Base url of the web server.
273     */
274    public String urlbase;
275  
276    /**
277     *  Font family name
278     */
279    protected String fontName = "";
280  
281    /**
282     *  Font size
283     */
284    protected int fontSize = 0;
285  
286    /**
287     *  Indicates if update of the status controls --font, size, format--
288     *  must be done.
289     */
290    protected boolean skipUpdate;
291  
292    /**
293     *  Current format of variable.
294     */
295    protected long varFormat;
296  
297    /**
298     *  Proxi for communicating with the servlet.
299     */
300    protected TemplateEditorProxy proxy;
301  
302    /**
303     *  The list of available images for insertion
304     */
305    protected String[] remoteImages = null;
306  
307    /**
308     *  The set of available template categories.
309     */
310    protected CodeDescription[] categories = null;
311  
312    /**
313     *  The set of available variable formats.
314     */
315    protected CodeDescription[] varFormats = null;
316  
317    /**
318     *  The Letter Template under edition.
319     */
320    protected Template template;
321  
322    /**
323     *  The set of template names for all categories with the current printType.
324     *  Content is: < categoryName, CodeDescription[] of (templateCode,
325     *  templDescr)>
326     */
327    protected Hashtable templatesNames = new Hashtable();
328  
329  
330    /**
331     *  Initializes the user interface
332     */
333    public void init() {
334      try {
335        UIManager.setLookAndFeel(
336          "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
337        SwingUtilities.updateComponentTreeUI(this);
338      }
339      catch(Exception ex) {
340        //MessageFrame.getFrame().addText("Could not load LookAndFeel");
341      }
342  
343      urlbase = shortenUrl(getCodeBase().toExternalForm(), 1);
344  
345      //Inits the proxy for communicating with the servlet.
346      try {
347        String lurl = shortenUrl(this.getCodeBase().toExternalForm(), 2);
348        proxy = new TemplateEditorProxy(new URL(lurl));
349      }
350      catch(MalformedURLException urlx) {
351      }
352  
353      //Loads template categories.
354      try {
355        this.categories = proxy.loadCategories();
356      }
357      catch(Exception ex) {
358        ex.printStackTrace();
359        return;
360      }
361  
362      if(categories == null) {
363        JOptionPane.showMessageDialog(null, "There are no categories. \n" +
364          "Categories should be defined before editing templates.");
365        goHome();
366        return;
367      }
368  
369      String fakePrint[] = {"laser", "typewriter"};
370      // Asks for the print type of the template.
371      String selected = (String)
372        JOptionPane.showInputDialog(TemplateEditor.this,
373        "Please choose a print type",
374        "Selecting Print Type",
375        JOptionPane.QUESTION_MESSAGE,
376        null, fakePrint, fakePrint[0]);
377  
378      if(selected == null) {  // Cancel
379        goHome();
380        return;
381      }
382  
383      printType =
384        (selected.equals("laser")) ?
385        Template.LASER : Template.TYPEWRITTER;
386  
387      // Initializes a void template.
388      this.template = new Template(printType);
389  
390      setSize(900, 510);
391  
392      // The control Panel
393      pnlControl.setBackground(backColor);
394      pnlControl.setLayout(new GridBagLayout());
395      GridBagConstraints c = new GridBagConstraints();
396  
397      //Template Controls
398      lbtTemplate = new LabelText("Template", LetterTemplateGlobals.STR_UNNAMED,
399        backColor, MiscDecoration.longField, MiscDecoration.rBorder, false);
400      c.insets = new Insets(3, 3, 3, 3);
401      c.gridx = 0;
402      c.gridy = 0;
403      c.gridwidth = 1;
404      pnlControl.add(lbtTemplate, c);
405  
406      //Category
407      lbtCategory = new LabelText("Category", LetterTemplateGlobals.STR_UNDEF,
408        backColor, MiscDecoration.longField, MiscDecoration.rBorder, false);
409      c.gridx = 1;
410      c.gridwidth = 1;
411      pnlControl.add(lbtCategory, c);
412  
413      //PrinterType Control
414      lbtPrintType = new LabelText("PrintType", this.printTypes[printType],
415        backColor, MiscDecoration.longField, MiscDecoration.rBorder, false);
416      c.gridx = 2;
417      c.gridwidth = 1;
418  
419      pnlControl.add(lbtPrintType, c);
420  
421      //Font Controls
422      lbccFont = new LabelComboCombo("Font",
423        LetterOp.FONTNAME,
424        LetterOp.FONTSIZE, backColor,
425        MiscDecoration.longField, MiscDecoration.shortField, MiscDecoration.tdBorder);
426  
427      //ActionListener for font name.
428      ActionListener lst =
429        new ActionListener() {
430          public void actionPerformed(ActionEvent e) {
431            String fName = lbccFont.getBigCombo().getSelectedItem().toString();
432            MutableAttributeSet attr = new SimpleAttributeSet();
433            StyleConstants.setFontFamily(attr, fName);
434            fontName = fName;
435            selectedTed.setAttributeSet(attr);
436            selectedTed.grabFocus();
437          }
438        };
439  
440      lbccFont.getBigCombo().addActionListener(lst);
441  
442      //Action Listener for font size.
443      lst =
444        new ActionListener() {
445          public void actionPerformed(ActionEvent e) {
446            int fSize = 0;
447            try {
448              fSize = Integer.parseInt(
449                lbccFont.getSmallCombo().getSelectedItem().toString());
450            }
451            catch(NumberFormatException ex) {
452              return;
453            }
454  
455            fontSize = fSize;
456            MutableAttributeSet attr = new SimpleAttributeSet();
457            StyleConstants.setFontSize(attr, fontSize);
458            selectedTed.setAttributeSet(attr);
459            selectedTed.grabFocus();
460          }
461        };
462      lbccFont.getSmallCombo().addActionListener(lst);
463  
464      c.anchor = GridBagConstraints.EAST;
465      c.gridx = 3;
466      pnlControl.add(lbccFont, c);
467  
468      //Header Controls
469      lbtHeader = new LabelText("Header",
470        LetterTemplateGlobals.STR_UNNAMED,
471        backColor, MiscDecoration.longField, MiscDecoration.rBorder, false);
472      c.gridx = 0;
473      c.gridy = 1;
474      c.gridwidth = 1;
475      pnlControl.add(lbtHeader, c);
476  
477      //Body Controls
478      lbtBody = new LabelText("Body",
479        LetterTemplateGlobals.STR_UNNAMED,
480        backColor, MiscDecoration.longField, MiscDecoration.rBorder, false);
481      c.gridx = 1;
482      pnlControl.add(lbtBody, c);
483  
484      //Closing controls
485      lbtClosing = new LabelText("Closing",
486        LetterTemplateGlobals.STR_UNNAMED,
487        backColor, MiscDecoration.longField, MiscDecoration.rBorder, false);
488  
489      c.gridx = 2;
490      pnlControl.add(lbtClosing, c);
491  
492      //formats
493      try {
494        varFormats = proxy.loadVariableFormats();
495      }
496      catch(Exception ex) {
497        varFormats = new CodeDescription[0];
498      }
499  
500      long initvarFormat = VariablesManager.DEFAULT_STRING_FORMAT;
501  
502      String[] strFormats =
503        CodeDescription.toDescriptions(varFormats);
504      lbcFormat = new LabelCombo("Format", strFormats,
505        backColor, MiscDecoration.longField, MiscDecoration.rBorder);
506      lbcFormat.getCombo().setSelectedIndex(
507        CodeDescription.getIndexCode(initvarFormat, varFormats));
508  
509      //Action Listener for variable format insertion.
510      lst = new VariableFormatInsertion();
511      lbcFormat.getCombo().addActionListener(lst);
512  
513      c.gridx = 3;
514      pnlControl.add(lbcFormat, c);
515  
516      //The Editors and controls panel (the right panel)
517      pnlRight.setLayout(new BorderLayout());
518      pnlRight.add(pnlControl, BorderLayout.NORTH);
519  
520      edtStuff = new EditorStuff();
521  
522      // Adding the editor frame
523      pnlRight.add(edtStuff, BorderLayout.CENTER);
524  
525      //The Tree and its scroll
526      jtrVariables = buildTree();
527      ToolTipManager.sharedInstance().registerComponent(jtrVariables);
528      jsTree = new JScrollPane(jtrVariables);
529      jsTree.setSize(600, 500);
530  
531      //Final location (Tree and Editor)
532      JSplitPane split = new JSplitPane(
533        JSplitPane.HORIZONTAL_SPLIT, jsTree, pnlRight);
534      split.setDividerSize(2);
535      split.setBorder(new LineBorder(Color.black, 1));
536      this.getContentPane().add(split, BorderLayout.CENTER);
537  
538      try {
539        this.remoteImages = proxy.loadImagesNamesRepository();
540      }
541      catch(Exception ex) {
542        //pend: What to do.
543        //MessageFrame.getFrame().addText("Problems loading images names!!");
544      }
545  
546      //Inits the array of basic controls
547      basicControls[LetterTemplateGlobals.TEMPLATE_INDEX] = lbtTemplate;
548      basicControls[LetterTemplateGlobals.HEADER_INDEX] = lbtHeader;
549      basicControls[LetterTemplateGlobals.BODY_INDEX] = lbtBody;
550      basicControls[LetterTemplateGlobals.CLOSING_INDEX] = lbtClosing;
551      basicControls[LetterTemplateGlobals.CATEGORY] = lbtCategory;
552  
553      // Selects the "header" component.
554      selectedTed = edtStuff.tedh;
555      selectedTed.showAttributes(0);
556      setVisible(true);
557  
558      //edtStuff.initEditorStuffGui();
559  
560      //Images and font attributes are only available for
561      // laser print type.
562      edtStuff.btnImg.setEnabled(printType == Template.LASER);
563      edtStuff.btnBold.setEnabled(printType == Template.LASER);
564      edtStuff.btnItalic.setEnabled(printType == Template.LASER);
565      edtStuff.btnUnderline.setEnabled(printType == Template.LASER);
566      TemplateEditor.this.lbccFont.setEnabled(printType == Template.LASER);
567      //edtStuff.btnPreview.setEnabled(false);
568  
569    }
570    //End of TemplateEditor.init()
571  
572    /**
573     *  Deletes a number of components at the end of the url
574     *
575     * @param url An url path
576     * @param ncomp Number of components to delete
577     * @return The url without its last ncomp components.
578     */
579    private String shortenUrl(String url, int ncomp) {
580      StringBuffer urlBuff = new StringBuffer(url);
581      int p = urlBuff.length() - 1;
582      while(ncomp != 0) {
583        urlBuff.deleteCharAt(p--);
584        if(p == 0) {
585          return urlBuff.toString();
586        }
587        while(urlBuff.charAt(p) != '/') {
588          urlBuff.deleteCharAt(p--);
589          if(p == 0) {
590            return urlBuff.toString();
591          }
592        }
593        ncomp--;
594      }
595      return urlBuff.toString();
596    }
597  
598  
599    /**
600     *  Exit to home page
601     */
602    public void goHome() {
603      try {
604        if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
605          return;
606        }
607        String homeurl = shortenUrl(getCodeBase().toExternalForm(), 2);
608        homeurl += "lettertemplate/control_web/home.jsp";
609        //Dbg MessageFrame.getFrame().addText("homeurl = " + homeurl);
610        getAppletContext().showDocument(new URL(homeurl));
611        //proxy.exit(homeurl); //The previous effect via the servlet (FAILS!!)
612      }
613      catch(MalformedURLException mex) {
614        //MessageFrame.getFrame().addText("Back to home: " + mex.toString());
615      }
616      catch(Exception ex) {
617        //MessageFrame.getFrame().addText("Back to home: " + ex.toString());
618      }
619    }
620  
621  
622  
623    /**
624     *  Constructs the Variables tree.
625     *
626     * @return The variables tree
627     */
628    private JTree buildTree() {
629      DefaultMutableTreeNode root =
630        new DefaultMutableTreeNode("Variables");
631  
632      DefaultMutableTreeNode loan =
633        new DefaultMutableTreeNode("Loan");
634  
635      try {
636        ArrayList loanVariables = proxy.loadVariables();
637        if(loanVariables != null) {
638          for(int i = 0; i < loanVariables.size(); i++) {
639            ArrayList tmp = (ArrayList)loanVariables.get(i);
640            String varName = (String)tmp.get(1);
641            loan.add(new DefaultMutableTreeNode(varName));
642          }
643        }
644        varManager = new VariablesManager(loanVariables);
645      }
646      catch(Exception ex) {
647        // MessageFrame.getFrame().addText("Problems loading variables");
648      }
649  
650      DefaultMutableTreeNode system =
651        new DefaultMutableTreeNode("System");
652      system.add(new DefaultMutableTreeNode("Date"));
653  
654      root.add(loan);
655      //Include SystemDate as a variable: Watch!!
656      //root.add(system);
657  
658      JTree jt =
659        new JTree(root) {
660          public String getToolTipText(MouseEvent ev) {
661            if(ev == null) {
662              return null;
663            }
664            TreePath path = this.getPathForLocation(ev.getX(), ev.getY());
665            if(path != null) {
666              Object s = path.getLastPathComponent();
667              if(this.getModel().isLeaf(s)) {
668                return s.toString();
669              }
670            }
671            return null;
672          }
673        };
674  
675      DefaultTreeCellRenderer tcr =
676        (DefaultTreeCellRenderer)jt.getCellRenderer();
677      tcr.setTextSelectionColor(Color.white);
678  
679      jt.getSelectionModel().setSelectionMode(
680        TreeSelectionModel.SINGLE_TREE_SELECTION);
681      return jt;
682    }
683  
684  
685    /**
686     *  Shows the basic status of a Template in the upper controls of the GUI
687     *  (except for the Category).
688     *
689     * @param templ The template whose status is showed.
690     */
691    private void refreshStatusGui(Template templ) {
692      lbtTemplate.setText(templ.getName());
693      lbtPrintType.setText(printTypes[templ.getPrintType()]);
694      lbtHeader.setText(templ.getHeader().getName());
695      lbtBody.setText(templ.getBody().getName());
696      lbtClosing.setText(templ.getClosing().getName());
697    }
698  
699  
700    /**
701     * Verifies if its argument has the right syntax for template and
702     * letter components names. Java identifiers syntax is currently used.
703     *
704     * @param name The string to be verified.
705     * @return true if valid, false otherwise.
706     */
707    private boolean isValidName(String name) {
708      if(name.length() == 0) {
709        return false;
710      }
711      char c = name.charAt(0);
712      if(!Character.isJavaIdentifierStart(c)) {
713        return false;
714      }
715      for(int i = 1; i < name.length(); i++) {
716        c = name.charAt(i);
717        if(!Character.isJavaIdentifierPart(c)) {
718          return false;
719        }
720      }
721      return true;
722    }
723  
724  
725    /**
726     *  Contains the widgets that fire external actions on the editors of the
727     *  template's components: header, body, closing.
728     *
729     * @author InstantBank (Rodrigo Lopez)
730     * @created September 2002
731     */
732    class EditorStuff extends JPanel {
733  
734      ////////////////////////////////////////////////////
735      //Buttons bound to actions over the current template.
736      ////////////////////////////////////////////////////
737  
738      /**
739       *  When pressed, a new template is created to replace the {@link #template
740       *  current one}. <p>
741       *
742       *  See {@link TemplateEditor.EditorStuff.NewTemplateAction
743       *  NewTemplateAction}.
744       */
745      JButton btnNewTemplate;
746  
747      /**
748       *  When pressed, an existing {@link Template} can be opened to replace the
749       *  {@link #template current one}. <p>
750       *
751       *  See {@link TemplateEditor.EditorStuff.OpenTemplateAction
752       *  OpenTemplateAction}.
753       */
754      JButton btnOpenTemplate;
755  
756      /**
757       *  When pressed, the {@link #template current template} is saved. <p>
758       *
759       *  See {@link TemplateEditor.EditorStuff.SaveTemplateAction
760       *  SaveTemplateAction}.
761       */
762      JButton btnSaveTemplate;
763  
764      /**
765       *  When pressed, the {@link #template current template} can be saved with a
766       *  new name or changing any of its components. <p>
767       *
768       *  See {@link TemplateEditor.EditorStuff.SaveAsTemplateAction
769       *  SaveAsTemplateAction}.
770       */
771      JButton btnSaveAsTemplate;
772  
773      /////////////////////////////////////////////////////
774      //Buttons bound to actions over the current component.
775      /////////////////////////////////////////////////////
776  
777      /**
778       *  When pressed a new component is created as part of the {@link #template
779       *  current template}. <p>
780       *
781       *  See {@link TemplateEditor.EditorStuff.NewComponentAction
782       *  NewComponentAction}.
783       */
784      JButton btnNew;
785  
786      /**
787       *  When pressed, an existing component can be opened to replace the current
788       *  component of the {@link #template current template}. <p>
789       *
790       *  See {@link TemplateEditor.EditorStuff.OpenComponentAction
791       *  OpenComponentAction}.
792       */
793      JButton btnOpen;
794  
795      /**
796       *  When pressed, the current component of the {@link #template current
797       *  template} is saved. <p>
798       *
799       *  See {@link TemplateEditor.EditorStuff.SaveComponentAction
800       *  SaveComponentAction}.
801       */
802      JButton btnSave;
803  
804      /**
805       *  When pressed, the current component of the {@link #template current
806       *  template} can be saved with a different name. <p>
807       *
808       *  See {@link TemplateEditor.EditorStuff.SaveAsComponentAction
809       *  SaveAsComponentAction}.
810       */
811      JButton btnSaveAs;
812  
813      /**
814       *  When pressed an image can be inserted in the current component at
815       *  cursor's position. <p>
816       *
817       *  See {@link TemplateEditor.EditorStuff.InsertImageAction
818       *  InsertImageAction}.
819       */
820      JButton btnImg;
821  
822      /**
823       *  When pressed the editor is exited and control flows to the system's home
824       *  page.
825       */
826      JButton btnHome;
827  
828      /**
829       * When pressed, the current template is previewed in a new window.
830       */
831      JButton btnPreview;
832  
833      /**
834       * When pressed, the margin dialogs is launched.
835       */
836      JButton btnMargins;
837  
838      /**
839       * Extra button. Used for debugging purposes.
840       */
841      JButton btnExtra;  //Extra!!
842  
843      /**
844       *  Bold button
845       */
846      SmallToggleButton btnBold;
847  
848      /**
849       *  Italic button
850       */
851      SmallToggleButton btnItalic;
852  
853      /**
854       *  Underline button
855       */
856      SmallToggleButton btnUnderline;
857  
858      /**
859       *  ComponentEditor for the template's header.
860       */
861      ComponentEditor tedh;
862  
863      /**
864       *  ComponentEditor for the template's body.
865       */
866      ComponentEditor tedb;
867  
868      /**
869       *  ComponentEditor for the template's closing.
870       */
871      ComponentEditor tedc;
872  
873      /**
874       *  Array of ComponentEditors referencing --in its order-- the header, the
875       *  body and the closing editors.
876       */
877      ComponentEditor editors[];
878  
879      /**
880       *  Toolbar for action buttons
881       */
882      JToolBar toolBar;
883  
884      /**
885       *  Tabbed pane share by theeditors of the components.
886       */
887      JTabbedPane tabpane;
888  
889      /**
890       *  Thin lower panel for status messages.
891       */
892      JPanel pnlStatus;
893  
894      /**
895       *  Label for status messages.
896       */
897      JLabel lblStatus;
898  
899      /**
900       *  Timer for vanishing the status messages.
901       */
902      javax.swing.Timer statusTimer;
903  
904  
905      /**
906       *  Constructor for the EditorStuff object
907       */
908      public EditorStuff() {
909  
910        try {
911  
912          ImageIcon iconNewTemplate = new ImageIcon(
913            new URL(urlbase + "images/New24.gif"));
914  
915          ImageIcon iconOpenTemplate = new ImageIcon(
916            new URL(urlbase + "images/Open24.gif"));
917  
918          ImageIcon iconSaveAll = new ImageIcon(
919            new URL(urlbase + "images/SaveAll24.gif"));
920  
921          ImageIcon iconSaveAsTempl = new ImageIcon(
922            new URL(urlbase + "images/SaveAs24.gif"));
923  
924          ImageIcon iconNew = new ImageIcon(
925            new URL(urlbase + "images/NewComponent.gif"));
926  
927          ImageIcon iconOpen = new ImageIcon(
928            new URL(urlbase + "images/Edit24.gif"));
929  
930          ImageIcon iconSave = new ImageIcon(
931            new URL(urlbase + "images/file_save.gif"));
932  
933          ImageIcon iconSaveAs = new ImageIcon(
934            new URL(urlbase + "images/SaveComponentAs.gif"));
935  
936          // Buttons and actions for templates
937          btnNewTemplate =
938            new SmallButton(
939            new NewTemplateAction("New Template", iconNewTemplate),
940            "New Template");
941  
942          btnOpenTemplate = new SmallButton(
943            new OpenTemplateAction("Open Template", iconOpenTemplate),
944            "Open Template");
945  
946          btnSaveTemplate = new SmallButton(
947            new SaveTemplateAction("Save Template", iconSaveAll),
948            "Save Template");
949  
950          btnSaveAsTemplate = new SmallButton(
951            new SaveAsTemplateAction("Save Template as ..", iconSaveAsTempl),
952            "Save Template as ..");
953  
954          // Buttons and actions for components
955  
956          btnNew = new SmallButton(
957            new NewComponentAction("New component", iconNew),
958            "New component");
959  
960          btnOpen = new SmallButton(
961            new OpenComponentAction("Open component", iconOpen),
962            "Open component");
963  
964          btnSave = new SmallButton(
965            new SaveComponentAction("Save component", iconSave),
966            "Save component");
967  
968          btnSaveAs = new SmallButton(
969            new SaveAsComponentAction("Save component as..", iconSaveAs),
970            "Save component as..");
971  
972          //Bold, Italic, Insert Image buttons and actions
973          ImageIcon img1 = new ImageIcon(
974            new URL(urlbase + "images/font_bold1.gif"));
975          ImageIcon img2 = new ImageIcon(
976            new URL(urlbase + "images/font_bold2.gif"));
977  
978          btnBold = new SmallToggleButton(false, img1, img2, "Bold font");
979          btnBold.addActionListener(new SetBoldAction());
980  
981          img1 = new ImageIcon(
982            new URL(urlbase + "images/font_italic1.gif"));
983          img2 = new ImageIcon(
984            new URL(urlbase + "images/font_italic2.gif"));
985  
986          btnItalic = new SmallToggleButton(false, img1, img2, "Italic font");
987          btnItalic.addActionListener(new SetItalicAction());
988  
989          img1 = new ImageIcon(
990            new URL(urlbase + "images/font_underline1.gif"));
991          img2 = new ImageIcon(
992            new URL(urlbase + "images/font_underline2.gif"));
993  
994          btnUnderline = new SmallToggleButton(false, img1, img2, "Underline");
995          btnUnderline.addActionListener(new SetUnderlineAction());
996  
997          img1 = new ImageIcon(new URL(urlbase + "images/insertImag.gif"));
998  
999          btnImg = new SmallButton(
1000           new InsertImageAction("Insert Image", img1), "Insert Image");
1001 
1002         // Preview and go home.
1003 
1004         img1 = new ImageIcon(new URL(urlbase + "images/Margins24.gif"));
1005 
1006         btnMargins = new SmallButton(
1007           new MarginsAction("Set Margins", img1), "Set Margins");
1008 
1009         img1 = new ImageIcon(new URL(urlbase + "images/PrintPreview24.gif"));
1010 
1011         btnPreview = new SmallButton(
1012           new PreviewAction("Preview", img1), "Preview");
1013 
1014         img1 = new ImageIcon(new URL(urlbase + "images/Home24.gif"));
1015 
1016         btnHome = new SmallButton(
1017           new GoHomeAction("Exit", img1), "Exit from editor");
1018 
1019         img1 = new ImageIcon(new URL(urlbase + "images/manchot.gif"));  //Extra!!
1020         btnExtra = new SmallButton(  //Extra!!
1021         new ExtraAction("Letter Job", img1), "Letter Job");
1022 
1023         /*
1024          *  -------------------------------------------------------
1025          *  Toolbar and TabPane stuff
1026          *  -------------------------------------------------------
1027          */
1028         toolBar = new JToolBar();
1029         tabpane = new JTabbedPane();
1030 
1031         tedh = new ComponentEditor(LetterComponent.HEADER);
1032         tedb = new ComponentEditor(LetterComponent.BODY);
1033         tedc = new ComponentEditor(LetterComponent.CLOSING);
1034         editors = new ComponentEditor[]{tedh, tedb, tedc};
1035 
1036         JScrollPane psh = new JScrollPane(tedh);
1037         JScrollPane psb = new JScrollPane(tedb);
1038         JScrollPane psc = new JScrollPane(tedc);
1039         Dimension shortSep = new Dimension(30, 5);
1040         Dimension longSep = new Dimension(250, 5);
1041         this.setBackground(backColor);
1042 
1043         toolBar.add(btnNewTemplate);
1044         toolBar.add(btnOpenTemplate);
1045         toolBar.add(btnSaveTemplate);
1046         toolBar.add(btnSaveAsTemplate);
1047         toolBar.addSeparator(shortSep);
1048 
1049         toolBar.add(btnNew);
1050         toolBar.add(btnOpen);
1051         toolBar.add(btnSave);
1052         toolBar.add(btnSaveAs);
1053         toolBar.addSeparator(shortSep);
1054 
1055         toolBar.add(btnBold);
1056         toolBar.add(btnItalic);
1057         toolBar.add(btnUnderline);
1058         toolBar.addSeparator(shortSep);
1059 
1060         toolBar.add(btnImg);
1061         toolBar.addSeparator(longSep);
1062 
1063         toolBar.add(btnMargins);
1064         toolBar.add(btnPreview);
1065         toolBar.add(btnHome);
1066         //toolBar.add(btnExtra); //Extra!!
1067 
1068         this.setLayout(new BorderLayout());
1069         this.add(toolBar, BorderLayout.NORTH);
1070 
1071         tabpane.add(psh, "    Header    ");
1072         tabpane.setBackground(tabColor);
1073         tabpane.add(psb, "     Body     ");
1074         tabpane.add(psc, "    Closing   ");
1075         this.add(tabpane, BorderLayout.CENTER);
1076 
1077         pnlStatus = new JPanel();
1078         pnlStatus.setBorder(BorderFactory.createEtchedBorder());
1079         pnlStatus.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
1080         lblStatus = new JLabel("");
1081         pnlStatus.add(lblStatus);
1082         this.add(pnlStatus, BorderLayout.SOUTH);
1083 
1084         statusTimer = new javax.swing.Timer(2000,
1085           new ActionListener() {
1086             public void actionPerformed(ActionEvent e) {
1087               lblStatus.setText("");
1088             }
1089           });
1090         statusTimer.setRepeats(false);
1091 
1092         tabpane.addChangeListener(
1093           new ChangeListener() {
1094             public void stateChanged(ChangeEvent e) {
1095               proxy.controlTimeout(TemplateEditor.this.getAppletContext());
1096               int i = ((JTabbedPane)e.getSource()).getSelectedIndex();
1097               selectedTed = editors[i];
1098             }
1099           });
1100 
1101       }
1102       catch(Exception ex) {
1103         //MessageFrame.getFrame().addText(ex.getMessage());
1104       }
1105     }
1106 
1107 
1108     // End of EditorStuff() constructor.
1109 
1110     /**
1111      *  Fill a Template with the content managed by the three ComponentEditors:
1112      *  header, body and closing. Moreover, fills the names of the components
1113      *  and template from the a CodeDescription array that follows the <a
1114      *  href="./package-summary.html#thbc">THBC order.</a>
1115      *
1116      * @param templ The template to be filled.
1117      * @param result The array where names are stored.
1118      */
1119     public void fillTemplateFromGuiResult(Template templ, CodeDescription[] result) {
1120       if(templ == null) {
1121         return;
1122       }
1123       templ.setName(result[LetterTemplateGlobals.TEMPLATE_INDEX].getDescription());
1124 
1125       LetterComponent comp = templ.getHeader();
1126       tedh.fillLetterComponent(comp);
1127       comp.setName(result[LetterTemplateGlobals.HEADER_INDEX].getDescription());
1128 
1129       comp = templ.getBody();
1130       tedb.fillLetterComponent(comp);
1131       comp.setName(result[LetterTemplateGlobals.BODY_INDEX].getDescription());
1132 
1133       comp = templ.getClosing();
1134       tedc.fillLetterComponent(comp);
1135       comp.setName(result[LetterTemplateGlobals.CLOSING_INDEX].getDescription());
1136     }
1137 
1138 
1139     /**
1140      *  Fill a Template with the content managed by the three ComponentEditors:
1141      *  header, body and closing.
1142      *
1143      * @param templ The template to be filled.
1144      */
1145     public void fillTemplateFromGui(Template templ) {
1146       if(templ == null) {
1147         return;
1148       }
1149 
1150       tedh.fillLetterComponent(templ.getHeader());
1151       tedb.fillLetterComponent(templ.getBody());
1152       tedc.fillLetterComponent(templ.getClosing());
1153     }
1154 
1155 
1156     /**
1157      *  Fill the code and stamp attributes of a template and its components.
1158      *
1159      * @param templ The template to be filled.
1160      * @param codes Array containing the attributes in the <a
1161      *      href="./package-summary.html#thbc">THBC order.</a>
1162      */
1163     public void fillTemplateCodes(Template templ, CodeDescription[] codes) {
1164 
1165       templ.setCode(codes[LetterTemplateGlobals.TEMPLATE_INDEX].getCode());
1166       templ.setStamp(codes[LetterTemplateGlobals.TEMPLATE_INDEX].getDescription());
1167 
1168       templ.getHeader().setCode(codes[LetterTemplateGlobals.HEADER_INDEX].getCode());
1169       templ.getHeader().setStamp(codes[LetterTemplateGlobals.HEADER_INDEX].getDescription());
1170 
1171       templ.getBody().setCode(codes[LetterTemplateGlobals.BODY_INDEX].getCode());
1172       templ.getBody().setStamp(codes[LetterTemplateGlobals.BODY_INDEX].getDescription());
1173 
1174       templ.getClosing().setCode(codes[LetterTemplateGlobals.CLOSING_INDEX].getCode());
1175       templ.getClosing().setStamp(codes[LetterTemplateGlobals.CLOSING_INDEX].getDescription());
1176     }
1177 
1178 
1179     /**
1180      *  Fills < code, name, stamp> attributes of a template, from an array of
1181      *  TemplateCodes. Moreover it also fills the template's category attribute.
1182      *
1183      * @param templ The template to be filled.
1184      * @param oldTemplate The array containing the attribute values. It follows
1185      *      the <a href="./package-summary.html#thbccr">THBCCR
1186      *      order.</a>
1187      */
1188     public void restoreTemplateCodes(Template templ, TemplateCodes[] oldTemplate) {
1189       templ.setCode(oldTemplate[LetterTemplateGlobals.TEMPLATE_INDEX].code);
1190       templ.setName(oldTemplate[LetterTemplateGlobals.TEMPLATE_INDEX].name);
1191       templ.setStamp(oldTemplate[LetterTemplateGlobals.TEMPLATE_INDEX].stamp);
1192 
1193       templ.setCategory(oldTemplate[CategoryNameTemplateDialog.CATEGORY].code);
1194 
1195       LetterComponent comp = templ.getHeader();
1196       comp.setCode(oldTemplate[LetterTemplateGlobals.HEADER_INDEX].code);
1197       comp.setName(oldTemplate[LetterTemplateGlobals.HEADER_INDEX].name);
1198       comp.setStamp(oldTemplate[LetterTemplateGlobals.HEADER_INDEX].stamp);
1199 
1200       comp = templ.getBody();
1201       comp.setCode(oldTemplate[LetterTemplateGlobals.BODY_INDEX].code);
1202       comp.setName(oldTemplate[LetterTemplateGlobals.BODY_INDEX].name);
1203       comp.setStamp(oldTemplate[LetterTemplateGlobals.BODY_INDEX].stamp);
1204 
1205       comp = templ.getClosing();
1206       comp.setCode(oldTemplate[LetterTemplateGlobals.CLOSING_INDEX].code);
1207       comp.setName(oldTemplate[LetterTemplateGlobals.CLOSING_INDEX].name);
1208       comp.setStamp(oldTemplate[LetterTemplateGlobals.CLOSING_INDEX].stamp);
1209     }
1210 
1211 
1212     /**
1213      *  Displays a template in the user interface. See {@link
1214      *  TemplateEditor.ComponentEditor#displayLetterComponent(LetterComponent)}.
1215      *
1216      * @param templ The template to be displayed.
1217      */
1218     private void displayTemplate(Template templ) {
1219       int current = selectedTed.componentType - 1;
1220       tedh.displayLetterComponent(templ.getHeader());
1221       tedb.displayLetterComponent(templ.getBody());
1222       tedc.displayLetterComponent(templ.getClosing());
1223       edtStuff.tabpane.setSelectedIndex(current);
1224     }
1225 
1226 
1227     /**
1228      *  The current template is stored in the data base.
1229      */
1230     private void saveTemplate() {
1231       if(template.getCode() == LetterTemplateGlobals.UNDEF) {
1232         // A new template
1233         saveTemplateAs(LetterOp.SAVEAS);
1234       }
1235       else if(template.getHeader().getCode() == LetterTemplateGlobals.UNDEF
1236         || template.getBody().getCode() == LetterTemplateGlobals.UNDEF
1237         || template.getClosing().getCode() == LetterTemplateGlobals.UNDEF) {
1238         // Some component has changed.
1239 
1240         //dbg MessageFrame.getFrame().addText(template.codesToString());
1241         saveTemplateAs(LetterOp.SAVEWITHNEW);
1242       }
1243       else {
1244         //Normal save of an old template
1245         TemplateCodes[] oldTemplateCodes = null;
1246         try {
1247 
1248           //fill template from user interface and remember its  fields.
1249           oldTemplateCodes = getTemplateCodes(template);
1250           fillTemplateFromGui(template);
1251 
1252           //Store it
1253           CodeDescription[] answer = proxy.storeTemplate(template);
1254 
1255           if(answer == null) {
1256             JOptionPane.showMessageDialog(null,
1257               "Problems storing the \"" + template.getName() + "\" template.\n");
1258             return;
1259           }
1260           //template was saved. Refresh codes only in memory.
1261           fillTemplateCodes(template, answer);
1262 
1263           //Enable buttons to work with components.
1264           //setEnableComponentsButtons(true);
1265           //btnPreview.setEnabled(true);
1266           template.upToDate();
1267           edtStuff.showStatus("The template was saved");
1268 
1269         }
1270         catch(Exception ex) {
1271           restoreTemplateCodes(template, oldTemplateCodes);
1272           JOptionPane.showMessageDialog(null,
1273             "Problems storing the \"" + template.getName() + "\" template.\n"
1274             );
1275           ex.printStackTrace();
1276         }
1277       }
1278     }
1279 
1280 
1281     /**
1282      *  Requests to save the {@link #template current template}.
1283      *
1284      * @param mode The saving mode.
1285      *      <ul>
1286      *        <li> {@link LetterOp#SAVEAS} =>
1287      *        <ul>
1288      *          <li> The template is new (it is the first time it is going to be
1289      *          saved), or
1290      *          <li> It is an old template and the user wants to change its name
1291      *          and/or the component's names.
1292      *        </ul>
1293      *
1294      *        <li> {@link LetterOp#SAVEWITHNEW} => It is an old template and the
1295      *        user wants to change one of its components.
1296      *      </ul>
1297      *      The provided Gui is based on the {@link
1298      *      TemplateEditor.CategoryNameTemplateDialog} widget.
1299      */
1300     private void saveTemplateAs(int mode) {
1301       int pType = template.getPrintType();
1302 
1303       //Place holder for data captured by the next CategoryNameTemplateDialog.
1304       CodeDescription[] result = initSaveAsResult();
1305 
1306       //if there is a category it must be sent to the next dialog.
1307 
1308       CategoryNameTemplateDialog cntd =
1309         new CategoryNameTemplateDialog(
1310         template.getCategory(), result, mode);
1311 
1312       cntd.setLocationRelativeTo(TemplateEditor.this);
1313       cntd.show();
1314 
1315       long codeCategory =
1316         result[CategoryNameTemplateDialog.CATEGORY].getCode();
1317       String nameCategory =
1318         result[CategoryNameTemplateDialog.CATEGORY].getDescription();
1319       String templName = result[LetterTemplateGlobals.TEMPLATE_INDEX].getDescription();
1320 
1321       //dbg
1322       //showLocals(result);
1323 
1324       if(result[CategoryNameTemplateDialog.RESPONSE].getCode() ==
1325         JOptionPane.CANCEL_OPTION) {
1326         return;
1327       }
1328 
1329       // The template will be stored; so ...
1330       // Verify a last time the code and time stamp of the template
1331       // and its components, based on their names.
1332       CodeDescription[] codeStamps = null;
1333       TemplateCodes[] oldTemplateCodes = null;
1334 
1335       try {
1336 
1337         //fill template from user interface and result and remember its old fields.
1338         oldTemplateCodes = getTemplateCodes(template);
1339         fillTemplateFromGuiResult(template, result);
1340 
1341         codeStamps = proxy.loadCodesStamps(
1342           codeCategory,
1343           printType,
1344           result[LetterTemplateGlobals.TEMPLATE_INDEX].getDescription(),
1345           result[LetterTemplateGlobals.HEADER_INDEX].getDescription(),
1346           result[LetterTemplateGlobals.BODY_INDEX].getDescription(),
1347           result[LetterTemplateGlobals.CLOSING_INDEX].getDescription());
1348 
1349         //fill template with definitive codes and stamps.
1350         fillTemplateCodes(template, codeStamps);
1351         template.setCategory(codeCategory);
1352 
1353         CodeDescription[] answer = proxy.storeTemplate(template);
1354 
1355         if(answer == null) {
1356           JOptionPane.showMessageDialog(null,
1357             "Problems storing the \"" + templName + "\" template.\n");
1358           return;
1359         }
1360         //template was saved. Refresh codes in memory and GUI
1361         fillTemplateCodes(template, answer);
1362         TemplateEditor.this.lbtTemplate.setText(template.getName());
1363         TemplateEditor.this.lbtHeader.setText(template.getHeader().getName());
1364         TemplateEditor.this.lbtBody.setText(template.getBody().getName());
1365         TemplateEditor.this.lbtClosing.setText(template.getClosing().getName());
1366         TemplateEditor.this.lbtCategory.setText(nameCategory);
1367 
1368         template.upToDate();
1369         edtStuff.showStatus("The template was saved");
1370 
1371       }
1372       catch(Exception ex) {
1373 
1374         JOptionPane.showMessageDialog(null,
1375           "Problems storing the \"" + templName + "\" template.\n"
1376           );
1377         ex.printStackTrace();
1378         restoreTemplateCodes(template, oldTemplateCodes);
1379       }
1380     }
1381 
1382 
1383     /**
1384      *  Saves a letter component in the data base.
1385      *
1386      * @param component The component to be saved.
1387      * @return True if the store action was succesful, False otherwise.
1388      */
1389     private boolean saveComponent(LetterComponent component) {
1390       if(component.getCode() == LetterTemplateGlobals.UNDEF) {
1391         return saveComponentAs(component);
1392       }
1393       else {
1394         selectedTed.fillLetterComponent(component);
1395         try {
1396           CodeDescription cd = proxy.storeComponent(component);
1397           if(cd == null) {
1398             JOptionPane.showMessageDialog(null, "The Component could not be saved");
1399             return false;
1400           }
1401           component.setStamp(cd.getDescription());
1402           edtStuff.showStatus("The component was saved");
1403           return true;
1404         }
1405         catch(Exception ex) {
1406           ex.printStackTrace();
1407           JOptionPane.showMessageDialog(null, "The Component could not be saved");
1408           return false;
1409         }
1410       }
1411     }
1412 
1413 
1414     /**
1415      *  Requests to save a component.
1416      *
1417      * @param component The component to be saved. <p>
1418      *
1419      *      The provided Gui is based on {@link
1420      *      TemplateEditor.SaveAsComponentDialog}
1421      * @return True if the component could be saved, False otherwise.
1422      */
1423     private boolean saveComponentAs(LetterComponent component) {
1424 
1425       CodeDescription[] components = null;
1426       SaveAsComponentDialog sacDialog;
1427       TemplateCodes compCodes =
1428         new TemplateCodes(component.getCode(),
1429         component.getName(),
1430         component.getStamp());
1431       try {
1432         int compType = component.getType();
1433         components =
1434           proxy.loadComponentsDescription(compType, component.getPrintType());
1435 
1436         String compTypeName = LetterComponent.typeToString(compType);
1437         CodeDescription answer = new CodeDescription(LetterTemplateGlobals.UNDEF, "");
1438         sacDialog =
1439           new SaveAsComponentDialog(
1440           components, compTypeName, LetterOp.SAVEAS, answer);
1441         sacDialog.setLocationRelativeTo(TemplateEditor.this);
1442         sacDialog.show();
1443 
1444         if(answer.getCode() == JOptionPane.CANCEL_OPTION) {
1445           return false;
1446         }
1447 
1448         //The component will be saved.
1449         component.setName(answer.getDescription());
1450         answer = proxy.loadComponentCode(
1451           compType, component.getPrintType(), answer.getDescription());
1452 
1453         component.setCode(answer.getCode());
1454         component.setStamp(answer.getDescription());
1455         selectedTed.fillLetterComponent(component);
1456 
1457         if(template.getCode() == LetterTemplateGlobals.UNDEF) {
1458           answer = proxy.storeComponent(component);
1459         }
1460         else {
1461           answer = proxy.storeComponentAs(template.getCode(), component);
1462         }
1463 
1464         if(answer == null) {
1465           throw new Exception();
1466         }
1467         component.setCode(answer.getCode());
1468         component.setStamp(answer.getDescription());
1469         basicControls[compType].setText(component.getName());
1470         edtStuff.showStatus("The component was saved");
1471         return true;
1472       }
1473       catch(Exception ex) {
1474         ex.printStackTrace();
1475         JOptionPane.showMessageDialog(null,
1476           "The component could not be saved");
1477         component.setCode(compCodes.code);
1478         component.setName(compCodes.name);
1479         component.setStamp(compCodes.stamp);
1480         return false;
1481       }
1482     }
1483 
1484 
1485     /**
1486      *  Allows to enable/disable the toolbar buttons related to basic operations
1487      *  over the letter component under edition.
1488      *
1489      * @param mode       <ul>
1490      *        <li> <tt>True</tt> => Buttons are enabled.
1491      *        <li> <tt>False</tt> => Buttons are disabled.
1492      *      </ul>
1493      */
1494     public void setEnableComponentsButtons(boolean mode) {
1495       btnOpen.setEnabled(mode);
1496       btnSave.setEnabled(mode);
1497       btnNew.setEnabled(mode);
1498       btnSaveAs.setEnabled(mode);
1499     }
1500 
1501 
1502     /**
1503      *  Calculates a "void" value for the response that is calculated by the
1504      *  {@link TemplateEditor.CategoryNameTemplateDialog} Gui. It is used by the
1505      *  caller of that Gui.
1506      *
1507      * @return An array of < code,description> in the <a
1508      *      href="./package-summary.html#thbccr">THBCCR order</a>
1509      *      with all attributes "undefined".
1510      */
1511     public CodeDescription[] initSaveAsResult() {
1512       CodeDescription[] res = new CodeDescription[CategoryNameTemplateDialog.RESPONSE + 1];
1513       for(int i = 0; i <= CategoryNameTemplateDialog.RESPONSE; i++) {
1514         res[i] = new CodeDescription(LetterTemplateGlobals.UNDEF, "");
1515       }
1516       return res;
1517     }
1518 
1519 
1520     /**
1521      *  Inits the Gui for the component editors: cleans the text, and puts
1522      *  the cursor at the 0 position.
1523      */
1524     public void initEditorStuffGui() {
1525       template = new Template(printType);
1526       refreshStatusGui(template);
1527       lbtCategory.setText(LetterTemplateGlobals.STR_UNDEF);
1528       edtStuff.tedh.clean();
1529       edtStuff.tedb.clean();
1530       edtStuff.tedc.clean();
1531       template.upToDate();
1532     }
1533 
1534 
1535     /**
1536      *  Debug method that shows the content of a < code, description> array
1537      *  in a window dialog. The array is in the <a
1538      *  href="./package-summary.html#thbccr">THBCCR order</a>
1539      *
1540      * @param locals The array to be shown.
1541      */
1542     public void showLocals(CodeDescription[] locals) {
1543       JOptionPane.showMessageDialog(null,
1544         "category = " + locals[CategoryNameTemplateDialog.CATEGORY].getCode() + " ,"
1545         + locals[CategoryNameTemplateDialog.CATEGORY].getDescription() + "\n" +
1546         "template = " + locals[LetterTemplateGlobals.TEMPLATE_INDEX].getCode() + " ,"
1547         + locals[LetterTemplateGlobals.TEMPLATE_INDEX].getDescription() + "\n" +
1548         "header = " + locals[LetterTemplateGlobals.HEADER_INDEX].getCode() + " ,"
1549         + locals[LetterTemplateGlobals.HEADER_INDEX].getDescription() + "\n" +
1550         "body = " + locals[LetterTemplateGlobals.BODY_INDEX].getCode() + " ,"
1551         + locals[LetterTemplateGlobals.BODY_INDEX].getDescription() + "\n" +
1552         "closing = " + locals[LetterTemplateGlobals.CLOSING_INDEX].getCode() + " ,"
1553         + locals[LetterTemplateGlobals.CLOSING_INDEX].getDescription() + "\n" +
1554         "response = " + locals[CategoryNameTemplateDialog.RESPONSE].getCode() + " ,"
1555         + locals[CategoryNameTemplateDialog.RESPONSE].getDescription()
1556         );
1557     }
1558 
1559 
1560     /**
1561      *  Calculates an array of < code,name,stamp> values corresponding to a
1562      *  {@link Template} and its {@link LetterComponent}s.
1563      *
1564      * @param template The template.
1565      * @return The array of codes in the <a
1566      *      href="./package-summary.html#thbc">THBC order</a> .
1567      */
1568     public TemplateCodes[] getTemplateCodes(Template template) {
1569       TemplateCodes[] res =
1570         new TemplateCodes[CategoryNameTemplateDialog.CATEGORY + 1];
1571       LetterComponent comp;
1572 
1573       res[LetterTemplateGlobals.TEMPLATE_INDEX] =
1574         new TemplateCodes(template.getCode(), template.getName(), template.getStamp());
1575       res[CategoryNameTemplateDialog.CATEGORY] =
1576         new TemplateCodes(template.getCategory(), LetterTemplateGlobals.STR_UNDEF, LetterTemplateGlobals.STR_UNDEF);
1577 
1578       comp = template.getHeader();
1579       res[LetterTemplateGlobals.HEADER_INDEX] =
1580         new TemplateCodes(comp.getCode(), comp.getName(), comp.getStamp());
1581 
1582       comp = template.getBody();
1583       res[LetterTemplateGlobals.BODY_INDEX] =
1584         new TemplateCodes(comp.getCode(), comp.getName(), comp.getStamp());
1585 
1586       comp = template.getClosing();
1587       res[LetterTemplateGlobals.CLOSING_INDEX] =
1588         new TemplateCodes(comp.getCode(), comp.getName(), comp.getStamp());
1589 
1590       return res;
1591     }
1592 
1593 
1594     /**
1595      *  Shows a message in the {@link TemplateEditor.EditorStuff#pnlStatus
1596      *  status area}. The message will disappear after 2 seconds.
1597      *
1598      * @param s The message to be shown.
1599      */
1600     public void showStatus(String s) {
1601       lblStatus.setText(s);
1602       this.statusTimer.start();
1603     }
1604 
1605 
1606     private String brokenVarsMessage(String brokenVars) {
1607       StringBuffer sb = new StringBuffer(300);
1608       sb.append("Date offsets  for the following variables have\n");
1609       sb.append("been found inconsistent:\n\n");
1610       sb.append(brokenVars);
1611       sb.append("\n\n");
1612       sb.append("The  offsets  have  been zeroed in the editor.\n");
1613       sb.append("If you save this document, the offsets will be\n");
1614       sb.append("zeroed in the database.\n\n");
1615       sb.append("Contact your  sysadmin  if you want to fix the\n");
1616       sb.append("Company fields definition.");
1617       return sb.toString();
1618     }
1619 
1620     /////////////////////////////////
1621     // EditorStuff's Inner classes //
1622     /////////////////////////////////
1623 
1624     /**
1625      *  Action bound to the {@link TemplateEditor.EditorStuff#btnNewTemplate
1626      *  btnNewTemplate} button. Creates a new {@link Template}, cleans the Gui
1627      *  for each of its {@link LetterComponent components} and disables the
1628      *  toolbar buttons corresponding to operations on the components.
1629      *
1630      * @author InstantBank (Rodrigo Lopez)
1631      * @created September 2002
1632      */
1633     class NewTemplateAction extends AbstractAction {
1634 
1635       /**
1636        *  NewTemplateAction Constructor.
1637        *
1638        * @param s Tip to be shown when browsing over the {@link
1639        *      TemplateEditor.EditorStuff#btnNewTemplate btnNewTemplate} button.
1640        * @param i Image inside the button.
1641        */
1642       NewTemplateAction(String s, ImageIcon i) {
1643         super(s, i);
1644       }
1645 
1646 
1647       /**
1648        *  Creates a new {@link Template}, cleans the Gui for each of its {@link
1649        *  LetterComponent components} and disables the toolbar buttons
1650        *  corresponding to operations on the components.
1651        *
1652        * @param e Description of the Parameter
1653        */
1654       public void actionPerformed(ActionEvent e) {
1655         if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
1656           return;
1657         }
1658         if(template.hasChanged()) {
1659           int option =
1660             JOptionPane.showConfirmDialog(
1661             null, "Do you want to save the current template ?",
1662             "Saving before loading",
1663             JOptionPane.YES_NO_CANCEL_OPTION);
1664 
1665           switch (option) {
1666             case JOptionPane.YES_OPTION:
1667               saveTemplate();
1668               break;
1669             case JOptionPane.NO_OPTION:
1670               break;
1671             case JOptionPane.CANCEL_OPTION:
1672               return;
1673             default:
1674           }
1675         }
1676 
1677         initEditorStuffGui();
1678       }
1679 
1680     }
1681 
1682 
1683     /**
1684      *  Action bound to the {@link TemplateEditor.EditorStuff#btnOpenTemplate
1685      *  btnOpenTemplate} button. Opens an existing {@link Template}. The
1686      *  provided Gui is a {@link TemplateEditor.CategoryNameTemplateDialog} with
1687      *  <tt>mode =</tt> {@link LetterOp#LOAD}. Buttons bound to component's
1688      *  actions are enabled.
1689      *
1690      * @author InstantBank (Rodrigo Lopez)
1691      * @created September 2002
1692      */
1693     class OpenTemplateAction extends AbstractAction {
1694 
1695       /**
1696        *  OpenTemplateAction Constructor.
1697        *
1698        * @param s Tip to be shown when browsing over the {@link
1699        *      TemplateEditor.EditorStuff#btnOpenTemplate btnOpenTemplate}
1700        *      button.
1701        * @param i Image inside the button.
1702        */
1703       OpenTemplateAction(String s, ImageIcon i) {
1704         super(s, i);
1705       }
1706 
1707 
1708       /**
1709        *  Opens an existing {@link Template}. The provided Gui is a {@link
1710        *  TemplateEditor.CategoryNameTemplateDialog} with <tt>mode =</tt> {@link
1711        *  LetterOp#LOAD}. Buttons bound to component's actions are enabled.
1712        *
1713        * @param e Description of the Parameter
1714        */
1715       public void actionPerformed(ActionEvent e) {
1716         if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
1717           return;
1718         }
1719         if(template.hasChanged()) {
1720           int option =
1721             JOptionPane.showConfirmDialog(
1722             null, "Do you want to save the current template ?",
1723             "Saving Before Opening",
1724             JOptionPane.YES_NO_CANCEL_OPTION);
1725 
1726           switch (option) {
1727             case JOptionPane.YES_OPTION:
1728               saveTemplate();
1729               break;
1730             case JOptionPane.NO_OPTION:
1731               break;
1732             case JOptionPane.CANCEL_OPTION:
1733               return;
1734             default:
1735           }
1736         }
1737 
1738         int pType = template.getPrintType();
1739 
1740         //Place holder for data captured by the next CategoryNameTemplateDialog.
1741         CodeDescription[] result = initSaveAsResult();
1742 
1743         //if there is a category it must be sent to the next dialog.
1744 
1745         CategoryNameTemplateDialog cntd =
1746           cntd =
1747           new CategoryNameTemplateDialog(
1748           template.getCategory(), result, LetterOp.LOAD);
1749 
1750         cntd.setLocationRelativeTo(TemplateEditor.this);
1751         cntd.txtTemplateName.setEditable(false);
1752         cntd.show();
1753 
1754         //dbg showLocals(result);
1755 
1756         if(result[CategoryNameTemplateDialog.RESPONSE].getCode() ==
1757           JOptionPane.CANCEL_OPTION) {
1758           return;
1759         }
1760 
1761         long templCode = result[LetterTemplateGlobals.TEMPLATE_INDEX].getCode();
1762         String templName = result[LetterTemplateGlobals.TEMPLATE_INDEX].getDescription();
1763         String nameCategory =
1764           result[CategoryNameTemplateDialog.CATEGORY].getDescription();
1765 
1766         //The template will be loaded
1767         try {
1768           ArrayList tmpPair = proxy.loadTemplate(templCode);
1769           if(tmpPair == null) {
1770             throw new Exception();
1771           }
1772 
1773           Template tmp = (Template)tmpPair.get(0);
1774           String brokenVars = (String)tmpPair.get(1);
1775 
1776           //Warns the user if broken vars.
1777           if(brokenVars != null) {
1778             JOptionPane.showMessageDialog(
1779               TemplateEditor.this,
1780               brokenVarsMessage(brokenVars),
1781               "Date Offset Inconsistencies",
1782               JOptionPane.WARNING_MESSAGE);
1783           }
1784 
1785           TemplateEditor.this.lbtTemplate.setText(tmp.getName());
1786           TemplateEditor.this.lbtHeader.setText(tmp.getHeader().getName());
1787           TemplateEditor.this.lbtBody.setText(tmp.getBody().getName());
1788           TemplateEditor.this.lbtClosing.setText(tmp.getClosing().getName());
1789           TemplateEditor.this.lbtCategory.setText(nameCategory);
1790 
1791           displayTemplate(tmp);
1792 
1793           //Now, to avoid troubles with the focusGained handler in
1794           //ComponentEditor...
1795           tedh.initSelection();
1796           tedb.initSelection();
1797           tedc.initSelection();
1798 
1799           template = tmp;
1800           if(brokenVars != null) {  //The template was fixed so it is out of date
1801             template.outOfDate();
1802           }
1803           else {
1804             template.upToDate();
1805           }
1806         }
1807         catch(Exception ex) {
1808           JOptionPane.showMessageDialog(null,
1809             "Problems loading the \"" + templName + "\" template.\n"
1810             );
1811           ex.printStackTrace();
1812         }
1813       }
1814     }
1815 
1816 
1817     /**
1818      *  Action bound to the {@link TemplateEditor.EditorStuff#btnSaveTemplate
1819      *  btnSaveTemplate} button. Saves in the data base the {@link #template
1820      *  current template}.
1821      *  <ul>
1822      *    <li> If the template is new, it is saved by the {@link
1823      *    TemplateEditor.EditorStuff#saveTemplateAs(int) saveTemplateAs} method
1824      *    with <tt>mode =</tt> {@link LetterOp#SAVEAS}.
1825      *    <li> If it is an old template but any of its components is new, it is
1826      *    saved by the {@link TemplateEditor.EditorStuff#saveTemplateAs(int)
1827      *    saveTemplateAs} method with <tt>mode =</tt> {@link
1828      *    LetterOp#SAVEWITHNEW}.
1829      *    <li> Otherwise it is silently saved.
1830      *  </ul>
1831      *
1832      * @author InstantBank (Rodrigo Lopez)
1833      * @created September 2002
1834      */
1835     class SaveTemplateAction extends AbstractAction {
1836 
1837       /**
1838        *  SaveTemplateAction Constructor.
1839        *
1840        * @param s Tip to be shown when browsing over the {@link
1841        *      TemplateEditor.EditorStuff#btnSaveTemplate btnSaveTemplate}
1842        *      button.
1843        * @param i Image inside the button.
1844        */
1845       SaveTemplateAction(String s, ImageIcon i) {
1846         super(s, i);
1847       }
1848 
1849 
1850       /**
1851        *  Saves in the data base the {@link #template current template}.
1852        *  <ul>
1853        *    <li> If the template is new, it is saved by the {@link
1854        *    TemplateEditor.EditorStuff#saveTemplateAs(int) saveTemplateAs}
1855        *    method with <tt>mode =</tt> {@link LetterOp#SAVEAS}.
1856        *    <li> If it is an old template but any of its components is new, it
1857        *    is saved by the {@link TemplateEditor.EditorStuff#saveTemplateAs(int)
1858        *    saveTemplateAs} method with <tt>mode =</tt> {@link
1859        *    LetterOp#SAVEWITHNEW}.
1860        *    <li> Otherwise it is silently saved.
1861        *  </ul>
1862        *
1863        * @param e Description of the Parameter
1864        */
1865       public void actionPerformed(ActionEvent e) {
1866         if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
1867           return;
1868         }
1869         saveTemplate();
1870       }
1871     }
1872 
1873 
1874     /**
1875      *  Action bound to the {@link TemplateEditor.EditorStuff#btnSaveAsTemplate
1876      *  btnSaveAsTemplate} button. The {@link #template current template} is
1877      *  saved by means of the {@link TemplateEditor.EditorStuff#saveTemplateAs(int)
1878      *  saveTemplateAs} method with <tt>mode =</tt> {@link LetterOp#SAVEAS}.
1879      *
1880      * @author InstantBank (Rodrigo Lopez)
1881      * @created September 2002
1882      */
1883     class SaveAsTemplateAction extends AbstractAction {
1884 
1885       /**
1886        *  SaveTemplateAction Constructor.
1887        *
1888        * @param s Tip to be shown when browsing over the {@link
1889        *      TemplateEditor.EditorStuff#btnSaveAsTemplate btnSaveAsTemplate}
1890        *      button.
1891        * @param i Image inside the button.
1892        */
1893       SaveAsTemplateAction(String s, ImageIcon i) {
1894         super(s, i);
1895       }
1896 
1897 
1898       /**
1899        *  The {@link #template current template} is saved by means of the {@link
1900        *  TemplateEditor.EditorStuff#saveTemplateAs(int) saveTemplateAs} method
1901        *  with <tt>mode =</tt> {@link LetterOp#SAVEAS}.
1902        *
1903        * @param e Description of the Parameter
1904        */
1905       public void actionPerformed(ActionEvent e) {
1906         if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
1907           return;
1908         }
1909         saveTemplateAs(LetterOp.SAVEAS);
1910       }
1911     }
1912 
1913 
1914     /**
1915      *  Action bound to the {@link TemplateEditor.EditorStuff#btnNew btnNew}
1916      *  button. It creates a new {@link LetterComponent} as part of the {@link
1917      *  #template current template}.
1918      *
1919      * @author InstantBank (Rodrigo Lopez)
1920      * @created September 2002
1921      */
1922     class NewComponentAction extends AbstractAction {
1923 
1924       /**
1925        *  NewComponentAction Constructor.
1926        *
1927        * @param s Tip to be shown when browsing over the {@link
1928        *      TemplateEditor.EditorStuff#btnNew btnNew} button.
1929        * @param i Image inside the button.
1930        */
1931       NewComponentAction(String s, ImageIcon i) {
1932         super(s, i);
1933       }
1934 
1935 
1936       /**
1937        *  A new {@link LetterComponent} is created and is bound to the {@link
1938        *  #template current template}
1939        *
1940        * @param e Description of the Parameter
1941        */
1942       public void actionPerformed(ActionEvent e) {
1943         if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
1944           return;
1945         }
1946         int componentType = selectedTed.componentType;
1947 
1948         if(template.getComponent(componentType).getCode()
1949           != LetterTemplateGlobals.UNDEF) {
1950 
1951           int r = JOptionPane.showConfirmDialog(
1952             TemplateEditor.this,
1953             "The current \""
1954             + LetterComponent.typeToString(componentType)
1955             + "\" component will be detached from the template.\n" +
1956             "Do you want to continue?",
1957             "New Component",
1958             JOptionPane.OK_CANCEL_OPTION,
1959             JOptionPane.WARNING_MESSAGE);
1960 
1961           if(r == JOptionPane.CANCEL_OPTION) {
1962             return;
1963           }
1964         }
1965 
1966         LetterComponent newComponent =
1967           new LetterComponent(componentType, printType);
1968 
1969         basicControls[componentType].setText(newComponent.getName());
1970 
1971         template.setComponent(componentType, newComponent);
1972 
1973         selectedTed.clean();
1974 
1975         //Although the component is up to date, the template is not, so
1976         newComponent.hasChanged = true;
1977 
1978       }
1979     }
1980 
1981 
1982     /**
1983      *  Action bound to the {@link TemplateEditor.EditorStuff#btnOpen btnOpen}
1984      *  button. It Allows to choose an existing component to replace the current
1985      *  one. The provided Gui is a standard JOptionPane dialog.
1986      *
1987      * @author InstantBank (Rodrigo Lopez)
1988      * @created September 2002
1989      */
1990     class OpenComponentAction extends AbstractAction {
1991 
1992       /**
1993        *  [code,name] array of the components that can be opened.
1994        */
1995       private CodeDescription[] components;
1996 
1997       /**
1998        *  Names of the components that can be opened.
1999        */
2000       String[] compNames;
2001 
2002 
2003       /**
2004        *  OpenComponentAction Constructor.
2005        *
2006        * @param s Tip to be shown when browsing over the {@link
2007        *      TemplateEditor.EditorStuff#btnOpen btnOpen} button.
2008        * @param i Image inside the button.
2009        */
2010       OpenComponentAction(String s, ImageIcon i) {
2011         super(s, i);
2012       }
2013 
2014 
2015       /**
2016        *  Allows to choose an existing component to replace the current one.
2017        *  The provided Gui is a standard JOptionPane dialog.
2018        *
2019        * @param e Description of the Parameter
2020        */
2021       public void actionPerformed(ActionEvent e) {
2022         if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
2023           return;
2024         }
2025         int componentType = selectedTed.componentType;
2026         LetterComponent component = template.getComponent(componentType);
2027         if(component.hasChanged) {
2028           int option =
2029             JOptionPane.showConfirmDialog(
2030             null, "Do you want to save the current " +
2031             LetterComponent.typeToString(componentType) +
2032             " ?",
2033             "Saving before loading",
2034             JOptionPane.YES_NO_CANCEL_OPTION);
2035 
2036           switch (option) {
2037             case JOptionPane.YES_OPTION:
2038               if(saveComponent(component)) {
2039                 template.getComponent(componentType).hasChanged = false;
2040               }
2041               break;
2042             case JOptionPane.NO_OPTION:
2043               break;
2044             case JOptionPane.CANCEL_OPTION:
2045               return;
2046             default:
2047           }
2048         }
2049 
2050         try {
2051 
2052           String typeName = LetterComponent.typeToString(componentType);
2053 
2054           components =
2055             proxy.loadComponentsDescription(componentType, printType);
2056 
2057           if(components == null) {
2058             JOptionPane.showMessageDialog(null,
2059               "There are no " + typeName + " components to be opened");
2060             return;
2061           }
2062 
2063           compNames = CodeDescription.toDescriptions(components);
2064 
2065           Object[] answer = new Object[2];
2066           JDialog nameDlg =
2067             new GetLineFromListDialog("Loading a " + typeName,
2068             "Existing " +
2069             LetterComponent.typeToPlural(componentType),
2070             compNames, answer);
2071 
2072           nameDlg.setLocationRelativeTo(TemplateEditor.this);
2073           nameDlg.show();
2074 
2075           int ansCode = ((Integer)answer[0]).intValue();
2076           if(ansCode == GetLineFromListDialog.CANCEL) {
2077             return;
2078           }
2079 
2080           //OK button was pushed
2081           String selected = (String)answer[1];
2082           if(selected == null) {  //There was no selection in the dialog.
2083             return;
2084           }
2085 
2086           long componentCode =
2087             CodeDescription.assocDescription(selected, components).getCode();
2088 
2089           ArrayList compResp = proxy.loadComponent(componentCode);
2090 
2091           if(compResp == null) {
2092             JOptionPane.showMessageDialog(null, "The component could not be loaded");
2093             return;
2094           }
2095 
2096           // Gets actual component and broken vars.
2097           LetterComponent newComp = (LetterComponent)compResp.get(0);
2098           String brokenVars = (String)compResp.get(1);
2099 
2100           //Warns the user if broken vars.
2101           if(brokenVars != null) {
2102             JOptionPane.showMessageDialog(
2103               TemplateEditor.this,
2104               brokenVarsMessage(brokenVars),
2105               "Date Offset Inconsistencies",
2106               JOptionPane.WARNING_MESSAGE);
2107           }
2108 
2109           template.setComponent(componentType, newComp);
2110           basicControls[componentType].setText(newComp.getName());
2111           selectedTed.displayLetterComponent(newComp);
2112           selectedTed.initSelection();
2113           //Although the component is up to date the template is not, so
2114           newComp.hasChanged = true;
2115         }
2116         catch(Exception ex) {
2117 
2118           JOptionPane.showMessageDialog(null, "Internal error loading component.");
2119           ex.printStackTrace();
2120         }
2121 
2122       }
2123     }
2124 
2125 
2126     /**
2127      *  Action bound to the {@link TemplateEditor.EditorStuff#btnSave btnSave}
2128      *  button. It saves the current component in the data base. If it succeeds
2129      *  a status message is shown.
2130      *
2131      * @author InstantBank (Rodrigo Lopez)
2132      * @created September 2002
2133      */
2134     class SaveComponentAction extends AbstractAction {
2135 
2136       /**
2137        *  SaveComponentAction Constructor.
2138        *
2139        * @param s Tip to be shown when browsing over the {@link
2140        *      TemplateEditor.EditorStuff#btnSave btnSave} button.
2141        * @param i Image inside the button.
2142        */
2143       SaveComponentAction(String s, ImageIcon i) {
2144         super(s, i);
2145       }
2146 
2147 
2148       /**
2149        *  Saves the current component in the data base. If it succeeds a
2150        *  status message is shown.
2151        *
2152        * @param e Description of the Parameter
2153        */
2154       public void actionPerformed(ActionEvent e) {
2155         if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
2156           return;
2157         }
2158         int compType = selectedTed.componentType;
2159         LetterComponent component = template.getComponent(compType);
2160 
2161         //The next two instructions must be separated because of a vicious
2162         // side effect in saveComponent.
2163         if(saveComponent(component)) {
2164           template.getComponent(compType).hasChanged = false;
2165         }
2166       }
2167     }
2168 
2169 
2170     /**
2171      *  Action bound to the {@link TemplateEditor.EditorStuff#btnSaveAs
2172      *  btnSaveAs} button. It saves the current component --maybe with a new
2173      *  name-- and replaces the corresponding component of the {@link #template
2174      *  current template}. The provided Gui is the {@link
2175      *  TemplateEditor.SaveAsComponentDialog SaveAsComponentDialog}.
2176      *
2177      * @author InstantBank (Rodrigo Lopez)
2178      * @created September 2002
2179      */
2180     class SaveAsComponentAction extends AbstractAction {
2181 
2182       /**
2183        *  SaveComponentAction Constructor.
2184        *
2185        * @param s Tip to be shown when browsing over the {@link
2186        *      TemplateEditor.EditorStuff#btnSave btnSave} button.
2187        * @param i Image inside the button.
2188        */
2189       SaveAsComponentAction(String s, ImageIcon i) {
2190         super(s, i);
2191       }
2192 
2193 
2194       /**
2195        *  It saves the current component --maybe with a new name-- and replaces
2196        *  the corresponding component of the {@link #template current template}.
2197        *  The provided Gui is the {@link TemplateEditor.SaveAsComponentDialog
2198        *  SaveAsComponentDialog}.
2199        *
2200        * @param e Description of the Parameter
2201        */
2202       public void actionPerformed(ActionEvent e) {
2203         if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
2204           return;
2205         }
2206         int componentType = selectedTed.componentType;
2207         LetterComponent component = template.getComponent(componentType);
2208         if(saveComponentAs(component)) {
2209           template.getComponent(componentType).hasChanged = false;
2210         }
2211       }
2212     }
2213 
2214 
2215     /**
2216      *  Toggles selected text between Bold-nonBold.
2217      */
2218     class SetBoldAction
2219         implements ActionListener {
2220 
2221       public void actionPerformed(ActionEvent e) {
2222         MutableAttributeSet attr = new SimpleAttributeSet();
2223         StyleConstants.setBold(attr, btnBold.isSelected());
2224         selectedTed.setAttributeSet(attr);
2225         selectedTed.grabFocus();
2226       }
2227     }
2228 
2229 
2230     /**
2231      *  Toggles selected text between Italic-nonItalic.
2232      */
2233     class SetItalicAction
2234         implements ActionListener {
2235 
2236       public void actionPerformed(ActionEvent e) {
2237         MutableAttributeSet attr = new SimpleAttributeSet();
2238         StyleConstants.setItalic(attr, btnItalic.isSelected());
2239         selectedTed.setAttributeSet(attr);
2240         selectedTed.grabFocus();
2241       }
2242     }
2243 
2244 
2245     /**
2246      *  Toggles selected text between Underlined-non Underlined.
2247      */
2248     class SetUnderlineAction
2249         implements ActionListener {
2250 
2251       public void actionPerformed(ActionEvent e) {
2252         MutableAttributeSet attr = new SimpleAttributeSet();
2253         StyleConstants.setUnderline(attr, btnUnderline.isSelected());
2254         selectedTed.setAttributeSet(attr);
2255         selectedTed.grabFocus();
2256       }
2257     }
2258 
2259 
2260     /**
2261      *  Action bound to the {@link TemplateEditor.EditorStuff#btnImg btnImg}
2262      *  button. When pressed, an image can be inserted in text from a list of
2263      *  accessible images in the data base. The provided Gui is a standard
2264      *  JOptionPane.
2265      *
2266      * @author InstantBank (Rodrigo Lopez).
2267      * @created September 2002
2268      */
2269     class InsertImageAction extends AbstractAction {
2270 
2271       /**
2272        *  InsertImageAction Constructor.
2273        *
2274        * @param s Tip to be shown when browsing over the {@link
2275        *      TemplateEditor.EditorStuff#btnSave btnSave} button.
2276        * @param i Image inside the button.
2277        */
2278       InsertImageAction(String s, ImageIcon i) {
2279         super(s, i);
2280       }
2281 
2282 
2283       public void actionPerformed(ActionEvent e) {
2284         if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
2285           return;
2286         }
2287         if(remoteImages == null) {
2288           JOptionPane.showMessageDialog(TemplateEditor.this,
2289             "There are no available images",
2290             "Warning",
2291             JOptionPane.WARNING_MESSAGE);
2292           return;
2293         }
2294 
2295         String result = (String)JOptionPane.showInputDialog(
2296           null, "Choose an image",
2297           "Choosing an Image",
2298           JOptionPane.QUESTION_MESSAGE, null,
2299           remoteImages, remoteImages[0]);
2300 
2301         try {
2302           if(result != null) {
2303             byte[] imageFromDB = proxy.loadImageRepository(result);
2304             if(imageFromDB == null) {
2305               JOptionPane.showConfirmDialog(
2306                 null, "Seems like the image is no longer in the data base");
2307               return;
2308             }
2309             int p = selectedTed.getCaretPosition();
2310             selectedTed.insertImage(p, imageFromDB);
2311           }
2312         }
2313         catch(Exception ex) {
2314           //MessageFrame.getFrame().addText("In InsertImageAction\n" +
2315           //    ex.toString());
2316         }
2317 
2318       }
2319     }
2320 
2321 
2322     /**
2323      *  MarginsAction. Launches the Margin Dialog that allows to
2324      *  define values for the 4 standard margins of a template.
2325      *
2326      * @author Instantbank (Rodrigo Lopez)
2327      * @created August 2002
2328      */
2329     class MarginsAction extends AbstractAction {
2330 
2331       /**
2332        *  MarginsAction Constructor.
2333        *
2334        * @param s Tip to be shown when browsing over the {@link
2335        *      TemplateEditor.EditorStuff#btnPreview btnPreview} button.
2336        * @param i Image inside the button.
2337        */
2338       MarginsAction(String s, ImageIcon i) {
2339         super(s, i);
2340       }
2341 
2342 
2343       public void actionPerformed(ActionEvent e) {
2344         int[] answer = new int[5];
2345 
2346         MarginDialog mDlg = new MarginDialog(answer,
2347           template.getLeftMargin(),
2348           template.getRightMargin(),
2349           template.getTopMargin(),
2350           template.getBottomMargin());
2351 
2352         mDlg.setTitle("Margins Size (in inches)");
2353         mDlg.setLocationRelativeTo(TemplateEditor.this);
2354         mDlg.show();
2355         if(answer[0] == JOptionPane.OK_OPTION) {
2356           template.setLeftMargin(answer[1]);
2357           template.setRightMargin(answer[2]);
2358           template.setTopMargin(answer[3]);
2359           template.setBottomMargin(answer[4]);
2360           template.outOfDate();
2361         }
2362         else {  //Cancel
2363 
2364         }
2365       }
2366     }
2367 
2368 
2369     /**
2370      *  PreviewAction
2371      *
2372      * @author Instantbank (Rodrigo Lopez)
2373      * @created August 2002
2374      */
2375     class PreviewAction extends AbstractAction {
2376 
2377       /**
2378        *  PreviewAction Constructor.
2379        *
2380        * @param s Tip to be shown when browsing over the {@link
2381        *      TemplateEditor.EditorStuff#btnPreview btnPreview} button.
2382        * @param i Image inside the button.
2383        */
2384       PreviewAction(String s, ImageIcon i) {
2385         super(s, i);
2386       }
2387 
2388 
2389       public void actionPerformed(ActionEvent e) {
2390         if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
2391           return;
2392         }
2393 
2394         if(template.hasChanged()
2395           || template.getCode() == LetterTemplateGlobals.UNDEF
2396           || template.getHeader().getCode() == LetterTemplateGlobals.UNDEF
2397           || template.getBody().getCode() == LetterTemplateGlobals.UNDEF
2398           || template.getClosing().getCode() == LetterTemplateGlobals.UNDEF) {
2399 
2400           JOptionPane.showMessageDialog(
2401             null, "The template must be saved before being previewed");
2402           return;
2403         }
2404 
2405         String strTemplateCode = "" + template.getCode();
2406 
2407         String pdfServletUrl = shortenUrl(getCodeBase().toExternalForm(), 2);
2408         pdfServletUrl +=
2409           "lettertemplate/templatePreview/pdfShowServlet?viewableType=TEMPLATE"
2410           + "&viewableCode=" + strTemplateCode
2411           + "&loanCode=DUMMY"
2412           + "&num=" + new Date().getTime();
2413         try {
2414           getAppletContext().showDocument(new URL(pdfServletUrl), "_blank");
2415         }
2416         catch(MalformedURLException ex) {
2417         }
2418       }
2419     }
2420 
2421 
2422     /**
2423      *  Exit from the editor.
2424      */
2425     class GoHomeAction extends AbstractAction {
2426 
2427       /**
2428        *  GoHomeAction Constructor.
2429        *
2430        * @param s Tip to be shown when browsing over the {@link
2431        *      TemplateEditor.EditorStuff#btnHome btnHome} button.
2432        * @param i Image inside the button.
2433        */
2434       GoHomeAction(String s, ImageIcon i) {
2435         super(s, i);
2436       }
2437 
2438 
2439       public void actionPerformed(ActionEvent e) {
2440         if(proxy.controlTimeout(TemplateEditor.this.getAppletContext())) {
2441           return;
2442         }
2443         if(template.hasChanged()) {
2444           int option =
2445             JOptionPane.showConfirmDialog(
2446             null, "Do you want to save the current template ?",
2447             "Saving before going home",
2448             JOptionPane.YES_NO_CANCEL_OPTION);
2449 
2450           switch (option) {
2451             case JOptionPane.YES_OPTION:
2452               saveTemplate();
2453               break;
2454             case JOptionPane.NO_OPTION:
2455               break;
2456             case JOptionPane.CANCEL_OPTION:
2457               return;
2458             default:
2459           }
2460         }
2461 
2462         TemplateEditor.this.goHome();
2463 
2464       }
2465     }
2466 
2467 
2468 
2469     /**
2470      *  Test class: sends rtf text to servlet and saves it in a fixed file.
2471      */
2472     class SaveRawRtfAction extends AbstractAction {
2473 
2474       /**
2475        *  Debug action. For intern usage.
2476        *
2477        * @param s
2478        * @param i
2479        */
2480       public SaveRawRtfAction(String s, ImageIcon i) {
2481         super(s, i);
2482       }
2483 
2484 
2485       public void actionPerformed(ActionEvent e) {
2486 
2487         String content = selectedTed.toRtfString();
2488       }
2489     }
2490 
2491 
2492     /**
2493      *  Extra Action for debugging purposes.
2494      */
2495     class ExtraAction extends AbstractAction {
2496 
2497       ExtraAction(String s, ImageIcon i) {
2498         super(s, i);
2499       }
2500 
2501 
2502       public void actionPerformed(ActionEvent e) {
2503 
2504         String JobServletUrl = shortenUrl(getCodeBase().toExternalForm(), 2);
2505         JobServletUrl +=
2506           "lettertemplate/letterjobServlet" + "?num=" + new Date().getTime();
2507         try {
2508           getAppletContext().showDocument(new URL(JobServletUrl), "_blank");
2509         }
2510         catch(MalformedURLException ex) {
2511         }
2512         // Remember there is an extraservice.
2513         //Object answer = proxy.extraservice();
2514       }
2515     }
2516 
2517 
2518     /**
2519      *  Test class: Echoes the position of images and variables in the selected
2520      *  component.
2521      */
2522     class TraceImgVarsAction extends AbstractAction {
2523       public TraceImgVarsAction(String s, ImageIcon i) {
2524         super(s, i);
2525       }
2526 
2527 
2528       public void actionPerformed(ActionEvent e) {
2529         selectedTed.echoVarsImages();
2530 
2531       }
2532     }
2533 
2534   }
2535 
2536 
2537   //End of EditorStuff class.
2538 
2539   /**
2540    *  Actual Editor for the template's components. One instance of this class is
2541    *  needed for each template's component. It provides the required edition
2542    *  services.
2543    *
2544    * @author InstantBank (Rodrigo Lopez)
2545    * @created September 2002
2546    */
2547   class ComponentEditor extends JTextPane {
2548 
2549     /**
2550      *  Context manager for the Elements' attributes.
2551      */
2552     protected StyleContext context;
2553     /**
2554      *  Document model for this editor.
2555      */
2556     protected DefaultStyledDocument doc;
2557     /**
2558      *  Editor "kit" for this editor.
2559      */
2560     protected RTFEditorKit kit;
2561 
2562     /**
2563      *  Starting point of the current selection.
2564      */
2565     protected int xStart = -1;
2566     /**
2567      *  Final point of the current selection.
2568      */
2569     protected int xFinish = -1;
2570 
2571     /**
2572      *  Type of LetterComponent edited by this editor.
2573      */
2574     int componentType;
2575 
2576 
2577     /**
2578      *  Constructor for the ComponentEditor object
2579      *
2580      * @param type Print type of the component: Laser, typewritter.
2581      */
2582     ComponentEditor(int type) {
2583       componentType = type;
2584 
2585       kit = new RTFEditorKit();
2586       this.setEditorKit(kit);
2587       context = new StyleContext();
2588       doc = new DefaultStyledDocument(context);
2589       this.setDocument(doc);
2590       docClipboard = new DefaultStyledDocument(new StyleContext());
2591 
2592       setupKeymap();
2593 
2594       CaretListener lst =
2595         new CaretListener() {
2596           public void caretUpdate(CaretEvent e) {
2597             showAttributes(e.getDot());
2598           }
2599         };
2600       this.addCaretListener(lst);
2601 
2602       FocusListener flst =
2603         new FocusListener() {
2604           public void focusGained(FocusEvent e) {
2605             if(xStart >= 0 && xFinish >= 0) {
2606               if(ComponentEditor.this.getCaretPosition() == xStart) {
2607                 ComponentEditor.this.setCaretPosition(xFinish);
2608                 ComponentEditor.this.moveCaretPosition(xStart);
2609               }
2610               else {
2611                 ComponentEditor.this.select(xStart, xFinish);
2612               }
2613             }
2614           }
2615 
2616 
2617           public void focusLost(FocusEvent e) {
2618             xStart = ComponentEditor.this.getSelectionStart();
2619             xFinish = ComponentEditor.this.getSelectionEnd();
2620           }
2621         };
2622 
2623       MouseListener msl = new VariableInsertAction();
2624 
2625       this.addFocusListener(flst);
2626       this.addMouseListener(msl);
2627 
2628       doc.addDocumentListener(new DocumentChange());
2629 
2630     }  // End of ComponentEditor() constructor.
2631 
2632 
2633     /**
2634      *  Signals changes occurred to the document under this editor, setting the
2635      *  {@link com.instantbank.component.lettertemplate.util.LetterComponent#hasChanged
2636      *  hasChanged} attribute of the corresponding component.
2637      */
2638     class DocumentChange
2639         implements DocumentListener {
2640       /**
2641        * Puts the template in "out of date" status.
2642        *
2643        * @param e Description of the Parameter
2644        */
2645       public void insertUpdate(DocumentEvent e) {
2646         template.getComponent(componentType).hasChanged = true;
2647       }
2648 
2649 
2650       /**
2651        * Puts the template in "out of date" status.
2652        *
2653        * @param e Description of the Parameter
2654        */
2655       public void removeUpdate(DocumentEvent e) {
2656         template.getComponent(componentType).hasChanged = true;
2657       }
2658 
2659 
2660       /**
2661        * Puts the template in "out of date" status.
2662        *
2663        * @param e Description of the Parameter
2664        */
2665       public void changedUpdate(DocumentEvent e) {
2666         template.getComponent(componentType).hasChanged = true;
2667       }
2668 
2669     }
2670 
2671 
2672     /**
2673      *  Implements variable insertion at caret position, via right mouse click
2674      *  and if there is a selected leaf in the tree of variables.
2675      */
2676     class VariableInsertAction extends MouseAdapter {
2677 
2678       /**
2679        *  Implements variable insertion at caret position, via right mouse click
2680        *  and if there is a selected leaf in the tree of variables.
2681        *
2682        * @param e Description of the Parameter
2683        */
2684       public void mouseClicked(MouseEvent e) {
2685 
2686         proxy.controlTimeout(TemplateEditor.this.getAppletContext());
2687         Long delta = LetterTemplateGlobals.VOIDELTA;
2688 
2689         if(SwingUtilities.isRightMouseButton(e)) {
2690           TreePath[] tps = jtrVariables.getSelectionPaths();
2691           if(tps != null) {
2692             Object s = tps[0].getLastPathComponent();
2693             if(jtrVariables.getModel().isLeaf(s)) {
2694               int p = selectedTed.getCaretPosition();
2695               Long varCode = varManager.getCode(s.toString());
2696               String varType = varManager.getType(varCode);
2697               String offsetType = varManager.getOffsetType(varCode);
2698 
2699               Long varFormat = null;
2700               if(varType.equals(LetterTemplateGlobals.FIELD_STRING)) {
2701                 varFormat = new Long(varManager.DEFAULT_STRING_FORMAT);
2702               }
2703               else if(varType.equals(LetterTemplateGlobals.FIELD_NUMERIC)) {
2704                 varFormat = new Long(varManager.DEFAULT_NUMBER_FORMAT);
2705                 //it is a date
2706               }
2707               else {
2708                 varFormat = new Long(varManager.DEFAULT_DATE_FORMAT);
2709                 if(!offsetType.equals(LetterTemplateGlobals.NO_OFFSET)) {
2710                   delta = deltaDialog(varCode, offsetType);
2711                 }
2712               }
2713 
2714               insertVariable(p, varCode, varFormat, delta);
2715               //jtrVariables.clearSelection();
2716             }
2717           }
2718         }
2719       }
2720     }
2721 
2722 
2723     /**
2724      * Captures the value of an offset to be applied to a date, measured
2725      * in days.
2726      *
2727      * @param varCode Code of the date variable.
2728      * @param offsetType "workable" or "chronological".
2729      * @return The offset as a Long object.
2730      */
2731     private Long deltaDialog(Long varCode, String offsetType) {
2732       Object[] answer = new Object[2];
2733       String varName = varManager.getName(varCode);
2734       DeltaDialog dDlg = new DeltaDialog(answer);
2735       dDlg.setTitle("Getting Date Offset");
2736       dDlg.setHeader("Days Offset for: " + varName);
2737       String subTitle =
2738         offsetType.equals(LetterTemplateGlobals.WORKABLE_DAYS_OFFSET) ?
2739         "(workable days)" : "(chronological days)";
2740       dDlg.setSubHeader(subTitle);
2741       dDlg.setUnits("days");
2742       dDlg.setLocationRelativeTo(TemplateEditor.this);
2743       dDlg.show();
2744       if(answer[0] != null) {  // OK was pressed
2745         return (Long)answer[1];
2746       }
2747       else {
2748         return LetterTemplateGlobals.VOIDELTA;
2749       }
2750     }
2751 
2752 
2753     /**
2754      *  Inserts a variable at a position in the document. VARCODE, VARFORMAT
2755      *  DATEDELTA attributes are
2756      *  bound to the "display representation" of the variable.
2757      *
2758      * @param pos Position of the variable
2759      * @param varCode Code of the inserted variable
2760      * @param varFormat Printing format when the variable is substituted
2761      *                   for an actual value.
2762      * @param delta Date offset (in days) for the variable. Makes sense only
2763      *         if the variable is of Date type.
2764      */
2765     public void insertVariable(int pos, Long varCode, Long varFormat, Long delta) {
2766       try {
2767 
2768         //Creates attribute to be attached to the variable mark.
2769         MutableAttributeSet attr = new SimpleAttributeSet();
2770         JLabel var = new JLabel(buildGuiVarName(varCode, delta));
2771         var.setForeground(varColor);
2772         var.setBorder(BorderFactory.createLineBorder(varColor, 1));
2773         var.setVerticalAlignment(SwingConstants.TOP);
2774         StyleConstants.setComponent(attr, var);
2775         attr.addAttribute(VARCODE, varCode);
2776         attr.addAttribute(VARFORMAT, varFormat);
2777         attr.addAttribute(DATEDELTA, delta);
2778 
2779         doc.insertString(pos, varChar, attr);
2780       }
2781       catch(BadLocationException bed) {
2782         //MessageFrame.getFrame().addText("Bad Location for insert var.");
2783         bed.printStackTrace();
2784       }
2785     }
2786 
2787 
2788     /**
2789      * Delivers the name for a Date variable as shown in the user iterface.
2790      * The actual name ends with a + or - offset suffix.
2791      *
2792      * @param varCode Variable's code.
2793      * @param delta The date offset in days (workable or chronological).
2794      * @return Description of the Return Value
2795      */
2796     private String buildGuiVarName(Long varCode, Long delta) {
2797       ArrayList varSlot = varManager.assocCode(varCode);
2798       String name = (String)varSlot.get(VariablesManager.NAME);
2799 
2800       if(delta.equals(LetterTemplateGlobals.VOIDELTA)) {
2801         return name;
2802       }
2803 
2804       String offType = (String)varSlot.get(VariablesManager.OFFSET);
2805 
2806       //Calculates a suffix for the offset figure.
2807       String suffix;
2808       if(offType.equals(LetterTemplateGlobals.CHRONO_DAYS_OFFSET)) {
2809         suffix = "C";
2810       }
2811       else if(offType.equals(LetterTemplateGlobals.WORKABLE_DAYS_OFFSET)) {
2812         suffix = "W";
2813       }
2814       else {
2815         suffix = "";
2816       }
2817 
2818       //Calculates the final name
2819       long val = delta.longValue();
2820 
2821       if(val > 0) {
2822         return name + " + " + val + suffix;
2823       }
2824       else {
2825         return name + " - " + (-val) + suffix;
2826       }
2827     }
2828 
2829 
2830     /**
2831      *  Inserts an image at the specified position inside this ComponentEditor.
2832      *
2833      * @param pos Position in the text
2834      * @param image Raw bytes of the image
2835      */
2836     public void insertImage(int pos, byte[] image) {
2837       try {
2838         ImageIcon icon = new ImageIcon(image);
2839 
2840         if(icon == null) {
2841           JOptionPane.showMessageDialog(TemplateEditor.this,
2842             "Error building an image icon\n",
2843             "Warning",
2844             JOptionPane.WARNING_MESSAGE);
2845           return;
2846         }
2847 
2848         int w = icon.getIconWidth();
2849         int h = icon.getIconHeight();
2850         if(w <= 0 || h <= 0) {
2851           JOptionPane.showMessageDialog(TemplateEditor.this,
2852             "Error building an image icon\n",
2853             "Warning",
2854             JOptionPane.WARNING_MESSAGE);
2855           return;
2856         }
2857         MutableAttributeSet attr = new SimpleAttributeSet();
2858         StyleConstants.setIcon(attr, icon);
2859         attr.addAttribute(ICONBYTES, image);
2860         doc.insertString(pos, imgChar, attr);
2861 
2862       }
2863       catch(Exception ex) {
2864         //MessageFrame.getFrame().addText("In insertImage\n" +
2865         //ex.toString());
2866       }
2867     }
2868 
2869 
2870     /**
2871      *  Sets up the keymap in order to capture Ctrl-C, Ctrl-X and Ctr-V
2872      *  keystrokes and make copy-cut-paste with attributes.
2873      */
2874 
2875     public void setupKeymap() {
2876       Keymap locKeymap = this.addKeymap("locKeymap", this.getKeymap());
2877       this.setKeymap(locKeymap);
2878 
2879       Action copyAction =
2880         new AbstractAction() {
2881           public void actionPerformed(ActionEvent ev) {
2882             copyWithAttr();
2883           }
2884         };
2885 
2886       Action cutAction =
2887         new AbstractAction() {
2888           public void actionPerformed(ActionEvent ev) {
2889             cutWithAttr();
2890           }
2891         };
2892 
2893       Action pasteAction =
2894         new AbstractAction() {
2895           public void actionPerformed(ActionEvent ev) {
2896             pasteWithAttr();
2897           }
2898         };
2899 
2900       locKeymap.addActionForKeyStroke(KeyStroke.getKeyStroke(
2901         KeyEvent.VK_C, Event.CTRL_MASK), copyAction);
2902       locKeymap.addActionForKeyStroke(KeyStroke.getKeyStroke(
2903         KeyEvent.VK_X, Event.CTRL_MASK), cutAction);
2904       locKeymap.addActionForKeyStroke(KeyStroke.getKeyStroke(
2905         KeyEvent.VK_V, Event.CTRL_MASK), pasteAction);
2906     }
2907 
2908 
2909     /**
2910      *  Calculates the RTF representation of a document.
2911      *
2912      * @param doc The document the RTF representations is calculated for.
2913      * @return A String containing the RTF representation of the document.
2914      */
2915     public String toRtfString(DefaultStyledDocument doc) {
2916       String resp = null;
2917       try {
2918         ByteArrayOutputStream out = new ByteArrayOutputStream();
2919         kit.write(out, doc, 0, doc.getLength());
2920         out.close();
2921         resp = out.toString();
2922       }
2923       catch(Exception ex) {
2924         //MessageFrame.getFrame().addText("Exception writing component\n" +
2925         //ex.toString());
2926       }
2927 
2928       return resp;
2929     }
2930 
2931 
2932     /**
2933      *  Calculates the RTF representation of the text contained in this editor's
2934      *  {@link #doc document}.
2935      *
2936      * @return A String containing the RTF representation.
2937      */
2938     public String toRtfString() {
2939       return toRtfString(this.doc);
2940     }
2941 
2942 
2943     /**
2944      *  Copy the selected text --with attributes-- to the {@link #docClipboard
2945      *  local clipboard}.
2946      */
2947     public void copyWithAttr() {
2948       int start = getSelectionStart();
2949       int end = getSelectionEnd();
2950 
2951       //MessageFrame.getFrame().addText(whoAmI());
2952       try {
2953         if(end > start) {
2954           docClipboard.remove(0, docClipboard.getLength());
2955           for(int pos = start, posClip = 0; pos < end; pos++, posClip++) {
2956             String c = doc.getText(pos, 1);
2957             AttributeSet atr = doc.getCharacterElement(pos).getAttributes();
2958             docClipboard.insertString(posClip, c, atr);
2959           }
2960         }
2961       }
2962       catch(BadLocationException ble) {
2963         //MessageFrame.getFrame().addText("Copying with attributes ...");
2964         //MessageFrame.getFrame().addText(ble.toString());
2965       }
2966     }
2967 
2968 
2969     /**
2970      *  Cut the selected text and copy it --with attributes-- to the {@link
2971      *  #docClipboard local clipboard}.
2972      */
2973     public void cutWithAttr() {
2974       int start = getSelectionStart();
2975       int end = getSelectionEnd();
2976 
2977       if(end > start) {
2978         copyWithAttr();
2979         try {
2980           doc.remove(start, end - start);
2981         }
2982         catch(BadLocationException ble) {
2983           //MessageFrame.getFrame().addText("Cutting with attributes ...");
2984           //MessageFrame.getFrame().addText(ble.toString());
2985         }
2986 
2987       }
2988     }
2989 
2990 
2991     /**
2992      *  Paste the {@link #docClipboard local clipboard} text --with attributes--
2993      *  to the selected region.
2994      */
2995     public void pasteWithAttr() {
2996       if(docClipboard.getLength() == 0) {
2997         return;
2998       }
2999 
3000       int start = getSelectionStart();
3001       int end = getSelectionEnd();
3002       //MessageFrame.getFrame().addText(whoAmI());
3003       //Removing selected region
3004       if(end > start) {
3005         try {
3006           doc.remove(start, end - start);
3007         }
3008         catch(BadLocationException blex) {
3009           //MessageFrame.getFrame().addText("Cutting while pasting with attributes ...");
3010           //MessageFrame.getFrame().addText(blex.toString());
3011         }
3012       }
3013 
3014       //Pasting at start of the selected region
3015       try {
3016         for(int posClip = 0, posDoc = start;
3017           posClip < docClipboard.getLength();
3018           posClip++, posDoc++) {
3019           String c = docClipboard.getText(posClip, 1);
3020           AttributeSet atr = docClipboard.getCharacterElement(posClip).getAttributes();
3021           doc.insertString(posDoc, c, atr);
3022         }
3023       }
3024       catch(BadLocationException ble) {
3025         //MessageFrame.getFrame().addText("Pasting with attributes ...");
3026         //MessageFrame.getFrame().addText(ble.toString());
3027       }
3028     }
3029 
3030 
3031     /**
3032      *  Calculates a clone of the editor's doc where variables are substituted
3033      *  by a "varChar" and a suitable VARCODE attribute. It is not associated to
3034      *  any editorKit, so it can be manipulated with no visual effect on the
3035      *  user interface.
3036      *
3037      * @return The calculated clone.
3038      */
3039     public DefaultStyledDocument cloneDoc() {
3040       DefaultStyledDocument cdoc = new DefaultStyledDocument();
3041       int cpos = 0;
3042       int pos = 0;
3043       try {
3044         String s = this.doc.getText(0, doc.getLength());
3045         while(pos < s.length()) {
3046 
3047           AttributeSet atrObj = doc.getCharacterElement(pos).getAttributes();
3048           MutableAttributeSet satr = (MutableAttributeSet)atrObj;
3049           if(satr.isDefined(VARCODE)) {
3050             cdoc.insertString(cpos, varChar, atrObj);
3051             cpos++;
3052             pos++;
3053             atrObj = doc.getCharacterElement(pos).getAttributes();
3054             while(atrObj.isDefined(VARCODE)) {
3055               pos++;
3056               atrObj = doc.getCharacterElement(pos).getAttributes();
3057             }
3058           }
3059           else {
3060             String ss = s.substring(pos, pos + 1);
3061             cdoc.insertString(cpos, ss, atrObj);
3062             cpos++;
3063             pos++;
3064           }
3065         }
3066       }
3067       catch(BadLocationException ex) {
3068         //MessageFrame.getFrame().addText("In cloneDoc: \n" + ex.toString());
3069       }
3070       return cdoc;
3071     }
3072 
3073 
3074     /**
3075      *  Calculates a trace of the variables in a 'clone' of this.document. See
3076      *  {@link TemplateEditor.ComponentEditor#cloneDoc() cloneDoc()} method.
3077      *
3078      * @return A set (Hashtable) of < position, code-of-variable,
3079      *           code-of-format > tuples.
3080      */
3081     public ArrayList traceVariables() {
3082       return traceVariables(cloneDoc());
3083     }
3084 
3085 
3086     /**
3087      *  Calculates a trace of the variables in a 'cloned' document.
3088      *
3089      * @param doc The cloned document that contains the variables. See {@link
3090      *      #cloneDoc() cloneDoc} method.
3091      * @return A set (Hashtable) of < position, code-of-variable, format
3092      *      > tuples.
3093      */
3094     public ArrayList traceVariables(DefaultStyledDocument doc) {
3095       ArrayList trace = new ArrayList();
3096       try {
3097         String s = doc.getText(0, doc.getLength());
3098 
3099         for(
3100           int searchIndex = 0,
3101           pos = s.indexOf(varChar, searchIndex);
3102           pos >= 0;
3103           searchIndex = pos + 1,
3104           pos = s.indexOf(varChar, searchIndex)) {
3105 
3106           AttributeSet atrObj = doc.getCharacterElement(pos).getAttributes();
3107           MutableAttributeSet satr = (MutableAttributeSet)atrObj;
3108           if(satr.isDefined(VARCODE)) {
3109             ArrayList slot = new ArrayList(3);
3110             slot.add(new Integer(pos));
3111             slot.add(satr.getAttribute(VARCODE));
3112             slot.add(satr.getAttribute(VARFORMAT));
3113             slot.add(satr.getAttribute(DATEDELTA));
3114             trace.add(slot);
3115           }
3116         }
3117 
3118       }
3119       catch(BadLocationException ble) {
3120         //MessageFrame.getFrame().addText("*** In traceVariables ****\n" +
3121         //ble.toString());
3122       }
3123       catch(Exception ex) {
3124         //MessageFrame.getFrame().addText("*** In traceVariables ****\n" +
3125         //ex.toString());
3126       }
3127       finally {
3128         return trace;
3129       }
3130     }
3131 
3132 
3133     /**
3134      *  Calculates a trace of the images in the document tied to this
3135      *  ComponentEditor.
3136      *
3137      * @return a ArrayList containing <position,iconbytes> pairs. These
3138      *      pairs record the position of each image in the document. The
3139      *      'iconbytes' value is the value of the {@link #ICONBYTES ICONBYTES}
3140      *      attribute that was inserted whith the image.
3141      * @author InstantBank (Rodrigo Lopez)
3142      */
3143     public ArrayList traceImages() {
3144       return traceImages(this.doc);
3145     }
3146 
3147 
3148     /**
3149      *  Calculates a trace of the images in a document.
3150      *
3151      * @param doc The document the trace of images is calculated for.
3152      * @return a Hashtable containing <position,iconbytes> pairs. These
3153      *      pairs record the position of each image in the document. The
3154      *      'iconbytes' value is the value of the {@link #ICONBYTES ICONBYTES}
3155      *      attribute that was inserted whith the image which currently is an
3156      *      array with the raw bytes of the image.
3157      * @author InstantBank (Rodrigo Lopez)
3158      */
3159     public ArrayList traceImages(DefaultStyledDocument doc) {
3160       ArrayList trace = new ArrayList();
3161       try {
3162         String s = doc.getText(0, doc.getLength());
3163 
3164         for(
3165           int searchIndex = 0,
3166           pos = s.indexOf(imgChar, searchIndex);
3167           pos >= 0;
3168           searchIndex = pos + 1,
3169           pos = s.indexOf(imgChar, searchIndex)) {
3170 
3171           AttributeSet atrObj = doc.getCharacterElement(pos).getAttributes();
3172 
3173           MutableAttributeSet satr = (MutableAttributeSet)atrObj;
3174           if(satr.isDefined(StyleConstants.IconAttribute)) {
3175             ArrayList slot = new ArrayList(2);
3176             slot.add(new Integer(pos));
3177             slot.add(satr.getAttribute(ICONBYTES));
3178             trace.add(slot);
3179           }
3180         }
3181       }
3182       catch(BadLocationException ble) {
3183         //MessageFrame.getFrame().addText("*** In traceImages ****\n" +
3184         //ble.toString());
3185       }
3186       catch(Exception ex) {
3187         //MessageFrame.getFrame().addText("*** In traceImages ****\n" +
3188         //ex.toString());
3189       }
3190       finally {
3191         return trace;
3192       }
3193     }
3194 
3195 
3196     /**
3197      *  Debug method, it echoes the trace of images and variables contained in
3198      *  the document.
3199      */
3200     public void echoVarsImages() {
3201       //DefaultStyledDocument ldoc = cloneDoc();
3202       ArrayList traceImg = traceImages(this.doc);
3203       ArrayList traceVars = traceVariables(this.doc);
3204       echoVars(traceVars);
3205     }
3206 
3207 
3208     /**
3209      *  Debug method. Shows the variables and their positions.
3210      *
3211      * @param trace The set of variables to be shown.
3212      */
3213     public void echoVars(ArrayList trace) {
3214       //MessageFrame.getFrame().addText("\nVarTrace = \n");
3215       for(int i = 0; i < trace.size(); i++) {
3216         ArrayList slot = (ArrayList)trace.get(i);
3217         Integer pos = (Integer)slot.get(0);
3218         Long varCode = (Long)slot.get(1);
3219         String name = varManager.getName(varCode);
3220         //MessageFrame.getFrame().addText(
3221         //"[ pos =" + pos + " , varCode = " + varCode + " " + name + " ]");
3222       }
3223     }
3224 
3225 
3226     /**
3227      *  Fills a letter component with the status of this ComponentEditor: the
3228      *  text, images and variables.
3229      *
3230      * @param comp The Letter Component to be filled.
3231      */
3232     public void fillLetterComponent(LetterComponent comp) {
3233       if(comp == null) {
3234         return;
3235       }
3236 
3237       //DefaultStyledDocument doc = cloneDoc();
3238       comp.setRtfText(toRtfString(this.doc));
3239       comp.setTraceImages(traceImages(this.doc));
3240       comp.setTraceVariables(traceVariables(this.doc));
3241       //MessageFrame.getFrame().addText(comp.traceVarsToString());
3242     }
3243 
3244 
3245     /**
3246      *  Shows the content of a LetterComponent in the text area of this
3247      *  ComponentEditor.
3248      *
3249      * @param comp The component to be displayed.
3250      */
3251     public void displayLetterComponent(LetterComponent comp) {
3252       if(comp == null) {
3253         return;
3254       }
3255 
3256       edtStuff.tabpane.setSelectedIndex(comp.getType() - 1);
3257 
3258       try {
3259         doc.remove(0, doc.getLength());
3260         ByteArrayInputStream buf =
3261           new ByteArrayInputStream(comp.getRtfText().getBytes());
3262         kit.read(buf, doc, 0);
3263 
3264         //Fixing a Swing bug:
3265         //Delete an eol character appended by kit when reading
3266         //the buf content into the doc.
3267         int lastPos = doc.getLength() - 1;
3268         if(lastPos >= 0) {
3269           String lastStr = doc.getText(lastPos, 1);
3270           if(lastStr.equals("\n")) {
3271             doc.remove(lastPos, 1);
3272           }
3273         }
3274       }
3275       catch(Exception ex) {
3276         JOptionPane.showMessageDialog(null,
3277           "The raw text part of the component can not be displayed");
3278         ex.printStackTrace();
3279         return;
3280       }
3281       ArrayList[] merge = comp.mergeVarsImages();
3282 
3283       for(int i = 0; i < merge.length; i++) {
3284         ArrayList slot = merge[i];
3285         String type = (String)slot.get(0);
3286         slot = (ArrayList)slot.get(1);
3287         int pos = ((Integer)slot.get(0)).intValue();
3288 
3289         if(type.equals(LetterComponent.IMGTYPE)) {
3290           displayImage(pos, (byte[])slot.get(1));
3291         }
3292         else {
3293           displayVariable(pos, slot);
3294         }
3295       }
3296     }
3297 
3298 
3299     /**
3300      *  Displays an image inside this ComponentEditor
3301      *
3302      * @param pos Position for insertion.
3303      * @param image The image to be displayed
3304      */
3305     public void displayImage(int pos, byte[] image) {
3306       try {
3307         ImageIcon icon = new ImageIcon(image);
3308         setCaretPosition(pos);
3309         //Otherwise the change will not be visible
3310         doc.remove(pos, 1);
3311         insertImage(pos, image);
3312       }
3313       catch(BadLocationException bed) {
3314         MessageFrame.getFrame().addText("Location problems displaying image");
3315         bed.printStackTrace();
3316       }
3317     }
3318 
3319 
3320     /**
3321      *  Displays a variable inside this ComponentEditor.
3322      *
3323      * @param pos Variable's position in the component
3324      * @param slot Variable's < --, code, format, delta>
3325      */
3326     public void displayVariable(int pos, ArrayList slot) {
3327       try {
3328         setCaretPosition(pos);
3329         doc.remove(pos, 1);
3330         Long varCode = (Long)slot.get(1);
3331         Long varFormat = (Long)slot.get(2);
3332         Long delta = (Long)slot.get(3);
3333         insertVariable(pos, varCode, varFormat, delta);
3334       }
3335       catch(BadLocationException bed) {
3336         MessageFrame.getFrame().addText("Location problems inserting variable");
3337         bed.printStackTrace();
3338       }
3339     }
3340 
3341 
3342     /**
3343      *  Removes the text displayed by this ComponentEditor.
3344      */
3345     public void clean() {
3346       try {
3347         doc.remove(0, doc.getLength());
3348         xStart = 0;
3349         xFinish = 0;
3350         this.select(0, 0);
3351       }
3352       catch(Exception ex) {
3353         ex.printStackTrace();
3354       }
3355     }
3356 
3357 
3358     /**
3359      *  Establishes an initial --void-- selection of the text displayed by this
3360      *  ComponentEditor. See {@link TemplateEditor.ComponentEditor#xStart} and
3361      *  {@link TemplateEditor.ComponentEditor#xFinish}.
3362      */
3363     public void initSelection() {
3364       xStart = 0;
3365       xFinish = 0;
3366       this.select(0, 0);
3367     }
3368 
3369 
3370     /**
3371      *  Updates the display of the attributes of the selected component on the
3372      *  corresponding controls.
3373      *
3374      * @param p Position in the document.
3375      */
3376     protected void showAttributes(int p) {
3377       skipUpdate = true;
3378       AttributeSet a = doc.getCharacterElement(p).getAttributes();
3379 
3380       String name = StyleConstants.getFontFamily(a);
3381       if(!fontName.equals(name)) {
3382         fontName = name;
3383         lbccFont.getBigCombo().setSelectedItem(name);
3384       }
3385       int size = StyleConstants.getFontSize(a);
3386       if(fontSize != size) {
3387         fontSize = size;
3388         lbccFont.getSmallCombo().setSelectedItem(Integer.toString(fontSize));
3389       }
3390       boolean bold = StyleConstants.isBold(a);
3391       if(bold != edtStuff.btnBold.isSelected()) {
3392         edtStuff.btnBold.setSelected(bold);
3393       }
3394       boolean italic = StyleConstants.isItalic(a);
3395       if(italic != edtStuff.btnItalic.isSelected()) {
3396         edtStuff.btnItalic.setSelected(italic);
3397       }
3398 
3399       boolean underline = StyleConstants.isUnderline(a);
3400       if(underline != edtStuff.btnUnderline.isSelected()) {
3401         edtStuff.btnUnderline.setSelected(underline);
3402       }
3403 
3404       //Variables Format refreshing
3405       try {
3406         String s = doc.getText(p, 1);
3407         if(s.equals(varChar) && a.isDefined(VARFORMAT)) {
3408           long format = ((Long)a.getAttribute(VARFORMAT)).longValue();
3409           varFormat = format;
3410           lbcFormat.getCombo().setSelectedIndex(
3411             CodeDescription.getIndexCode(varFormat, varFormats));
3412           lbcFormat.getCombo().setEnabled(true);
3413         }
3414         else {
3415           varFormat = VariablesManager.DEFAULT_STRING_FORMAT;
3416           lbcFormat.getCombo().setSelectedIndex(
3417             CodeDescription.getIndexCode(varFormat, varFormats));
3418           lbcFormat.getCombo().setEnabled(false);
3419         }
3420       }
3421       catch(BadLocationException bex) {
3422         if(varFormat != VariablesManager.DEFAULT_STRING_FORMAT) {
3423           varFormat = VariablesManager.DEFAULT_STRING_FORMAT;
3424           lbcFormat.getCombo().setSelectedIndex(
3425             CodeDescription.getIndexCode(varFormat, varFormats));
3426         }
3427         lbcFormat.getCombo().setEnabled(false);
3428       }
3429       skipUpdate = false;
3430     }
3431 
3432 
3433     /**
3434      *  Sets the attributes for the selected portion of the text.
3435      *
3436      * @param attr The values of the attributes
3437      */
3438     protected void setAttributeSet(AttributeSet attr) {
3439 
3440       if(skipUpdate) {
3441         return;
3442       }
3443 
3444       int start = this.getSelectionStart();
3445       int finish = this.getSelectionEnd();
3446 
3447       if(!this.hasFocus()) {
3448         start = xStart;
3449         finish = xFinish;
3450       }
3451 
3452       if(start != finish) {
3453         doc.setCharacterAttributes(start, finish - start,
3454           attr, false);
3455       }
3456       else {
3457         MutableAttributeSet inputAttributes =
3458           kit.getInputAttributes();
3459         inputAttributes.addAttributes(attr);
3460       }
3461     }
3462 
3463 
3464     /**
3465      *  Sets the variable format attribute for the character at the start of the
3466      *  selected region. If the caracter just after the cursor is not a "variable
3467      *  mark"
3468      *  this method has no effect.
3469      *
3470      * @param format Code of the variable format.
3471      */
3472     protected void setVarFormatAttribute(Long format) {
3473       if(skipUpdate) {
3474         return;
3475       }
3476 
3477       int start = this.getSelectionStart();
3478       this.setSelectionEnd(start);
3479       xStart = xFinish = start;
3480 
3481       AttributeSet atrObj = doc.getCharacterElement(start).getAttributes();
3482 
3483       if(atrObj.isDefined(VARCODE)) {
3484         try {
3485           doc.remove(start, 1);
3486           insertVariable(start, (Long)atrObj.getAttribute(VARCODE),
3487             format, (Long)atrObj.getAttribute(DATEDELTA));
3488         }
3489         catch(BadLocationException ex) {
3490           //MessageFrame.getFrame().addText("BadLOcation.");
3491           ex.printStackTrace();
3492         }
3493 
3494       }
3495     }
3496 
3497 
3498     /**
3499      *  Debug method that identifies this ComponentEditor among the three
3500      *  possibilities: header, body, closing.
3501      *
3502      * @return The name of component's type.
3503      */
3504     public String whoAmI() {
3505       String res = "";
3506       if(this == edtStuff.editors[0]) {
3507         res += "Header and ";
3508       }
3509       else if(this == edtStuff.editors[1]) {
3510         res += "Body and ";
3511       }
3512       else if(this == edtStuff.editors[2]) {
3513         res += "Closing and ";
3514       }
3515       else {
3516         res += "Don't know who am I";
3517       }
3518 
3519       if(this == selectedTed) {
3520         res += "selected";
3521       }
3522       else {
3523         res += "unselected";
3524       }
3525 
3526       return res;
3527     }
3528 
3529   }
3530 
3531 
3532   // End of ComponentEditor class
3533 
3534   /**
3535    *  Gui that allows to capture/display --fully or partially-- the main
3536    *  attributes of a template: its category, its name, the name of its
3537    *  components. It doesn't deal with the text itself nor its images and
3538    *  variables.
3539    *
3540    * @author InstantBank (Rodrigo Lopez)
3541    * @created September 2002
3542    */
3543   class CategoryNameTemplateDialog extends JDialog {
3544 
3545     public static final int CATEGORY = LetterTemplateGlobals.CATEGORY;
3546 
3547     public static final int RESPONSE = LetterTemplateGlobals.RESPONSE;
3548 
3549     GridBagLayout grbgDialog = new GridBagLayout();
3550     JPanel pnlSup = new JPanel();
3551     JPanel pnlSupLeft = new JPanel();
3552     JPanel pnlSupRight = new JPanel();
3553     JPanel pnlInf = new JPanel();
3554     JPanel pnlCtrl = new JPanel();
3555 
3556     // Components management
3557     JPanel pnlComp = new JPanel();
3558     JPanel pnlOkCncel = new JPanel();
3559 
3560     GridLayout gridSupLeft = new GridLayout();
3561     GridLayout gridSupRight = new GridLayout();
3562     BorderLayout brdLySup = new BorderLayout();
3563     BorderLayout brdLyCtrl = new BorderLayout();
3564 
3565     JLabel lblPrintType = new JLabel();
3566     JLabel lblCategory = new JLabel();
3567     JLabel lblName = new JLabel();
3568     JTextField txtPrintType = new JTextField();
3569     JComboBox cbxCategory;
3570     JTextField txtTemplateName = new JTextField();
3571     JList lstNames = new JList();
3572     JScrollPane scrNames;
3573     JButton btnOK = new JButton();
3574     JButton btnCancel = new JButton();
3575 
3576     ComponentNameDisplayComponentNameDisplayComponentNameDisplayivate CodeDescription[] categories;
3577 
3578     private CodeDescription[] headers;
3579     private CodeDescription[] bodies;
3580     private CodeDescription[] closings;
3581 
3582     String[] voidNames = new String[]{""};
3583 
3584     private String catName = null;
3585 
3586     /**
3587      *  Code and description of the templates in the current category.
3588      */
3589     private CodeDescription[] cdTempl = null;
3590 
3591     private CodeDescription[] localCodes;
3592 
3593     public CodeDescription[] cntResult;
3594     private int mode;
3595 
3596 
3597     /**
3598      *  CategoryNameTemplateDialog constructor.
3599      *
3600      * @param codeCategory Template's category code. It can be undefined and
3601      *      the user will have to choose one.
3602      * @param result An array of < code, description> that must be
3603      *      provided by the caller. It will be filled with the results so it can
3604      *      be used by the caller. The entries are arranged in the <a
3605      *      href="./package-summary.html#thbccr">THBCCR order</a>
3606      *      . Moreover, the last entry follows the convention,
3607      *      <ul>
3608      *        <li> <tt>code = JOptionPane.OK_OPTION</tt> if the OK button is
3609      *        pressed.
3610      *        <li> <tt>code = JOptionPane.CANCEL_OPTION</tt> if the Cancel
3611      *        button is pressed.
3612      *      </ul>
3613      * @param mode Establishes the way the Gui can be used. Conventions
3614      *      are:
3615      *      <ul>
3616      *        <li> {@link LetterOp#SAVEAS} =>
3617      *        <ul>
3618      *          <li> The template is new (it is the first time it is going to be
3619      *          saved), or
3620      *          <li> It is an old template and the user wants to change its name
3621      *          and/or the component's names.
3622      *        </ul>
3623      *
3624      *        <li> {@link LetterOp#SAVEWITHNEW} => It is an old template and the
3625      *        user wants to change one of its components.
3626      *        <li> {@link LetterOp#LOAD} => An existing template will be opened.
3627      *        This Gui is used to choose it and to display --not to change-- its
3628      *        main attributes.
3629      *      </ul>
3630      */
3631     public CategoryNameTemplateDialog(
3632                                       long codeCategory, CodeDescription[] result, int mode) {
3633       super((Frame)null, "", true);
3634       this.cntResult = result;
3635       this.mode = mode;
3636       try {
3637 
3638         //Load categories
3639         categories = proxy.loadCategories();
3640         cbxCategory =
3641           new JComboBox(CodeDescription.toDescriptionsWithUndef(categories, ""));
3642         lstNames.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
3643         scrNames = new JScrollPane(lstNames);
3644 
3645         //Load Templates descriptions for all categories.
3646         for(int i = 0; i < categories.length; i++) {
3647           String catName = categories[i].getDescription();
3648           CodeDescription[] cd =
3649             proxy.loadTemplatesDescription(categories[i].getCode(), printType);
3650           templatesNames.put(catName, cd);
3651         }
3652 
3653         //Load components descriptions for all types of components.
3654         headers =
3655           proxy.loadComponentsDescription(LetterTemplateGlobals.HEADER_INDEX, printType);
3656 
3657         bodies =
3658           proxy.loadComponentsDescription(LetterTemplateGlobals.BODY_INDEX, printType);
3659 
3660         closings =
3661           proxy.loadComponentsDescription(LetterTemplateGlobals.CLOSING_INDEX, printType);
3662 
3663         //Local codes for template and components.
3664         localCodes = new CodeDescription[CATEGORY + 1];
3665         for(int i = 0; i <= CATEGORY; i++) {
3666           localCodes[i] = new CodeDescription(LetterTemplateGlobals.UNDEF, "");
3667         }
3668 
3669         pnlCtrl.setBorder(new TitledBorder(new EtchedBorder(), "Existing Templates"));
3670 
3671         guiInit(mode);
3672 
3673         txtPrintType.setText(printTypes[template.getPrintType()]);
3674 
3675         //Choosing a category refreshes the list of existing templates
3676         cbxCategory.addActionListener(
3677           new ActionListener() {
3678             public void actionPerformed(ActionEvent e) {
3679               catName = (String)cbxCategory.getSelectedItem();
3680 
3681               if(!catName.equals("")) {
3682                 cdTempl = (CodeDescription[])templatesNames.get(catName);
3683                 CodeDescription cd = CodeDescription.assocDescription(catName, categories);
3684                 localCodes[CATEGORY].setCode(cd.getCode());
3685                 localCodes[CATEGORY].setDescription(catName);
3686 
3687                 // cdTempl is never null but can have 0 length!!
3688                 if(cdTempl.length > 0) {
3689                   lstNames.setListData(CodeDescription.toDescriptions(cdTempl));
3690                 }
3691                 else {
3692                   lstNames.setListData(voidNames);
3693                 }
3694               }
3695               else {
3696                 lstNames.setListData(voidNames);
3697                 localCodes[CATEGORY].setCode(LetterTemplateGlobals.UNDEF);
3698                 localCodes[CATEGORY].setDescription("");
3699                 cdTempl = null;
3700               }
3701 
3702               txtTemplateName.setText("");
3703               cndHeader.setName("");
3704               cndBody.setName("");
3705               cndClosing.setName("");
3706             }
3707           });
3708 
3709         //Choosing a template refreshes its name and those of its components.
3710         lstNames.addListSelectionListener(
3711           new ListSelectionListener() {
3712             public void valueChanged(ListSelectionEvent e) {
3713               if(!e.getValueIsAdjusting()) {
3714                 //Warning!!. Avoids index out of bounds !!
3715                 if(lstNames.isSelectionEmpty()) {
3716                   return;
3717                 }
3718 
3719                 long localTemplateCode =
3720                   cdTempl[lstNames.getSelectedIndex()].getCode();
3721                 txtTemplateName.setText(lstNames.getSelectedValue().toString());
3722 
3723                 // Clear selection. This fires a new ListSelectionEvent from
3724                 // the very same source!!. The code above --marked as Warning--
3725                 // avoids the ensuing troubles.
3726                 lstNames.clearSelection();
3727 
3728                 try {
3729                   refreshComponentsNames(localTemplateCode);
3730                 }
3731                 catch(Exception ex) {
3732                   ex.printStackTrace();
3733                   return;
3734                 }
3735               }
3736             }
3737           });
3738 
3739         //Refresh the current category and templates --if any--.
3740         //This code must be here: after the actions tied to the
3741         //selection of a category and selection of a template.
3742 
3743         if(codeCategory != LetterTemplateGlobals.UNDEF) {
3744 
3745           cbxCategory.setSelectedIndex(
3746             CodeDescription.getIndexCode(codeCategory, categories) + 1);
3747         }
3748 
3749         //If the template to be saved contains new components, the names
3750         //of the old components are anyway pre-selected.
3751         if(mode == LetterOp.SAVEWITHNEW) {
3752 
3753           int templIndex =
3754             CodeDescription.getIndexDescription(template.getName(), cdTempl);
3755 
3756           lstNames.setSelectedIndex(templIndex);
3757 
3758           cbxCategory.setEnabled(false);
3759           txtTemplateName.setEditable(false);
3760           lstNames.setEnabled(false);
3761 
3762           //The old components gui is disabled.
3763           if(template.getHeader().getCode() != LetterTemplateGlobals.UNDEF) {
3764             cndHeader.setEnabled(false);
3765           }
3766           if(template.getBody().getCode() != LetterTemplateGlobals.UNDEF) {
3767             cndBody.setEnabled(false);
3768           }
3769           if(template.getClosing().getCode() != LetterTemplateGlobals.UNDEF) {
3770             cndClosing.setEnabled(false);
3771           }
3772         }
3773 
3774         //Typing a template name searches the existing templates and refreshes
3775         //the names of its components (if the template already exists).
3776         txtTemplateName.addActionListener(
3777           new ActionListener() {
3778             public void actionPerformed(ActionEvent e) {
3779               String name = txtTemplateName.getText();
3780               Object check = UtilOnJdk.isValidName(name);
3781               if(check instanceof Integer) {
3782                 JOptionPane.showMessageDialog(null,
3783                   "You must type a valid template name");
3784                 txtTemplateName.grabFocus();
3785                 return;
3786               }
3787 
3788               name = (String)check;
3789               txtTemplateName.setText(name);
3790               CodeDescription cd = CodeDescription.assocDescription(name, cdTempl);
3791               if(cd != null) {
3792                 // The template already exists.
3793                 try {
3794                   refreshComponentsNames(cd.getCode());
3795                 }
3796                 catch(Exception ex) {
3797                   ex.printStackTrace();
3798                   return;
3799                 }
3800               }
3801               else {
3802                 // It is a new template.
3803                 localCodes[LetterTemplateGlobals.TEMPLATE_INDEX].setCode(LetterTemplateGlobals.UNDEF);
3804                 localCodes[LetterTemplateGlobals.TEMPLATE_INDEX].setDescription(name);
3805                 cleanComponentsNamesCodes();
3806               }
3807             }
3808           });
3809 
3810         //pressing the OK button
3811         if(mode == LetterOp.SAVEAS) {
3812 
3813           btnOK.addActionListener(
3814             new ActionListener() {
3815               public void actionPerformed(ActionEvent e) {
3816                 int catIndex = cbxCategory.getSelectedIndex();
3817                 String catName = (String)cbxCategory.getSelectedItem();
3818 
3819                 //Check a valid category
3820                 if(catIndex == 0) {
3821                   JOptionPane.showMessageDialog(null, "You must choose a category");
3822                   return;
3823                 }
3824 
3825                 //The next string is never null.
3826                 String name = txtTemplateName.getText();
3827 
3828                 //Check a valid template name
3829                 if(name.equals("") || name.equals(LetterTemplateGlobals.STR_UNNAMED)) {
3830                   JOptionPane.showMessageDialog(null, "You must choose or type a valid template name");
3831                   txtTemplateName.selectAll();
3832                   return;
3833                 }
3834 
3835                 //Component Names are valid?
3836                 Object check = UtilOnJdk.isValidName(name);
3837                 if(check instanceof Integer) {
3838                   JOptionPane.showMessageDialog(null,
3839                     "You must choose or type a valid template name");
3840                   txtTemplateName.grabFocus();
3841                   txtTemplateName.selectAll();
3842                   return;
3843                 }
3844                 txtTemplateName.setText((String)check);
3845 
3846                 name = cndHeader.getName();
3847                 check = UtilOnJdk.isValidName(name);
3848                 if(check instanceof Integer) {
3849                   JOptionPane.showMessageDialog(null,
3850                     "You must choose or type a valid header name");
3851                   cndHeader.grabFocus();
3852                   cndHeader.selectAll();
3853                   return;
3854                 }
3855                 cndHeader.setName((String)check);
3856 
3857                 name = cndBody.getName();
3858                 check = UtilOnJdk.isValidName(name);
3859                 if(check instanceof Integer) {
3860                   JOptionPane.showMessageDialog(null,
3861                     "You must choose or type a valid body name");
3862                   cndBody.grabFocus();
3863                   cndBody.selectAll();
3864                   return;
3865                 }
3866                 cndBody.setName((String)check);
3867 
3868                 name = cndClosing.getName();
3869                 check = UtilOnJdk.isValidName(name);
3870                 if(check instanceof Integer) {
3871                   JOptionPane.showMessageDialog(null,
3872                     "You must choose or type a valid closing name");
3873                   cndClosing.grabFocus();
3874                   cndClosing.selectAll();
3875                   return;
3876                 }
3877                 cndClosing.setName((String)check);
3878 
3879                 //Some components will be overwritten?
3880                 boolean[] overwrite = checkOverwrite();
3881 
3882                 if(overwrite != null) {
3883                   int resp = JOptionPane.showConfirmDialog(
3884                     null,
3885                     saveWarningMessage(overwrite),
3886                     "Save Warning",
3887                     JOptionPane.YES_NO_OPTION,
3888                     JOptionPane.WARNING_MESSAGE);
3889 
3890                   if(resp == JOptionPane.NO_OPTION) {
3891                     return;
3892                   }
3893                 }
3894 
3895                 // The template will be stored.
3896                 putResult(cntResult);
3897                 cntResult[RESPONSE].setDescription("ok");
3898                 cntResult[RESPONSE].setCode(JOptionPane.OK_OPTION);
3899 
3900                 CategoryNameTemplateDialog.this.dispose();
3901               }
3902             });
3903 
3904         }
3905         else if(mode == LetterOp.LOAD) {
3906           //loading a template
3907           btnOK.addActionListener(
3908             new ActionListener() {
3909               public void actionPerformed(ActionEvent e) {
3910                 int catIndex = cbxCategory.getSelectedIndex();
3911                 String catName = (String)cbxCategory.getSelectedItem();
3912 
3913                 //Check a valid category
3914                 if(catIndex == 0) {
3915                   JOptionPane.showMessageDialog(null, "You have not chosen a category");
3916                   return;
3917                 }
3918 
3919                 CodeDescription cd = CodeDescription.assocDescription(catName, categories);
3920                 cntResult[CATEGORY].setCode(cd.getCode());
3921                 cntResult[CATEGORY].setDescription(catName);
3922 
3923                 //The next string is never null
3924                 String name = txtTemplateName.getText().trim().toLowerCase();
3925 
3926                 //Check a valid template name
3927                 if(name.equals("") || name.equals(LetterTemplateGlobals.STR_UNNAMED)) {
3928                   JOptionPane.showMessageDialog(null, "You have not chosen a template");
3929                   return;
3930                 }
3931 
3932                 cntResult[LetterTemplateGlobals.TEMPLATE_INDEX] =
3933                   CodeDescription.assocDescription(name, cdTempl);
3934 
3935                 // The template will be loaded.
3936                 cntResult[RESPONSE].setDescription("ok");
3937                 cntResult[RESPONSE].setCode(JOptionPane.OK_OPTION);
3938 
3939                 CategoryNameTemplateDialog.this.dispose();
3940               }
3941             });
3942         }
3943         else if(mode == LetterOp.SAVEWITHNEW) {
3944           //saving with new components
3945           btnOK.addActionListener(
3946             new ActionListener() {
3947               public void actionPerformed(ActionEvent e) {
3948 
3949                 String name = cndHeader.getName();
3950                 Object check = UtilOnJdk.isValidName(name);
3951 
3952                 check = UtilOnJdk.isValidName(name);
3953                 if(check instanceof Integer) {
3954                   JOptionPane.showMessageDialog(null,
3955                     "You must choose or type a valid header name");
3956                   cndHeader.grabFocus();
3957                   cndHeader.selectAll();
3958                   return;
3959                 }
3960                 cndHeader.setName((String)check);
3961 
3962                 name = cndBody.getName();
3963                 check = UtilOnJdk.isValidName(name);
3964                 if(check instanceof Integer) {
3965                   JOptionPane.showMessageDialog(null,
3966                     "You must choose or type a valid body name");
3967                   cndBody.grabFocus();
3968                   cndBody.selectAll();
3969                   return;
3970                 }
3971                 cndBody.setName((String)check);
3972 
3973                 name = cndClosing.getName();
3974                 check = UtilOnJdk.isValidName(name);
3975                 if(check instanceof Integer) {
3976                   JOptionPane.showMessageDialog(null,
3977                     "You must choose or type a valid closing name");
3978                   cndClosing.grabFocus();
3979                   cndClosing.selectAll();
3980                   return;
3981                 }
3982                 cndClosing.setName((String)check);
3983 
3984                 String msg = checkOverwritteWithNew();
3985                 if(msg != null) {
3986                   int resp = JOptionPane.showConfirmDialog(
3987                     null,
3988                     "The following components will be overwritten:\n"
3989                     + msg
3990                     + "\nAre you sure you want to continue?",
3991                     "Save Warning",
3992                     JOptionPane.YES_NO_OPTION,
3993                     JOptionPane.WARNING_MESSAGE);
3994 
3995                   if(resp == JOptionPane.NO_OPTION) {
3996                     return;
3997                   }
3998                 }
3999 
4000                 // The template will be saved.
4001                 putResult(cntResult);
4002                 cntResult[RESPONSE].setDescription("ok");
4003                 cntResult[RESPONSE].setCode(JOptionPane.OK_OPTION);
4004 
4005                 CategoryNameTemplateDialog.this.dispose();
4006               }
4007             });
4008         }
4009 
4010         //Pressing the Cancel button
4011         btnCancel.addActionListener(
4012           new ActionListener() {
4013             public void actionPerformed(ActionEvent e) {
4014               cntResult[RESPONSE].setCode(JOptionPane.CANCEL_OPTION);
4015               CategoryNameTemplateDialog.this.dispose();
4016 
4017             }
4018           });
4019 
4020       }
4021       catch(Exception e) {
4022         e.printStackTrace();
4023       }
4024 
4025     }
4026 
4027 
4028     /**
4029      *  Inits the CategoryNameTemplateDialog Gui after the 'interaction mode'
4030      *
4031      * @param mode The mode of interaction: SAVEAS, LOAD, SAVEWITHNEW.
4032      *      See {@link TemplateEditor.CategoryNameTemplateDialog
4033      *      CategoryNameTemplateDialog main constructor}
4034      * @throws Exception Description of the Exception
4035      */
4036     private void guiInit(int mode) throws Exception {
4037 
4038       this.setSize(new Dimension(440, 330));
4039       this.getContentPane().setLayout(new BorderLayout());
4040       switch (mode) {
4041         case LetterOp.SAVEAS:
4042           this.setTitle("Choosing Category and Template");
4043           break;
4044         case LetterOp.LOAD:
4045           this.setTitle("Loading Template");
4046           break;
4047         case LetterOp.SAVEWITHNEW:
4048           this.setTitle("Saving template with new components");
4049           break;
4050         default:
4051       }
4052       this.setModal(true);
4053       pnlSup.setLayout(brdLySup);
4054       pnlCtrl.setLayout(brdLyCtrl);
4055       pnlSupLeft.setLayout(gridSupLeft);
4056       pnlSupRight.setLayout(gridSupRight);
4057       gridSupLeft.setRows(3);
4058       gridSupLeft.setColumns(1);
4059       gridSupLeft.setHgap(5);
4060       gridSupLeft.setVgap(5);
4061       gridSupRight.setColumns(1);
4062       gridSupRight.setRows(3);
4063       gridSupRight.setHgap(5);
4064       gridSupRight.setVgap(5);
4065       lblPrintType.setText("Print Type");
4066       lblPrintType.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
4067       lblCategory.setText("Category");
4068       lblName.setText("Name");
4069       txtPrintType.setEditable(false);
4070       btnOK.setText("OK");
4071       btnCancel.setText("Cancel");
4072       pnlSupRight.add(txtPrintType, null);
4073       pnlSupRight.add(cbxCategory, null);
4074       pnlSupRight.add(txtTemplateName, null);
4075       pnlSup.add(pnlSupRight, BorderLayout.CENTER);
4076       pnlSupLeft.add(lblPrintType, null);
4077       pnlSupLeft.add(lblCategory, null);
4078       pnlSupLeft.add(lblName, null);
4079       pnlSup.add(pnlSupLeft, BorderLayout.WEST);
4080       pnlCtrl.add(scrNames);
4081       //-----------
4082       pnlInf.setLayout(new GridLayout(2, 1, 0, 5));
4083       pnlComp.setLayout(new GridLayout(1, 3, 5, 0));
4084       cndHeader =
4085         new ComponentNameDisplay(
4086         headers, "Header", mode);
4087       cndHeader.setBorder(new TitledBorder(new EtchedBorder(), "Header"));
4088 
4089       cndBody =
4090         new ComponentNameDisplay(
4091         bodies, "Body", mode);
4092       cndBody.setBorder(new TitledBorder(new EtchedBorder(), "Body"));
4093 
4094       cndClosing =
4095         new ComponentNameDisplay(
4096         closings, "Closing", mode);
4097       cndClosing.setBorder(new TitledBorder(new EtchedBorder(), "Closing"));
4098 
4099       pnlComp.add(cndHeader);
4100       pnlComp.add(cndBody);
4101       pnlComp.add(cndClosing);
4102       pnlOkCncel.add(btnOK, null);
4103       pnlOkCncel.add(btnCancel, null);
4104       pnlInf.add(pnlComp);
4105       pnlInf.add(pnlOkCncel);
4106       //---------------------
4107       this.getContentPane().add(pnlSup, BorderLayout.NORTH);
4108       this.getContentPane().add(pnlCtrl, BorderLayout.CENTER);
4109       this.getContentPane().add(pnlInf, BorderLayout.SOUTH);
4110 
4111     }
4112 
4113 
4114     /**
4115      *  Searches code and names of a template and --if they are found-- displays
4116      *  the names in the user interface. Moreover, it updates the template and
4117      *  components codes in the localCodes array.
4118      *
4119      * @param code Template's code.
4120      * @throws Exception Description of the Exception
4121      */
4122     private void refreshComponentsNames(long code) throws Exception {
4123       try {
4124 
4125         CodeDescription[] codeDescr = proxy.loadTemplateCodes(code);
4126         localCodes[LetterTemplateGlobals.TEMPLATE_INDEX] = codeDescr[LetterTemplateGlobals.TEMPLATE_INDEX];
4127         localCodes[LetterTemplateGlobals.HEADER_INDEX] = codeDescr[LetterTemplateGlobals.HEADER_INDEX];
4128         localCodes[LetterTemplateGlobals.BODY_INDEX] = codeDescr[LetterTemplateGlobals.BODY_INDEX];
4129         localCodes[LetterTemplateGlobals.CLOSING_INDEX] = codeDescr[LetterTemplateGlobals.CLOSING_INDEX];
4130         cndHeader.setName(localCodes[LetterTemplateGlobals.HEADER_INDEX].getDescription());
4131         cndBody.setName(localCodes[LetterTemplateGlobals.BODY_INDEX].getDescription());
4132         cndClosing.setName(localCodes[LetterTemplateGlobals.CLOSING_INDEX].getDescription());
4133 
4134       }
4135       catch(Exception ex) {
4136         JOptionPane.showMessageDialog(
4137           null,
4138           "Internal error. Template not found in data base");
4139         cleanComponentsNamesCodes();
4140         throw ex;
4141       }
4142     }
4143 
4144 
4145     /**
4146      *  Cleans the names of the components in the user interface. Morover, it
4147      *  cleans the codes in the localCodes array.
4148      */
4149     private void cleanComponentsNamesCodes() {
4150       cndHeader.setName("");
4151       cndBody.setName("");
4152       cndClosing.setName("");
4153       localCodes[LetterTemplateGlobals.HEADER_INDEX].setCode(LetterTemplateGlobals.UNDEF);
4154       localCodes[LetterTemplateGlobals.BODY_INDEX].setCode(LetterTemplateGlobals.UNDEF);
4155       localCodes[LetterTemplateGlobals.CLOSING_INDEX].setCode(LetterTemplateGlobals.UNDEF);
4156     }
4157 
4158 
4159     /**
4160      *  Copies values from a < code,description> array to another <
4161      *  code,description> array. The arrays follow the <a
4162      *  href="./package-summary.html#thbccr">THBCCR order</a> but
4163      *  the {@link LetterTemplateGlobals#RESPONSE RESPONSE} entry is not copied.
4164      *
4165      * @param from The array the values will be copied from.
4166      * @param to The array the values will be copied to.
4167      */
4168     private void copyResult(CodeDescription[] from, CodeDescription[] to) {
4169       for(int i = 0; i < LetterTemplateGlobals.RESPONSE; i++) {
4170         to[i].setCode(from[i].getCode());
4171         to[i].setDescription(from[i].getDescription());
4172       }
4173     }
4174 
4175 
4176     /**
4177      *  Copies the names of the template and components in the result. Moreover,
4178      *  copies the code and name of the selected category.
4179      *
4180      * @param to Array where the results --in the gui interface-- are moved to.
4181      */
4182     private void putResult(CodeDescription[] to) {
4183       to[LetterTemplateGlobals.TEMPLATE_INDEX].
4184         setDescription(txtTemplateName.getText().trim().toLowerCase());
4185 
4186       to[LetterTemplateGlobals.HEADER_INDEX].
4187         setDescription(cndHeader.getName());
4188 
4189       to[LetterTemplateGlobals.BODY_INDEX].
4190         setDescription(cndBody.getName());
4191 
4192       to[LetterTemplateGlobals.CLOSING_INDEX].
4193         setDescription(cndClosing.getName());
4194 
4195       to[CATEGORY].
4196         setCode(localCodes[CATEGORY].getCode());
4197       to[CATEGORY].
4198         setDescription(localCodes[CATEGORY].getDescription());
4199     }
4200 
4201 
4202     /**
4203      *  Checks the template and/or components that can be overwritten by a save
4204      *  operation.
4205      *
4206      * @return A 4 positions boolean array following the <a
4207      *      href="./package-summary.html#thbc">THBC order</a> .
4208      *      <p>
4209      *
4210      *      For each entry in the returned array:
4211      *      <ul>
4212      *        <li> True = component will change.
4213      *        <li> False = component will not change.
4214      *      </ul>
4215      *      <p>
4216      *
4217      *      Moreover, if every entry is going to be false, the value actually
4218      *      produced is <tt>null</tt> instead of the array of booleans.
4219      */
4220     private boolean[] checkOverwrite() {
4221       boolean[] res = new boolean[4];
4222 
4223       if(cdTempl == null) {
4224         //MessageFrame.getFrame().addText("cdTempl is null");
4225       }
4226       CodeDescription cd =
4227         CodeDescription.assocDescription(
4228         txtTemplateName.getText().trim().toLowerCase(), cdTempl);
4229       res[LetterTemplateGlobals.TEMPLATE_INDEX] = (cd != null);
4230 
4231       if(cndHeader == null) {
4232         //MessageFrame.getFrame().addText("cndHeader is null");
4233       }
4234 
4235       if(headers == null) {
4236         //MessageFrame.getFrame().addText("headers is null");
4237       }
4238       else {
4239         //MessageFrame.getFrame().addText("headers.lenght = " + headers.length);
4240       }
4241       cd = CodeDescription.assocDescription(cndHeader.getName(), headers);
4242       res[LetterTemplateGlobals.HEADER_INDEX] = (cd != null);
4243 
4244       cd = CodeDescription.assocDescription(cndBody.getName(), bodies);
4245       res[LetterTemplateGlobals.BODY_INDEX] = (cd != null);
4246 
4247       cd = CodeDescription.assocDescription(cndClosing.getName(), closings);
4248       res[LetterTemplateGlobals.CLOSING_INDEX] = (cd != null);
4249 
4250       boolean someoneChanges = res[0] || res[1] || res[2] || res[3];
4251 
4252       if(someoneChanges) {
4253         return res;
4254       }
4255       else {
4256         return null;
4257       }
4258     }
4259 
4260 
4261     /**
4262      *  Helper method that aids to produce a convenient message warning about
4263      *  the components that can be modified when saving a template in the {@link
4264      *  LetterOp#SAVEWITHNEW} mode.
4265      *
4266      * @return       <ul>
4267      *        <li> The type names of the components being modified.
4268      *        <li> "null" If there is no such components
4269      *      </ul>
4270      */
4271     private String checkOverwritteWithNew() {
4272       String res = "";
4273 
4274       if(template.getHeader().getCode() == LetterTemplateGlobals.UNDEF) {
4275         res += "header ";
4276       }
4277       if(template.getBody().getCode() == LetterTemplateGlobals.UNDEF) {
4278         res += "body ";
4279       }
4280       if(template.getClosing().getCode() == LetterTemplateGlobals.UNDEF) {
4281         res += "closing ";
4282       }
4283       if(res.equals("")) {
4284         return null;
4285       }
4286       else {
4287         return res;
4288       }
4289     }
4290 
4291 
4292     /**
4293      *  Checks if the user has chosen valid names for the template and its
4294      *  components.
4295      *
4296      * @param includeTemplate When true, the template name is included in the
4297      *      verification.
4298      * @return Null if all names are valid. Otherwise, a String
4299      *      explaining the first names which is invalid.
4300      */
4301     private String checkValidNames(boolean includeTemplate) {
4302       String res = "You must choose or type a valid name for the \n";
4303 
4304       boolean invalid = false;
4305       Object check;
4306 
4307       if(includeTemplate) {  // && !isValidName(txtTemplateName.getText())) {
4308         check = UtilOnJdk.isValidName(txtTemplateName.getText());
4309         if(check instanceof Integer) {
4310           res += "template ";
4311           return res;
4312           //invalid = true;
4313         }
4314         txtTemplateName.setText((String)check);
4315       }
4316 
4317       check = UtilOnJdk.isValidName(cndHeader.getName());
4318       if(check instanceof Integer) {
4319         res += "header ";
4320         return res;
4321         //invalid = true;
4322       }
4323       cndHeader.setName((String)check);
4324 
4325       /*if (!isValidName(cndHeader.getName())) {
4326         res += "header ";
4327         invalid = true;
4328       }*/
4329       check = UtilOnJdk.isValidName(cndBody.getName());
4330       if(check instanceof Integer) {
4331         res += "body ";
4332         return res;
4333         //invalid = true;
4334       }
4335       cndBody.setName((String)check);
4336 
4337       /*if (!isValidName(cndBody.getName())) {
4338         res += "body ";
4339         invalid = true;
4340       }*/
4341       check = UtilOnJdk.isValidName(cndClosing.getName());
4342       if(check instanceof Integer) {
4343         res += "closing ";
4344         return res;
4345         //invalid = true;
4346       }
4347       cndClosing.setName((String)check);
4348       return null;
4349       /*if (!isValidName(cndClosing.getName())) {
4350         res += "closing ";
4351         invalid = true;
4352       }*/
4353       /*if (invalid) {
4354         return res;
4355       } else {
4356         return null;
4357       }*/
4358     }
4359 
4360 
4361     /**
4362      *  Calculates a warning message with names and types of the template and/or
4363      *  components that will be modified.
4364      *
4365      * @param overwrite
4366      * @return The warning message.
4367      */
4368     private String saveWarningMessage(boolean[] overwrite) {
4369       String res = "The following template and/or components will be modified:\n";
4370 
4371       if(overwrite[LetterTemplateGlobals.TEMPLATE_INDEX]) {
4372         res += "   Template: \""
4373           + txtTemplateName.getText().trim().toLowerCase() + "\"\n";
4374       }
4375 
4376       if(overwrite[LetterTemplateGlobals.HEADER_INDEX]) {
4377         res += "   Header: \""
4378           + cndHeader.getName() + "\"\n";
4379       }
4380 
4381       if(overwrite[LetterTemplateGlobals.BODY_INDEX]) {
4382         res += "   Body: \""
4383           + cndBody.getName() + "\"\n";
4384       }
4385 
4386       if(overwrite[LetterTemplateGlobals.CLOSING_INDEX]) {
4387         res += "   Closing: \""
4388           + cndClosing.getName() + "\"\n";
4389       }
4390 
4391       res += "Are you sure, you want to continue?";
4392 
4393       return res;
4394     }
4395   }
4396 
4397 
4398   /**
4399    * User dialog that allows to define margins for a template.
4400    *
4401    * @author InstantBank (Rodrigo Lopez)
4402    * @created Dic-2002
4403    */
4404   class MarginDialog extends JDialog {
4405     /**
4406      * Number of twips in one inch
4407      */
4408     public static final int TWIPS_IN_INCH = 1440;
4409 
4410     /**
4411      * Maximum horizontal margin, in inches.
4412      */
4413     private static final int MAX_HOR_INCH = 6;
4414 
4415     /**
4416      * Maximum vertical margin, in inches.
4417      */
4418     private static final int MAX_VERT_INCH = 8;
4419 
4420     /**
4421      * Maximum horizontal margin (left+right) in twips.
4422      */
4423     public static final int MAX_HOR = TWIPS_IN_INCH * MAX_HOR_INCH;
4424 
4425     /**
4426      * Maximum vertical margin (top+bottom) in twips.
4427      */
4428     public static final int MAX_VERT = TWIPS_IN_INCH * MAX_VERT_INCH;
4429 
4430     JLabel lblTitle = new JLabel();
4431     JPanel pnlInf = new JPanel();
4432     JButton btnOK = new JButton("OK");
4433     JButton btnCancel = new JButton("Cancel");
4434     JPanel pnlCtrl = new JPanel();
4435     JLabel lblLeft = new JLabel("Left Margin");
4436     JLabel lblRight = new JLabel("Right Margin");
4437     JLabel lblTop = new JLabel("Top Margin");
4438     JLabel lblBottom = new JLabel("Bottom Margin");
4439     JTextField txtLeft = new JTextField(5);
4440     JTextField txtRight = new JTextField(5);
4441     JTextField txtTop = new JTextField(5);
4442     JTextField txtBottom = new JTextField(5);
4443 
4444     /**
4445      * Place holder for values sent to the client. Must be
4446      * provided by the client.
4447      */
4448     private int answer[];
4449     /**
4450      * Left margin value (in twips)
4451      */
4452     private int left;
4453 
4454     /**
4455      * Right margin value (in twips)
4456      */
4457     private int right;
4458 
4459     /**
4460      * Top margin value (in twips)
4461      */
4462     private int top;
4463 
4464     /**
4465      * Bottom margin value (in twips)
4466      */
4467     private int bottom;
4468 
4469     /**
4470      * Formatter for margin values.
4471      */
4472     private DecimalFormat df;
4473 
4474 
4475     /**
4476      * MarginDialog constructor.
4477      *
4478      * @param answer Array where values captured by this dialog are stored.
4479      *        Must be provided by the client.
4480      * @param left Left margin value (in twips)
4481      * @param right Right margin value (in twips)
4482      * @param top Top margin value (in twips)
4483      * @param bottom margin value (in twips)
4484      */
4485     public MarginDialog(int answer[], int left, int right, int top, int bottom) {
4486       super((Frame)null, "Setting Margins Sizes", true);
4487 
4488       this.answer = answer;
4489       this.left = left;
4490       this.right = right;
4491       this.bottom = bottom;
4492       this.top = top;
4493 
4494       NumberFormat nf = NumberFormat.getInstance(Locale.US);
4495 
4496       df = (DecimalFormat)nf;
4497       df.setMinimumFractionDigits(2);
4498       df.setMaximumFractionDigits(2);
4499       df.setDecimalSeparatorAlwaysShown(true);
4500       df.applyPattern("#0.00");
4501 
4502       guiInit();
4503 
4504     }
4505 
4506 
4507     /**
4508      * User controls initialization
4509      */
4510     private void guiInit() {
4511       this.setSize(255, 225);
4512 
4513       lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
4514       lblTitle.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5));
4515       lblTitle.setText("Margins Size (in inches)");
4516       getContentPane().add(lblTitle, BorderLayout.NORTH);
4517 
4518       pnlCtrl.setLayout(new GridLayout(4, 2, 5, 5));
4519       pnlCtrl.add(lblLeft);
4520       pnlCtrl.add(txtLeft);
4521       txtLeft.setDocument(new DoubleDocument());
4522       setMargin(left, txtLeft);
4523 
4524       pnlCtrl.add(lblRight);
4525       pnlCtrl.add(txtRight);
4526       txtRight.setDocument(new DoubleDocument());
4527       setMargin(right, txtRight);
4528 
4529       pnlCtrl.add(lblTop);
4530       pnlCtrl.add(txtTop);
4531       txtTop.setDocument(new DoubleDocument());
4532       setMargin(top, txtTop);
4533 
4534       pnlCtrl.add(lblBottom);
4535       pnlCtrl.add(txtBottom);
4536       txtBottom.setDocument(new DoubleDocument());
4537       setMargin(bottom, txtBottom);
4538 
4539       pnlCtrl.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5));
4540       getContentPane().add(pnlCtrl, BorderLayout.CENTER);
4541 
4542       pnlInf.add(btnOK);
4543       pnlInf.add(btnCancel);
4544       getContentPane().add(pnlInf, BorderLayout.SOUTH);
4545 
4546       btnOK.addActionListener(
4547         new ActionListener() {
4548           public void actionPerformed(ActionEvent e) {
4549             try {
4550               answer[1] = checkDouble("left margin size", txtLeft, MAX_HOR);
4551               answer[2] = checkDouble("right margin size", txtRight, MAX_HOR);
4552               checkAdd(answer[1], answer[2], MAX_HOR, txtRight);
4553               answer[3] = checkDouble("top margin size", txtTop, MAX_VERT);
4554               answer[4] = checkDouble("bottom margin size", txtBottom, MAX_VERT);
4555               checkAdd(answer[3], answer[4], MAX_VERT, txtBottom);
4556             }
4557             catch(Exception ex) {
4558               return;
4559             }
4560             answer[0] = JOptionPane.OK_OPTION;
4561             MarginDialog.this.dispose();
4562           }
4563         }
4564         );
4565 
4566       btnCancel.addActionListener(
4567         new ActionListener() {
4568           public void actionPerformed(ActionEvent e) {
4569             answer[0] = JOptionPane.CANCEL_OPTION;
4570             MarginDialog.this.dispose();
4571           }
4572         }
4573         );
4574     }
4575 
4576 
4577     /**
4578      * Checks if the value typed in a text box does not exceed
4579      * a margin limit.
4580      *
4581      * @param txt The text box where the value is typed.
4582      * @param max The limit not to be exceeded.
4583      * @param msg A short message identifying the type of margin.
4584      * @return The accepted value converted to twips.
4585      * @throws NumberFormatException if the value is not numeric.
4586      * @throws Exception If the limit is exceeded.
4587      */
4588     private int checkDouble(String msg, JTextField txt, int max)
4589        throws NumberFormatException, Exception {
4590       try {
4591         double val = Double.parseDouble(txt.getText());
4592         int margin = (int)(val * TWIPS_IN_INCH);
4593         if(margin > max) {
4594 
4595           JOptionPane.showMessageDialog(MarginDialog.this,
4596             "Maximum " + msg + " exceeded.");
4597           val = (double)max / TWIPS_IN_INCH;
4598           txt.setText(df.format(val));
4599           txt.grabFocus();
4600           throw new Exception();
4601         }
4602         return margin;
4603       }
4604       catch(NumberFormatException pex) {
4605         JOptionPane.showMessageDialog(MarginDialog.this, "Invalid " + msg);
4606         txt.grabFocus();
4607         throw pex;
4608       }
4609     }
4610 
4611 
4612     /**
4613      * Checks if the sum of two opposed margins does not exceed
4614      * a limit.
4615      *
4616      * @param first First margin (in twips)
4617      * @param snd Second margin (in twips)
4618      * @param sndTxt Text box that is zeroed if limit is exceeded.
4619      * @param maxadd Description of the Parameter
4620      * @throws Exception If the limit is exceeded.
4621      */
4622     private void checkAdd(int first, int snd, int maxadd, JTextField sndTxt)
4623        throws Exception {
4624       if((first + snd) > maxadd) {
4625         JOptionPane.showMessageDialog(MarginDialog.this,
4626           "Maximum horizontal margins size exceeded");
4627         sndTxt.setText("0.00");
4628         sndTxt.grabFocus();
4629         throw new Exception();
4630       }
4631     }
4632 
4633 
4634     /**
4635      * Displays a value (converted to inches) in a text field.
4636      *
4637      * @param twips Value to be displayed (in twips)
4638      * @param txt Field where the value is displayed.
4639      */
4640     public void setMargin(int twips, JTextField txt) {
4641       double size = (double)twips / TWIPS_IN_INCH;
4642       txt.setText(df.format(size));
4643     }
4644 
4645 
4646     /**
4647      * Setter for the title attribute.
4648      *
4649      * @param s The new title value
4650      */
4651     public void setTitle(String s) {
4652       lblTitle.setText(s);
4653     }
4654   }
4655 
4656   //End of CategoryNameTemplateDialog class
4657 
4658   /**
4659    *  Auxiliary class that inserts a format for a variable in the text. Can be
4660    *  used only if the cursor is just before a variable mark in the text.
4661    */
4662   class VariableFormatInsertion
4663       implements ActionListener {
4664     public void actionPerformed(ActionEvent e) {
4665       int i = lbcFormat.getCombo().getSelectedIndex();
4666       Long format = new Long(varFormats[i].getCode());
4667       selectedTed.setVarFormatAttribute(format);
4668       selectedTed.grabFocus();
4669     }
4670   }
4671 
4672 
4673   /**
4674    *  Auxiliary Gui class used to type/choose the name of a component. It is
4675    *  invoked only from the {@link TemplateEditor.EditorStuff#saveComponentAs(LetterComponent)}
4676    *  method and it is based on the {@link ComponentNameDisplay} widget.
4677    *
4678    * @author InstantBank (Rodrigo Lopez)
4679    * @created September 2002
4680    */
4681   class SaveAsComponentDialog extends JDialog {
4682 
4683     protected GridLayout gridLyt;
4684 
4685     protected ComponentNameDisplay compDisplay;
4686 
4687     protected JPanel pnlOkCancel = new JPanel();
4688 
4689     protected JButton btnOK = new JButton("OK");
4690 
4691     protected JButton btnCancel = new JButton("Cancel");
4692 
4693     protected JLabel lblTitle;
4694 
4695     /**
4696      *  The answer sent to the caller.
4697      */
4698     private CodeDescription answer;
4699 
4700 
4701     /**
4702      *  SaveAsComponentDialog constructor.
4703      *
4704      * @param cmpNames Component's names to be chosen.
4705      * @param compType Type of the component to be saved (HEADER,BODY,CLOSING)
4706      * @param mode Usage mode. It is needed by the auxiliary widget {@link
4707      *      ComponentNameDisplay}. The only meaningful value in this case is
4708      *      {@link LetterOp#SAVEAS}.
4709      * @param answer Place holder for the answer. It must be provided by the
4710      *      caller. Conventions are:
4711      *      <ul>
4712      *        <li> (answer.code == JOptionPane.OK_OPTION) => The OK button was
4713      *        pressed.
4714      *        <li> (answer.code == JOptionPane.CANCEL_OPTION) => The Cancel
4715      *        button was pressed.
4716      *        <li> If The OK button was pressed, <tt>answer.description</tt>
4717      *        contains the typed/chosen component name.
4718      *      </ul>
4719      */
4720     public SaveAsComponentDialog(CodeDescription[] cmpNames, String compType,
4721                                  int mode, CodeDescription answer) {
4722       super((Frame)null, "", true);
4723 
4724       this.answer = answer;
4725       gridLyt = new GridLayout(3, 1);
4726       this.getContentPane().setLayout(gridLyt);
4727       this.setTitle("Choosing Component's name");
4728       compDisplay = new ComponentNameDisplay(cmpNames, compType, mode);
4729       lblTitle = new JLabel("Choosing or Typing a name for " + compType);
4730 
4731       pnlOkCancel.add(btnOK);
4732       pnlOkCancel.add(btnCancel);
4733       lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
4734       this.getContentPane().add(lblTitle);
4735       compDisplay.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
4736       this.getContentPane().add(compDisplay);
4737       this.getContentPane().add(pnlOkCancel);
4738       this.setSize(260, 190);
4739 
4740       btnOK.addActionListener(
4741         new ActionListener() {
4742           public void actionPerformed(ActionEvent e) {
4743             String s = compDisplay.getName();
4744             Object check = UtilOnJdk.isValidName(s);
4745             if(check instanceof Integer) {
4746               int r = ((Integer)check).intValue();
4747               if(r == UtilOnJdk.VOID_NAME) {
4748                 JOptionPane.showMessageDialog(
4749                   null, "A void name is not a valid component name." +
4750                   "\nYou should choose or type a valid name.");
4751               }
4752               else {
4753                 JOptionPane.showMessageDialog(
4754                   null, "\"" + s + "\"" + "is not a valid component name." +
4755                   "\nYou should choose or type a valid name.");
4756 
4757               }
4758               return;
4759             }
4760 
4761             SaveAsComponentDialog.this.answer.setDescription((String)check);
4762             SaveAsComponentDialog.this.answer.setCode(JOptionPane.OK_OPTION);
4763             SaveAsComponentDialog.this.dispose();
4764           }
4765         });
4766 
4767       btnCancel.addActionListener(
4768         new ActionListener() {
4769           public void actionPerformed(ActionEvent e) {
4770             SaveAsComponentDialog.this.answer.setCode(JOptionPane.CANCEL_OPTION);
4771             SaveAsComponentDialog.this.dispose();
4772           }
4773         });
4774     }
4775   }
4776   // End of SaveAsComponentDialog class
4777 
4778 
4779   /**
4780    *  Auxiliary class to group basic attributes of a template or a letter
4781    *  component.
4782    *
4783    * @author InstantBank (Rodrigo Lopez)
4784    * @created September 2002
4785    */
4786   class TemplateCodes {
4787     /**
4788      *  The template/component code.
4789      */
4790     public long code;
4791 
4792     /**
4793      *  The template/component name.
4794      */
4795     public String name;
4796 
4797     /**
4798      *  The template/component time stamp.
4799      */
4800     public String stamp;
4801 
4802 
4803     /**
4804      *  TemplateCodes big constructor.
4805      *
4806      * @param c Code
4807      * @param n Name
4808      * @param s Stamp
4809      */
4810     public TemplateCodes(long c, String n, String s) {
4811       code = c;
4812       name = n;
4813       stamp = s;
4814     }
4815 
4816 
4817     /**
4818      *  TemplateCodes default constructor. Initializes all its attributes as
4819      *  "undefined" values.
4820      */
4821     public TemplateCodes() {
4822       code = LetterTemplateGlobals.UNDEF;
4823       name = LetterTemplateGlobals.STR_UNDEF;
4824       stamp = LetterTemplateGlobals.STR_UNDEF;
4825     }
4826   }
4827   //End of TemplateCodes class
4828 
4829 }
4830 
4831 ??????????????????????????cndHeader?????????????????????????????????????cndBody??????????????????????????????????????????????cndClosing?????????????CodeDescription???????????????????????????????categories?????????????CodeDescription???????????????????????????????headers?????????????CodeDescription???????????????????????????????bodies?????????????CodeDescription???????????????????????????????closings??????????????voidNames????????????????????catName????????????????????????????????????????????????????????????????????????????????????????????????????CodeDescription???????????????????????????????cdTempl?????????????CodeDescription???????????????????????????????localCodes????????????CodeDescription??????????????????????????????cntResult?????????????????mode??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????CategoryNameTemplateDialog??????????????????????????????????????????????????????????CodeDescription????????????????????????result???????????????????mode???????????????????????????????????categories??????????????????????proxy????????????????????????????loadCategories?????????cbxCategory?????????????????????????CodeDescription?????????????????????????????????????????toDescriptionsWithUndef?????????????????????????????????????????????????????????????????categories?????????lstNames?????????scrNames????????????????????????????????????lstNames??????????????????????????????????????????????????????????????????????????????????i????????????????????????????categories???????????????????????????????????????????????i????????????????????????????categories???????????????????????????????????????i??????????????????????????????????????????getDescription???????????CodeDescription?????????????proxy???????????????????loadTemplatesDescription????????????????????????????????????????????categories???????????????????????????????????????????????????????i??????????????????????????????????????????????????????????getCode?????????????????????????????????????????????????????????????????????printType???????????templatesNames??????????????????????????????catName???????????????????????????????????????cd?????????????????????????????????????????????????????????????????????????????headers???????????proxy?????????????????loadComponentsDescription???????????????????????????????????????????LetterTemplateGlobals?????????????????????????????????????????????????????????????????HEADER_INDEX???????????????????????????????????????????????????????????????????????????????printType?????????bodies???????????proxy?????????????????loadComponentsDescription???????????????????????????????????????????LetterTemplateGlobals?????????????????????????????????????????????????????????????????BODY_INDEX?????????????????????????????????????????????????????????????????????????????printType?????????closings???????????proxy?????????????????loadComponentsDescription???????????????????????????????????????????LetterTemplateGlobals?????????????????????????????????????????????????????????????????CLOSING_INDEX????????????????????????????????????????????????????????????????????????????????printType????????????????????????????????????????????????????????????localCodes??????????????????????????CodeDescription??????????????????????????????????????????CATEGORY????????????????????????i?????????????????????????????CATEGORY???????????????????????????????????????i???????????localCodes??????????????????????i???????????????????????????????CodeDescription???????????????????????????????????????????????LetterTemplateGlobals?????????????????????????????????????????????????????????????????????UNDEF?????????pnlCtrl?????????guiInit?????????????????mode?????????txtPrintType??????????????????????????????printTypes?????????????????????????????????????????template??????????????????????????????????????????????????getPrintType????????????????????????????????????????????????????????????????????????????????cbxCategory???????????????catName?????????????????????????????????cbxCategory???????????????????catName?????????????????cdTempl????????????????????????????CodeDescription??????????????????????????????????????????????templatesNames?????????????????????????????????????????????????????????????????catName?????????????????CodeDescription??????????????????????????????????????CodeDescription??????????????????????????????????????????????????????assocDescription???????????????????????????????????????????????????????????????????????catName????????????????????????????????????????????????????????????????????????????????categories?????????????????localCodes????????????????????????????CATEGORY??????????????????????????????????????setCode??????????????????????????????????????????????cd?????????????????????????????????????????????????getCode?????????????????localCodes????????????????????????????CATEGORY??????????????????????????????????????setDescription?????????????????????????????????????????????????????catName?????????????????????????????????????????????????????????????????????????????????????cdTempl???????????????????lstNames????????????????????????????????????????CodeDescription????????????????????????????????????????????????????????toDescriptions???????????????????????????????????????????????????????????????????????cdTempl???????????????????lstNames????????????????????????????????????????voidNames?????????????????lstNames??????????????????????????????????????voidNames?????????????????localCodes????????????????????????????CATEGORY??????????????????????????????????????setCode??????????????????????????????????????????????LetterTemplateGlobals????????????????????????????????????????????????????????????????????UNDEF?????????????????localCodes????????????????????????????CATEGORY??????????????????????????????????????setDescription?????????????????cdTempl???????????????txtTemplateName???????????????cndHeader?????????????????????????setName???????????????cndBody???????????????????????setName???????????????cndClosing??????????????????????????setName???????????????????????????????????????????????????????????????????????????????????????lstNames???????????????????e???????????????????????????????????????????????????????????????????????????????lstNames???????????????????cdTempl???????????????????????????lstNames????????????????????????????????????????????????????????getCode?????????????????txtTemplateName?????????????????????????????????????????lstNames??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????lstNames???????????????????refreshComponentsNames??????????????????????????????????????????localTemplateCode???????????????????ex????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????codeCategory????????????????????????????LetterTemplateGlobals??????????????????????????????????????????????????UNDEF???????????cbxCategory?????????????CodeDescription?????????????????????????????getIndexCode??????????????????????????????????????????codeCategory????????????????????????????????????????????????????????categories??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????mode????????????????????LetterOp?????????????????????????????SAVEWITHNEW?????????????CodeDescription?????????????????????????????getIndexDescription?????????????????????????????????????????????????template??????????????????????????????????????????????????????????getName?????????????????????????????????????????????????????????????????????cdTempl???????????lstNames?????????????????????????????????????templIndex???????????cbxCategory???????????txtTemplateName???????????lstNames??????????????????????????????????????????????????????????????template???????????????????????getHeader???????????????????????????????????getCode????????????????????????????????????????????????LetterTemplateGlobals??????????????????????????????????????????????????????????????????????UNDEF?????????????cndHeader??????????????template???????????????????????getBody?????????????????????????????????getCode??????????????????????????????????????????????LetterTemplateGlobals????????????????????????????????????????????????????????????????????UNDEF?????????????cndBody??????????????template???????????????????????getClosing????????????????????????????????????getCode?????????????????????????????????????????????????LetterTemplateGlobals???????????????????????????????????????????????????????????????????????UNDEF?????????????cndClosing????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????txtTemplateName?????????????????????????????txtTemplateName??????????????????????????????UtilOnJdk????????????????????????????????????????isValidName????????????????????????????????????????????????????name??????????????????check?????????????????txtTemplateName???????????????name??????????????????????????????check???????????????txtTemplateName???????????????????????????????????????name???????????????CodeDescription????????????????????????????????????CodeDescription????????????????????????????????????????????????????assocDescription?????????????????????????????????????????????????????????????????????name???????????????????????????????????????????????????????????????????????????cdTempl??????????????????cd???????????????????????????????????????????????????????????????????refreshComponentsNames??????????????????????????????????????????cd?????????????????????????????????????????????getCode???????????????????ex??????????????????????????????????????????????????????????localCodes????????????????????????????LetterTemplateGlobals??????????????????????????????????????????????????TEMPLATE_INDEX??????????????????????????????????????????????????????????????????setCode??????????????????????????????????????????????????????????????????????????LetterTemplateGlobals????????????????????????????????????????????????????????????????????????????????????????????????UNDEF?????????????????localCodes????????????????????????????LetterTemplateGlobals??????????????????????????????????????????????????TEMPLATE_INDEX??????????????????????????????????????????????????????????????????setDescription?????????????????????????????????????????????????????????????????????????????????name?????????????????cleanComponentsNamesCodes?????????????????????????????????????????????mode????????????????????LetterOp?????????????????????????????SAVEAS???????????btnOK????????????????????????????????cbxCategory??????????????????????????????????????????cbxCategory?????????????????????????????????????????????????????????????catIndex????????????????????????????????????????????????????????????????????????????????txtTemplateName??????????????????????????????????????????????????????????????????name???????????????????????????????????????name???????????????????????????????????????????????????LetterTemplateGlobals?????????????????????????????????????????????????????????????????????????STR_UNNAMED???????????????????txtTemplateName?????????????????????????????????????????????????????????????????????????????UtilOnJdk??????????????????????????????????????????isValidName??????????????????????????????????????????????????????name????????????????????check???????????????????txtTemplateName???????????????????txtTemplateName?????????????????txtTemplateName?????????????????????????????????????????????????check?????????????????name????????????????????????cndHeader??????????????????????????????????getName?????????????????check?????????????????????????UtilOnJdk???????????????????????????????????isValidName???????????????????????????????????????????????name????????????????????check???????????????????cndHeader?????????????????????????????grabFocus???????????????????cndHeader?????????????????????????????selectAll?????????????????cndHeader???????????????????????????setName???????????????????????????????????????????check?????????????????name????????????????????????cndBody????????????????????????????????getName?????????????????check?????????????????????????UtilOnJdk???????????????????????????????????isValidName???????????????????????????????????????????????name????????????????????check???????????????????cndBody???????????????????????????grabFocus???????????????????cndBody???????????????????????????selectAll?????????????????cndBody?????????????????????????setName?????????????????????????????????????????check?????????????????name????????????????????????cndClosing???????????????????????????????????getName?????????????????check?????????????????????????UtilOnJdk???????????????????????????????????isValidName???????????????????????????????????????????????name????????????????????check???????????????????cndClosing??????????????????????????????grabFocus???????????????????cndClosing??????????????????????????????selectAll?????????????????cndClosing????????????????????????????setName????????????????????????????????????????????check??????????????????????????????????????????????????????????????????????????????????????????????checkOverwrite????????????????????overwrite?????????????????????saveWarningMessage????????????????????????????????????????overwrite??????????????????????resp?????????????????????????????????????????????????????????????????putResult???????????????????????????cntResult?????????????????cntResult???????????????????????????RESPONSE?????????????????????????????????????setDescription?????????????????cntResult???????????????????????????RESPONSE?????????????????????????????????????setCode?????????????????CategoryNameTemplateDialog?????????????????mode?????????????????????????LetterOp??????????????????????????????????LOAD??????????????????????????????????????????btnOK????????????????????????????????cbxCategory??????????????????????????????????????????cbxCategory?????????????????????????????????????????????????????????????catIndex?????????????????CodeDescription??????????????????????????????????????CodeDescription??????????????????????????????????????????????????????assocDescription???????????????????????????????????????????????????????????????????????catName????????????????????????????????????????????????????????????????????????????????categories?????????????????cntResult???????????????????????????CATEGORY?????????????????????????????????????setCode?????????????????????????????????????????????cd????????????????????????????????????????????????getCode?????????????????cntResult???????????????????????????CATEGORY?????????????????????????????????????setDescription????????????????????????????????????????????????????catName???????????????????????????????????????????????????????????????????????????????txtTemplateName??????????????????????????????????????????????????????????????????name???????????????????????????????????????name???????????????????????????????????????????????????LetterTemplateGlobals?????????????????????????????????????????????????????????????????????????STR_UNNAMED?????????????????cntResult???????????????????????????LetterTemplateGlobals?????????????????????????????????????????????????TEMPLATE_INDEX???????????????????CodeDescription???????????????????????????????????assocDescription????????????????????????????????????????????????????name??????????????????????????????????????????????????????????cdTempl?????????????????????????????????????????????????????????????????cntResult???????????????????????????RESPONSE?????????????????????????????????????setDescription?????????????????cntResult???????????????????????????RESPONSE?????????????????????????????????????setCode?????????????????CategoryNameTemplateDialog?????????????????mode?????????????????????????LetterOp??????????????????????????????????SAVEWITHNEW??????????????????????????????????????????????????btnOK???????????????????????????????cndHeader?????????????????????????????????????????getName????????????????????????????????UtilOnJdk??????????????????????????????????????????isValidName??????????????????????????????????????????????????????name?????????????????check?????????????????????????UtilOnJdk???????????????????????????????????isValidName???????????????????????????????????????????????name????????????????????check???????????????????cndHeader?????????????????????????????grabFocus???????????????????cndHeader?????????????????????????????selectAll?????????????????cndHeader???????????????????????????setName???????????????????????????????????????????check?????????????????name????????????????????????cndBody????????????????????????????????getName?????????????????check?????????????????????????UtilOnJdk???????????????????????????????????isValidName???????????????????????????????????????????????name????????????????????check???????????????????cndBody???????????????????????????grabFocus???????????????????cndBody???????????????????????????selectAll?????????????????cndBody?????????????????????????setName?????????????????????????????????????????check?????????????????name????????????????????????cndClosing???????????????????????????????????getName?????????????????check?????????????????????????UtilOnJdk???????????????????????????????????isValidName???????????????????????????????????????????????name????????????????????check???????????????????cndClosing??????????????????????????????grabFocus???????????????????cndClosing??????????????????????????????selectAll?????????????????cndClosing????????????????????????????setName????????????????????????????????????????????check??????????????????????????????checkOverwritteWithNew????????????????????msg???????????????????????msg??????????????????????resp????????????????????????????????????????????????????????????????putResult???????????????????????????cntResult?????????????????cntResult???????????????????????????RESPONSE?????????????????????????????????????setDescription?????????????????cntResult???????????????????????????RESPONSE?????????????????????????????????????setCode?????????????????CategoryNameTemplateDialog??????????????????????????????????????????????btnCancel???????????????cntResult?????????????????????????RESPONSE???????????????????????????????????setCode???????????????CategoryNameTemplateDialog?????????e??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????guiInit???????????????mode??????????????LetterOp???????????????????????SAVEAS??????????????LetterOp???????????????????????LOAD??????????????LetterOp???????????????????????SAVEWITHNEW???????pnlSup????????????????????????brdLySup???????pnlCtrl?????????????????????????brdLyCtrl???????pnlSupLeft????????????????????????????gridSupLeft???????pnlSupRight?????????????????????????????gridSupRight???????gridSupLeft???????gridSupLeft???????gridSupLeft???????gridSupLeft???????gridSupRight???????gridSupRight???????gridSupRight???????gridSupRight???????lblPrintType???????lblPrintType???????lblCategory???????lblName???????txtPrintType???????btnOK???????btnCancel???????pnlSupRight???????????????????????txtPrintType???????pnlSupRight???????????????????????cbxCategory???????pnlSupRight???????????????????????txtTemplateName???????pnlSup??????????????????pnlSupRight???????pnlSupLeft??????????????????????lblPrintType???????pnlSupLeft??????????????????????lblCategory???????pnlSupLeft??????????????????????lblName???????pnlSup??????????????????pnlSupLeft???????pnlCtrl???????????????????scrNames???????????????????????????pnlInf???????pnlComp???????cndHeader?????????????ComponentNameDisplay?????????headers????????????????????????????mode???????cndHeader???????cndBody?????????????ComponentNameDisplay?????????bodies?????????????????????????mode???????cndBody???????cndClosing?????????????ComponentNameDisplay?????????closings??????????????????????????????mode???????cndClosing???????pnlComp???????????????????cndHeader???????pnlComp???????????????????cndBody???????pnlComp???????????????????cndClosing???????pnlOkCncel??????????????????????btnOK???????pnlOkCncel??????????????????????btnCancel???????pnlInf??????????????????pnlComp???????pnlInf??????????????????pnlOkCncel???????????????????????????????????????????????????????????????pnlSup?????????????????????????????????pnlCtrl?????????????????????????????????pnlInf?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????refreshComponentsNames?????????CodeDescription???????????????????????????????????????proxy?????????????????????????????????????????????loadTemplateCodes???????????????????????????????????????????????????????????????code?????????localCodes????????????????????LetterTemplateGlobals??????????????????????????????????????????TEMPLATE_INDEX????????????????????????????????????????????????????????????codeDescr??????????????????????????????????????????????????????????????????????LetterTemplateGlobals????????????????????????????????????????????????????????????????????????????????????????????TEMPLATE_INDEX?????????localCodes????????????????????LetterTemplateGlobals??????????????????????????????????????????HEADER_INDEX??????????????????????????????????????????????????????????codeDescr????????????????????????????????????????????????????????????????????LetterTemplateGlobals??????????????????????????????????????????????????????????????????????????????????????????HEADER_INDEX?????????localCodes????????????????????LetterTemplateGlobals??????????????????????????????????????????BODY_INDEX????????????????????????????????????????????????????????codeDescr??????????????????????????????????????????????????????????????????LetterTemplateGlobals????????????????????????????????????????????????????????????????????????????????????????BODY_INDEX?????????localCodes????????????????????LetterTemplateGlobals??????????????????????????????????????????CLOSING_INDEX???????????????????????????????????????????????????????????codeDescr?????????????????????????????????????????????????????????????????????LetterTemplateGlobals???????????????????????????????????????????????????????????????????????????????????????????CLOSING_INDEX?????????cndHeader???????????????????setName???????????????????????????localCodes??????????????????????????????????????LetterTemplateGlobals????????????????????????????????????????????????????????????HEADER_INDEX??????????????????????????????????????????????????????????????????????????getDescription?????????cndBody?????????????????setName?????????????????????????localCodes????????????????????????????????????LetterTemplateGlobals??????????????????????????????????????????????????????????BODY_INDEX??????????????????????????????????????????????????????????????????????getDescription?????????cndClosing????????????????????setName????????????????????????????localCodes???????????????????????????????????????LetterTemplateGlobals?????????????????????????????????????????????????????????????CLOSING_INDEX????????????????????????????????????????????????????????????????????????????getDescription?????????cleanComponentsNamesCodes???????????????ex??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????cleanComponentsNamesCodes???????cndHeader?????????????????setName???????cndBody???????????????setName???????cndClosing??????????????????setName???????localCodes??????????????????LetterTemplateGlobals????????????????????????????????????????HEADER_INDEX??????????????????????????????????????????????????????setCode??????????????????????????????????????????????????????????????LetterTemplateGlobals????????????????????????????????????????????????????????????????????????????????????UNDEF???????localCodes??????????????????LetterTemplateGlobals????????????????????????????????????????BODY_INDEX????????????????????????????????????????????????????setCode????????????????????????????????????????????????????????????LetterTemplateGlobals??????????????????????????????????????????????????????????????????????????????????UNDEF???????localCodes??????????????????LetterTemplateGlobals????????????????????????????????????????CLOSING_INDEX???????????????????????????????????????????????????????setCode???????????????????????????????????????????????????????????????LetterTemplateGlobals?????????????????????????????????????????????????????????????????????????????????????UNDEF??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????copyResult?????????????????????????????CodeDescription?????????????????????????????????????????????????????CodeDescription??????????????????????i??????????????????????????LetterTemplateGlobals????????????????????????????????????????????????RESPONSE??????????????????????????????????????????????????????????i?????????to????????????i???????????????setCode???????????????????????from????????????????????????????i???????????????????????????????getCode?????????to????????????i???????????????setDescription??????????????????????????????from???????????????????????????????????i??????????????????????????????????????getDescription?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????putResult????????????????????????????CodeDescription???????to?????????setDescription??????????LetterTemplateGlobals????????????????????????????????TEMPLATE_INDEX????????????????????????txtTemplateName???????to?????????setDescription??????????LetterTemplateGlobals????????????????????????????????HEADER_INDEX????????????????????????cndHeader??????????????????????????????????getName???????to?????????setDescription??????????LetterTemplateGlobals????????????????????????????????BODY_INDEX????????????????????????cndBody????????????????????????????????getName???????to?????????setDescription??????????LetterTemplateGlobals????????????????????????????????CLOSING_INDEX????????????????????????cndClosing???????????????????????????????????getName???????to?????????setCode??????????CATEGORY?????????????????localCodes????????????????????????????CATEGORY??????????????????????????????????????getCode???????to?????????setDescription??????????CATEGORY????????????????????????localCodes???????????????????????????????????CATEGORY?????????????????????????????????????????????getDescription?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????checkOverwrite???????????????????????????boolean??????????cdTempl?????????????????????????????????????????????????????????????????????CodeDescription?????????CodeDescription?????????????????????????assocDescription?????????txtTemplateName?????????????????????????????????????????????????????????cdTempl???????res???????????LetterTemplateGlobals?????????????????????????????????TEMPLATE_INDEX????????????????????????????????????????????????????cd??????????cndHeader??????????????????????????????????????????????????????????????????????????headers??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????cd????????????CodeDescription????????????????????????????assocDescription?????????????????????????????????????????????cndHeader???????????????????????????????????????????????????????getName??????????????????????????????????????????????????????????????????headers???????res???????????LetterTemplateGlobals?????????????????????????????????HEADER_INDEX??????????????????????????????????????????????????cd???????cd????????????CodeDescription????????????????????????????assocDescription?????????????????????????????????????????????cndBody?????????????????????????????????????????????????????getName????????????????????????????????????????????????????????????????bodies???????res???????????LetterTemplateGlobals?????????????????????????????????BODY_INDEX????????????????????????????????????????????????cd???????cd????????????CodeDescription????????????????????????????assocDescription?????????????????????????????????????????????cndClosing????????????????????????????????????????????????????????getName???????????????????????????????????????????????????????????????????closings???????res???????????LetterTemplateGlobals?????????????????????????????????CLOSING_INDEX???????????????????????????????????????????????????cd????????????????????????????????res??????????????????????????????????????????res????????????????????????????????????????????????????res??????????????????????????????????????????????????????????????res??????????someoneChanges????????????????res???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????checkOverwritteWithNew??????????template???????????????????getHeader???????????????????????????????getCode????????????????????????????????????????????LetterTemplateGlobals??????????????????????????????????????????????????????????????????UNDEF?????????res??????????template???????????????????getBody?????????????????????????????getCode??????????????????????????????????????????LetterTemplateGlobals????????????????????????????????????????????????????????????????UNDEF?????????res??????????template???????????????????getClosing????????????????????????????????getCode?????????????????????????????????????????????LetterTemplateGlobals???????????????????????????????????????????????????????????????????UNDEF?????????res??????????res????????????????res???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????checkValidNames??????????includeTemplate???????????????????????????????????????????????????????????????????????????????????????check?????????????????UtilOnJdk???????????????????????????isValidName???????????????????????????????????????txtTemplateName????????????check???????????res??????????????????res?????????????????????????????????????txtTemplateName?????????????????????????????????????????check???????check???????????????UtilOnJdk?????????????????????????isValidName?????????????????????????????????????cndHeader???????????????????????????????????????????????getName??????????check?????????res????????????????res?????????????????????????????????cndHeader?????????????????setName?????????????????????????????????check????????????????????????????????????????????????????????????????????????????????????????????????????????????????????check???????????????UtilOnJdk?????????????????????????isValidName?????????????????????????????????????cndBody?????????????????????????????????????????????getName??????????check?????????res????????????????res?????????????????????????????????cndBody???????????????setName???????????????????????????????check????????????????????????????????????????????????????????????????????????????????????????????????????????????????check???????????????UtilOnJdk?????????????????????????isValidName?????????????????????????????????????cndClosing????????????????????????????????????????????????getName??????????check?????????res????????????????res?????????????????????????????????cndClosing??????????????????setName??????????????????????????????????check??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????saveWarningMessage??????????overwrite????????????????????LetterTemplateGlobals??????????????????????????????????????????TEMPLATE_INDEX?????????res?????????????txtTemplateName??????????overwrite????????????????????LetterTemplateGlobals??????????????????????????????????????????HEADER_INDEX?????????res?????????????cndHeader???????????????????????getName??????????overwrite????????????????????LetterTemplateGlobals??????????????????????????????????????????BODY_INDEX?????????res?????????????cndBody?????????????????????getName??????????overwrite????????????????????LetterTemplateGlobals??????????????????????????????????????????CLOSING_INDEX?????????res?????????????cndClosing????????????????????????getName???????res??????????????res?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????MarginDialog??????????????????????????????JDialog????????????????????????????????????????????????????????????????????????????????TWIPS_IN_INCH???????????????????????????????????????????????????????????????????????????????????????????MAX_HOR_INCH?????????????????????????????????????????????????????????????????????????????????????????MAX_VERT_INCH?????????????????????????????????????????????????????????????????????????????????????????????????????MAX_HOR???????????????????????????????????????TWIPS_IN_INCH???????????????????????????????????????????????????????MAX_HOR_INCH???????????????????????????????????????????????????????????????????????????????????????????????????MAX_VERT????????????????????????????????????????TWIPS_IN_INCH????????????????????????????????????????????????????????MAX_VERT_INCH????????????lblTitle????????????pnlInf?????????????btnOK?????????????btnCancel????????????pnlCtrl????????????lblLeft????????????lblRight????????????lblTop????????????lblBottom????????????????txtLeft????????????????txtRight????????????????txtTop????????????????txtBottom???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????answer?????????????????????????????????????????????????????????????????????left??????????????????????????????????????????????????????????????????????right????????????????????????????????????????????????????????????????????top???????????????????????????????????????????????????????????????????????bottom???????????????????????????????????????????????????????????????????????????????df???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????MarginDialog?????????????????????answer???????????????????left????????????????????right?????????????????????bottom??????????????????top???????df???????????????????????????nf???????df???????df???????df???????df???????guiInit??????????????????????????????????????????????????????????????????????guiInit???????lblTitle???????lblTitle???????lblTitle????????????????????????????lblTitle???????pnlCtrl???????pnlCtrl???????????????????lblLeft???????pnlCtrl???????????????????txtLeft???????txtLeft???????????????????????????????DoubleDocument???????setMargin?????????????????left???????????????????????txtLeft???????pnlCtrl???????????????????lblRight???????pnlCtrl???????????????????txtRight???????txtRight????????????????????????????????DoubleDocument???????setMargin?????????????????right????????????????????????txtRight???????pnlCtrl???????????????????lblTop???????pnlCtrl???????????????????txtTop???????txtTop??????????????????????????????DoubleDocument???????setMargin?????????????????top??????????????????????txtTop???????pnlCtrl???????????????????lblBottom???????pnlCtrl???????????????????txtBottom???????txtBottom?????????????????????????????????DoubleDocument???????setMargin?????????????????bottom?????????????????????????txtBottom???????pnlCtrl????????????????????????????pnlCtrl???????pnlInf??????????????????btnOK???????pnlInf??????????????????btnCancel????????????????????????????pnlInf???????btnOK???????????????answer???????????????????????????checkDouble???????????????????????????????????????????????????????????txtLeft????????????????????????????????????????????????????????????????????MAX_HOR???????????????answer???????????????????????????checkDouble????????????????????????????????????????????????????????????txtRight??????????????????????????????????????????????????????????????????????MAX_HOR???????????????checkAdd????????????????????????answer???????????????????????????????????answer??????????????????????????????????????????????MAX_HOR???????????????????????????????????????????????????????txtRight???????????????answer???????????????????????????checkDouble??????????????????????????????????????????????????????????txtTop??????????????????????????????????????????????????????????????????MAX_VERT???????????????answer???????????????????????????checkDouble?????????????????????????????????????????????????????????????txtBottom????????????????????????????????????????????????????????????????????????MAX_VERT???????????????checkAdd????????????????????????answer???????????????????????????????????answer??????????????????????????????????????????????MAX_VERT????????????????????????????????????????????????????????txtBottom?????????????answer?????????????MarginDialog???????btnCancel?????????????answer?????????????MarginDialog????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????checkDouble?????????????????????????????????????????txt????????????????????????????val??????????????????????????????????TWIPS_IN_INCH????????????margin?????????????????????max?????????????????????????????????????????MarginDialog??????????????????????????msg???????????val?????????????????????????max???????????????????????????????TWIPS_IN_INCH???????????txt???????????????????????df?????????????????????????????????val???????????txt????????????????margin???????????????????????????????????????MarginDialog???????????????????????????????????????????????????????????????????????msg?????????txt???????????????pex????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????checkAdd???????????first???????????????????snd??????????????????????????maxadd???????????????????????????????????????MarginDialog?????????sndTxt?????????sndTxt??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setMargin?????????????????????????????twips?????????????????????????????????????TWIPS_IN_INCH???????txt???????????????????df?????????????????????????????size???????????????????????????????????????????????????????????????????????????????????????????????????????????????????setTitle???????lblTitle????????????????????????s??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????VariableFormatInsertion?????????????????actionPerformed???????????????lbcFormat?????????????????????????getCombo??????????????????????????????varFormats?????????????????????????????????????????i????????????????????????????????????????????getCode???????selectedTed???????????????????setVarFormatAttribute?????????????????????????????????????????format???????selectedTed??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????SaveAsComponentDialog???????????????????????????????????????JDialog??????????????????????????gridLyt???????????????ComponentNameDisplay????????????????????????????????????compDisplay??????????????????????pnlOkCancel???????????????????????btnOK???????????????????????btnCancel??????????????????????lblTitle????????????????????????????????????????????????????????????????????CodeDescription?????????????????????????????answer???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????SaveAsComponentDialog??????????????????????????????????CodeDescription????????????????????????????????????????????CodeDescription?????????????????????answer???????gridLyt???????????????????????????????????????gridLyt???????compDisplay?????????????????????????ComponentNameDisplay??????????????????????????????????????????????cmpNames????????????????????????????????????????????????????????compType??????????????????????????????????????????????????????????????????mode???????lblTitle????????????????????????????????????????????????????????????????compType???????pnlOkCancel???????????????????????btnOK???????pnlOkCancel???????????????????????btnCancel???????lblTitle?????????????????????????????????lblTitle???????compDisplay?????????????????????????????????compDisplay?????????????????????????????????pnlOkCancel???????btnOK????????????????????????compDisplay????????????????????????????????????getName????????????????????????????UtilOnJdk??????????????????????????????????????isValidName??????????????????????????????????????????????????s????????????????check?????????????????????????????????check??????????????????r???????????????????????UtilOnJdk?????????????????????????????????VOID_NAME????????????????????????????????s?????????????SaveAsComponentDialog????????????????????????????????????????answer???????????????????????????????????????????????setDescription??????????????????????????????????????????????????????????????????????check?????????????SaveAsComponentDialog????????????????????????????????????????answer???????????????????????????????????????????????setCode?????????????SaveAsComponentDialog???????btnCancel?????????????SaveAsComponentDialog????????????????????????????????????????answer???????????????????????????????????????????????setCode?????????????SaveAsComponentDialog???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????TemplateCodes??????????????????????????????????????????????????????????????????????code????????????????????????????????????????????????????????????????????????name??????????????????????????????????????????????????????????????????????????????stamp??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????TemplateCodes???????code??????????????c???????name??????????????n???????stamp???????????????s?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????TemplateCodes???????code??????????????LetterTemplateGlobals????????????????????????????????????UNDEF???????name??????????????LetterTemplateGlobals????????????????????????????????????STR_UNDEF???????stamp???????????????LetterTemplateGlobals?????????????????????????????????????STR_UNDEF???????????????????????????????