1    /*
2    Copyright 2001 by Ralph Hartley
3    This software is licenced under the terms of the
4    Gnu Public Licence
5    */
6    //package carto;
7    
8    import java.awt.*;
9    import javax.swing.*;
10   import java.awt.event.*;
11   import java.awt.image.*;
12   import java.util.*;
13   import java.io.*;
14   
15   public class CompEditor extends Editor{
16   
17     static public int TYPE = 1;
18   
19     public static String SURVEY = "Survey";
20     public static String HASSURVEY = "Surv";
21     public static String PLAN = "Plan";
22     public static String MERGE = "Merge...";
23   
24     public static String COPY = "Copy";
25     public static String PASTE = "Paste";
26     public static String CUT = "Cut";
27     public static String CLEARBUF = "Clear Paste Buffer";
28   
29     public static String ALL = "All";
30     public static String NONE = "None";
31     public static String INVERT = "Invert";
32   
33     public static String FRONT = "Bring to Top";
34     public static String BACK = "Push to Bottom";
35     public static String FORWARD = "Move Up";
36     public static String BACKWARD = "Move Down";
37   
38     public static String SUBEDIT = "Sub-Composite edit";
39     public static String ENDEDIT = "End Sub-Composite";
40   
41     public static String SELECT = "Select mode";
42     public static String SUBSELECT = "SubSelect mode";
43     public static String ADD = "Add curve";
44     public static String ZOOM = "Zoom";
45     public static String HAND = "Hand";
46     public static String DELETE = "Delete";
47     public static String NEWCURVE = "New curve";
48     public static String SMOOTHCURVE = "Smooth";
49     public static String LINETYPE = "Line type";
50     public static String FLIP = "Flip";
51     public static String FILLTYPE = "Fill type";
52     public static String NEWSEG = "New Seg";
53     public static String ADDSEG = "Add Seg";
54     public static String NEWPAS = "New Passage";
55     public static String ADDPAS = "Add Passage";
56     public static String NEWPHOTO = "Add Photo";
57     public static String NEWSECTION = "New XSection";
58     public static String NEWSUB = "New Sub";
59     public static String NEWRECT = "New Rect";
60     public static String NEWPAGE = "New Page";
61     public static String NEWOFFSET = "New Offset";
62     public static String LIBITEM = "New Libitem";
63     public static String TEXT = "Text";
64     public static String NOFILL = "No Fill";
65   
66     public static String BLACK = "Black";
67     public static String RED = "Red";
68     public static String GREEN = "Green";
69     public static String BLUE = "Blue";
70   
71     public static String VIEWTRANS = "Transform";
72     public static String VIEWALL = "Show All";
73     public static String SETLAYER = "Set Layer";
74   
75     public static String ALIGN = "Align";
76     public static String VIEWALIGN = "Show Aln";
77     public static String ALIGNSET = "Aligner";
78     
79     CompPane pane;
80     JPanel pallete;
81     ButtonGroup selectgroup;
82   
83     Comp rootsymbol;
84   
85     JButton atbutton;
86     JButton fillbutton;
87     JButton addsegbutton;
88     JButton addsubbutton;
89   
90     JLabel layerlabel;
91   
92     Alignment alignment = new Alignment();;
93   
94     public CompEditor(Comp root,CartoFrame frame) {
95       this(root,frame,true);
96     }
97   
98     public CompEditor(Comp root,CartoFrame frame,boolean insert) {
99       super(frame,root.name,true,true,true,true,insert);
100  
101      rootsymbol = root;
102      target = root;
103  
104      JMenu menu = new JMenu("View");
105      menu.setMnemonic('v');
106      addMenuItem(menu,VIEWTRANS,'m');
107      addMenuItem(menu,VIEWALL);
108      addMenuItem(menu,SETLAYER);
109      addMenuItem(menu,VIEWALIGN);
110      bar.add(menu);
111  //    addMenuItem(menu,SURVEY);
112  //    addMenuItem(menu,MERGE);
113  //    addMenuItem(menu,CLOSE);
114  
115      menu = new JMenu("Edit");
116      menu.setMnemonic('e');
117      bar.add(menu);
118      addMenuItem(menu,CUT,'t');
119      addMenuItem(menu,COPY,'c');
120      addMenuItem(menu,PASTE,'p');
121      addMenuItem(menu,CLEARBUF,'l');
122      addMenuItem(menu,DELETE,'d');
123  
124      menu = new JMenu("Select");
125      menu.setMnemonic('t');
126      bar.add(menu);
127      addMenuItem(menu,SELECT,'s');
128      addMenuItem(menu,SUBSELECT,'u');
129      addMenuItem(menu,ALL,'a');
130      addMenuItem(menu,NONE,'n');
131      addMenuItem(menu,INVERT,'i');
132      addMenuItem(menu,BLACK,'b');
133      addMenuItem(menu,RED,'r');
134      addMenuItem(menu,GREEN,'g');
135      addMenuItem(menu,BLUE,'l');
136  
137      menu = new JMenu("Arrange");
138      menu.setMnemonic('a');
139      bar.add(menu);
140      addMenuItem(menu,FRONT,'t');
141      addMenuItem(menu,BACK,'b');
142      addMenuItem(menu,FORWARD,'u');
143      addMenuItem(menu,BACKWARD,'d');
144      addMenuItem(menu,ALIGNSET,'s');
145      addMenuItem(menu,ALIGN,'a');
146  
147      menu = new JMenu("mode");
148      menu.setMnemonic('o');
149      addMenuItem(menu,TEXT,'x');
150      addMenuItem(menu,ZOOM,'z');
151      addMenuItem(menu,HAND,'h');
152      addMenuItem(menu,NEWCURVE,'c');
153      addMenuItem(menu,ADD,'d');
154      addMenuItem(menu,SMOOTHCURVE,'s');
155      addMenuItem(menu,DELETE,'l');
156      addMenuItem(menu,NEWSUB,'u');
157      addMenuItem(menu,NEWSEG,'g');
158      addMenuItem(menu,ADDSEG,'e');
159      addMenuItem(menu,NEWPAS,'w');
160      addMenuItem(menu,ADDPAS,'q');
161      addMenuItem(menu,NEWSECTION,'o');
162      addMenuItem(menu,NEWPAGE,'p');
163      addMenuItem(menu,NEWRECT,'r');
164      addMenuItem(menu,NEWOFFSET,'t');
165      addMenuItem(menu,LINETYPE,'y');
166      addMenuItem(menu,FLIP,'f');
167      addMenuItem(menu,NOFILL,'i');
168      addMenuItem(menu,FILLTYPE,'k');
169      addMenuItem(menu,VIEWALL,'v');
170      addMenuItem(menu,SETLAYER,'a');
171      addMenuItem(menu,NEWPHOTO,'m');
172      bar.add(menu);
173  
174      pane = new CompPane(this);
175      add(scroll=pane.getScrollPane(),BorderLayout.CENTER);
176  
177      scale = new Scale(1,pane);
178      add(scale,BorderLayout.SOUTH);
179  
180      pallete = new JPanel();
181      selectgroup = new ButtonGroup();
182      pallete.setBackground(Color.pink);
183      pallete.setLayout(new GridLayout(9,4));
184  
185      addButton("select",SELECT,CompPane.SELECT);
186      JToggleButton subsel = (JToggleButton)addButton("subselect",SUBSELECT,CompPane.SUBSELECT);
187      addButton("alpha",TEXT,CompPane.NEW);
188      addButton("delete",DELETE);
189      
190      ButtonGroup group = new ButtonGroup();
191      group.add(addButton("select",BLACK,-1));
192      group.add(addButton("selred",RED,-1));
193      group.add(addButton("selgreen",GREEN,-1));
194      group.add(addButton("selblue",BLUE,-1));
195  
196      addButton("magnify",ZOOM,CompPane.ZOOM);
197      addButton("hand",HAND,CompPane.HAND);
198      addButton();
199      addButton();
200  
201      addButton("new",NEWCURVE,CompPane.NEW);
202      addButton("add",ADD,CompPane.ADD);
203      addButton("corner",SMOOTHCURVE,CompPane.SMOOTH|CompPane.SUBSELECT);
204      addButton();
205  
206      addButton("page",NEWPAGE,CompPane.NEW);
207      addButton("rectangle",NEWRECT,CompPane.NEW);
208      addButton("offset",NEWOFFSET,CompPane.NEW);
209      addButton("photo",NEWPHOTO,CompPane.NEW);
210  
211      addButton("addpas",ADDPAS);
212      addButton("newpas",NEWPAS);
213      addButton("addsub",NEWSUB,CompPane.NEW);
214      addButton(new Library(
215        new File(Carto.filebase,"symbol"),
216        new LibraryUserRep(frame,Glyph.class)));
217  //    addButton(new Library(new File(Carto.filebase,"stamp"),
218  //        		  new LibraryUserRep(frame,Stamp.class)));
219  
220      addButton("addseg",ADDSEG);
221      addButton("newseg",NEWSEG);
222      addButton("section",NEWSECTION,CompPane.NEW);
223      addButton();
224  
225      addButton("atributes",LINETYPE);
226      addButton("flip",FLIP);
227      addButton();
228      addButton();
229  
230      addButton("nofill",NOFILL);
231      addButton(new Library(new File(Carto.filebase,"fill"),
232          		  new ImageIcon(getClass().getResource("icons/fill.gif")),
233          		  new LibraryUserRep(frame,Fill.class)));
234      addButton("colors",FILLTYPE);
235      addButton();
236  
237  //    pallete.setPreferredSize(new Dimension(110,300));
238  
239      JPanel viewpan = new JPanel();
240      viewpan.setLayout(new GridLayout(1,2));
241  /*
242      JButton layerbut = new JButton(SETLAYER);
243      layerbut.addActionListener(this);
244      viewpan.add(layerbut);
245  
246      layerlabel = new JLabel(rootsymbol.visible!=null?rootsymbol.visible.getName():"No Layer (all shown)");
247      viewpan.add(layerlabel);
248  */
249  //    JPanel alignpan = new JPanel();
250      JButton button = new JButton(ALIGNSET);
251      button.addActionListener(this);
252      viewpan.add(button);
253      button = new JButton(ALIGN);
254      button.addActionListener(this);
255      viewpan.add(button);
256      
257      JPanel left = new JPanel();
258      left.setLayout(new BorderLayout());
259  
260      left.add(viewpan,"North");
261      left.add(pallete,"Center");
262      javax.swing.Box bot = new javax.swing.Box(BoxLayout.X_AXIS);
263      javax.swing.Box botleft = new javax.swing.Box(BoxLayout.Y_AXIS);
264      botleft.add(new JCheckBox(HASSURVEY,rootsymbol.survey));
265      botleft.add(new JCheckBox(PLAN,!rootsymbol.isVertical));
266      bot.add(botleft);
267  
268      rose = new Rose(pane);
269      bot.add(rose);
270  
271      left.add(bot,"South");
272  
273      add(left,"West");
274  
275      editframe.setSize(null);
276  
277      pane.contents = rootsymbol;
278  
279      scale.setValue(pane.center()); 
280  
281      subsel.doClick();
282    }
283  
284    public AbstractButton[] buttonlist = new AbstractButton[27];
285    String[] commands = new String[27];
286    int[] modes = new int[27];
287    int buttoncnt = 0;
288  
289    static ImageFilter invfilter = new RGBImageFilter() {
290        public int filterRGB(int x, int y, int rgb) {
291          if ((rgb & 0Xffffff) == 0) return(0Xffffffff);
292          if ((rgb & 0Xffffff) == 0Xffffff) return(0Xff000000);
293          return(rgb);}};
294  
295    public AbstractButton addButton(String iname,String command,int mode) {
296      AbstractButton button=null;
297  
298      Image im = Toolkit.getDefaultToolkit().createImage(getClass().getResource("icons/"+iname+".gif"));
299  
300      if (mode != 0) {
301        button = new JToggleButton();
302        if (mode>0) selectgroup.add(button);
303      }
304      else
305        button = new JButton();
306  
307      button.setIcon(new ImageIcon(im));
308      button.setSelectedIcon(new ImageIcon(createImage(new FilteredImageSource(im.getSource(), invfilter))));
309  
310      button.setToolTipText(command);
311  
312      buttonlist[buttoncnt] = button;
313      commands[buttoncnt]=command;
314      modes[buttoncnt++]=mode;
315  
316      button.setActionCommand(command);
317      insertButton(button);
318      button.addActionListener(this);
319      return(button);
320    }
321    
322    public AbstractButton addButton(String iname,String command) {
323      return(addButton(iname,command,0));
324    }
325  
326    public JButton addButton(Library lib) {
327      JButton button = new JButton();
328      button.addActionListener(lib);
329      button.setIcon(lib);
330      button.setToolTipText("library "+lib.getName());
331      insertButton(button);
332      return(button);
333    }
334  
335    public JButton addButton() {
336      JButton button = new JButton();
337      insertButton(button);
338      return(button);
339    }
340  
341    public void insertButton(AbstractButton button) {
342      button.setMargin(new Insets(0,0,0,0));
343  //    button.setMinimumSize(new Dimension(32,32,32,32));
344  //    button.setPreferredSize(new Dimension(32,32,32,32));
345  //    button.setMaximumSize(new Dimension(32,32,32,32));
346      pallete.add(button);
347    }
348  
349  //  public boolean isDirty(){
350  //    return(rootsymbol.isDirty());
351  //  }
352  
353    public void setMode(int mode) {
354      for (int i=0;i<buttoncnt;i++)
355        if (mode==modes[i]) buttonlist[i].setSelected(true);
356    }
357  
358    SavableStroke defaultstroke = new SavableStroke();
359  
360    public void actionPerformed(ActionEvent e) {
361  
362      if (e.getSource() instanceof AbstractButton) {
363        String command = ((AbstractButton)e.getSource()).getActionCommand();
364        int cnum;
365  
366        for (cnum=0;cnum<buttoncnt;cnum++)
367          if (command==commands[cnum]) break;
368  
369        if (cnum<buttoncnt) {
370  
371          if (command == LINETYPE) new LinePicker(pane.defaultlinetype,
372          					pane.defaultlinesize,
373          					pane.defaultlinecolor).display(frame);
374  
375          else if (command == FILLTYPE) {
376            pane.setFill(JColorChooser.showDialog(pane,"Fill color",pane.defaultcolor));
377          }
378  
379          else if (command == BLACK) pane.setSelection(0);
380          else if (command == RED) pane.setSelection(1);
381          else if (command == GREEN) pane.setSelection(2);
382          else if (command == BLUE) pane.setSelection(3);
383  
384          else if (command == DELETE) pane.sel.delete(pane);
385          else if (command == FLIP) pane.sel.flip();
386          else if (command == NOFILL) pane.setFill((Color)null);
387  
388          else if (command == NEWSEG) {
389            Segment newseg = new Segment(frame.carto.survey,false);
390            if (newseg.check()) {
391              frame.carto.segmentlist.add(newseg);
392              rootsymbol.add(newseg,Comp.BOTTOM);
393              frame.addEditor(newseg);
394            }
395          }
396          else if (command == ADDSEG) {
397            Object[] newseg = frame.selectFromList(frame.carto.segmentlist,
398          					 "Add Segment to Plan",
399          					 "Segment Add");
400            if (newseg!=null) {
401              for (int i=0;i<newseg.length;i++)
402                rootsymbol.add((Symbol)newseg[i],Comp.BOTTOM);
403              repaint();
404            }
405          }
406          else if (command == NEWPAS) {
407            String name = (Symbol.makenames?null:JOptionPane.showInputDialog("Name of new "+CartoFrame.COMPWORD));
408            Comp comp = new Comp(name,frame.carto.survey,false);
409            frame.carto.complist.add(comp);
410            frame.addEditor(comp);
411            rootsymbol.add(comp,Comp.BOTTOM);
412          }
413          else if (command == ADDPAS) {
414            Object[] newpas = frame.selectFromList(frame.carto.complist,
415          					 "Add Passage to Plan",
416          					 "Passgae Add");
417            if (newpas!=null) {
418              for (int i=0;i<newpas.length;i++)
419                if (newpas[i]!=rootsymbol) {
420          	((Symbol)newpas[i]).recursiveDelete(rootsymbol);
421          	rootsymbol.add((Symbol)newpas[i],Comp.BOTTOM);
422                }
423              repaint();
424            }
425          }
426          else if (command == NEWSECTION) {
427            Symbol newsec = (Symbol)frame.chooseFromList(frame.carto.complist,
428          						 "Add CrossSection to Composite",
429          						 "Section Add");
430            if (newsec!=null) {
431              pane.newtype = Section.class;
432              pane.newarg = newsec;
433            }
434          }
435          else if (command == NEWSUB) {
436            Comp newcomp = (Comp)frame.chooseFromList(frame.carto.complist,
437          					    "Add Subcomposite to Composite",
438          					    "Sub Add");
439            if (newcomp!=null) {
440              pane.newtype = Glyph.class;
441              pane.newarg = newcomp;
442            }
443          }
444          else if (command==NEWRECT) {
445            pane.newtype= Box.class;
446            pane.newarg = null;
447          }
448          else if (command==NEWPAGE) {
449            pane.newtype= Page.class;
450            pane.newarg = rootsymbol;
451          }
452          else if (command==NEWOFFSET) {
453            pane.newtype= Offset.class;
454            pane.newarg = rootsymbol;
455          }
456          else if (command==NEWPHOTO) {
457            pane.newtype= Picture.class;
458            pane.newarg = ImageFile.getImageFile(null,null);
459          }
460          else if (command==NEWCURVE) {
461            pane.newtype= Curve.class;
462            pane.newarg = null;
463          }
464          else if (command==TEXT) {
465            pane.newtype= Text.class;
466  //          pane.viewtrans = new ViewTransform(ViewTransform.ABSOLUTE);
467            pane.newarg = null;
468          }
469          if (modes[cnum]>0) pane.setMode(modes[cnum]);
470        }
471        else if (command == VIEWTRANS) {
472  //        ErrorLog.log("viewtrans");
473          PrefTrans tra = new PrefTrans(scale,rose,pane);
474          if (JOptionPane.OK_OPTION==JOptionPane.showConfirmDialog(this,
475          							 tra.getPane(frame)))
476            tra.save();
477          tra.abandon();
478          repaint();
479        }
480            
481        else {
482          if (command == FRONT) rootsymbol.change_level(pane.sel.selection,Comp.TOP);
483          else if ((command == COPY) || (command == CUT)) {
484            pane.sel.copy();
485            if (command == CUT) pane.sel.delete(pane);
486          }
487          else if (command == PASTE) {
488            pane.sel.delete(pane);
489            frame.carto.cutbuffer.paste(pane);
490          }
491          else if (command == CLEARBUF) {
492            frame.carto.cutbuffer = null;
493          }
494          else if (command == BACK) rootsymbol.change_level(pane.sel.selection,Comp.BOTTOM);
495          else if (command == FORWARD) rootsymbol.change_level(pane.sel.selection,Comp.ABOVE);
496          else if (command == BACKWARD) rootsymbol.change_level(pane.sel.selection,Comp.BELOW);
497          else if (command == ALL) pane.sel.selectAll(rootsymbol);
498          else if (command == NONE) pane.sel.clearSelection();
499          else if (command == INVERT) pane.sel.invertSelection(rootsymbol);
500          else if (command == VIEWALL) rootsymbol.showall = ((AbstractButton)e.getSource()).isSelected();
501          else if (command == VIEWALIGN) pane.view.showalign = ((AbstractButton)e.getSource()).isSelected();
502          else if (command == ALIGNSET) alignment.setSource(pane.sel.oneSelection());
503          else if (command == ALIGN) {
504            alignment.setTargets(pane.sel.selectionOrSub());
505            if (JOptionPane.OK_OPTION == 
506                JOptionPane.showConfirmDialog(this,
507          				    alignment.getPane(frame)))
508              alignment.save();
509            alignment.abandon();
510            pane.repaint();
511          }
512  
513          else if (command == SETLAYER) {
514            Object[] all = FileDefaultable.getAll(Layer.class,frame.carto.defaults);
515            Layer newlayer = (Layer)JOptionPane.showInputDialog(this,
516          						      "Choose the visible Filter",
517          						      "Set Filter",
518          						      JOptionPane.QUESTION_MESSAGE,
519          						      null,
520          						      all,
521          						      all[0]);
522            if (newlayer!=null) {
523              rootsymbol.visible = newlayer;
524              layerlabel.setText(newlayer.getName());
525            }
526          }
527          pane.repaint();
528        }
529        frame.requestFocus();
530      }
531    }
532  
533    void cleanup() {
534      super.cleanup();
535      rootsymbol =null;
536      alignment = null;
537      pallete=null;
538      selectgroup=null;
539      atbutton=null;
540      fillbutton=null;
541      addsegbutton=null;
542      addsubbutton=null;
543      layerlabel=null;
544  
545      if (pane!=null) pane.cleanup();
546      pane = null;
547    }
548  
549  }
550  
551