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 javax.swing.event.*;
11   import java.awt.event.*;
12   import java.util.*;
13   import java.io.*;
14   
15   public class SegEditor extends Editor
16     implements MouseListener,MouseMotionListener,ListSelectionListener,DocumentListener {
17   
18     static public int TYPE = 2;
19   
20     static int LOCATEMODE = 0;
21     static int MOVEMODE = 1;
22     static int SELECTMODE = 2;
23     static int DELETEMODE = 3;
24   
25     public static String COOK = "Morph";
26     public static String DELETE = "Delete";
27     public static String LOCATE = "Mark";
28     public static String MOVE = "Move";
29     public static String STATION = "Station";
30     public static String BOUNDARY = "Boundary";
31     public static String READIMAGE = "Reload Image";
32     public static String CHANGEIMAGE = "Change Image...";
33   
34     int mode = LOCATEMODE;
35     SegPane pane;
36     Segment seg;
37   //  boolean dirty = false;
38     JScrollPane window;
39   
40     public ThreadMessage status =null;
41   
42     JTextField stationfield;
43     JTextField scalefield;
44     JList stationlist;
45   
46     JCheckBox transparentfield;
47     JCheckBox verticalfield;
48   //  JTextField densityfield;
49   
50     JCheckBox stationmodebox;
51     JCheckBox boundarymodebox;
52     JToggleButton locatemodebutton;
53     JToggleButton movemodebutton;
54     JToggleButton deletemodebutton;
55   
56     Dragable mousetarget;
57     Vector stationset = new Vector();
58   
59     public SegEditor(Segment seg,CartoFrame frame) {
60       super(frame,seg.name,true,true,true,true);
61       init(seg,frame);
62     }
63   
64     public SegEditor(Segment seg,CartoFrame frame,boolean insert) {
65       super(frame);
66       init(seg,frame);
67     }
68   
69     public void init(Segment seg,CartoFrame frame) {
70       this.seg = seg;
71       seg.map.editor = this;
72   
73       JMenu menu = new JMenu("Segment");
74       menu.setMnemonic('g');
75   
76       bar.add(menu);
77       addMenuItem(menu,COOK,'m');
78       addMenuItem(menu,CLOSE,'c');
79       addMenuItem(menu,STATION,'n');
80       addMenuItem(menu,READIMAGE,'l');
81       addMenuItem(menu,CHANGEIMAGE,'f');
82       addMenuItem(menu,BOUNDARY,'b');
83       addMenuItem(menu,LOCATE,'a');
84       addMenuItem(menu,MOVE,'v');
85       addMenuItem(menu,DELETE,'d');
86   
87       pane = new SegPane();
88       pane.addMouseListener(this);
89       pane.addMouseMotionListener(this);
90   
91       add(scroll=pane.getScrollPane(),BorderLayout.CENTER);
92   
93       add(scale = new Scale(1,pane),BorderLayout.SOUTH);
94   
95       JPanel left = new JPanel();
96       left.setLayout(new GridLayout(4,1));
97   
98       JPanel vtop = new JPanel();
99       vtop.setLayout(new GridLayout(2,1));
100  
101  //    densityfield = PrefEditor.addDouble(vtop,seg.density,"Density %",5);
102  
103  //    JPanel subpane = new JPanel();
104  //    subpane.add(new JLabel("Density %"));
105  //    densityfield = new JTextField(""+seg.density,5);
106  //    subpane.add(densityfield);
107  //    vtop.add(subpane);
108  
109      transparentfield = new JCheckBox("Transparent",seg.transparent);
110      transparentfield.setToolTipText("Make white pixels transparent (Deprecated)");
111      vtop.add(transparentfield);
112  
113      verticalfield = new JCheckBox("Vertical",seg.map.isVertical);
114      vtop.add(verticalfield);
115  
116      scalefield = PrefEditor.addDouble(vtop,seg.map.getScale(),"Scale",8);
117  
118      left.add(vtop);
119  
120      JPanel top = new JPanel();
121      top.setLayout(new GridLayout(2,1));
122      status = new ThreadMessage("");
123      top.add(status);
124  
125      JPanel pallete = new JPanel();
126      ButtonGroup modegroup = new ButtonGroup();
127      stationmodebox = new JCheckBox(STATION);
128      stationmodebox.setSelected(true);
129      stationmodebox.addActionListener(this);
130      stationmodebox.setToolTipText("edit station positions");
131      modegroup.add(stationmodebox);
132      pallete.add(stationmodebox);
133  
134      boundarymodebox = new JCheckBox(BOUNDARY);
135      boundarymodebox.addActionListener(this);
136      boundarymodebox.setSelected(false);
137      boundarymodebox.setToolTipText("edit boundary of segment");
138      modegroup.add(boundarymodebox);
139      pallete.add(boundarymodebox);
140  
141      top.add(pallete);
142      left.add(top);
143     
144      pallete = new JPanel();
145      pallete.setLayout(new GridLayout(1,3));
146      ButtonGroup selectgroup = new ButtonGroup();
147      pallete.setBackground(Color.pink);
148      
149      JToggleButton tbutton = new JToggleButton(new ImageIcon(getClass().getResource("icons/seglocate.gif")));
150      tbutton.setActionCommand(LOCATE);
151      tbutton.setSelected(true);
152      tbutton.setToolTipText("Add new points");
153      tbutton.addActionListener(this);
154      pallete.add(tbutton);
155      selectgroup.add(tbutton);
156      locatemodebutton = tbutton;
157  
158      tbutton = new JToggleButton(new ImageIcon(getClass().getResource("icons/segmove.gif")));
159      tbutton.setActionCommand(MOVE);
160      tbutton.setToolTipText("Move existing points");
161      tbutton.addActionListener(this);
162      pallete.add(tbutton);
163      selectgroup.add(tbutton);
164      movemodebutton = tbutton;
165  
166      tbutton = new JToggleButton(new ImageIcon(getClass().getResource("icons/segdelete.gif")));
167      tbutton.setActionCommand(DELETE);
168      tbutton.setToolTipText("Delete points");
169      tbutton.addActionListener(this);
170      pallete.add(tbutton);
171      selectgroup.add(tbutton);
172      deletemodebutton = tbutton;
173  
174      left.add(pallete);
175  
176      pallete = new JPanel();
177      JButton button = new JButton(COOK);
178      button.addActionListener(this);
179      button.setToolTipText("Remorph this segment");
180      pallete.add(button);
181      pallete.add(new JLabel("Station:"));
182      stationfield = new JTextField();
183      stationfield.setToolTipText("Enter # of station to locate");
184      stationfield.getDocument().addDocumentListener(this);
185      stationfield.setColumns(5);
186      pallete.add(stationfield);
187  
188      left.add(pallete);
189  
190      JPanel controls = new JPanel();
191      controls.setLayout(new BorderLayout());
192      controls.add(left,"North");
193      JScrollPane stationlistpane = new JScrollPane();
194      controls.add(stationlistpane,"Center");
195  
196      add(controls,"West");
197  
198      editframe.setSize(null);
199  
200      target = seg;
201      pane.seg = seg;
202  
203      for (Iterator e=seg.set.stations.iterator();e.hasNext();)
204        stationset.add(new StationItem((Vertex)(e.next())));
205      stationlist = new JList(stationset) {public void paint(Graphics g) {checkMarked();super.paint(g);}};
206      if (seg.map.selected!=-1) stationlist.setSelectedIndex(seg.map.selected);
207      else stationlist.setSelectedIndex(0);
208      stationlist.addListSelectionListener(this);
209      stationlistpane.setViewportView(stationlist);
210      stationlist.setToolTipText("Select station to locate");
211  
212      mousetarget = seg.map;
213  
214      pane.image = seg.getImage();
215  
216      if (seg.set.stations.contains(new Vertex(seg.name))) {
217        stationfield.setText(seg.name);
218        selectByLabel(seg.name);
219      }
220  
221  //    seg.getMorphStatusString(status);
222    }
223  
224    public void fitScale() {
225      int width=-1,height=-1;
226      Image raw = pane.image;
227      if (raw == null) return;
228      try {
229        for (width= -1;width<0;width = raw.getWidth(pane)) Thread.sleep(50);
230        for (height= -1;height<0;height = raw.getHeight(pane)) Thread.sleep(50);
231      } catch(InterruptedException e){ErrorLog.exception(e);};
232  
233      Dimension size = scroll.getViewport().getSize();
234      
235      double scale1 = size.getWidth()/width;
236      double scale2 = size.getHeight()/height;
237  
238      if (scale1>scale2) scale.change(scale1);
239      scale.change(scale2);
240    }
241  
242    public void cleanup() {
243      if (seg!=null && seg.map!=null) seg.map.editor = null;
244      seg=null;
245      stationset=null;
246      window=null;
247      status=null;
248      stationfield=null;
249      scalefield=null;
250      stationlist=null;
251      transparentfield=null;
252      verticalfield=null;
253  //    densityfield=null;
254      stationmodebox=null;
255      boundarymodebox=null;
256      locatemodebutton=null;
257      movemodebutton=null;
258      deletemodebutton=null;
259      mousetarget=null;
260  
261      if (pane !=null) pane.cleanup();
262      pane=null;
263      super.cleanup();
264    }
265  
266    public boolean isDirty(){
267      return(seg.isDirty());
268    }
269  
270    public void valueChanged(ListSelectionEvent e) {
271      seg.map.setSelection(((StationItem)stationlist.getSelectedValue()).station);
272      pane.repaint();
273    }
274  
275    public void insertUpdate(javax.swing.event.DocumentEvent e) {
276      selectByLabel(stationfield.getText());
277    }
278    public void removeUpdate(javax.swing.event.DocumentEvent e) {
279      selectByLabel(stationfield.getText());
280    }
281    public void changedUpdate(javax.swing.event.DocumentEvent e) {
282      selectByLabel(stationfield.getText());
283    }
284  
285    public void saveData() {
286      if (seg==null) return;
287      try {
288  //      if (densityfield!=null && densityfield.getText()!=null)
289  // seg.density = Double.parseDouble(densityfield.getText());
290        if (scalefield!=null && scalefield.getText()!=null)
291          seg.map.setScale(Double.parseDouble(scalefield.getText()));
292      } catch (NumberFormatException ex) {
293  //      seg.density=Segment.defdensity;
294      }
295      //    seg.density = 1;
296  //    if (seg.density>1) seg.density=1;
297  //    if (seg.density<0) seg.density=0;
298  //    if (densityfield!=null) densityfield.setText(""+seg.density);
299  //    seg.transparent = false;
300      seg.transparent = transparentfield.isSelected();
301      if (verticalfield!=null) seg.map.isVertical = verticalfield.isSelected();
302    }
303  
304    public void actionPerformed(ActionEvent e) {
305  
306      if (e.getSource() instanceof AbstractButton) {
307        String command = ((AbstractButton)e.getSource()).getActionCommand();
308  
309        if (command == READIMAGE) {
310          seg.isource.image = null;
311          pane.image = seg.getImage();
312        }
313  
314        else if (command == CHANGEIMAGE) {
315          File old = seg.isource.source;
316          seg.isource.source = null;
317          if (!seg.isource.check(null,null)) 
318            seg.isource.source = old;
319          if (seg.isource.source != old)
320            pane.image = seg.getImage();
321        }
322  
323        else if (command == COOK) {
324          saveData();
325          seg.doCook(this);
326        }
327  
328        else if (command == DELETE) {
329          deletemodebutton.setSelected(true);
330          mode = DELETEMODE;
331        }
332  
333        else if (command == LOCATE) {
334          locatemodebutton.setSelected(true);
335          mode = LOCATEMODE;
336        }
337  
338        else if (command == MOVE) {
339          movemodebutton.setSelected(true);
340          mode = MOVEMODE;
341        }
342  
343        else if (command == STATION) {
344          stationmodebox.setSelected(true);
345          mousetarget = seg.map;
346        }
347  
348        else if (command == BOUNDARY) {
349          mousetarget = seg.boundary;
350          boundarymodebox.setSelected(true);
351        }
352        if (command == CLOSE) {
353          cleanup();
354  //        setClosed(true);
355        }
356  
357        frame.requestFocus();
358      }
359    }
360  
361  
362    public void mouseClicked(java.awt.event.MouseEvent e) {}
363    public void mouseEntered(java.awt.event.MouseEvent e) {}
364    public void mouseExited(java.awt.event.MouseEvent e) {}
365    public void mouseMoved(java.awt.event.MouseEvent e){}        
366  
367    public void mouseDragged(java.awt.event.MouseEvent e) {
368      if (mode==MOVEMODE||mode == LOCATEMODE) {
369        mousetarget.move((int)(e.getX()/pane.scale),(int)(e.getY()/pane.scale));
370        seg.map.solved = false;
371        seg.unCook();
372      }
373    }
374  
375    public void mousePressed(java.awt.event.MouseEvent e) {
376      frame.dirty = true;
377      float[] pos = new float[2];
378      pos[0]=(float)(e.getX()/pane.scale);
379      pos[1]=(float)(e.getY()/pane.scale);
380      if (mode==LOCATEMODE) {
381        mousetarget.locate(((StationItem)stationlist.getSelectedValue()).station,
382          		 (int)pos[0],(int)pos[1]);
383        int i = stationlist.getSelectedIndex();
384        if (i<stationlist.getModel().getSize()-1) {
385          stationlist.setSelectedValue(stationset.elementAt(i+1),true);
386        }
387        seg.map.solved = false;
388        seg.unCook();
389      }
390      if (mousetarget.select((int)pos[0],(int)pos[1],pane.getGraphics()) &&
391               mode==DELETEMODE) {
392        mousetarget.delete();
393        seg.map.solved = false;
394        seg.unCook();
395      }
396      if (seg.map==mousetarget) 
397        checkMarked();
398    }
399  
400    void checkMarked() {
401  
402      int first = stationlist.getFirstVisibleIndex();
403      int last = stationlist.getLastVisibleIndex();
404      if (first>=0 && last<0) last = stationset.size()-1;
405      if (last >= stationset.size()) last = stationset.size()-1;
406      for (int i = first;i<=last;i++ )
407        if (((StationItem)stationset.elementAt(i)).checkMarked(seg.map)) stationlist.repaint();
408    }
409  
410    public void select(Vertex v) {
411      selectByLabel(v.label);
412    }
413  
414    public void selectByLabel(String lab) {
415      int pos = seg.set.stations.headSet(new Vertex(lab)).size();
416      if (pos<stationset.size())
417        stationlist.setSelectedValue(stationset.elementAt(pos),true);
418    }
419  
420    public void mouseReleased(java.awt.event.MouseEvent e) {
421      if (mode==MOVEMODE||mode==LOCATEMODE)
422        mousetarget.fix();
423  //      if (locating==true && mousetarget==seg.map) {
424  //        int i = stationlist.getSelectedIndex();
425  //        if (i<stationlist.getModel().getSize()-1) {
426  //          stationlist.setSelectedValue(stationlist.getModel().getElementAt(i+1),true);
427  //        }
428  //      }
429  
430      pane.repaint();
431    }
432  
433  }
434