1
6 import javax.swing.*;
7 import java.awt.event.*;
8 import java.awt.*;
9 import java.awt.print.*;
10 import java.util.*;
11 import java.util.zip.*;
12 import java.io.*;
13 import java.lang.ref.*;
14
15
18 public class CartoFrame extends JFrame implements ActionListener,Styleable{
19
20
21 Carto carto;
22
23
24 JDesktopPane desk;
25
26 public static String SEGWORD = "Segment";
27 public static String COMPWORD = "Plan";
28 public static String SECTION = "XSection";
29
30 public static String DRAWING = "Drawings";
31
32
33 public static String NEWPROJECT = "New Project";
34 public static String NEW = "New empty file";
35 public static String OPEN = "Open...";
36 public static String SAVE = "Save";
37 public static String QUIT = "Exit";
38 public static String PRINT = "Print Enabled";
39 public static String PRINTSEL = "Print Selected";
40 public static String IPRINT = "Print Images";
41 public static String PREVIEW = "Print preview";
42 public static String PRINTSETUP = "Print Setup...";
43 public static String STATS = "Stats";
44
45
46 public static String SAVEAS = "Save as...";
47 public static String PREFS = "Global Prefs...";
48 public static String FPREFS = "File Prefs...";
49
50
51 public static String EDITSEGMENT = "Edit "+SEGWORD+"...";
52 public static String EDITCOMPOSITE = "Edit "+COMPWORD+"...";
53 public static String EDITSECTION = "Edit "+SECTION+"...";
54 public static String ADDSEGMENT = "New "+SEGWORD+"...";
55
56 public static String ADDCOMPOSITES = "New "+COMPWORD+" ...";
57
58 public static String ADDSECTION = "New "+SECTION+" ...";
59 public static String ADDPAGE = "New Page...";
60 public static String ADDSURVEY = "Set/Update";
61 public static String PURGESURVEY = "Purge";
62 public static String DELETE = "Delete ...";
63 public static String RECOOK = "Remorph all";
64 public static String HARDRECOOK = "Soft Remorph";
65 public static String IMAGELOAD = "Reload Images";
66 public static String STOPCOOK = "Interupt Morphing";
67 public static String STOPPRINT = "Interupt Printing";
68 public static String DELETESEG = "Del "+SEGWORD+" ...";
69 public static String IMPORTSEG = "Import "+SEGWORD+" ...";
70 public static String IMPORTCOMP = "Import "+COMPWORD+" ...";
71 public static String IMPORTSECTION = "Import "+SECTION+" ...";
72 public static String DELETECOMP = "Del "+COMPWORD+" ...";
73 public static String DELETESECTION = "Del "+SECTION+" ...";
74 public static String OLDER = "Previous Version";
75 public static String HISTORY = "Versions ...";
76 public static String NEWER = "Next Version";
77 public static String DELSTA = "Delete stations ...";
78 public static String DELSHOT = "Delete shots ...";
79
80
81 public static String DEBUG = "Debug";
82 public static String GC = "GC";
83 public static String ERROR = "Test Error";
84 public static String CLEAN = "Clean";
85 public static String CLOSEDITS = "Close editors";
86 public static String JAR = "Write debug file";
87 public static String ERRORFILE = "View error file";
88
89
90 public static String HELP = "Help";
91 public static String ABOUT = "About";
92 public static String LICENCE = "Licence";
93
94
95 static public boolean cookonopen;
96
97
98 static public boolean lastopen;
99
100
102 static public boolean openmaximized;
103
104
105 static public boolean openeditormaximized;
106
107
108 static public boolean restoreplace;
109
110
111 static public boolean saveplace;
112
113
114 static public int initialx;
115
116
117 static public int initialy;
118
119
120 static public int initialwidth;
121
122
123 static public int initialheight;
124
125
126 public static String NEWTITLE = "Carto - New";
127
128
130 public static CartoFrame topframe = null;
131
132
135 public Editor lastselected = null;
136
137
139 File file = null;
140
141
144 public static ThreadMessage message = new ThreadMessage();
145
147 JLabel surveylabel = new JLabel("No Survey");
148
149 JPanel statusbar = new JPanel();
150
151
152
155 public boolean dirty = false;
156
157
159 public CartoFrame(File startfile) {
160 addWindowListener(new WindowAdapter() {
161 public void windowClosing(WindowEvent e) {
162 closefile();
163 shutDown();
164 }});
165
166 topframe = this;
167
168 setBounds(initialx,initialy,initialwidth,initialheight);
169
170 desk = new JDesktopPane();
171 getContentPane().add(desk,BorderLayout.CENTER);
172
173 JMenuBar bar = new JMenuBar();
174 getContentPane().add(bar,BorderLayout.NORTH);
175
176 statusbar.setLayout(new BorderLayout());
177 statusbar.add(message,BorderLayout.WEST);
178 statusbar.add(surveylabel,BorderLayout.EAST);
179 getContentPane().add(statusbar,BorderLayout.SOUTH);
180
181 JMenu menu = new JMenu("File");
182 menu.setMnemonic('f');
183 bar.add(menu);
184 addMenuItem(menu,NEW,'n');
185 addMenuItem(menu,NEWPROJECT,'j');
186 addMenuItem(menu,OPEN,'o');
187 addMenuItem(menu,SAVE,'s');
188 addMenuItem(menu,SAVEAS,'a');
189
190
191
192
193
194
195 addMenuItem(menu,PRINT,'p');
196 addMenuItem(menu,PRINTSEL,'l');
197 addMenuItem(menu,STOPPRINT,'i');
198
199
200 addMenuItem(menu,STATS,'t');
201
202
203 addMenuItem(menu,PREFS,'r');
204 addMenuItem(menu,FPREFS,'e');
205 addMenuItem(menu,QUIT,'x');
206
207 menu = new JMenu("Survey");
208 menu.setMnemonic('u');
209 bar.add(menu);
210
211 addMenuItem(menu,ADDSURVEY,'a');
212 addMenuItem(menu,PURGESURVEY,'g');
213 addMenuItem(menu,OLDER,'o');
214 addMenuItem(menu,NEWER,'n');
215
216
217
218
219 menu = new JMenu(SEGWORD);
220 menu.setMnemonic('s');
221 bar.add(menu);
222 addMenuItem(menu,ADDSEGMENT,'a');
223
224 addMenuItem(menu,EDITSEGMENT,'e');
225 addMenuItem(menu,DELETESEG,'d');
226 addMenuItem(menu,RECOOK,'r');
227 addMenuItem(menu,IMAGELOAD,'d');
228 addMenuItem(menu,STOPCOOK,'i');
229 addMenuItem(menu,IMPORTSEG,'m');
230
231 menu = new JMenu(COMPWORD);
232 menu.setMnemonic('p');
233 bar.add(menu);
234 addMenuItem(menu,ADDCOMPOSITES,'n');
235 addMenuItem(menu,EDITCOMPOSITE,'e');
236 addMenuItem(menu,DELETECOMP,'d');
237
238 menu = new JMenu(SECTION);
239 menu.setMnemonic('x');
240 bar.add(menu);
241 addMenuItem(menu,ADDSECTION,'n');
242 addMenuItem(menu,EDITSECTION,'e');
243 addMenuItem(menu,DELETESECTION,'d');
244
245 menu = new JMenu(HELP);
246 menu.setMnemonic('h');
247 bar.add(menu);
248 addMenuItem(menu,HELP,'e');
249 addMenuItem(menu,ABOUT,'a');
250 addMenuItem(menu,LICENCE,'l');
251
252 menu = new JMenu(DEBUG);
253 menu.setMnemonic('d');
254 bar.add(menu);
255 addMenuItem(menu,ERRORFILE,'f');
256 addMenuItem(menu,GC,'g');
257 addMenuItem(menu,ERROR,'e');
258 addMenuItem(menu,JAR,'b');
259 addMenuItem(menu,CLEAN,'c');
260 addMenuItem(menu,CLOSEDITS,'t');
261 addMenuItem(menu,HARDRECOOK,'r');
262
263 if (startfile!=null) open(startfile);
264 else if (lastopen && Persist.current.last!=null) open(Persist.current.last);
265 else {
266 setTitle(NEWTITLE);
267 carto = new Carto();
268 }
269 }
270
271
273 public void setLineType(LineType type,Size thick,Color color,Set subsel) {
274
275 if (lastselected==null || !(lastselected instanceof CompEditor)) return;
276
277 ((CompEditor)lastselected).pane.setLineType(type,thick,color);
278 }
279
280
281 public void addMenuItem(JMenu menu,String comand,char mne) {
282 JMenuItem item = new JMenuItem(comand);
283 item.setMnemonic(mne);
284 item.addActionListener(this);
285 menu.add(item);
286 }
287
288
291 public void addMenuItem(JMenu menu,String comand) {
292 JMenuItem item = new JMenuItem(comand);
293 item.addActionListener(this);
294 menu.add(item);
295 }
296
297
306
307
312 public void importElement(String word) {
313 dirty = true;
314
315 if (Carto.background!=null) {
316 ErrorLog.log("Importing not permitted while printing or morphing");
317 return;
318 }
319
320 File f = Carto.choose(null);
321 if (f==null) return;
322
323 Carto source = Carto.read(f);
324 if (source==null) return;
325
326 Object[] res = CartoFrame.selectFromList(carto.getList(word),
327 "Choose a " + word +
328 " to Import from "+f.getName(),
329 "Import " + word);
330 if (res==null) return;
331 for (int i=0;i<res.length;i++) {
332 res[i] = ((Symbol)res[i]).importSym(carto,source);
333 addEditor((Editable)res[i]);
334 }
335 }
336
337
341 public static Element chooseFromList(java.util.List list,String message,String title) {
342 int i;
343 if (list==null || list.size()==0) return(null);
344 if (list.size()==1) return((Element)list.get(0));
345
346 Object[] names = list.toArray();
347
348
349 return((Element)JOptionPane.showInputDialog(null,
350 message,
351 title,
352 JOptionPane.QUESTION_MESSAGE,
353 null,
354 names,
355 names[0]));
356
357 }
358
359
363 public static Object[] selectFromList(java.util.List list,String message,String title) {
364 if (list==null || list.size()==0) return(null);
365 if (list.size()==1) return(list.toArray());
366
367 Object[] names = list.toArray();
368 JList choices = new JList(names);
369
370 if (JOptionPane.showOptionDialog(null,
371 new JScrollPane(choices),
372 title,
373 JOptionPane.OK_CANCEL_OPTION,
374 JOptionPane.QUESTION_MESSAGE,
375 null,
376 null,
377 null)
378 !=JOptionPane.OK_OPTION) return(null);
379
380 return(choices.getSelectedValues());
381
382
383
384
385
386
387 }
388
389
391 public void editElement(String typestring) {
392 Object[] elems = selectFromList(carto.getList(typestring),
393 "Choose a "+typestring+" to edit.",
394 "Edit "+typestring);
395 if (elems!=null)
396 for (int i=0;i<elems.length;i++)
397 addEditor((Editable)elems[i]);
398 }
399
400
404 public Editor addEditor(Editable elem) {
405 Editor editor = elem.getEditor(this);
406 if (editor != null) {
407 editor.editframe.setOpaque(true);
408 desk.add(editor.editframe,desk.getComponentCount());
409 editor.editframe.setVisible(true);
410 try {
411 editor.editframe.setMaximum(openeditormaximized);
412 } catch (java.beans.PropertyVetoException ex) {
413 ErrorLog.exception(ex,"Couldn't maximize editor");
414 }
415 if (elem instanceof Segment && Segment.openscaled)
416 ((SegEditor)editor).fitScale();
417
418
419 }
420 return(editor);
421 }
422
423
426 public void printSelected() {
427 dirty=true;
428 Print.printer.printSelected(this,message);
429 }
430
431
434 public void print() {
435 dirty=true;
436 Print.printer.printAll(carto,message);
437 }
438
439
443 public void addSurvey() {
444 dirty = true;
445
446 if (carto.survey!=null) carto.prepareForSurveyUpdate();
447
448 Survey newsurvey = Survey.open(carto.survey);
449 if (newsurvey!=null) {
450 carto.survey = newsurvey;
451 surveylabel.setText(carto.survey.name);
452 forceReCook();
453 carto.useSurveyUpdate();
454 }
455 }
456
457
460 public boolean newFile() {
461 if (!closefile()) return(false);
462
463 carto = new Carto();
464 Persist.current.last = file;
465 Persist.save();
466 file=null;
467 surveylabel.setText("No Survey");
468 setTitle(NEWTITLE);
469
470 return(true);
471 }
472
473
477 public void actionPerformed(ActionEvent e) {
478 if (e.getSource() instanceof AbstractButton) {
479 String command = ((AbstractButton)e.getSource()).getActionCommand();
480
481
482 if (command == NEW)
483 newFile();
484
485 else if (command == NEWPROJECT) {
486 if (newFile()) {
487 addSurvey();
488 Comp comp = new Comp("plan",carto.survey,false);
489
490 carto.complist.add(comp);
491 addEditor(comp);
492 dirty = false;
493 }
494 }
495 else if (command == OPEN) open();
496 else if (command == SAVE) {dirty = true;save(file);}
497 else if (command == SAVEAS) save(null);
498 else if (command == PRINT) print();
499 else if (command == PRINTSEL) printSelected();
500
501
502 else if (command == PREFS) (new Prefs(this)).show();
503 else if (command == FPREFS) (new Prefs(this,carto)).show();
504 else if (command == PRINTSETUP) Print.printSetup();
505 else if (command == QUIT && closefile()) shutDown();
506 else if (command == CLOSEDITS) closeEditors();
507 else if (command == GC) System.gc();
508 else if (command == HARDRECOOK) {
509 JInternalFrame[] eds = desk.getAllFrames();
510 for (int i=0;i<eds.length;i++)
511 ((EditFrame)eds[i]).edit.saveData();
512 carto.reCookAll(message,this);
513 dirty=true;
514 }
515 else if (command == RECOOK) {
516 JInternalFrame[] eds = desk.getAllFrames();
517 for (int i=0;i<eds.length;i++)
518 ((EditFrame)eds[i]).edit.saveData();
519 carto.hardReCookAll(message,this);
520 dirty=true;
521 }
522 else if (command == IMAGELOAD) {
523 ImageFile.flushImages();
524 JInternalFrame[] eds = desk.getAllFrames();
525 for (int i=0;i<eds.length;i++) {
526 Editor ed = ((EditFrame)eds[i]).edit;
527 if (ed instanceof SegEditor) {
528 ((SegEditor)ed).pane.image = ((SegEditor)ed).seg.getImage();
529 ed.repaint();
530 }
531 ed.saveData();
532 }
533 carto.reCookAll(message,this);
534 dirty=true;
535 }
536 else if (command == STOPPRINT) stopPrint();
537 else if (command == STOPCOOK) stopReCook();
538 else if (command == CLEAN) carto.clean();
539 else if (command == ERROR) throw new RuntimeException("this is a test");
540 else if (command == DELETECOMP) deleteElement(COMPWORD);
541 else if (command == DELETESECTION) deleteElement(SECTION);
542 else if (command == DELETESEG) deleteElement(SEGWORD);
543 else if (command == OLDER) {
544 carto.survey.undo();
545 surveylabel.setText(carto.survey.name);
546 forceReCook();
547 }
548 else if (command == NEWER) {
549 carto.survey.redo();
550 surveylabel.setText(carto.survey.name);
551 forceReCook();
552 }
553 else if (command==STATS) {
554
555 try {
556 PrintStream out = new PrintStream(new FileOutputStream("stats.txt"));
557 out.println("Carto file "+file.getName());
558 carto.printStats(out);
559
560 out.flush();
561 out.close();
562 } catch (IOException ex) {
563 ErrorLog.exception(ex,"Could not write stats.txt");
564 }
565 Help.showFile(this,"stats.txt","stats.txt");
566 }
567 else if (command==LICENCE) Help.showFile(this,"gpl.txt","Licence");
568 else if (command==ERRORFILE) Help.showFile(this,"error.txt","Error File");
569 else if (command==JAR) new DebugFile(this);
570 else if (command==ABOUT) Help.about(this);
571 else if (command==HELP) (new Help()).show();
572
573
574 else if (command == ADDSURVEY)
575 addSurvey();
576
577 else if (command == PURGESURVEY && carto.survey!=null)
578 carto.survey.purge(carto);
579
580 else if (command == ADDSEGMENT) {
581
582 Segment newseg = new Segment(carto.survey,false);
583 if (newseg!=null && newseg.check()) {
584 dirty = true;
585 carto.segmentlist.add(newseg);
586 addEditor(newseg);
587 }
588 }
589
590 else if (command == IMPORTCOMP) importElement(COMPWORD);
591 else if (command == IMPORTSEG) importElement(SEGWORD);
592
593 else if (command == EDITSEGMENT) editElement(SEGWORD);
594 else if (command == EDITCOMPOSITE) editElement(COMPWORD);
595 else if (command == EDITSECTION) editElement(SECTION);
596 else if (command == ADDCOMPOSITES) {
597 String name = (Symbol.makenames?null:JOptionPane.showInputDialog("Name of new "+COMPWORD));
598 Comp comp = new Comp(name,carto.survey,false);
599 dirty = true;
600 carto.complist.add(comp);
601 addEditor(comp);
602 }
603 else if (command==ADDSECTION) {
604 String name = (Symbol.makenames?null:JOptionPane.showInputDialog("Name of new "+SECTION));
605 SectionComp comp = new SectionComp(name,null);
606 System.out.println("ADDSECTION comp = "+comp);
607
608
609
610
611
612
613
614
615
616 dirty = true;
617 carto.sectionlist.add(comp);
618 addEditor(comp);
619 }
620
628 }
629 }
630
631
637 public void deleteElement(String typestring) {
638 Vector elist = carto.getList(typestring);
639 Object[] elem = selectFromList(elist,
640 "Choose a "+typestring+" to delete.",
641 "Delete "+typestring);
642 if (elem==null) return;
643 StringBuffer buf = new StringBuffer("Really Delete"+typestring+(elem.length>1?"s\n":"\n"));
644 for (int i=0;i<elem.length;i++) {
645 buf.append(((Symbol)elem[i]).getName());
646 if (i<elem.length-1) buf.append("\n");
647 }
648 buf.append("?");
649 if (JOptionPane.YES_OPTION ==
650 JOptionPane.showConfirmDialog(this,buf.toString(),
651 "delete",
652 JOptionPane.YES_NO_OPTION)) {
653 dirty = true;
654
655 for (int i=0;i<elem.length;i++) {
656 elist.remove(elem[i]);
657 Component[] contents = desk.getComponents();
658 for (int j=0;j<contents.length;j++) {
659 if ((contents[j] instanceof EditFrame) &&
660 ((EditFrame)contents[j]).edit.target==elem[i]) {
661 desk.remove((EditFrame)contents[j]);
662 repaint();
663 }
664 }
665
666 for (Iterator it = carto.complist.iterator();it.hasNext();) {
667 Comp composite = (Comp) it.next();
668 composite.recursiveDelete((Symbol)elem[i]);
669 }
670 }
671 }
672 }
673
674
677 public void closeEditors() {
678 Component[] contents = desk.getComponents();
679 for (int j=0;j<contents.length;j++)
680 if (contents[j] instanceof EditFrame)
681 desk.remove((EditFrame)contents[j]);
682 repaint();
683 }
684
685
688 public void shutDown() {
689 Persist.save();
690 System.out.println("Exit RunID = "+Persist.current.getRunID());
691 System.exit(0);
692 }
693
694
698 public void open() {
699 int type;
700 String title;
701 Editor ed;
702
703 if (!closefile()) return;
704
705 File f = Carto.choose(this);
706 if (f!=null) open(f);
707 else setTitle(NEWTITLE);
708 }
709
710 public void open(File filename) {
711 if (!closefile()) return;
712
713 Carto result = Carto.read(filename);
714 if (result != null) {
715 carto = (Carto)result;
716 dirty = false;
717 file = filename;
718 showname(file);
719 carto.clean();
720
721
722 if (cookonopen) forceReCook();
723 if (restoreplace && carto.place!=null)
724 EditState.restoreAll(carto.place,this);
725 }
726 else carto = new Carto();
727 repaint();
728 }
729
730
731 void showname(File file) {
732 Persist.current.last = file;
733 Persist.save();
734 setTitle("Carto - "+file.getName());
735 if (carto.survey!=null)
736 surveylabel.setText(carto.survey.name);
737
738 }
739
740
744 public boolean closefile() {
745
746 if (carto==null)return(true);
747 for (boolean saveit=dirty;saveit;) {
748 int res = JOptionPane.showConfirmDialog(this,"file changed - save?","Close",
749 JOptionPane.YES_NO_CANCEL_OPTION);
750 if (res==JOptionPane.CANCEL_OPTION) return(false);
751 if (res==JOptionPane.NO_OPTION) saveit = false;
752 if (res==JOptionPane.YES_OPTION) saveit = !save(file);
753 }
754 stopReCook();
755 lastselected = null;
756 JInternalFrame[] editors = desk.getAllFrames();
757
758 desk.setSelectedFrame(null);
759 for (int i=0;i<editors.length;i++) {
760 try {
761 editors[i].setClosed(true);
762 }
763 catch (java.beans.PropertyVetoException ex) {
764 editors[i].dispose();
765 }
766 desk.remove(editors[i]);
767 }
768 editors=null;
769 file=null;
770 dirty = false;
771 repaint();
772
773 return(true);
774 }
775
776
783 public boolean save(File savefile) {
784
785 File backfile = null;
786 if (savefile==null) {
787 JFileChooser choose = Persist.current.getFileChooser();
788 choose.setFileFilter(new FileTypes(FileTypes.CARTO));
789 choose.rescanCurrentDirectory();
790 if (choose.showSaveDialog(this)!=choose.APPROVE_OPTION) return(false);
791 savefile = choose.getSelectedFile();
792 if (!savefile.getName().endsWith(".cto") &&
793 !savefile.getName().endsWith(".zip") &&
794 !savefile.getName().endsWith(".jar"))
795 savefile = new File(savefile.toString().concat(".cto"));
796 dirty = true;
797 showname(savefile);
798 }
799
800 if (dirty) {
801 if (saveplace) carto.place = EditState.saveEditors(desk);
802 carto.saved_version = Carto.runversion.getVersion();
803 try {
804 backfile = null;
805 if (savefile.exists()) {
806 backfile = new File(savefile.getParent(),"backup_of_"+savefile.getName());
807 savefile.renameTo(backfile);
808 }
809 OutputStream ostream = new FileOutputStream(savefile);
810 if (savefile.getName().endsWith(".cto")) {
811 ImageFile.fileSave(carto);
812 ObjectOutputStream out = new ObjectOutputStream(ostream);
813 carto.zipfile = null;
814 carto.zipent = null;
815 carto.base = savefile.getCanonicalFile().getParentFile();
816 out.writeObject(carto);
817 out.flush();
818 }
819 else {
820 if (!savefile.getName().endsWith(".zip"))
821 ErrorLog.log(savefile.getName()+"is not .cto or .zip");
822 ZipOutputStream zout = new ZipOutputStream(ostream);
823 zout.setLevel(8);
824 String name = savefile.getName();
825 name = name.substring(0,name.lastIndexOf(".")) + ".cto";
826 ZipEntry zipent = new ZipEntry(name);
827 zout.putNextEntry(zipent);
828 ObjectOutputStream out = new ObjectOutputStream(zout);
829 out.writeObject(carto);
830 out.flush();
831 zout.closeEntry();
832 ImageFile.zipSave(zout,carto,backfile);
833 zout.finish();
834 }
835 ostream.close();
836 dirty = false;
837 } catch (IOException e) {
838 ErrorLog.log("I/O error writing: "+savefile);
839 ErrorLog.exception(e);
840 return(false);
841 }
842 file = savefile;
843 }
844 return(true);
845 }
846
847
850 public void stopReCook() {
851 Carto.stopBackground(Carto.COOKKILL);
852 ImageThread.stopLoading();
853 }
854
855
858 public void stopPrint() {
859 Carto.stopBackground(Carto.PRINTKILL);
860 }
861
862
866 void forceReCook() {
867 stopReCook();
868 carto.reCookAll(message,this);
869 }
870 }
871