NEURON
pwman.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include "gui-redirect.h"
3 
4 extern char* ivoc_get_temp_file();
5 extern int hoc_return_type_code;
6 
7 #if HAVE_IV
8 #if (MAC && !defined(carbon)) || defined(WIN32)
9 #define MACPRINT 1
10 #else
11 #define MACPRINT 0
12 #endif
13 
14 #if defined(WIN32)|| MAC
15 #define SNAPSHOT 0
16 #else
17 #define SNAPSHOT 1
18 #endif
19 
20 #define DECO 2 // 1 means default on, 2 off. for Carnvale,Hines book figures
21 
22 #include <ivstream.h>
23 #include <string.h>
24 #include "ivoc.h"
25 #endif // HAVE_IV
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include "classreg.h"
29 #include "oc2iv.h"
30 
31 #if HAVE_IV
32 #include "utility.h"
33 
34 void single_event_run();
35 extern char **hoc_strpop();
36 
37 #if defined(CYGWIN)
38 #include <IV-Win/mprinter.h>
39 void iv_display_scale(float);
40 void iv_display_scale(Coord, Coord); // Make if fit into the screen
41 extern "C" char* hoc_back2forward(char*);
42 #endif
43 
44 #if defined(WIN32) && !defined(CYGWIN)
45 #include <IV-Win/mprinter.h>
46 #include "../winio/debug.h"
47 void iv_display_scale(float);
48 void iv_display_scale(Coord, Coord); // Make if fit into the screen
49 #if defined(__MWERKS__)
50 #include <OS/dirent.h>
51 extern char * mktemp(char *);
52 extern int unlink(const char *);
53 
54 #else //!__MWERKS__
55 #include <dir.h>
56 #endif // __MWERKS__
57 
58 #include <fstream.h>
59 // there seems to be a bug here in that writing goes to the beginning
60 // but any existing trailing info remains! So be sure to unlink first.
61 #undef IOS_OUT
62 #define IOS_OUT (ios::out)
63 extern "C" char* hoc_back2forward(char*);
64 #else //!WIN32
65 #if MAC && !defined(carbon)
66 #include <fstream.h>
67 #include <file_io.h>
68 #undef IOS_OUT
69 #define IOS_OUT (ios::out | ios::trunc)
70 extern char * mktemp(char *);
71 extern int unlink(const char *);
72 #include <IV-Mac/mprinter.h>
73 extern void debugfile(const char*, ...);
74 #else //!MAC
75 #include <unistd.h>
76 #define Output output
77 #endif //MAC
78 #endif //WIN32
79 
80 #include <IV-look/kit.h>
81 #include <IV-look/dialogs.h>
82 #include <InterViews/layout.h>
83 #include <InterViews/hit.h>
84 #include <InterViews/display.h>
85 #include <InterViews/session.h>
86 #include <InterViews/color.h>
87 #include <InterViews/brush.h>
88 #include <InterViews/font.h>
89 #include <InterViews/event.h>
90 #include <InterViews/handler.h>
91 #include <InterViews/printer.h>
92 #include <InterViews/style.h>
93 #include <InterViews/background.h>
94 #include <InterViews/label.h>
95 #include <OS/string.h>
96 #include "apwindow.h"
97 #include "scenevie.h"
98 #include "rect.h"
99 #include "ivoc.h"
100 #include "utility.h"
101 #include "ocbox.h"
102 #include "idraw.h"
103 #include "mymath.h"
104 #include "graph.h"
105 #include "oc2iv.h"
106 #include "rubband.h"
107 
108 // PGH begin
109 // static const float Scl = 10.;
110 // static const float pr_scl = 8.;
111 static float Scl;
112 static float pr_scl;
113 static PixelCoord pixres = 0;
114 // PGH end
115 
116 #if SNAPSHOT
117 extern bool (*ivoc_snapshot_)(const Event*);
118 static bool ivoc_snapshot(const Event*);
119 #endif
120 
121 #define PWM_help_ "help"
122 #define PWM_do_print_ "Print PWM"
123 #define PWM_ScreenItem_ "ScreenItem PWM"
124 #define PWM_PaperItem_ "PaperItem PWM"
125 #define PWM_landscape_ "LandPort Other"
126 #define PWM_virt_screen_ "VirtualScreen Other"
127 #define PWM_printer_control_ "SelectPrinter Other"
128 #define PWM_file_control_ "PostScript PrintToFile"
129 #define PWM_idraw_control_ "Idraw PrintToFile"
130 #define PWM_save_control2_ "SaveAll Session"
131 #define PWM_save_control1_ "SaveSelected Session"
132 #define PWM_retrieve_control_ "Retrieve Session"
133 #define PWM_tray_ "Tray Other"
134 #define PWM_ascii_ "Ascii PrintToFile"
135 #define PWM_quit_ "Quit Other"
136 
137 #define pwm_impl PrintableWindowManager::current()->pwmi_
138 class HocPanel {
139 public:
140  static void save_all(ostream&);
141 };
142 
143 int inside(Coord x, Coord y, const Allocation& a) {
144  if (x >= a.left() && x <= a.right()
145  && y >= a.bottom() && y <= a.top()) {
146  return true;
147  }else {
148  return false;
149  }
150 }
151 
152 #define DBG 0
153 void print_alloc(Canvas* c, char* s, const Allocation& a) {
154 #if DBG || 1
155  printf("%s allocation %g %g %g %g\n", s, a.left(), a.bottom(), a.right(),
156  a.top());
157  if (c) {
158  Extension e;
159  e.set(c, a);
160 printf(" canvas %g %g %g %g\n", e.left(), e.bottom(), e.right(), e.top());
161  }
162 #endif
163 }
164 
165 /* static */ class ScreenScene : public Scene {
166 public:
167  ScreenScene(Coord , Coord, Coord, Coord, Glyph* g = NULL);
168  virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
169  virtual Coord mbs() const;
170 };
171 
172 /* static */ class PaperScene : public Scene {
173 public:
174  PaperScene(Coord , Coord, Coord, Coord, Glyph* g = NULL);
175  virtual Coord mbs() const;
176 };
177 
178 /* static */ class ScreenSceneHandler : public Handler {
179 public:
180  ScreenSceneHandler(Coord, Coord);
181  virtual bool event(Event&);
182 private:
183  Coord x_, y_;
184 };
185 
186 extern double (*p_java2nrn_dmeth)(Object* ho, Symbol* method);
187 extern char** (*p_java2nrn_smeth)(Object* ho, Symbol* method);
188 const char* (*p_java2nrn_classname)(Object* ho);
189 bool (*p_java2nrn_identity)(Object* o1, Object* o2);
190 
191 //just enough info to get a java window represented in the PWM.
192 // The distinction is that window() is NULL for these.
193 /*static*/ class JavaWindow {
194 public:
195  JavaWindow(const char*, Object*);
196  virtual ~JavaWindow();
197  virtual void map();
198  virtual void hide();
199  virtual void move(Coord l, Coord b);
200  virtual void pmove(int l, int t);
201  virtual void presize(int w, int h);
202  virtual int priority();
203  virtual void save_session(const char* fname, ostream& o);
204  void ref();
205  void unref();
206  Coord l(); Coord b(); Coord w(); Coord h();
207  char* title;
208  int pl, pt, pw, ph; // pixel coords straight from java
209  bool is_mapped, reffing_, closing_;
210  Object* ho;
211 };
212 
213 class PaperItem;
214 
215 /*static*/ class ScreenItem : public Glyph {
216 public:
217  friend class PaperItem;
218  ScreenItem(PrintableWindow*);
219  ScreenItem(JavaWindow*);
220  ~ScreenItem();
221  virtual void request(Requisition&) const;
222  virtual void allocate(Canvas*, const Allocation&, Extension&);
223  virtual void draw(Canvas*, const Allocation&) const;
224  virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
225  PrintableWindow* window() { return w_;}
226  JavaWindow* jwindow() {return jw_;}
227  void relabel(GlyphIndex);
228 // void reconfigured(Scene*);
229  PaperItem* paper_item() const {return pi_;}
230  GlyphIndex index() const { return i_;}
231  Object* group_obj_;
232  bool iconify_via_hide_;
233 private:
234  Glyph* label_;
235  GlyphIndex i_;
237  JavaWindow* jw_;
238  PaperItem* pi_;
239 };
240 
241 /*static*/ class PaperItem : public Glyph {
242 public:
243  PaperItem(ScreenItem*);
244  ~PaperItem();
245  virtual void request(Requisition&) const;
246  virtual void allocate(Canvas*, const Allocation&, Extension&);
247  virtual void draw(Canvas*, const Allocation&) const;
248 // virtual void print(Printer*, const Allocation&) const;
249  virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
250  void scale(float s) { scale_ = s; }
251  float scale() { return scale_; }
252  ScreenItem* screen_item() const { return si_;}
253  Coord width(); /* width of icon in pixels */
254  static Coord fsize_; // font height
255 private:
256 #if 1
257  friend class ScreenItem;
258 #else
259  //I prefer this but the SGI compiler doesn't like it
260  friend ScreenItem::~ScreenItem();
261 #endif
262  ScreenItem* si_;
263  float scale_;
264 };
265 
266 /*static*/ class PWMImpl {
267 public:
268  void append_paper(ScreenItem*);
269  void remove_paper(PaperItem*);
270  void unshow_paper(PaperItem*);
271  GlyphIndex paper_index(PaperItem*);
272  PaperScene* paper() { return paper_;}
273  ScreenScene* screen() { return screen_; }
274 
275  void help();
276 #if SNAPSHOT
277  void snapshot(const Event*);
278  Window* snap_owned(Printer*, Window*);
279  void snap(Printer*, Window*);
280  void snap_cursor(Printer*, const Event*);
281 #endif
282  void do_print0();
283  void do_print(bool printer, const char* name);
284  void do_print_session(bool also_controller = true);
285  void do_print_session(bool printer, const char* name);
286  void ps_file_print(bool, const char*, bool, bool);
287  void common_print(Printer*, bool, bool);
288 #if DECO
289  void print_deco(Printer*, Allocation& a, const char*);
290 #endif
291 #if MACPRINT
292  void mac_do_print();
293  MacPrinter* mprinter();
294  void paperscale();
295 #endif
296  void select_tool();
297  EventButton tool(EventButton);
298  void move_tool();
299  void resize_tool();
300  void landscape();
301  void landscape(bool);
302  bool is_landscape() { return landscape_; }
303  void deco(int);
304  void virt_screen();
305  void tray();
306  void printer_control();
307  void file_control();
308 #if SNAPSHOT
309  void snapshot_control();
310 #endif
311  bool file_control1();
312  void idraw_control();
313  void idraw_write(const char* fname, bool ses_style = false);
314  void ascii_control();
315  void ascii_write(const char* fname, bool ses_style = false);
316  void quit_control();
317  void save_selected_control();
318  void save_all_control();
319  void save_control(int);
320  void save_session(int, const char*, const char* head = NULL);
321  int save_group(Object*, const char*);
322  void retrieve_control();
323  float round(float);
324  float round_factor() {return round_factor_;}
325  void map_all();
326  void unmap_all();
327  StandardWindow* window();
328  void window(StandardWindow* w) { w_ = w; }
329  void all_window_bounding_box(Extension&, bool with_screen = true, bool also_controller = true);
330  void view_screen(Coord, Coord);
331  FileChooser* fc_save_;
332  const Color* window_outline_;
333  CopyString cur_ses_name_;
334 #if carbon
335  void all2front();
336 #endif
337 private:
338  friend class PrintableWindowManager;
339  PWMImpl(ScreenScene*, PaperScene*, Rect*);
340  ~PWMImpl();
341  GlyphIndex index(void*);
342  void relabel();
343  GlyphIndex upper_left();
344  void redraw(Window*);
345  bool none_selected(const char*, const char*)const;
346  void ses_group(ScreenItem* si, ostream& o); int ses_group_first_;
347  void save_begin(ostream&);
348  void save_list(int, ScreenItem**, ostream&);
349 private:
351  ScreenScene* screen_;
352  PaperScene* paper_;
353  View* pview_;
354  bool landscape_;
355  Rect* prect_;
356  bool use_printer;
357  bool printer_control_accept_;
358  String printer_;
359  FieldDialog* b_printer_;
360  FileChooser* fc_print_;
361  FileChooser* fc_idraw_;
362  FileChooser* fc_ascii_;
363  FileChooser* fc_retrieve_;
364  Coord canvasheight_;
365  float round_factor_;
366  TelltaleState* p_title_;
367  Glyph* left_; //ugh
368  EventButton tool_;
369  const Event* snap_event_;
370  bool print_leader_flag_;
371 #if DECO
372  TelltaleState* p_deco_;
373 #endif
374  Rect* screen_rect_;
375 #if MACPRINT
376  MacPrinter* mprinter_;
377 #endif
378 };
379 
380 /* static */ class VirtualWindow : public DismissableWindow {
381 public:
382  static void makeVirtualWindow();
383  static void view();
384  virtual ~VirtualWindow();
385 private:
386  VirtualWindow(View*, Glyph*);
387 private:
388  static VirtualWindow* virt_win_;
389  View* view_;
390 };
391 
392 VirtualWindow* VirtualWindow::virt_win_;
393 
394 #ifdef WIN32
395 
396 /* static */ class VirtualWindowScale : public Action {
397 public:
398  VirtualWindowScale(float);
399  virtual void execute();
400 private:
401  float scale_;
402 };
403 #endif
404 
405 /*static*/ class PaperItem_handler : public Handler {
406 public:
407  enum {resize, move};
408  PaperItem_handler(int type, Coord x, Coord y, PaperItem*, const Transformer&);
409  virtual ~PaperItem_handler();
410  virtual bool event(Event&);
411 private:
412  void resize_action(Coord, Coord);
413  void move_action(Coord, Coord);
414 private:
415  void (PaperItem_handler::*action_)(Coord, Coord);
416  Transformer t_;
417  PaperItem* pi_;
418  GlyphIndex index_;
419 
420 };
421 
422 /*static*/ class ScreenItemHandler : public Handler {
423 public:
424  ScreenItemHandler(Coord x, Coord y, ScreenItem*, const Transformer&);
425  virtual ~ScreenItemHandler();
426  virtual bool event(Event&);
427 private:
428  void move_action(bool, Coord, Coord);
429 private:
430  Transformer t_;
431  ScreenItem* si_;
432 };
433 
435 
436 /*static*/ class PWMDismiss : public WinDismiss {
437 public:
438  PWMDismiss(DismissableWindow*);
439  virtual ~PWMDismiss();
440  virtual void execute();
441 };
442 PWMDismiss::PWMDismiss(DismissableWindow* w) : WinDismiss(w) {}
443 PWMDismiss::~PWMDismiss() {}
444 void PWMDismiss::execute() {
446  pwm_impl->unmap_all();
447  }else{
448  PrintableWindow::leader()->iconify();
449  }
450 }
451 
452 #else //!HAVE_IV
453 #if defined(CYGWIN)
454 extern "C" char* hoc_back2forward(char*);
455 #endif
456 #endif //HAVE_IV
457 
458 extern Object** (*nrnpy_gui_helper_)(const char* name, Object* obj);
459 extern double (*nrnpy_object_to_double_)(Object*);
460 extern char** (*nrnpy_gui_helper3_str_)(const char* name, Object* obj, int handle_strptr);
461 
462 static void* pwman_cons(Object*) {
463  TRY_GUI_REDIRECT_OBJ("PWManager", NULL);
464  void* v = NULL;
465 #if HAVE_IV
466 IFGUI
467  v = (void*)PrintableWindowManager::current();
468 ENDGUI
469 #endif
470  return v;
471 }
472 static void pwman_destruct(void* v) {
473  TRY_GUI_REDIRECT_NO_RETURN("~PWManager", v);
474 }
475 
476 static double pwman_count(void* v) {
477  int cnt = 0;
478  hoc_return_type_code = 1; // integer
479  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.count", v);
480 #if HAVE_IV
481 IFGUI
483  cnt = p->screen()->count();
484 ENDGUI
485 #endif
486  return double(cnt);
487 }
488 static double pwman_is_mapped(void* v) {
489  hoc_return_type_code = 2; // boolean
490  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.is_mapped", v);
491 #if HAVE_IV
492 IFGUI
494  int i = (int)chkarg(1, 0, p->screen()->count()-1);
495  ScreenItem* si = (ScreenItem*)p->screen()->component(i);
496  if (si->window()) {
497  return double(si->window()->is_mapped());
498  }else{
499  return double(si->jwindow()->is_mapped);
500  }
501 ENDGUI
502 #endif
503  return 0.;
504 }
505 static double pwman_map(void* v) {
506  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.map", v);
507 #if HAVE_IV
508 IFGUI
510  int i = (int)chkarg(1, 0, p->screen()->count()-1);
511  ScreenItem* si = (ScreenItem*)p->screen()->component(i);
512  if (si->window()) {
513  si->window()->map();
514  }else{
515  si->jwindow()->map();
516  }
517 ENDGUI
518 #endif
519  return 0.;
520 }
521 static double pwman_hide(void* v) {
522  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.hide", v);
523 #if HAVE_IV
524 IFGUI
526  int i = (int)chkarg(1, 0, p->screen()->count()-1);
527  ScreenItem* si = (ScreenItem*)p->screen()->component(i);
528  if (si->window()) {
529  si->window()->hide();
530  }else{
531  si->jwindow()->hide();
532  }
533 ENDGUI
534 #endif
535  return 0.;
536 }
537 static const char** pwman_name(void* v) {
538  TRY_GUI_REDIRECT_ACTUAL_STR("PWManager.name", v);
539 #if HAVE_IV
540 IFGUI
542  int i = (int)chkarg(1, 0, p->screen()->count()-1);
543  ScreenItem* si = (ScreenItem*)p->screen()->component(i);
544  char** ps = hoc_temp_charptr();
545  if (si->window()) {
546  *ps = (char*)si->window()->name();
547  }else{
548  *ps = si->jwindow()->title;
549  }
550  return (const char**) ps;
551 ENDGUI
552 #endif
553  return 0;
554 }
555 static double pwman_close(void* v) {
556  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.close", v);
557 #if HAVE_IV
558 IFGUI
560  int i = (int)chkarg(1, 0, p->screen()->count()-1);
561  ScreenItem* si = (ScreenItem*)p->screen()->component(i);
562  if (p->window() == si->window()) {
563  p->window(NULL);
564  }
565  si->window()->dismiss();
566 ENDGUI
567 #endif
568  return 0.;
569 }
570 #if defined(MINGW)
571 static void pwman_iconify1(void* v) {
572 #if HAVE_IV
573 IFGUI
574  ((PrintableWindow*)v)->dismiss();
575 ENDGUI
576 #endif
577 }
578 #endif
579 
580 static double pwman_iconify(void* v) {
581  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.iconify", v);
582 #if HAVE_IV
583 IFGUI
585 #if defined(MINGW)
586  if (!nrn_is_gui_thread()) {
587  nrn_gui_exec(pwman_iconify1, pw);
588  return 0.;
589  }
590 #endif
591  pw->dismiss();
592 ENDGUI
593 #endif
594  return 0.;
595 }
596 static double pwman_deiconify(void* v) {
597  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.deiconify", v);
598 #if HAVE_IV
599 IFGUI
601  pw->map();
602 ENDGUI
603 #endif
604  return 0.;
605 }
606 static double pwman_leader(void* v) {
607  hoc_return_type_code = 1; // integer
608  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.leader", v);
609 #if HAVE_IV
610 IFGUI
613  int i, cnt = p->screen()->count();
614  for (i=0; i < cnt; ++i) {
615  ScreenItem* si = (ScreenItem*)p->screen()->component(i);
616  if (si->window() == pw) {
617  return double(i);
618  }
619  }
620 ENDGUI
621 #endif
622  return -1.;
623 }
624 static double pwman_manager(void* v) {
625  hoc_return_type_code = 1; // integer
626  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.manager", v);
627 #if HAVE_IV
628 IFGUI
630  PrintableWindow* pw = p->window();
631  int i, cnt = p->screen()->count();
632  for (i=0; i < cnt; ++i) {
633  ScreenItem* si = (ScreenItem*)p->screen()->component(i);
634  if (si->window() == pw) {
635  return double(i);
636  }
637  }
638 ENDGUI
639 #endif
640  return -1.;
641 }
642 
643 static double pwman_save(void* v) {
644  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.save", v);
645  int n = 0;
646 #if HAVE_IV
647 IFGUI
648  // if arg2 is an object then save all windows with that group_obj
649  // if arg2 is 1 then save all windows.
650  // if arg2 is 0 then save selected (on paper) windows.
652  if (ifarg(2)) {
653  if (hoc_is_object_arg(2)) {
654  n = p->save_group(*hoc_objgetarg(2), gargstr(1));
655  }else{
656  n = (int)chkarg(2, 0, 1);
657  p->save_session((n?2:0) , gargstr(1), (ifarg(3)? gargstr(3) : NULL));
658  }
659  }
660 ENDGUI
661 #endif
662  return (double)n;
663 
664 }
665 
666 static Object** pwman_group(void* v) {
667  TRY_GUI_REDIRECT_ACTUAL_OBJ("PWManager.group", v);
668 #if HAVE_IV
669 IFGUI
671  int i;
672  i = int(chkarg(1, 0, p->screen()->count()-1));
673  ScreenItem* si = (ScreenItem*)p->screen()->component(i);
674  if (ifarg(2)) {
675  hoc_obj_unref(si->group_obj_);
676  si->group_obj_ = *hoc_objgetarg(2);
677  hoc_obj_ref(si->group_obj_);
678  }
679  return hoc_temp_objptr(si->group_obj_);
680 ENDGUI
681 #endif
682  return hoc_temp_objptr(0);
683 }
684 
685 static double pwman_snap(void* v) {
686  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.snap", v);
687 #if HAVE_IV
688 IFGUI
689 #if SNAPSHOT
691  if (!ifarg(1)) {
692  p->snapshot_control();
693  }
694 #endif
695  return 1.;
696 ENDGUI
697 #endif
698  return 0;
699 }
700 
701 // position size and show/hide a java window on session retrieve
702 static double pwman_jwindow(void* v) {
703  hoc_return_type_code = 1; // integer
704  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.jwindow", v);
705 #if HAVE_IV
706 IFGUI
708  // arg order is objref, map/hide, x, y, w, h
709  // get java window owner object
710  Object* ho = *hoc_objgetarg(1);
711  // which java window is associated with this.
712  int i, cnt = p->screen()->count();
713  for (i=0; i < cnt; ++i) {
714  ScreenItem* si = (ScreenItem*)p->screen()->component(i);
715  JavaWindow* jw = si->jwindow();
716  if (jw && (*p_java2nrn_identity)(jw->ho, ho)) {
717  jw->pmove((int)*getarg(3), (int)*getarg(4));
718  jw->presize((int)*getarg(5), (int)*getarg(6));
719  if (chkarg(2,0,1) == 0.) {
720  jw->hide();
721  }
722 //printf("pwman_jwindow for %d\n", i);
723  return i;
724  }
725  }
726 ENDGUI
727 #endif
728  return -1;
729 }
730 
731 #if defined(MINGW)
732 static double scale_;
733 static void pwman_scale1(void*) {
734 #if HAVE_IV
735 IFGUI
736  iv_display_scale(scale_);
737 ENDGUI
738 #endif
739 }
740 #endif
741 
742 static double pwman_scale(void* v) {
743  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.scale", v);
744  double scale = chkarg(1, .01, 100);
745 #if HAVE_IV
746 IFGUI
747 #if defined(WIN32)
748 #if defined(MINGW)
749  if (!nrn_is_gui_thread()) {
750  scale_ = scale;
751  nrn_gui_exec(pwman_scale1, (void*)((intptr_t)1));
752  return scale;
753  }
754 #endif
755  iv_display_scale(scale);
756 #endif
757 ENDGUI
758 #endif
759  return scale;
760 }
761 
762 static double pwman_window_place(void* v){
763  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.window_place", v);
764 #if HAVE_IV
765 IFGUI
766  int i;
768  i = int(chkarg(1, 0, p->screen()->count()-1));
769  ScreenItem* si = (ScreenItem*)p->screen()->component(i);
770  if (si->window()) {
771  si->window()->xmove(int(*getarg(2)), int(*getarg(3)));
772  }else{
773  si->jwindow()->pmove(int(*getarg(2)), int(*getarg(3)));
774  }
775 ENDGUI
776 #endif
777  return 1.;
778 }
779 
780 static double pwman_paper_place(void* v){
781  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.paper_place", v);
782 #if HAVE_IV
783 IFGUI
784  // index, show=0 or 1
785  // index, x, y, scale where x and y in inches from left bottom
786  int i;
788  i = int(chkarg(1, 0, p->screen()->count()-1));
789  ScreenItem* si = (ScreenItem*)p->screen()->component(i);
790  p->append_paper(si);
791  PaperItem* pi = si->paper_item();
792  if (!ifarg(3)) {
793  if ((int(chkarg(2, 0, 1))) == 0) {
794  p->unshow_paper(pi);
795  }
796  }else{
797  pi->scale(chkarg(4, 1e-4, 1e4));
798  p->paper()->move(p->paper_index(pi), *getarg(2)/pr_scl, *getarg(3)/pr_scl);
799  }
800 ENDGUI
801 #endif
802  return 1.;
803 }
804 
805 static double pwman_printfile(void* v){
806  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.printfile", v);
807 #if HAVE_IV
808 IFGUI
809  // first arg is filename
810  // second arg is 0,1,2 refers to postscript, idraw, ascii mode
811  // third arg is 0,1 refers to selected, all
813  bool ses_style = false;
814  if (ifarg(3)) {
815  ses_style = int(chkarg(3, 0, 1))? true:false;
816  }
817  char* fname = gargstr(1);
818  switch ((int)chkarg(2, 0, 2)) {
819  case 0:
820  p->ps_file_print(false, fname, p->is_landscape(), ses_style);
821  break;
822  case 1:
823  p->idraw_write(fname, ses_style);
824  break;
825  case 2:
826  p->ascii_write(fname, ses_style);
827  break;
828  }
829 ENDGUI
830 #endif
831  return 1.;
832 }
833 
834 static double pwman_landscape(void* v){
835  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.landscape", v);
836 #if HAVE_IV
837 IFGUI
839  p->landscape(int(chkarg(1, 0, 1))?true:false);
840 ENDGUI
841 #endif
842  return 1.;
843 }
844 
845 static double pwman_deco(void* v){
846  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("PWManager.deco", v);
847 #if HAVE_IV
848 IFGUI
850  p->deco(int(chkarg(1, 0, 2)));
851 ENDGUI
852 #endif
853  return 1.;
854 }
855 
856 static Member_func members[] = {
857  "count", pwman_count,
858  "is_mapped", pwman_is_mapped,
859  "map", pwman_map,
860  "hide", pwman_hide,
861  "close", pwman_close,
862  "iconify", pwman_iconify,
863  "deiconify", pwman_deiconify,
864  "leader", pwman_leader,
865  "manager", pwman_manager,
866  "save", pwman_save,
867  "snap", pwman_snap,
868  "jwindow", pwman_jwindow,
869  "scale", pwman_scale,
870  "window_place", pwman_window_place,
871  "paper_place", pwman_paper_place,
872  "printfile", pwman_printfile,
873  "landscape", pwman_landscape,
874  "deco", pwman_deco,
875  0, 0
876 };
877 
879  "group", pwman_group,
880  0, 0
881 };
882 
884  "name", pwman_name,
885  0, 0
886 };
887 
889  class2oc("PWManager", pwman_cons, pwman_destruct, members, NULL,
890  retobj_members, s_memb);
891 }
892 
893 #if HAVE_IV // almost to end of file
894 
895 //PaperItem_handler
896 
897 PaperItem_handler::PaperItem_handler(int type, Coord x, Coord y, PaperItem* pi,
898 const Transformer& t) {
899 //printf("PaperItem_handler\n");
900  t_ = t;
901  pi_ = pi;
902  Resource::ref(pi);
903  index_ = pwm_impl->paper_index(pi);
904  Coord left, bottom;
905  pwm_impl->paper()->location(index_, left, bottom);
906  t_.invert();
907  switch (type) {
908  case resize:
909  action_ = &PaperItem_handler::resize_action; break;
910  case move:
911  t_.translate(left - x, bottom - y);
912  action_ = &PaperItem_handler::move_action; break;
913  }
914 
915 }
916 
917 PaperItem_handler::~PaperItem_handler() {
918 //printf("~PaperItem_handler\n");
919  Resource::unref(pi_);
920 }
921 
922 bool PaperItem_handler::event(Event& e) {
923 //printf("PaperItem_handler::event (%g, %g)\n", e.pointer_x(), e.pointer_y());
924  switch(e.type()) {
925  case Event::down:
926  e.grab(this);
927 #ifdef WIN32
928  e.window()->grab_pointer();
929 #endif
930  (this->*action_)(e.pointer_x(), e.pointer_y());
931  break;
932  case Event::up:
933  e.ungrab(this);
934 #ifdef WIN32
935  e.window()->ungrab_pointer();
936 #endif
937  break;
938  case Event::motion:
939  (this->*action_)(e.pointer_x(), e.pointer_y());
940  break;
941  }
942  return true;
943 }
944 
945 void PaperItem_handler::move_action(Coord x, Coord y) {
946 //printf("move_action\n");
947  Coord xs, ys;
948  t_.transform(x, y, xs, ys);
949  xs = pwm_impl->round(xs);
950  ys = pwm_impl->round(ys);
951  pwm_impl->paper()->move(index_, xs, ys);
952 }
953 
954 void PaperItem_handler::resize_action(Coord x, Coord y) {
955  Allotment ax;
956  pwm_impl->paper()->allotment(index_, Dimension_X, ax);
957  Allotment ay;
958  pwm_impl->paper()->allotment(index_, Dimension_Y, ay);
959  Coord xs, ys;
960  t_.transform(x, y, xs, ys);
961  float scl = Math::max((xs - ax.begin())/ax.span(),
962  (ys - ay.begin())/ay.span());
963 //printf("scl = %g\n", scl);
964  scl = pi_->scale() * scl;
965  scl = (scl > .1) ? scl : .1;
966  Coord w1;
967  w1 = pwm_impl->round(scl*pi_->width());
968  w1 = Math::max(w1, pwm_impl->round_factor());
969  scl = w1/pi_->width();
970  pi_->scale(scl);
971  pwm_impl->paper()->modified(index_);
972 }
973 
974 VirtualWindow::VirtualWindow(View* v, Glyph* g) : DismissableWindow(g, true) {
975  view_ = v;
976  view_->ref();
977 #ifdef WIN32
978  if (!style()) {
979  style(new Style(Session::instance()->style()));
980  style()->attribute("nrn_virtual_screen", "0");
981  }
982 
983  MenuItem* mi = append_menubar("Scale");
984  WidgetKit& wk = *WidgetKit::instance();
985  Menu* m = wk.pulldown();
986  mi->menu(m);
987 
988  mi = K::menu_item("normal");
989  mi->action(new VirtualWindowScale(1.0));
990  m->append_item(mi);
991 
992  mi = K::menu_item("see all");
993  mi->action(new VirtualWindowScale(fil));
994  m->append_item(mi);
995 
996  mi = K::menu_item("1.2");
997  mi->action(new VirtualWindowScale(1.2));
998  m->append_item(mi);
999 
1000  mi = K::menu_item("1.5");
1001  mi->action(new VirtualWindowScale(1.5));
1002  m->append_item(mi);
1003 
1004  mi = K::menu_item("2.0");
1005  mi->action(new VirtualWindowScale(2.0));
1006  m->append_item(mi);
1007 #endif
1008 }
1009 
1010 VirtualWindow::~VirtualWindow() {
1011  view_->unref();
1012  virt_win_ = NULL;
1013 }
1014 #if defined(WIN32) || carbon
1015 extern void ivoc_bring_to_top(Window*);
1016 #endif
1017 
1018 void VirtualWindow::makeVirtualWindow() {
1019  if (!virt_win_) {
1020  View* v = new View(pwm_impl->screen());
1021  virt_win_ = new VirtualWindow(v, LayoutKit::instance()->variable_span(
1022  new Background( v, WidgetKit::instance()->background())
1023  ));
1024  virt_win_->map();
1025  }
1026 #ifdef WIN32
1027  ivoc_bring_to_top(virt_win_);
1028 #endif
1029 }
1030 
1031 void virtual_window_top() {
1032  VirtualWindow::makeVirtualWindow();
1033 }
1034 
1035 void VirtualWindow::view() {
1036  if (virt_win_) {
1037  View* v = virt_win_->view_;
1038  Scene* s = v->scene();
1039  v->size(s->x1(), s->y1(), s->x2(), s->y2());
1040  virt_win_->canvas()->damage_all();
1041  }
1042 }
1043 
1044 #ifdef WIN32
1045 VirtualWindowScale::VirtualWindowScale(float scale) {
1046  scale_ = scale;
1047 }
1048 
1050  float scale = scale_;
1051  if (scale_ >= fil/10.) {
1052  Extension e;
1053  pwm_impl->all_window_bounding_box(e);
1054  iv_display_scale(e.right() - e.left(), e.top() - e.bottom());
1055  }else{
1056  iv_display_scale(scale);
1057  }
1058 
1059 }
1060 #endif
1061 
1062 //ScreenItemHandler
1063 
1064 ScreenItemHandler::ScreenItemHandler(Coord x, Coord y, ScreenItem* si,
1065 const Transformer& t) {
1066 //printf("ScreenItemHandler\n");
1067  t_ = t;
1068  si_ = si;
1069  Resource::ref(si);
1070  Coord left, bottom;
1071  pwm_impl->screen()->location(si_->index(), left, bottom);
1072  t_.invert();
1073  t_.translate(left - x, bottom - y);
1074 }
1075 
1076 ScreenItemHandler::~ScreenItemHandler() {
1077 //printf("~ScreenItemHandler\n");
1078  Resource::unref(si_);
1079 }
1080 
1081 bool ScreenItemHandler::event(Event& e) {
1082 //printf("ScreenItemHandler::event (%g, %g)\n", e.pointer_x(), e.pointer_y());
1083  switch(e.type()) {
1084  case Event::down:
1085  e.grab(this);
1086 #ifdef WIN32
1087  e.window()->grab_pointer();
1088 #endif
1089  move_action(false, e.pointer_x(), e.pointer_y());
1090  break;
1091  case Event::up:
1092  e.ungrab(this);
1093 #ifdef WIN32
1094  e.window()->ungrab_pointer();
1095 #endif
1096  move_action(true, e.pointer_x(), e.pointer_y());
1097  break;
1098  case Event::motion:
1099  move_action(false, e.pointer_x(), e.pointer_y());
1100  break;
1101  }
1102  return true;
1103 }
1104 
1105 void ScreenItemHandler::move_action(bool doit, Coord x, Coord y) {
1106 //printf("move_action\n");
1107  Coord xs, ys;
1108  t_.transform(x, y, xs, ys);
1109  if (doit) {
1110  if (si_->window()) {
1111  si_->window()->move(xs*Scl, ys*Scl);
1112  }else{
1113  si_->jwindow()->move(xs*Scl, ys*Scl);
1114  }
1115  }else{
1116  pwm_impl->screen()->move(si_->index(), xs, ys);
1117  }
1118 }
1119 
1120 ScreenScene::ScreenScene(Coord x1, Coord y1, Coord x2, Coord y2, Glyph* g)
1121  : Scene(x1, y1, x2, y2, g) {
1122 }
1123 
1124 void ScreenScene::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
1125  if (pwm_impl->tool(h.event()->pointer_button()) == Event::middle) {
1126  if (h.event()->type() == Event::down) {
1127  h.target(depth, this, 0,
1128  new ScreenSceneHandler(h.left()*Scl, h.bottom()*Scl));
1129  }
1130  }else{
1131  Scene::pick(c, a, depth, h);
1132  }
1133 }
1134 
1135 Coord ScreenScene::mbs() const { return 0.; }
1136 
1137 PaperScene::PaperScene(Coord x1, Coord y1, Coord x2, Coord y2, Glyph* g)
1138  : Scene(x1, y1, x2, y2, g) {
1139 }
1140 
1141 Coord PaperScene::mbs() const { return 0.; }
1142 
1143 ScreenSceneHandler::ScreenSceneHandler(Coord x, Coord y) : Handler() {
1144  x_ = x;
1145  y_ = y;
1146 }
1147 bool ScreenSceneHandler::event(Event&) {
1148  pwm_impl->view_screen(x_, y_);
1149  return true;
1150 }
1151 
1152 //PrintableWindowManager
1153 
1154 declareActionCallback(PWMImpl)
1155 implementActionCallback(PWMImpl)
1156 
1158  if (!current_) {
1160  }
1161  return current_;
1162 }
1163 
1165  LayoutKit& layout = *LayoutKit::instance();
1166  WidgetKit& kit = *WidgetKit::instance();
1167  PaperItem::fsize_ = kit.font()->size();
1168  current_ = this;
1169  Display* d = Session::instance()->default_display();
1170 
1171 // PGH begin
1172  Coord canvasheight;
1173  Style* q = Session::instance()->style();
1174  if (!q->find_attribute("pwm_canvas_height", canvasheight)) {
1175  canvasheight = 100.;
1176  }
1177  const Color* outline_color;
1178  String c;
1179  Display* dis = Session::instance()->default_display();
1180  if (!q->find_attribute("pwm_screen_outline_color", c)
1181  || ( outline_color = Color::lookup(dis, c)) == NULL) {
1182  outline_color = Color::lookup(dis, "#ff0000");
1183  }
1184  Scl = d->height()/canvasheight;
1185  Rect* sr = new Rect(0, 0 ,d->width()/Scl , d->height()/Scl, outline_color);
1186  sr->ref();
1187  ScreenScene* screen = new ScreenScene(-5, -2, d->width()/Scl + 5, d->height()/Scl + 2,
1188  sr);
1189  Coord pageheight;
1190  Coord pagewidth;
1191  if (!q->find_attribute("pwm_paper_height", pageheight)) {
1192  pageheight = 11.;
1193  }
1194  if (!q->find_attribute("pwm_paper_width", pagewidth)) {
1195  pagewidth = 8.5;
1196  }
1197  Coord wp1;
1198  if (pageheight > pagewidth) pr_scl = pageheight/canvasheight;
1199  else pr_scl = pagewidth/canvasheight;
1200 
1201  // width = max(d->width/Scl,pagewidth/prl_scl,pageheight/prl_scl)
1202  if (d->width() > d->height()) wp1 = d->width()/Scl;
1203  else wp1 = canvasheight;
1204 
1205  Coord wp = pagewidth/pr_scl;
1206  Coord hp = pageheight/pr_scl;
1207  Coord max = Math::max(wp,hp);
1208  Rect* r = new Rect(0,0,wp,hp, outline_color);
1209 // wp1 = wp1*1.2;
1210 // Scene* paper = new Scene(-5, -1, hp*1.2, hp+1, r);
1211  PaperScene* paper = new PaperScene(-5, -2, Math::max(max,d->width()/Scl),
1212  max+2, r);
1213 
1214 //PGH end
1215  pwmi_ = new PWMImpl(screen, paper, r);
1216  if (!q->find_attribute("pwm_window_outline_color", c)
1217  || ( outline_color = Color::lookup(dis, c)) == NULL) {
1218  outline_color = Color::lookup(dis, "#0000ff");
1219  }
1220  outline_color->ref();
1221  pwmi_->window_outline_ = outline_color;
1222  pwmi_->screen_rect_ = sr;
1223  if (!q->find_attribute("pwm_paper_resolution", pwmi_->round_factor_)) {
1224  pwmi_->round_factor_ = .25;
1225  }
1226  pwmi_->canvasheight_ = canvasheight;
1227  pwmi_->round_factor_ /= pr_scl;
1228  long ltmp;
1229  if (q->find_attribute("pwm_pixel_resolution", ltmp)) {
1230  pixres = (PixelCoord)ltmp;
1231  }
1232 
1233  PolyGlyph* hb = layout.hbox(6);
1234  pwmi_->left_ = hb;
1235  pwmi_->left_->ref();
1236 
1237  Menu* mbar, *mprint, *mses, *mother;
1238 #if 0
1239 #if !MAC
1240  if (q->value_is_on("pwm_help")) {
1241  vb->append(kit.push_button("Help",
1242  new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::help)
1243  ));
1244  }
1245 #endif
1246 #endif
1247  hb->append(mbar = kit.menubar());
1248 
1249  MenuItem* mi;
1250 
1251  mi = kit.menubar_item("Print");
1252  mbar->append_item(mi);
1253  mprint = kit.pulldown();
1254  mi->menu(mprint);
1255 
1256  mi = kit.menubar_item("Session");
1257  mbar->append_item(mi);
1258  mses = kit.pulldown();
1259  mi->menu(mses);
1260 
1261 #if 0
1262  mi = kit.menubar_item("Other");
1263  mbar->append_item(mi);
1264  mother = kit.pulldown();
1265  mi->menu(mother);
1266 #endif
1267 
1268  TelltaleGroup* ttg = new TelltaleGroup();
1269  mi = kit.radio_menu_item(ttg, "select");
1270  mbar->append_item(mi);
1271  mi->state()->set(TelltaleState::is_chosen, true);
1272  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::select_tool));
1273 
1274  mi = kit.radio_menu_item(ttg, "move");
1275  mbar->append_item(mi);
1276  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::move_tool));
1277 
1278  mi = kit.radio_menu_item(ttg, "resize");
1279  mbar->append_item(mi);
1280  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::resize_tool));
1281 
1282  mi = K::menu_item("To Printer");
1283  mprint->append_item(mi);
1284  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::do_print0));
1285 #if 1 || !MAC
1286  mi = K::menu_item("PostScript");
1287  mprint->append_item(mi);
1288  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::file_control));
1289 
1290 #if SNAPSHOT
1291  mi = K::menu_item("PS snapshot");
1292  mprint->append_item(mi);
1293  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::snapshot_control));
1294 #endif
1295 #endif
1296 
1297  mi = K::menu_item("Idraw");
1298  mprint->append_item(mi);
1299  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::idraw_control));
1300 
1301  mi = K::menu_item("Ascii");
1302  mprint->append_item(mi);
1303  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::ascii_control));
1304 #if MAC && !defined(carbon)
1305  mi = K::menu_item("Setup Printer");
1306  mprint->append_item(mi);
1307  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::paperscale));
1308 #else
1309  mi = K::menu_item("Select Printer");
1310  mprint->append_item(mi);
1311  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::printer_control));
1312 #endif
1313 
1314  mi = K::check_menu_item("Window Titles Printed");
1315  mprint->append_item(mi);
1316  pwmi_->p_title_ = mi->state();
1317 
1318 #if DECO
1319  mi = K::check_menu_item("Window Decorations Printed");
1320  mprint->append_item(mi);
1321  pwmi_->p_deco_ = mi->state();
1322  // automatically on. comment out otherwise
1323 #if DECO == 1
1324  pwmi_->p_deco_->set(TelltaleState::is_chosen, true);
1325 #else
1326  pwmi_->p_deco_->set(TelltaleState::is_chosen, false);
1327 #endif
1328 #endif
1329 
1330  mi = K::menu_item("Retrieve");
1331  mses->append_item(mi);
1332  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::retrieve_control));
1333 
1334  mi = K::menu_item("Save selected");
1335  mses->append_item(mi);
1336  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::save_selected_control));
1337 
1338  mi = K::menu_item("Save all");
1339  mses->append_item(mi);
1340  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::save_all_control));
1341 
1342  mi = K::menu_item("VirtualScreen");
1343  mses->append_item(mi);
1344  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::virt_screen));
1345 
1346 #if 1 || !MAC
1347  mi = K::menu_item("Land/Port");
1348  mprint->append_item(mi);
1349  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::landscape));
1350 #endif
1351 
1352  mi = K::menu_item("Tray");
1353  mses->append_item(mi);
1354  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::tray));
1355 
1356 #if 0
1357  mi = K::menu_item("Quit");
1358  mother->append_item(mi);
1359  mi->action(new ActionCallback(PWMImpl)(pwmi_, &PWMImpl::quit_control));
1360 #endif
1361  if (PrintableWindow::leader() == NULL) {
1362  pwmi_->window();
1364  if (PrintableWindow::leader() != pwmi_->w_) {
1365  pwmi_->w_->replace_dismiss_action(NULL);
1366  }
1367 #if OCSMALL
1368  pwmi_->w_->xplace(-800, 0);
1369 #else
1370 #if MAC
1371  pwmi_->w_->xplace(0,40);
1372 #else
1373  pwmi_->w_->xplace(0,0);
1374 #endif
1375 #endif
1376 // pwmi_->w_->map();
1378  }
1380 }
1381 
1382 void PWMImpl::select_tool() {
1383  tool_ = Event::right;
1384 }
1385 void PWMImpl::move_tool() {
1386  tool_ = Event::left;
1387 }
1388 void PWMImpl::resize_tool() {
1389  tool_ = Event::middle;
1390 }
1391 
1392 EventButton PWMImpl::tool(EventButton b) {
1393  if (b == Event::left) {
1394  return tool_;
1395  }
1396  return b;
1397 }
1398 
1399 StandardWindow* PWMImpl::window() {
1400  if (w_ == NULL) {
1401  LayoutKit& layout = *LayoutKit::instance();
1403  w_ = new StandardWindow(
1404 #if 1
1405  layout.hbox(
1406  layout.variable_span(new View(screen_)),
1407  layout.variable_span(pview_ = new View(paper_))
1408  ),
1409 #else
1410  new View(screen_),
1411 #endif
1412  left_,// really info
1413  NULL,
1414  NULL,
1415  NULL
1416  );
1418  Style* s = new Style(Session::instance()->style());
1419  s->attribute("name", "Print & File Window Manager");
1420  w_->style(s);
1421  }
1422  return w_;
1423 }
1424 
1426 // printf("~PrintableWindowManager\n");
1427  delete pwmi_;
1428  if (current_ == this) {
1429  current_ = NULL;
1430  }
1431 }
1432 
1433 void hoc_pwman_place() {
1434  TRY_GUI_REDIRECT_DOUBLE("pwman_place", NULL);
1435 #if HAVE_IV
1436 IFGUI
1437  int x, y;
1438  x = int(*getarg(1));
1439  y = int(*getarg(2));
1440  bool m = (ifarg(3) && int(*getarg(3)) == 0) ? false : true;
1442 ENDGUI
1443 #endif
1444  hoc_ret();
1445  hoc_pushx(0.);
1446 }
1447 
1448 void hoc_save_session() {
1449  TRY_GUI_REDIRECT_DOUBLE("save_session", NULL);
1450 #if HAVE_IV
1451 IFGUI
1452  if (pwm_impl) {
1453  pwm_impl->save_session(2, gargstr(1), (ifarg(2) ? gargstr(2) : NULL));
1454  }
1455 ENDGUI
1456 #endif
1457  hoc_ret();
1458  hoc_pushx(0.);
1459 }
1460 const char* pwm_session_filename() {
1461  if (pwm_impl) {
1462  return pwm_impl->cur_ses_name_.string();
1463  }
1464  return 0;
1465 }
1466 
1467 void hoc_print_session() {
1468  TRY_GUI_REDIRECT_DOUBLE("print_session", NULL);
1469 #if HAVE_IV
1470 IFGUI
1471  if (pwm_impl) {
1472  if (ifarg(3) && chkarg(3,0,1) == 1.) {
1473  pwm_impl->do_print((int)chkarg(1,0,1), gargstr(2));
1474  }else if (ifarg(2)) {
1475  pwm_impl->do_print_session((int)chkarg(1,0,1), gargstr(2));
1476  }else{
1477  bool b = ifarg(1) ? (chkarg(1, 0, 1) == 1.) : true;
1478  pwm_impl->do_print_session(b);
1479  }
1480  }
1481 ENDGUI
1482 #endif
1483  hoc_ret();
1484  hoc_pushx(0.);
1485 }
1486 
1487 void PrintableWindowManager::xplace(int left, int top, bool m) {
1488  PrintableWindow* w = pwm_impl->window();
1489  if (!w->is_mapped()) {
1491  if (pw && pw->is_mapped() && pw != w) {
1492  if (w->is_transient()) {
1493  w->transient_for(pw);
1494  }else{
1495  w->group_leader(pw);
1496  }
1497  }
1498  w->xplace(left, top);
1499  }
1500  if (m) {
1501  w->map();
1502  w->xmove(left, top);
1503  }else{
1504  w->hide();
1505  }
1506 #if MAC
1507  reconfigured(w);
1508 #endif
1509 
1510 }
1511 
1514 //printf("PrintableWindowManager::update(%p)\n", w);
1515  reconfigured(w);
1516 #if carbon
1517  if (w->leader() == w) {
1518  pwmi_->all2front();
1519  }
1520 #endif
1521 }
1522 
1524 // printf("disconnect %p\n", (PrintableWindow*)o);
1525 }
1526 
1528 //printf("PrintableWindowManager::append(%p)\n", w);
1529  if (w == NULL) {
1530  return;
1531  }
1532  w->attach(this);
1533  pwmi_->screen_->append(new ScreenItem(w));
1534  pwmi_->relabel();
1536  if (pw && pw->is_mapped() && pw != w) {
1537  if (w->is_transient()) {
1538  w->transient_for(pw);
1539 //printf("transient for %p\n", pw);
1540  }else{
1541  w->group_leader(pw);
1542 //printf("group leader is %p\n", pw);
1543  }
1544  }
1545 }
1546 
1547 void PrintableWindowManager::append(JavaWindow* w) {
1548 //printf("PrintableWindowManager::append(%p)\n", w);
1549  if (w == NULL) {
1550  return;
1551  }
1552  pwmi_->screen_->append(new ScreenItem(w));
1553  pwmi_->relabel();
1554 }
1555 
1557 //printf("PrintableWindowManager::remove(%p)\n", w);
1558  PWMImpl* impl = pwmi_;
1559  if (w == impl->window()) {
1560  impl->w_ = NULL;
1561  }
1562 // printf("remove %p\n", w);
1563  w->detach(this);
1564  Scene* s = impl->screen_;
1565  if (s) {
1566  GlyphIndex i = impl->index(w);
1567  if (i >= 0) s->remove(i);
1568  }
1569  impl->relabel();
1570 }
1571 void PrintableWindowManager::remove(JavaWindow* w) {
1572 //printf("PrintableWindowManager::remove(%p)\n", w);
1573  PWMImpl* impl = pwmi_;
1574 // printf("remove %p\n", w);
1575  Scene* s = impl->screen_;
1576  if (s) {
1577  GlyphIndex i = impl->index(w);
1578  if (i >= 0) s->remove(i);
1579  }
1580  impl->relabel();
1581 }
1582 
1583 
1584 #define PIXROUND(x,y,r) x = int((y + r/2)/r) * r
1585 
1587  // only if leader
1588  if (this == leader()) {
1589  PrintableWindowManager::current()->pwmi_->map_all();
1590  }
1591 }
1592 
1594  if (!pixres) {
1595  return;
1596  }
1597  PixelCoord x, y, x1, y1;
1598  x1 = xleft();
1599  y1 = xtop();
1600  PIXROUND(x, x1, pixres);
1601  PIXROUND(y, y1, pixres);
1602  if (x != x1 || y != y1) {
1603  xmove(x, y);
1604  }
1605 }
1606 
1607 void ViewWindow::reconfigured() {
1608  if (!pixres) {
1609  return;
1610  }
1611  PixelCoord x, y, w, h;
1612  w = canvas()->pwidth();
1613  h = canvas()->pheight();
1614  PIXROUND(x, w, pixres);
1615  PIXROUND(y, h, pixres);
1616  if (x == 0) x = pixres;
1617  if (y == 0) y = pixres;
1618  if (x != w || y != h) {
1619  canvas()->psize(x, y);
1620  Window::resize();
1621  }
1623 }
1624 
1626  PWMImpl* impl = pwmi_;
1627 
1628  GlyphIndex i = impl->index(w);
1629  if (i < 0) return; // mswin after a ShowWindow(hwnd, SW_HIDE);
1630  Coord l = w->left_pw();
1631  Coord r = l + w->width_pw();
1632  Coord b = w->bottom_pw();
1633  Coord t = b + w->height_pw();
1634  impl->screen_->move(i, l/Scl, b/Scl);
1635  impl->screen_->change(i);
1636  impl->screen_->show(i, w->is_mapped());
1637  ScreenItem* si = (ScreenItem*)impl->screen_->component(i);
1638  PaperItem* pi = si->paper_item();
1639  if (pi) {
1640  impl->paper_->change(impl->paper_index(pi));
1641  }
1642  Extension e;
1643  impl->all_window_bounding_box(e);
1644  impl->screen_->new_size(e.left()/Scl - 5, e.bottom()/Scl - 2,
1645  e.right()/Scl + 5, e.top()/Scl + 2);
1646  VirtualWindow::view();
1647 #if DBG
1648  Coord x, y;
1649  impl->screen_->location(i, x, y);
1650  printf("reconfigured %d %d %g %g\n", i, impl->screen_->showing(i), x, y);
1651 #endif
1652 }
1653 
1654 void PrintableWindowManager::reconfigured(JavaWindow* w) {
1655  PWMImpl* impl = pwmi_;
1656 
1657 //printf("reconfigured %g %g %g %g mapped=%d\n", w->l, w->b, w->w, w->h,w->is_mapped);
1658  GlyphIndex i = impl->index(w);
1659  if (i < 0) return; // mswin after a ShowWindow(hwnd, SW_HIDE);
1660  Coord l = w->l();
1661  Coord r = l + w->w();
1662  Coord b = w->b();
1663  Coord t = b + w->h();
1664  impl->screen_->move(i, l/Scl, b/Scl);
1665  impl->screen_->change(i);
1666  impl->screen_->show(i, w->is_mapped);
1667  ScreenItem* si = (ScreenItem*)impl->screen_->component(i);
1668  PaperItem* pi = si->paper_item();
1669  if (pi) {
1670  impl->paper_->change(impl->paper_index(pi));
1671  }
1672  Extension e;
1673  impl->all_window_bounding_box(e);
1674  impl->screen_->new_size(e.left()/Scl - 5, e.bottom()/Scl - 2,
1675  e.right()/Scl + 5, e.top()/Scl + 2);
1676  VirtualWindow::view();
1677 #if DBG
1678  Coord x, y;
1679  impl->screen_->location(i, x, y);
1680  printf("reconfigured %d %d %g %g\n", i, impl->screen_->showing(i), x, y);
1681 #endif
1682  single_event_run();
1683 }
1684 
1686  pwmi_->do_print0();
1687 }
1688 
1689 void PWMImpl::help() {
1691  Oc::helpmode(w_);
1692  if (Oc::helpmode()) {
1693  Oc::help(PWM_help_);
1694  }
1695 }
1696 
1697 void PWMImpl::all_window_bounding_box(Extension& e, bool with_screen, bool also_leader) {
1698  GlyphIndex i;
1699  PrintableWindow* w;
1700  Display* d = Session::instance()->default_display();
1701  if (with_screen) {
1702  e.set_xy(NULL, 0., 0., d->width(), d->height());
1703  }else{
1704  e.clear();
1705  }
1707  bool empty = true;
1708  for (i=0; i < screen_->count(); i++) {
1709  w = ((ScreenItem*)(screen_->component(i)))->window();
1710  if (w && w->is_mapped() && w != wl) {
1711  e.merge_xy(NULL, w->left(), w->bottom(),
1712  w->left() + w->width(), w->bottom() + w->height());
1713  empty = false;
1714  }
1715  }
1716  w = wl;
1717  if (w && w->is_mapped() && (also_leader || empty)) {
1718  e.merge_xy(NULL, w->left(), w->bottom(),
1719  w->left() + w->width(), w->bottom() + w->height());
1720  print_leader_flag_ = true;
1721  }else{
1722  print_leader_flag_ = false;
1723  }
1724  screen_rect_->width(d->width()/Scl);
1725  screen_rect_->height(d->height()/Scl);
1726 //printf("all_window_bounding_box %g %g %g %g\n", e.left(), e.bottom(), e.right(), e.top());
1727 }
1728 
1729 void PWMImpl::view_screen(Coord x, Coord y) {
1730  int xp, yp;
1731 // printf("view_sceen %g %g\n", x, y);
1732  GlyphIndex i;
1733  PrintableWindow* w;
1734  Display* d = Session::instance()->default_display();
1735  xp = d->to_pixels(-x) + d->pwidth()/2;
1736  yp = d->to_pixels(y) - d->pheight()/2;
1737  for (i=0; i < screen_->count(); i++) {
1738  ScreenItem* si = (ScreenItem*)screen_->component(i);
1739  if (si->window()) {
1740  w = si->window();
1741  if (w != window()) {
1742  w->xmove(w->xleft() + xp, w->xtop() + yp);
1743  }
1744  }else{
1745  JavaWindow* jw = si->jwindow();
1746  Coord l, b;
1747  l = jw->l() + d->to_coord(xp);
1748  b = jw->b() - d->to_coord(yp);
1749  jw->move(l, b);
1750  }
1751  }
1752 }
1753 
1754 void PWMImpl::do_print0() {
1755  if (Oc::helpmode()) {
1756  Oc::help(PWM_do_print_);
1757  return;
1758  }
1759  if (use_printer) {
1760  if (none_selected("No windows to print", "Print Anyway")) {
1761  return;
1762  }
1763 #if MAC && !defined(carbon)
1764  if (!mprinter_) {
1765  continue_dialog("First select SetupPrinter");
1766  }else{
1767  mac_do_print();
1768  }
1769 #else
1770  if (!b_printer_) {
1771  printer_control();
1772  if (!printer_control_accept_) {
1773  Resource::unref(b_printer_);
1774  b_printer_ = NULL;
1775  return;
1776  }
1777  }
1778  CopyString name(b_printer_->text()->string());
1779  do_print(use_printer, name.string());
1780 #endif
1781  }else{
1782  if (!fc_print_) {
1783  file_control();
1784  return; // file_control calls do_print
1785  }
1786  do_print(use_printer, fc_print_->selected()->string());
1787  }
1788 }
1789 
1790 void PWMImpl::do_print(bool use_printer, const char* name) {
1791 #if MAC && !defined(carbon)
1792  if (use_printer) {
1793  mac_do_print();
1794  return;
1795  }
1796 #endif
1797 #if defined(WIN32)
1798  if (use_printer && strcmp(name, "Windows") == 0) {
1799  mac_do_print();
1800  return;
1801  }
1802 #endif
1803  ps_file_print(use_printer, name, landscape_, false);
1804 }
1805 
1806 void PWMImpl::do_print_session(bool also_leader) {
1807  // must work for mac, mswin, unix. All windows on screen
1808  //scale so on paper
1809  bool p = true;
1810 #if DECO
1811  bool deco = p_deco_->test(TelltaleState::is_chosen);
1812  p_deco_->set(TelltaleState::is_chosen, true);
1813 #endif
1814 
1815 #if MACPRINT
1816  Extension e;
1817 #if defined(WIN32)
1818  if (!mprinter()->get()) { return; }
1819 #endif
1820  all_window_bounding_box(e, false, also_leader);
1821  // want 1/2 inch margins
1822  float s1 = (mprinter()->width() - 72.)/(e.right() - e.left() + 6.);// with deco
1823  float s2 = (mprinter()->height() - 72.)/(e.top() - e.bottom() + 23.);//with deco
1824  float sfac = (s1 < s2) ? s1 : s2;
1825  float xoff = mprinter()->width()/2/sfac - (e.right() + e.left() + 6.)/2.;
1826  float yoff = mprinter()->height()/2/sfac - (e.top() + e.bottom() + 23.)/2.;
1827  Transformer t;
1828  t.translate(xoff, yoff);
1829 #if MAC && !defined(carbon)
1830  mprinter()->prolog();
1831  t.scale(sfac, sfac);
1832 #else
1833  mprinter()->prolog(sfac);
1834 #endif
1835  mprinter()->push_transform();
1836  mprinter()->transform(t);
1837  common_print(mprinter(), false, true);
1838  mprinter()->pop_transform();
1839  mprinter()->epilog();
1840 #endif
1841 
1842 #if (!MAC || DARWIN) && !defined(WIN32)
1843 // must be a postscript printer so can use landscape mode
1844  if (!b_printer_) {
1845  printer_control();
1846  if (!printer_control_accept_) {
1847  Resource::unref(b_printer_);
1848  b_printer_ = NULL;
1849  p = false;
1850  }
1851  }
1852  if (p) {
1853  CopyString name(b_printer_->text()->string());
1854  ps_file_print(true, name.string(), true, true);
1855  }
1856 #endif
1857 
1858 #if DECO
1859  p_deco_->set(TelltaleState::is_chosen, deco);
1860 #endif
1861  print_leader_flag_ = true;
1862 }
1863 
1864 void PWMImpl::do_print_session(bool use_printer, const char* name) {
1865  print_leader_flag_ = true;
1866  ps_file_print(use_printer, name, true, true);
1867 }
1868 
1869 void PWMImpl::ps_file_print(bool use_printer, const char* name, bool land_style, bool ses_style) {
1870  Style* s = Session::instance()->style();
1871  static char* tmpfile = (char*)0;
1872  filebuf obuf;
1873 #if MAC && !DARWIN
1874  obuf.open(name, IOS_OUT);
1875 #else
1876  if (!tmpfile) {
1877  tmpfile = ivoc_get_temp_file();
1878  }
1879 #ifdef WIN32
1880  unlink(tmpfile);
1881 #endif
1882  obuf.open(tmpfile, IOS_OUT);
1883 #endif
1884  ostream o(&obuf);
1885  Printer* pr = new Printer(&o);
1886  pr->prolog();
1887 
1888  if (ses_style) {
1889 #if DECO
1890  bool deco = p_deco_->test(TelltaleState::is_chosen);
1891  p_deco_->set(TelltaleState::is_chosen, true);
1892 #endif
1893  Style* s = Session::instance()->style();
1894  Coord pageheight;
1895  Coord pagewidth;
1896  if (!s->find_attribute("pwm_paper_height", pageheight)) {
1897  pageheight = 11.;
1898  }
1899  if (!s->find_attribute("pwm_paper_width", pagewidth)) {
1900  pagewidth = 8.5;
1901  }
1902  Extension e;
1903  all_window_bounding_box(e, false, true);
1904  // want 1/2 inch margins
1905 float s1 = (pagewidth*72 - 72.)/(e.right() - e.left() + 6.);// with deco
1906 float s2 = (pageheight*72 - 72.)/(e.top() - e.bottom() + 23.);//with deco
1907  float sfac = (s1 < s2) ? s1 : s2;
1908 float xoff = pagewidth*72/2/sfac - (e.right() + e.left() + 6.)/2.;
1909 float yoff = pageheight*72/2/sfac - (e.top() + e.bottom() + 23.)/2.;
1910  Transformer t;
1911  t.translate(xoff, yoff);
1912  t.scale(sfac, sfac);
1913  pr->push_transform();
1914  pr->transform(t);
1915  common_print(pr, false, ses_style);
1916  pr->pop_transform();
1917 #if DECO
1918  p_deco_->set(TelltaleState::is_chosen, deco);
1919 #endif
1920  }else{
1921  common_print(pr, land_style, ses_style);
1922  }
1923  pr->epilog();
1924  obuf.close();
1925 #if !MAC || DARWIN
1926  String filt("cat");
1927  s->find_attribute("pwm_postscript_filter", filt);
1928  char* buf = new char[200 + strlen(name) + strlen(filt.string()) + 2*strlen(tmpfile)];
1929 
1930  if (use_printer) {
1931 #ifdef WIN32
1932  sprintf(buf, "%s %s %s", filt.string(), tmpfile,
1933  name);
1934 #else
1935  sprintf(buf, "%s < %s | %s ; rm %s", filt.string(), tmpfile,
1936  name, tmpfile);
1937 #endif
1938  }else{
1939 #ifdef WIN32
1940  sprintf(buf, "%s %s > %s", filt.string(), tmpfile,
1941  name);
1942 #else
1943  sprintf(buf, "%s < %s > %s ; rm %s", filt.string(), tmpfile,
1944  name, tmpfile);
1945 #endif
1946  }
1947 //printf("%s\n", buf);
1948  nrnignore = system(buf);
1949  delete [] buf;
1950 #ifdef WIN32
1951  unlink(tmpfile);
1952 #endif
1953 #endif
1954  delete pr; //input handlers later crash doing pr->damage()
1955 }
1956 
1957 #ifdef WIN32
1958 extern bool hoc_copyfile(const char*, const char*);
1959 #endif
1960 
1961 #if MACPRINT
1962 void PWMImpl::mac_do_print() {
1963 #if defined(WIN32)
1964  if (!mprinter()->get()) { return; }
1965 #endif
1966  mprinter()->prolog();
1967  common_print(mprinter(), landscape_, false);
1968  mprinter()->epilog();
1969 }
1970 #endif
1971 
1972 void PWMImpl::common_print(Printer* pr, bool land_style, bool ses_style) {
1973  Scene* p;
1974  if (ses_style) {
1975  p = screen();
1976  }else{
1977  p = paper();
1978  }
1979  Style* s = Session::instance()->style();
1980  Coord pageheight;
1981  Coord pagewidth;
1982  if (!s->find_attribute("pwm_paper_height", pageheight)) {
1983  pageheight = 11.;
1984  }
1985  if (!s->find_attribute("pwm_paper_width", pagewidth)) {
1986  pagewidth = 8.5;
1987  }
1988  pr->resize(0, 0, pagewidth*72, pageheight*72);
1989  if (land_style) {
1990  Transformer t;
1991  t.rotate(-90);
1992  //t.translate(0, pageheight*72);
1993  if (ses_style) {
1994  t.translate(20, pr->height() - 70);
1995  }else{
1996  t.translate(0, pr->height());
1997  }
1998  pr->transform(t);
1999  }
2000  GlyphIndex count = p->count();
2001  for (GlyphIndex i=0; i < count; ++i) {
2002  if (!p->showing(i)) {
2003  continue;
2004  }
2005  PrintableWindow* pw;
2006  float sfac;
2007  Transformer t;
2008  Coord x, y, x1, y1;
2009  if (ses_style) {
2010  ScreenItem* pi = (ScreenItem*)p->component(i);
2011  pw = pi->window();
2012  if (!pw->is_mapped()) { continue; } // probably the PFWM
2013  if (!print_leader_flag_ && pw == PrintableWindow::leader()) {
2014  continue;
2015  }
2016  float sfac = .9*pagewidth*72/pw->display()->height();
2017  sfac=1.;
2018  x = pw->left_pw();
2019  y = pw->bottom_pw();
2020  t.translate(x, y);
2021  t.scale(sfac, sfac);
2022  x1 = (x)*sfac;
2023  y1 = (y + pw->height_pw())*sfac;
2024  }else{
2025  PaperItem* pi = (PaperItem*)p->component(i);
2026  pw = pi->screen_item()->window();
2027  float sfac = pr_scl*72*pi->scale()/Scl;
2028  p->location(i, x, y);
2029  t.scale(sfac, sfac);
2030  t.translate(72*x*pr_scl, 72*y*pr_scl);
2031  //t.translate((pr->width() - pagewidth*72)/2, (pr->height() - pageheight*72)/2);
2032  x1 = 72*(x)*pr_scl;
2033  y1 = 72*(y + pi->width()*pw->height_pw()/pw->width_pw()*pi->scale())*pr_scl;
2034  }
2035  Requisition req;
2036  pw->print_glyph()->request(req);
2037  float align_x = req.x_requirement().alignment();
2038  float align_y = req.y_requirement().alignment();
2039  Allotment ax(align_x*pw->width_pw(), pw->width_pw(), align_x);
2040  Allotment ay(align_y*pw->height_pw(), pw->height_pw(), align_y);
2041  Allocation a;
2042  a.allot_x(ax);
2043  a.allot_y(ay);
2044 
2045  pr->push_transform();
2046  pr->transform(t);
2047  pr->push_clipping();
2048  pr->clip_rect(0, 0, pw->width_pw(), pw->height_pw());
2049 
2050  pw->print_glyph()->print(pr, a); //FieldEditor glyphs crash
2051  pr->pop_clipping();
2052 #if DECO
2053  if (p_deco_->test(TelltaleState::is_chosen) == true) {
2054  print_deco(pr, a, pw->name());
2055  }
2056 #endif
2057  pr->pop_transform();
2058 
2059  // flush the allocation tables for InputHandler glyphs so
2060  // no glyphs try to use the Printer after it has been deleted
2061  pw->print_glyph()->undraw();
2062 #if !MAC
2063  redraw(pw);
2064 #endif
2065  // print the window titles
2066  if ((ses_style || p_title_->test(TelltaleState::is_chosen) == true)
2067 #if DECO
2068  && p_deco_->test(TelltaleState::is_chosen) == false
2069 #endif
2070  ) {
2071  WidgetKit& wk = *WidgetKit::instance();
2072  Label label(pw->name(), wk.font(), wk.foreground());
2073  Requisition r;
2074  label.request(r);
2075  Allocation al;
2076  Allotment& alx = al.x_allotment();
2077  Allotment& aly = al.y_allotment();
2078  alx.origin(x1); alx.span(r.x_requirement().natural());
2079  aly.origin(y1); aly.span(r.y_requirement().natural());
2080  label.draw(pr, al);
2081  }
2082  }
2083 }
2084 
2085 #if DECO
2086 // for Carnevale, Hines book figures
2087 
2088 void PWMImpl::print_deco(Printer* pr, Allocation& a, const char* title) {
2089  WidgetKit& wk = *WidgetKit::instance();
2090  Coord l,b,r,t,w,h,s,x,y,dx,xx;
2091 
2092  // attributes
2093  static const Color* ctitle;
2094  static const Color* ctitlebar;
2095  static const Color* coutline;
2096  static const Color* bright;
2097  static const Color* dark;
2098  static const Font* ftitle;
2099  static const Brush* br;
2100  static int first = 1;
2101 
2102  w = 3; h = 20; // width of outer deco, height of title bar
2103  s = 2; // close button offset from bottom of title bar
2104  xx = 10; // x part of close button size
2105 
2106  if (first) {
2107  first = 0;
2108  bright = new Color(.9,.9,.9,1.); bright->ref();
2109  dark = new Color(.1,.1,.1,1.); dark->ref();
2110  ctitle = new Color(0.,0.,0.,1.); ctitle->ref();
2111  ctitlebar = new Color(.8,.8,.8,1.); ctitlebar->ref();
2112  coutline = new Color(.7,.7,.7,1.); coutline->ref();
2113  br = new Brush(1); br->ref();
2114  ftitle = wk.font(); ftitle->ref();
2115  }
2116 
2117  l=a.left(); b=a.bottom(); r=a.right(); t=a.top(); //inside
2118 
2119  //title bar
2120  pr->fill_rect(l, t, r, t+h, ctitlebar);
2121 
2122  // title
2123  Label label(title, ftitle, ctitle);
2124  Requisition req;
2125  label.request(req);
2126  x = req.x_requirement().natural();
2127  y = req.y_requirement().natural();
2128  Allocation al;
2129  Coord xo = (l + r)/2 - x/2;
2130  xo = (xo < h) ? h : xo;
2131  al.allot_x(Allotment(xo, x, 0.));
2132  al.allot_y(Allotment(t+h/2 - y/3, y, 0.));
2133  // clip the title
2134  pr->push_clipping();
2135  pr->clip_rect(l+h, t, r, t+h);
2136  label.draw(pr, al);
2137  pr->pop_clipping();
2138 
2139  // outline
2140  pr->fill_rect(l,b-w,l-w,t+h+w,coutline); // left
2141  pr->fill_rect(r,b-w,r+w,t+h+w,coutline); // right
2142  pr->fill_rect(l,b,r,b-w,coutline); // bottom
2143  pr->fill_rect(l,t+h,r,t+h+w,coutline); // top
2144  pr->rect(l-w,b-w,r+w,t+h+w,dark, br); // outside boundary
2145 
2146  // close button
2147  x = (l + (l+h-s))/2;
2148  y = (t+s + t+h)/2;
2149  dx = (h-s)/2;
2150  pr->rect(x-dx,y-dx,x+dx,y+dx,bright,br);
2151  dx = xx/2;
2152  pr->line(x-dx,y-dx,x+dx,y+dx, bright,br); // the x
2153  pr->line(x-dx,y+dx,x+dx,y-dx, bright,br); // the x
2154 }
2155 #endif
2156 
2157 void PrintableWindowManager::psfilter(const char* filename) {
2158  static char* tmpfile = (char*)0;
2159  if (!tmpfile) {
2160  tmpfile = ivoc_get_temp_file();
2161  }
2162  Style* s = Session::instance()->style();
2163  char buf[512];
2164  String filt("cat");
2165  if (s->find_attribute("pwm_postscript_filter", filt)) {
2166 #if defined(WIN32) && !defined(CYGWIN)
2167  if (!hoc_copyfile(filename, tmpfile)) {
2168  hoc_warning("CopyFile failed.", "Did not run pwm_postscript_filter");
2169  return;
2170  }
2171  sprintf(buf, "%s %s > %s",
2172  filt.string(), tmpfile, filename);
2173 #else
2174  sprintf(buf, "cat %s > %s; %s < %s > %s",
2175  filename, tmpfile,
2176  filt.string(), tmpfile, filename);
2177 #endif
2178  nrnignore = system(buf);
2179  unlink(tmpfile);
2180  }
2181 }
2182 
2183 #if defined(WIN32) || MAC
2184 void pwmimpl_redraw(Window* pw);
2185 #endif
2186 
2187 void PWMImpl::redraw(Window* pw) {
2188  // redraw the canvas so HocValEditor fields show up
2189  if (!pw->is_mapped()){
2190  return;
2191  }
2192  Canvas* c = pw->canvas();
2193  c->damage_all();
2194 #if defined(WIN32) || MAC
2195  pwmimpl_redraw(pw);
2196 #else
2197  Requisition req;
2198  Allocation a;
2199  Coord xsize = c->width();
2200  Coord ysize = c->height();
2201  pw->glyph()->request(req);
2202  Coord ox = xsize*req.x_requirement().alignment();
2203  Coord oy = ysize*req.y_requirement().alignment();
2204  a.allot_x(Allotment(ox, xsize, ox/xsize));
2205  a.allot_y(Allotment(oy, ysize, oy/ysize));
2206  Transformer t1;
2207  c->push_transform();
2208  c->transformer(t1);
2209  pw->glyph()->draw(c, a);
2210  c->pop_transform();
2211 #endif
2212 }
2213 
2214 //ScreenItem
2215 ScreenItem::ScreenItem(PrintableWindow* w) {
2216  w_ = w;
2217  jw_ = NULL;
2218  label_ = NULL;
2219  pi_ = NULL;
2220  i_ = -1;
2221  group_obj_ = NULL;
2222  iconify_via_hide_ = false;
2223 }
2224 ScreenItem::ScreenItem(JavaWindow* w) {
2225  w_ = NULL;
2226  jw_ = w;
2227  label_ = NULL;
2228  pi_ = NULL;
2229  i_ = -1;
2230  group_obj_ = NULL;
2231  iconify_via_hide_ = false;
2232 }
2233 
2234 ScreenItem::~ScreenItem(){
2235 // printf("~ScreenItem\n");
2236  if (pi_) {
2237  pi_->si_ = NULL;
2238  if (pwm_impl) {
2239  pwm_impl->remove_paper(pi_);
2240  }
2241  Resource::unref(pi_);
2242  pi_ = NULL;
2243  }
2244  hoc_obj_unref(group_obj_);
2245  Resource::unref(label_);
2246 }
2247 
2248 void ScreenItem::relabel(GlyphIndex i) {
2249  char buf[10];
2250  sprintf(buf, "%ld", i);
2251  i_ = i;
2252  Glyph* g = WidgetKit::instance()->label(buf);
2253  Resource::ref(g);
2254  Resource::unref(label_);
2255  label_ = g;
2256 }
2257 
2258 #if 0
2259 void ScreenItem::reconfigured(Scene* s) {
2260  Coord l = w_->left_pw();
2261  Coord r = l + w_->width_pw();
2262  Coord b = w_->bottom_pw();
2263  Coord t = b + w_->height_pw();
2264  s->move(i, l/Scl, b/Scl);
2265  Coord x, y;
2266  s->location(i, x, y);
2267 #if DBG
2268  printf("reconfigured %d %d %g %g\n", i, s->showing(i), x, y);
2269 #endif
2270  if (w_->is_mapped()) {
2271  impl->w_->canvas()->damage_all();
2272  }
2273 }
2274 #endif
2275 
2276 void ScreenItem::request(Requisition& req) const {
2277  Coord w, h;
2278  if (w_) {
2279  w = w_->width_pw()/Scl;
2280  h = w_->height_pw()/Scl;
2281  }else{
2282  w = jw_->w()/Scl;
2283  h = jw_->h()/Scl;
2284  }
2285  Requirement rx(w+2);
2286  Requirement ry(h+2);
2287  req.require_x(rx);
2288  req.require_y(ry);
2289 #if DBG
2290 printf("ScreenItem::request %d\n", index());
2291 #endif
2292 }
2293 
2294 void ScreenItem::allocate(Canvas* c, const Allocation& a, Extension& ext) {
2295  ext.set(c, a);
2296  MyMath::extend(ext, 1);
2297 #if DBG
2298 printf("ScreenItem::allocate %d\n", index());
2299 #endif
2300 }
2301 
2302 void ScreenItem::draw(Canvas* c, const Allocation& a) const {
2303 #if DBG
2304 printf("ScreenItem::draw %d\n", i_);
2305 //print_alloc(c,"draw", a);
2306 #endif
2307  Coord x = a.x();
2308  Coord y = a.y();
2309  if (w_) {
2310  c->rect(x, y, x + (w_->width_pw())/Scl, y + (w_->height_pw())/Scl, pwm_impl->window_outline_, NULL);
2311  }else{
2312  c->rect(x, y, x + (jw_->w())/Scl, y + (jw_->h())/Scl, pwm_impl->window_outline_, NULL);
2313  }
2314  label_->draw(c, a);
2315 }
2316 
2317 void ScreenItem::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
2318  Coord x = h.left();
2319  Coord y = h.bottom();
2320 // if (x >= 0 && x <= w_->width_pw() && y >= 0 && y <= w_->height_pw()) {
2321  if (inside(x, y, a)) {
2322  h.target(depth, this, 0);
2323  if (h.event()->type() == Event::down) {
2324  if (Oc::helpmode()) {
2325  Oc::help(PWM_ScreenItem_);
2326  return;
2327  }
2328  switch (pwm_impl->tool(h.event()->pointer_button())) {
2329  case Event::left:
2330  h.target(depth, this, 0,
2331  new ScreenItemHandler(
2332  x, y, this, c->transformer()
2333  )
2334  );
2335  break;
2336  case Event:: right:
2337  if (w_) {
2338  pwm_impl->append_paper(this);
2339  }
2340  break;
2341  }
2342 #if DBG
2343 printf("ScreenItem::pick %d hit(%g,%g)\n", i_, x, y);
2344 print_alloc(NULL, "ScreenItem", a);
2345 #endif
2346  }
2347  }
2348 }
2349 
2350 
2351 //PaperItem
2352 PaperItem::PaperItem(ScreenItem* s) {
2353  scale_ = 1.;
2354  si_ = s;
2355  s->pi_ = this;
2356  ref();
2357 }
2358 PaperItem::~PaperItem(){
2359 // printf("~PaperItem\n");
2360  if (si_) {
2361  si_->pi_ = NULL;
2362  }
2363  si_ = NULL;
2364 }
2365 
2366 Coord PaperItem::width() {return si_->w_->width_pw()/Scl;}
2367 Coord PaperItem::fsize_;
2368 
2369 void PaperItem::request(Requisition& req) const {
2370  Requirement rx(scale_ * si_->w_->width_pw()/Scl);
2371  Requirement ry(Math::max(fsize_, scale_ * si_->w_->height_pw()/Scl));
2372  req.require_x(rx);
2373  req.require_y(ry);
2374 #if DBG
2375 printf("PaperItem::request %d\n", screen_item()->index());
2376 #endif
2377 }
2378 
2379 void PaperItem::allocate(Canvas* c, const Allocation& a, Extension& ext) {
2380  ext.set(c, a);
2381  MyMath::extend(ext, 1);
2382 #if DBG
2383 printf("PaperItem::allocate %d\n", screen_item()->index());
2384 #endif
2385 }
2386 
2387 void PaperItem::draw(Canvas* c, const Allocation& a) const {
2388 #if DBG
2389 printf("PaperItem::draw %d\n", si_->i_);
2390 #endif
2391  Coord x = a.x();
2392  Coord y = a.y();
2393  c->rect(x, y, x + scale_*(si_->w_->width_pw())/Scl, y + scale_*(si_->w_->height_pw())/Scl, pwm_impl->window_outline_, NULL);
2394  si_->label_->draw(c, a);
2395 }
2396 
2397 #if 0
2398 void PaperItem::print(Printer* pr, const Allocation& a) const {
2399  Coord x = a.x();
2400  Coord y = a.y();
2401  pr->rect(x, y, x + scale_*(si_->w_->width_pw())/Scl, y + scale_*(si_->w_->height_pw())/Scl, blue, NULL);
2402  pr->push_transform();
2403  Transformer t(scale_/Scl, 0, 0, scale_/Scl, 0, 0);
2404  Allocation b = a;
2405  pr->transform(t);
2406  si_->w_->glyph()->print(pr, a);
2407  pr->pop_transform();
2408 }
2409 #endif
2410 void PaperItem::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
2411  Coord x = h.left();
2412  Coord y = h.bottom();
2413  if (::inside(x, y, a)) {
2414  h.target(depth, this, 0);
2415  if (h.event()->type() == Event::down) {
2416  if (Oc::helpmode()) {
2417  Oc::help(PWM_PaperItem_);
2418  return;
2419  }
2420  switch (pwm_impl->tool(h.event()->pointer_button())) {
2421  case Event::left:
2422  h.target(
2423  depth, this, 0,
2424  new PaperItem_handler(
2426  x, y, this, c->transformer()
2427  )
2428  );
2429  break;
2430  case Event::middle:
2431  h.target(
2432  depth, this, 0,
2433  new PaperItem_handler(
2435  x, y, this, c->transformer()
2436  )
2437  );
2438  break;
2439  case Event::right:
2440  pwm_impl->unshow_paper(this);
2441  break;
2442  }
2443 #if DBG
2444 printf("PaperItem::pick %d hit(%g, %g)\n", si_->i_, x, y);
2445 #endif
2446  }
2447  }
2448 }
2449 
2450 //PWMImpl
2451 PWMImpl::PWMImpl(ScreenScene* screen, PaperScene* paper, Rect* prect) {
2452  screen_ = screen;
2453  paper_ = paper;
2454  Resource::ref(screen);
2455  Resource::ref(paper);
2456  w_ = NULL;
2457  landscape_ = false;
2458  prect_ = prect;
2459  printer_ = "lp";
2460  use_printer = true;
2461  printer_control_accept_ = true;
2462  b_printer_ = NULL;
2463  fc_print_ = NULL;
2464  fc_idraw_ = NULL;
2465  fc_ascii_ = NULL;
2466  fc_save_ = NULL;
2467  fc_retrieve_ = NULL;
2468  p_title_ = NULL;
2469 #if MACPRINT
2470  mprinter_ = NULL;
2471 #endif
2472  tool_ = Event::right;
2473 }
2474 
2475 PWMImpl::~PWMImpl() {
2476 // printf("~PWMImpl\n");
2477  Resource::unref(screen_);
2478  screen_ = NULL;
2479  Resource::unref(paper_);
2480  paper_ = NULL;
2481  Resource::unref(b_printer_);
2482  Resource::unref(fc_print_);
2483  Resource::unref(fc_idraw_);
2484  Resource::unref(fc_ascii_);
2485  Resource::unref(fc_save_);
2486  Resource::unref(fc_retrieve_);
2487  Resource::unref(screen_rect_);
2488 #if MACPRINT
2489  if (mprinter_) {
2490  delete mprinter_;
2491  }
2492 #endif
2493 }
2494 
2495 #if MACPRINT
2496 MacPrinter* PWMImpl::mprinter() {
2497  if (!mprinter_) {
2498  mprinter_ = new MacPrinter();
2499  }
2500  return mprinter_;
2501 }
2502 #endif
2503 
2504 #if carbon
2505 void PWMImpl::all2front() {
2506  int i;
2507  PrintableWindow* w;
2508  if (screen_) for (i=0; i < screen_->count(); ++i) {
2509  ScreenItem* si = (ScreenItem*)(screen_->component(i));
2510  w = si->window();
2511  if (w && w != w->leader() && w->is_mapped()) {
2512  ivoc_bring_to_top(w);
2513  }
2514  }
2515 }
2516 #endif
2517 
2518 void PWMImpl::map_all() {
2519  GlyphIndex i;
2521  PrintableWindow* w;
2522  if (screen_) for (i=0; i < screen_->count(); i++) {
2523  ScreenItem* si = (ScreenItem*)(screen_->component(i));
2524  w = si->window();
2525  if (w) {
2526  if (w != pw) {
2527  if (si->iconify_via_hide_ == true) {
2528  w->map();
2529  }
2530  }else{
2531 // w->deiconify();
2532  }
2533  }else{
2534  si->jwindow()->map();
2535  }
2536  }
2537 }
2538 void PWMImpl::unmap_all() {
2539  GlyphIndex i;
2541  PrintableWindow* w;
2542  if (screen_) for (i=0; i < screen_->count(); i++) {
2543  ScreenItem* si = (ScreenItem*)(screen_->component(i));
2544  w = si->window();
2545  if (w) {
2546  if (w != pw) {
2547  if (screen_->showing(i)) {
2548  w->hide();
2549  si->iconify_via_hide_ = true;
2550  }else{
2551  si->iconify_via_hide_ = false;
2552  }
2553  }else{
2554  w->iconify();
2555  }
2556  }else{
2557  si->jwindow()->hide();
2558  }
2559  }
2560 }
2561 
2562 GlyphIndex PWMImpl::index(void* w) {
2563  GlyphIndex i;
2564  if (screen_) for (i=0; i < screen_->count(); i++) {
2565  ScreenItem* si = (ScreenItem*)screen_->component(i);
2566  if (w == (void*)si->window() || w == (void*)si->jwindow()) {
2567  return i;
2568  }
2569  }
2570  return -1;
2571 }
2572 
2573 void PWMImpl::relabel() {
2574  GlyphIndex i;
2575  for (i=0; i < screen_->count(); i++) {
2576  ((ScreenItem*)screen_->component(i))->relabel(i);
2577  }
2578 // if (w_) {
2579 // w_->canvas()->damage_all();
2580 // };
2581 }
2582 
2583 void PWMImpl::append_paper(ScreenItem* si) {
2584  PaperItem* pi = si->paper_item();
2585  GlyphIndex i;
2586  if (pi) {
2587  i = paper_index(pi);
2588  paper_->show(i, true);
2589  }else{
2590  pi = new PaperItem(si);
2591  pi->scale(.9);
2592  paper_->append(pi);
2593  i = paper_index(pi);
2594  Coord x = si->window()->left_pw()/Scl;
2595  Coord y = si->window()->bottom_pw()/Scl;
2596  x = (x < 0.) ? 0. : x;
2597  y = (y < 0.) ? 0. : y;
2598  x = (x > paper_->x2()*.8) ? paper_->x2()*.8 : x;
2599  y = (y > paper_->y2()*.8) ? paper_->y2()*.8 : y;
2600  paper_->move(i, x, y);
2601  }
2602  paper_->change(i);
2603 }
2604 
2605 void PWMImpl::unshow_paper(PaperItem* pi) {
2606  paper_->show(paper_index(pi), false);
2607 }
2608 
2609 void PWMImpl::remove_paper(PaperItem* pi) {
2610  GlyphIndex i = paper_index(pi);
2611  if (paper_ && i != -1) {
2612  paper_->remove(i);
2613  }
2614 }
2615 
2616 GlyphIndex PWMImpl::paper_index(PaperItem* pi) {
2617  GlyphIndex i;
2618  if (paper_) for (i=0; i < paper_->count(); i++) {
2619  if (pi == (PaperItem*)paper_->component(i)) {
2620  return i;
2621  }
2622  }
2623  return -1;
2624 }
2625 
2626 float PWMImpl::round(float x) {
2627  return Math::round(x/round_factor_) * round_factor_;
2628 }
2629 
2630 #if MACPRINT
2631 void PWMImpl::paperscale() {
2632  mprinter()->setup();
2633  Coord w, h, x;
2634  w = mprinter()->width()/72.;
2635  x = h = mprinter()->height()/72.;
2636  if (w > h) {
2637  x = w;
2638  }
2639  x = x/canvasheight_;
2640  prect_->width(w/pr_scl);
2641  prect_->height(h/pr_scl);
2642  pview_->box_size(-.2, -.2, prect_->width() + .2, prect_->height() + .2);
2643 
2644  paper_->damage_all();
2645 }
2646 #endif
2647 
2648 
2649 void PWMImpl::landscape() {
2650  if (Oc::helpmode()) {
2651  Oc::help(PWM_landscape_);
2652  }
2653  Coord w, h;
2654  w = prect_->width();
2655  h = prect_->height();
2656  prect_->width(h);
2657  prect_->height(w);
2658  paper_->damage_all();
2659  landscape_ = !landscape_;
2660 }
2661 
2662 void PWMImpl::landscape(bool b) {
2663  if (landscape_ != b) {
2664  landscape();
2665  }
2666 }
2667 
2668 void PWMImpl::deco(int i) {
2669  p_title_->set(TelltaleState::is_chosen, false);
2670  p_deco_->set(TelltaleState::is_chosen, false);
2671  if (i == 1) {
2672  p_title_->set(TelltaleState::is_chosen, true);
2673  }else if (i == 2) {
2674  p_deco_->set(TelltaleState::is_chosen, true);
2675  }
2676 }
2677 
2678 void PWMImpl::virt_screen() {
2679  if (Oc::helpmode()) {
2680  Oc::help(PWM_virt_screen_);
2681  return;
2682  }
2683  VirtualWindow::makeVirtualWindow();
2684 }
2685 
2686 //grabbed from unidraw dialogs.cpp
2687 static const char* DefaultPrintCmd () {
2688 #ifdef WIN32
2689  Style* style = Session::instance()->style();
2690  static String str;
2691  if (style->find_attribute("printer_command", str)) {
2692  ;
2693  }else{
2694  str = " > prn";
2695  }
2696  return str.string();
2697 #else
2698  static char buf[200];
2699  static const char* print_cmd = getenv("PRINT_CMD");
2700  if (print_cmd == NULL) {
2701  const char* printer_name = getenv("PRINTER");
2702 
2703  if (printer_name == NULL) {
2704  sprintf(buf, "lpr");
2705  }else{
2706  sprintf(buf, "lpr -P%s", printer_name);
2707  }
2708  print_cmd = buf;
2709  }
2710  return print_cmd;
2711 #endif
2712 }
2713 
2714 void PWMImpl::printer_control() {
2715  if (Oc::helpmode()) {
2716  Oc::help(PWM_printer_control_);
2717  }
2718  if (!b_printer_) {
2719  Style* style = new Style(Session::instance()->style());
2720  style->attribute("caption", "Postscript Printer Command");
2722  DefaultPrintCmd(), style);
2723  b_printer_->ref();
2724  }
2725  use_printer = true;
2726  bool b;
2727  if (w_ && w_->is_mapped()) {
2728  b = b_printer_->post_for(w_);
2729  }else{
2730  Coord x, y, ax, ay;
2731  if (nrn_spec_dialog_pos(x, y)) {
2732  ax = 0.0;
2733  ay = 0.0;
2734  } else { // original default
2735  x = 300.;
2736  y = 500.;
2737  ax = 0.5;
2738  ay = 0.5;
2739  }
2740 
2741  b = b_printer_->post_at_aligned(x, y, ax, ay);
2742  }
2743  if (b) {
2744  printer_control_accept_ = true;
2745  }else{
2746  printer_control_accept_ = false;
2747  }
2748 }
2749 
2750 void PWMImpl::quit_control() {
2751  if (Oc::helpmode()) {
2752  Oc::help(PWM_quit_);
2753  return;
2754  }
2755 
2756  if (boolean_dialog("Quit. Are you sure?", "Yes", "No", w_)) {
2757  Oc oc;
2758  oc.run("quit()\n");
2759  }
2760 }
2761 
2762 #if SNAPSHOT
2763 void PWMImpl::snapshot_control() {
2764  if (file_control1()) {
2765  ivoc_snapshot_ = ivoc_snapshot;
2766  }
2767 }
2768 #endif
2769 
2770 bool PWMImpl::file_control1() {
2771  if (Oc::helpmode()) {
2772  Oc::help(PWM_file_control_);
2773  }
2774  if (!fc_print_) {
2775  Style* style = new Style(Session::instance()->style());
2776  String str;
2777  if (style->find_attribute("pwm_print_file_filter", str)) {
2778  style->attribute("filter", "true");
2779  style->attribute("filterPattern", str);
2780  }
2781  style->attribute("caption", "Print Postscript to file");
2782  style->attribute("open", "Print to file");
2783  fc_print_ = DialogKit::instance()->file_chooser("./", style);
2784  fc_print_->ref();
2785  }else{
2786  fc_print_->reread();
2787  }
2788  while (fc_print_->post_for(w_)) {
2789  if (ok_to_write(*fc_print_->selected(), w_)) {
2790  return true;
2791  }
2792  }
2793  return false;
2794 }
2795 
2796 void PWMImpl::file_control() {
2797  if (none_selected("No windows to save", "Save Anyway")) {
2798  return;
2799  }
2800  if (file_control1()) {
2801  use_printer = false;
2802  do_print0();
2803  use_printer = true;
2804  }
2805 }
2806 
2807 #if SNAPSHOT
2808 void PWMImpl::snapshot(const Event* e) {
2809  snap_event_ = e;
2810  filebuf obuf;
2811  obuf.open(fc_print_->selected()->string(), IOS_OUT);
2812  ostream o(&obuf);
2813  Printer* pr = new Printer(&o);
2814  pr->prolog();
2815  pr->resize(0,0,1200, 1000);
2816  Window* w = e->window();
2817  snap_owned(pr, w);
2818 // for (w = e->window(); w; w = snap_owned(w)) {
2819 // snap(pr, w);
2820 // }
2821  snap_cursor(pr, e);
2822  pr->epilog();
2823  obuf.close();
2824  delete pr;
2825 }
2826 
2827 void PWMImpl::snap(Printer* pr, Window* w) {
2828  Transformer t;
2829  t.translate(w->left(), w->bottom());
2830  Requisition req;
2831  Glyph* g = w->Window::glyph();
2832  g->request(req);
2833  float align_x = req.x_requirement().alignment();
2834  float align_y = req.y_requirement().alignment();
2835  Allotment ax(align_x*w->width(), w->width(), align_x);
2836  Allotment ay(align_y*w->width(), w->height(), align_y);
2837  Allocation a;
2838  a.allot_x(ax);
2839  a.allot_y(ay);
2840 //printf("left=%g right=%g top=%g bottom=%g\n", a.left(), a.right(), a.top(), a.bottom());
2841  t.translate(a.left(), -a.bottom());
2842  Style* s = w->style();
2843  String str;
2844  bool pd = false;
2845  if (s && s->find_attribute("name", str)) {
2846  pd = true;
2847  pr->comment(str.string());
2848  }
2849  char buf[256];
2850  if (pd) {
2851  sprintf(buf, "BoundingBox: %g %g %g %g",
2852  w->left() - 3, w->bottom() - 3,
2853  w->left() + w->width() + 3,
2854  w->bottom() + w->height() + 20 + 3);
2855  pr->comment(buf);
2856  sprintf(buf, "\\begin{picture}(%g, %g)",
2857  w->width() + 6, w->height() + 23);
2858  pr->comment(buf);
2859  }else{
2860  sprintf(buf, "BoundingBox: %g %g %g %g", w->left(), w->bottom(),
2861  w->left() + w->width(), w->bottom() + w->height());
2862  pr->comment(buf);
2863  sprintf(buf, "\\begin{picture}(%g, %g)",
2864  w->width(), w->height());
2865  pr->comment(buf);
2866  }
2867  pr->push_transform();
2868  pr->transform(t);
2869  g->print(pr, a);
2870  if (pd) {
2871  print_deco(pr, a, str.string());
2872  }
2873  g->undraw();
2874  pr->pop_transform();
2875 // at this point cursor will be below any pop up windows so must be done last
2876 // if (w == snap_event_->window()) {
2877 // snap_cursor(pr, snap_event_);
2878 // }
2879  pr->comment("End BoundingBox");
2880 }
2881 
2882 void PWMImpl::snap_cursor(Printer* pr, const Event* e) {
2884  if (rb && rb->canvas()->window() == e->window()) {
2885  pr->comment("Begin Rubberband");
2886  Transformer t1;
2887  t1.translate(e->window()->left(), e->window()->bottom());
2888  pr->push_transform();
2889  pr->transform(t1);
2890  rb->snapshot(pr);
2891  pr->pop_transform();
2892  pr->comment("End Rubberband");
2893  }
2894 
2895  Coord x, y;
2896  x = e->pointer_x();
2897  y = e->pointer_y();
2898 
2899  Transformer t;
2900  t.rotate(30);
2901  t.translate(e->window()->left(), e->window()->bottom());
2902  t.translate(x, y);
2903  pr->comment("Begin cursor");
2904  pr->push_transform();
2905  pr->transform(t);
2906  pr->new_path();
2907  pr->move_to(0, 0);
2908  pr->line_to(8, -14);
2909  pr->line_to(2, -12);
2910  pr->line_to(2, -20);
2911  pr->line_to(-2, -20);
2912  pr->line_to(-2, -12);
2913  pr->line_to(-8, -14);
2914  pr->close_path();
2915  pr->fill(WidgetKit::instance()->foreground());
2916  pr->stroke(WidgetKit::instance()->background(), Appear::default_brush());
2917  pr->pop_transform();
2918  pr->comment("End cursor");
2919 }
2920 #endif
2921 
2922 void PWMImpl::idraw_control() {
2923  if (Oc::helpmode()) {
2924  Oc::help(PWM_idraw_control_);
2925  }
2926  if (!fc_idraw_) {
2927  Style* style = new Style(Session::instance()->style());
2928  String str;
2929  if (style->find_attribute("pwm_idraw_file_filter", str)) {
2930  style->attribute("filter", "true");
2931  style->attribute("filterPattern", str);
2932  }
2933  style->attribute("caption", "Idraw format to file");
2934  style->attribute("open", "Write to file");
2935  fc_idraw_ = DialogKit::instance()->file_chooser("./", style);
2936  fc_idraw_->ref();
2937  }else{
2938  fc_idraw_->reread();
2939  }
2940  if (none_selected("No windows to save", "Save Anyway")) {
2941  return;
2942  }
2943  while (fc_idraw_->post_for(w_)) {
2944  if (ok_to_write(*fc_idraw_->selected(), w_)) {
2945  idraw_write(fc_idraw_->selected()->string());
2946  break;
2947  }
2948  }
2949 }
2950 
2951 void PWMImpl::idraw_write(const char* fname, bool ses_style) {
2952 #ifdef WIN32
2953  unlink(fname);
2954 #endif
2955  filebuf obuf;
2956  obuf.open(fname, IOS_OUT);
2957  ostream o(&obuf);
2960  Scene* p = paper();
2961  GlyphIndex count = p->count();
2962  if (ses_style) {
2963  for (GlyphIndex i = 0; i < screen()->count(); ++i) {
2964  ScreenItem* pi = (ScreenItem*)screen()->component(i);
2965  redraw(pi->window());
2966  }
2967  }else{
2968  for (GlyphIndex i = 0; i < count; ++i) {
2969  if (!p->showing(i)) {
2970  continue;
2971  }
2972  PaperItem* pi = (PaperItem*)p->component(i);
2973  redraw(pi->screen_item()->window());
2974  }
2975  }
2976  OcIdraw::epilog();
2977  obuf.close();
2979 }
2980 
2981 void PWMImpl::ascii_control() {
2982  if (Oc::helpmode()) {
2983  Oc::help(PWM_ascii_);
2984  }
2985  if (!fc_ascii_) {
2986  Style* style = new Style(Session::instance()->style());
2987  String str;
2988  if (style->find_attribute("pwm_ascii_file_filter", str)) {
2989  style->attribute("filter", "true");
2990  style->attribute("filterPattern", str);
2991  }
2992  style->attribute("caption", "Ascii format to file");
2993  style->attribute("open", "Write to file");
2994  fc_ascii_ = DialogKit::instance()->file_chooser("./", style);
2995  fc_ascii_->ref();
2996  }else{
2997  fc_ascii_->reread();
2998  }
2999  if (none_selected("No windows to save", "Save Anyway")) {
3000  return;
3001  }
3002  while (fc_ascii_->post_for(w_)) {
3003  if (ok_to_write(*fc_ascii_->selected(), w_)) {
3004  ascii_write(fc_ascii_->selected()->string());
3005  break;
3006  }
3007  }
3008 }
3009 
3010 void PWMImpl::ascii_write(const char* fname, bool ses_style) {
3011  filebuf obuf;
3012 #ifdef WIN32
3013  unlink(fname);
3014 #endif
3015  obuf.open(fname, IOS_OUT);
3016  ostream o(&obuf);
3017  Graph::ascii(&o);
3018  Scene* p = paper();
3019  GlyphIndex count = p->count();
3020  if (ses_style) {
3021  for (GlyphIndex i = 0; i < screen()->count(); ++i) {
3022  ScreenItem* pi = (ScreenItem*)screen()->component(i);
3023  redraw(pi->window());
3024  }
3025  }else{
3026  for (GlyphIndex i = 0; i < count; ++i) {
3027  if (!p->showing(i) && !ses_style) {
3028  continue;
3029  }
3030  PaperItem* pi = (PaperItem*)p->component(i);
3031  redraw(pi->screen_item()->window());
3032  }
3033  }
3034  obuf.close();
3035  Graph::ascii(NULL);
3036 }
3037 
3038 ostream* Oc::save_stream;
3039 
3040 void PWMImpl::save_selected_control() {
3041  save_control(1);
3042 }
3043 void PWMImpl::save_all_control() {
3044  save_control(2);
3045 }
3046 bool PWMImpl::none_selected(const char* title, const char* accept)const{
3047  int i, n=0;
3048  if (paper_) for (i=0; i < paper_->count(); ++i) {
3049  if (paper_->showing(i)) {
3050  ++n;
3051  }
3052  }
3053  if (n == 0) {
3054  if (!boolean_dialog(title, accept, "Cancel", w_)) {
3055  return true;
3056  }
3057  }
3058  return false;
3059 }
3060 
3061 void PWMImpl::save_control(int mode) {
3062  if (Oc::helpmode()) {
3063  if (mode == 2) {
3064  Oc::help(PWM_save_control2_);
3065  }else{
3066  Oc::help(PWM_save_control1_);
3067  }
3068  }
3069  if (!fc_save_) {
3070  if (mode == 1) {
3071  if (none_selected("No windows to save", "Save Anyway")) {
3072  return;
3073  }
3074  }
3075  Style* style = new Style(Session::instance()->style());
3076  String str;
3077  if (style->find_attribute("pwm_save_file_filter", str)) {
3078  style->attribute("filter", "true");
3079  style->attribute("filterPattern", str);
3080  }
3081  style->attribute("caption", "Save windows on paper icon to file");
3082  style->attribute("open", "Save to file");
3083  fc_save_ = DialogKit::instance()->file_chooser("./", style);
3084  fc_save_->ref();
3085  }else{
3086  fc_save_->reread();
3087  }
3088  while (fc_save_->post_for(w_)) {
3089  if (ok_to_write(*fc_save_->selected(), w_)) {
3090  save_session(mode, fc_save_->selected()->string());
3091  break;
3092  }
3093  }
3094 }
3095 
3096 int PWMImpl::save_group(Object* ho, const char* filename) {
3097  int i;
3098  ScreenItem* si;
3099  ScreenItem** sivec = NULL;
3100  int nwin = 0;
3101  if (screen_ && screen_->count()) {
3102  sivec = new ScreenItem*[screen_->count()];
3103  for (i=0; i < screen_->count(); i++) {
3104  si = (ScreenItem*)(screen_->component(i));
3105  if (si->group_obj_ == ho) {
3106  sivec[nwin++] = si;
3107  }
3108  }
3109  }
3110  if (nwin > 0) {
3111  cur_ses_name_ = filename;
3112  filebuf obuf;
3113 #ifdef WIN32
3114  unlink(filename);
3115 #endif
3116  obuf.open(filename, IOS_OUT);
3117  ostream o(&obuf);
3118  save_begin(o);
3119  save_list(nwin, sivec, o);
3120  obuf.close();
3121  }
3122  if (sivec) {
3123  delete [] sivec;
3124  }
3125  return nwin;
3126 }
3127 
3128 void PWMImpl::save_session(int mode, const char* filename, const char* head) {
3129  int nwin = 0;
3130  ScreenItem* si;
3131  ScreenItem** sivec = NULL;
3132 
3133  filebuf obuf;
3134  cur_ses_name_ = filename;
3135 #ifdef WIN32
3136  unlink(filename);
3137 #endif
3138  obuf.open(filename, IOS_OUT);
3139  if (!obuf.is_open()) {
3140  hoc_execerror(filename, "is not open for writing");
3141  }
3142  ostream o(&obuf);
3143  if (head) {
3144  o << head << endl;
3145  }
3146  save_begin(o);
3147 
3148  PrintableWindow* w;
3149  GlyphIndex i;
3150  if (mode == 2) {
3151  if (screen_ && screen_->count()) {
3152  sivec = new ScreenItem*[screen_->count()];
3153  for (i=0; i < screen_->count(); i++) {
3154  si = (ScreenItem*)(screen_->component(i));
3155  w = si->window();
3156  if (w) {
3157  if (/*w->is_mapped() &&*/ w != PrintableWindow::leader()) {
3158  if (w_ != w) {
3159  sivec[nwin++] = si;
3160  }else{
3161  char buf[100];
3162 sprintf(buf,"{pwman_place(%d,%d,%d)}\n", w->xleft(), w->xtop(), w->is_mapped() ? 1 : 0);
3163  o << buf;
3164  }
3165  }
3166  }else if (si->jwindow()){
3167  sivec[nwin++] = si;
3168  }
3169  }
3170  }
3171  }else{
3172  if (paper_ && paper_->count()) {
3173  sivec = new ScreenItem*[paper_->count()];
3174  for (i=0; i < paper_->count(); i++) {
3175  if (paper_->showing(i)) {
3176  si = ((PaperItem*)(paper_->component(i)))->screen_item();
3177  w = si->window();
3178  if (w) {
3179  if (w_ != w) {
3180  sivec[nwin++] = si;
3181  }else{
3182  char buf[100];
3183  sprintf(buf,"{pwman_place(%d,%d)}\n", w->xleft(), w->xtop());
3184  o << buf;
3185  }
3186  }else if (si->jwindow()){
3187  sivec[nwin++] = si;
3188  }
3189 
3190  }
3191  }
3192  }
3193  }
3194  save_list(nwin, sivec, o); //sivec deleted here
3195  obuf.close();
3196  if (sivec) {
3197  delete [] sivec;
3198  }
3199 }
3200 
3201 void PWMImpl::save_begin(ostream& o) {
3202  Oc::save_stream = &o;
3203  Scene::save_all(o);
3204  HocPanel::save_all(o);
3205 o << "objectvar ocbox_, ocbox_list_, scene_, scene_list_" << endl;
3206 o << "{ocbox_list_ = new List() scene_list_ = new List()}" << endl;
3207 }
3208 
3209 void PWMImpl::save_list(int nwin, ScreenItem** sivec, ostream& o) {
3210  // save highest first, only a few priorities
3211  OcGlyph* ocg;
3212  int i, pri, max, working;
3213  ses_group_first_ = 1;
3214 //printf("will save %d windows\n", nwin);
3215  for (working = 10000; working >= 0; working = max) {
3216 //printf("working = %d\n", working);
3217  max = -1;
3218  for (i=0; i < nwin; ++i) {
3219  if (sivec[i]->window()) {
3220  ocg = (OcGlyph*)sivec[i]->window()->glyph();
3221  pri = ocg->session_priority();
3222  }else{
3223  pri = sivec[i]->jwindow()->priority();
3224  }
3225  if (pri == working) {
3226 //printf("saving item %d with priority %d\n", i, pri);
3227  if (sivec[i]->window()) {
3228  ocg->save(o);
3229  }else{
3230  sivec[i]->jwindow()->save_session(cur_ses_name_.string(), o);
3231  }
3232  ses_group(sivec[i], o);
3233  }
3234  if (pri < working && pri > max) {
3235  max = pri;
3236  }
3237  }
3238  }
3239  Oc::save_stream = NULL;
3240 o << "objectvar scene_vector_[1]\n{doNotify()}" << endl;
3241 }
3242 
3243 void PWMImpl::ses_group(ScreenItem* si, ostream& o) {
3244  char buf[512];
3245  char* name;
3246  if (si->group_obj_) {
3247  name = Oc2IV::object_str("name", si->group_obj_);
3248  sprintf(buf, "{WindowMenu[0].ses_gid(%d, %d, %d, \"%s\")}\n",
3249  ses_group_first_, si->group_obj_->index,
3250  (screen()->showing(si->index()) ? 1 : 0), name);
3251  o << buf;
3252  ses_group_first_ = 0;
3253  }
3254 }
3255 
3256 void PWMImpl::retrieve_control() {
3257  if (Oc::helpmode()) {
3258  Oc::help(PWM_retrieve_control_);
3259  }
3260  if (!fc_retrieve_) {
3261  Style* style = new Style(Session::instance()->style());
3262  String str;
3263  if (style->find_attribute("pwm_save_file_filter", str)) {
3264  style->attribute("filter", "true");
3265  style->attribute("filterPattern", str);
3266  }
3267  style->attribute("caption", "Retrieve windows from file");
3268  style->attribute("open", "Retrieve from file");
3269  fc_retrieve_ = DialogKit::instance()->file_chooser("./", style);
3270  fc_retrieve_->ref();
3271  }else{
3272  fc_retrieve_->reread();
3273  }
3274  while (fc_retrieve_->post_for(w_)) {
3275  if (ok_to_read(*fc_retrieve_->selected(), w_)) {
3276  Oc oc;
3277  char buf[256];
3278  sprintf(buf, "{load_file(1, \"%s\")}\n", fc_retrieve_->selected()->string());
3279  if( ! oc.run(buf)) {
3280  break;
3281  }
3282  }
3283  }
3284 }
3285 
3286 class OcLabelGlyph : public OcGlyph {
3287 public:
3288  OcLabelGlyph(const char*, OcGlyph*, Glyph*);
3289  virtual ~OcLabelGlyph();
3290  virtual void save(ostream&);
3291 private:
3292  CopyString label_;
3293  OcGlyph* og_;
3294 };
3295 
3296 OcLabelGlyph::OcLabelGlyph(const char* label, OcGlyph* og, Glyph* g){
3297  label_ = label;
3298  og_ = og;
3299  og_->parents(true);
3300  Resource::ref(og_);
3301  body(g);
3302 }
3303 
3304 OcLabelGlyph::~OcLabelGlyph(){
3305  og_->parents(false);
3306  Resource::unref(og_);
3307 }
3308 
3309 void OcLabelGlyph::save(ostream& o){
3310  char buf[256];
3311  o << "{xpanel(\"\")" << endl;
3312  sprintf(buf, "xlabel(\"%s\")", label_.string());
3313  o << buf << endl;
3314  o << "xpanel()}" << endl;
3315  og_->save(o);
3316 }
3317 
3318 /*static*/ class TrayDismiss : public WinDismiss {
3319 public:
3320  TrayDismiss(DismissableWindow*);
3321  virtual ~TrayDismiss();
3322  virtual void execute();
3323 };
3324 
3325 class OcTray : public OcBox {
3326 public:
3327  OcTray(GlyphIndex cnt);
3328  virtual ~OcTray();
3329  virtual PrintableWindow* make_window(Coord = -1, Coord = -1, Coord = -1, Coord = -1);
3330  virtual void start_vbox();
3331  virtual void win(PrintableWindow*);
3332  virtual void dissolve(Coord, Coord);
3333 private:
3334  PolyGlyph* pg_;
3335  OcBox* v_;
3336  float* x_, *y_;
3337 };
3338 
3339 TrayDismiss::TrayDismiss(DismissableWindow* w) : WinDismiss(w) {}
3340 TrayDismiss::~TrayDismiss() {}
3341 void TrayDismiss::execute() {
3342  if (boolean_dialog("Dismiss or Dissolve into components?", "Dissolve",
3343  "Dismiss", win_)) {
3344  OcTray* t = (OcTray*)win_->glyph();
3345  t->dissolve(win_->left(), win_->bottom());
3346  }
3348 }
3349 OcTray::OcTray(GlyphIndex cnt) : OcBox(OcBox::H)
3350 {
3351  x_ = new float[cnt];
3352  y_ = new float[cnt];
3353  pg_ = new PolyGlyph();
3354  pg_->ref();
3355  v_ = NULL;
3356 }
3357 
3358 OcTray::~OcTray() {
3359  pg_->unref();
3360  delete [] x_;
3361  delete [] y_;
3362 }
3363 
3364 void OcTray::dissolve(Coord left, Coord bottom) {
3365  Window* w;
3366  Coord l, b;
3367  OcGlyph* g;
3368  Requisition req;
3369  GlyphIndex i, cnt = pg_->count();
3370  for (i=0; i < cnt; ++i) {
3371  l = left;
3372  b = bottom;
3373  g = (OcGlyph*)pg_->component(i);
3374  g->request(req);
3375  w = g->make_window(
3376  l + x_[i] - x_[0],
3377  b + y_[i] - y_[0],
3378  req.x_requirement().natural(),
3379  req.y_requirement().natural()
3380  );
3381  w->map();
3382  }
3383 }
3384 
3385 void OcTray::start_vbox() {
3386  v_ = new OcBox(OcBox::V);
3387  box_append(v_);
3388 }
3389 
3390 void OcTray::win(PrintableWindow* w) {
3391  LayoutKit* lk = LayoutKit::instance();
3392  WidgetKit* wk = WidgetKit::instance();
3393  wk->begin_style("_tray_panel");
3394  GlyphIndex n = pg_->count();
3395  pg_->append(w->glyph());
3396  x_[n] = w->left();
3397  y_[n] = w->bottom();
3398  v_->box_append (new OcLabelGlyph(
3399  w->name(),
3400  (OcGlyph*)w->glyph(),
3401  lk->vbox(
3402  wk->label(w->name()),
3403  lk->fixed(w->glyph(), w->width(), w->height())
3404  )
3405  ));
3406  wk->end_style();
3407 }
3408 
3409 PrintableWindow* OcTray::make_window(Coord left, Coord bottom, Coord width, Coord height)
3410 {
3411  PrintableWindow* w = OcGlyph::make_window(left, bottom, width, height);
3412  w->replace_dismiss_action(new TrayDismiss(w));
3413  w->type("Tray");
3414  w->name("Tray");
3415  return w;
3416 }
3417 
3418 void PWMImpl::tray() {
3419  if (Oc::helpmode()) {
3420  Oc::help(PWM_tray_);
3421  return;
3422  }
3423  GlyphIndex count;
3424 
3425  count = paper_->count();
3426  // don't make a tray containing the main manager
3427 
3428  // build hbox(vbox) of the individual panels
3429  long index;
3430  Coord minleft = -1000;
3431  Coord top = -1000.;
3432  OcTray* tray = new OcTray(count);
3433  while ( (index = upper_left()) != -1) {
3434  PaperItem* pi = (PaperItem*)paper_->component(index);
3435  PrintableWindow* w = pi->screen_item()->window();
3436  Coord l,b;
3437  l = w->left();
3438  b = w->bottom();
3439  if (minleft < l) {
3440  tray->start_vbox();
3441  minleft = l + w->width()/2.;
3442  }
3443  if (top < 0) {
3444  top = b + w->height();
3445  }
3446  tray->win(w);
3447  paper_->show(index, false);
3448  w->dismiss();
3449  }
3450  Window* w = tray->make_window();
3451  w->map();
3452 }
3453 
3454 GlyphIndex PWMImpl::upper_left() {
3455  GlyphIndex index = -1;
3456  Coord minleft = 1e10;
3457  Coord maxbottom = -1e10;
3458  GlyphIndex count = paper_->count();
3459  for (GlyphIndex i = 0; i < count; ++i) {
3460  PaperItem* pi = (PaperItem*)paper_->component(i);
3461  PrintableWindow* w = pi->screen_item()->window();
3462  Coord l, b;
3463  if (!paper_->showing(i)) continue;
3464  if (w == pwm_impl->w_) {
3465  continue;
3466  }
3467 // paper_->location(i, l, b);
3468 // l *= Scl;
3469 // b *= Scl;
3470  l = w->left();
3471  b = w->bottom();
3472  if (l < minleft - 50.) {
3473  index = i;
3474  minleft = l;
3475  maxbottom = b;
3476  }else if (l < minleft + 50.) {
3477  if (maxbottom < b) {
3478  index = i;
3479  minleft = l;
3480  maxbottom = b;
3481  }
3482  }
3483  }
3484  return index;
3485 }
3486 
3487 #if 0
3488 void PWMImpl::dissolve() {
3489  for (long i = 0; i < panelList_.count(); i++) {
3490  new HocWin(panelList_.item(i));
3491  }
3492  dismiss();
3493 }
3494 #endif
3495 
3496 #if SNAPSHOT
3497 bool ivoc_snapshot(const Event* e) {
3498  char buf[4];
3499  e->mapkey(buf, 1);
3500  if (buf[0] == 'p') {
3501  ivoc_snapshot_ = NULL;
3502  PWMImpl* p = PrintableWindowManager::current()->pwmi_;
3503  p->snapshot(e);
3504  return true;
3505  }
3506  return false;
3507 }
3508 
3509 #if 1
3510 #include <OS/table.h>
3511 #include <InterViews/enter-scope.h>
3512 #include <IV-X11/Xlib.h>
3513 #include <IV-X11/xdisplay.h>
3514 
3516 
3517 
3518 Window* PWMImpl::snap_owned(Printer* pr, Window* wp) {
3519  WindowTable* wt = Session::instance()->default_display()->rep()->wtable_;
3520  for (TableIterator(WindowTable) i(*wt); i.more(); i.next()) {
3521  Window* w = i.cur_value();
3522  if (w->is_mapped()) {
3523  snap(pr, w);
3524  }
3525  }
3526  return NULL;
3527 }
3528 #endif
3529 #endif //SNAPSHOT
3530 
3531 JavaWindow::JavaWindow(const char* s, Object* o) {
3532 //printf("JavaWindow %s %s\n", s, hoc_object_name(o));
3533  title = new char[strlen(s) + 1];
3534  strcpy(title, s);
3535  is_mapped = false;
3536  pl = pt = 0; pw = ph = 100;
3537  ho = o;
3538  closing_ = false;
3539  reffing_ = false;
3540  ref();
3541 }
3542 JavaWindow::~JavaWindow() {
3543 //printf("~JavaWindow\n");
3544  delete [] title;
3545  unref();
3546 }
3547 
3548 void (*nrnjava_pwm_setwin)(void*, int, int, int);
3549 
3550 Coord JavaWindow::l() {
3551  return Session::instance()->default_display()->to_coord(pl);
3552 }
3553 
3554 Coord JavaWindow::b() {
3555  Display* d = Session::instance()->default_display();
3556  return d->to_coord(d->pheight() - (pt + ph));
3557 }
3558 
3559 Coord JavaWindow::w() {
3560  return Session::instance()->default_display()->to_coord(pw);
3561 }
3562 
3563 Coord JavaWindow::h() {
3564  return Session::instance()->default_display()->to_coord(ph);
3565 }
3566 
3567 void JavaWindow::map() {
3568  (*nrnjava_pwm_setwin)(this, 1, 0, 0);
3569 }
3570 void JavaWindow::hide() {
3571  (*nrnjava_pwm_setwin)(this, 2, 0, 0);
3572 }
3573 void JavaWindow::move(Coord x, Coord y) {
3574  Display* d = Session::instance()->default_display();
3575  int left = d->to_pixels(x);
3576  int top = d->pheight() - d->to_pixels(y) - ph;
3577  (*nrnjava_pwm_setwin)(this, 3, left, top);
3578 }
3579 void JavaWindow::pmove(int l, int t) {
3580  (*nrnjava_pwm_setwin)(this, 3, l, t);
3581 }
3582 void JavaWindow::presize(int w, int h) {
3583  (*nrnjava_pwm_setwin)(this, 4, w, h);
3584 }
3585 
3586 void JavaWindow::ref() {
3587  if (!reffing_) {
3588 //printf("JavaWindow ref %s\n", hoc_object_name(ho));
3589  hoc_obj_ref(ho);
3590  reffing_ = true;
3591  }
3592 }
3593 
3594 void JavaWindow::unref() {
3595  if (reffing_) {
3596 //printf("JavaWindow unref %s\n", hoc_object_name(ho));
3597  hoc_obj_unref(ho);
3598  reffing_ = false;
3599  }
3600 }
3601 
3602 int JavaWindow::priority() {
3603  // check for save_session method
3604  Symbol* s = NULL;
3605  if (ho) {
3606  s = hoc_table_lookup("hocSessionPriority", ho->ctemplate->symtable);
3607  }
3608  int i = 1;
3609  if (s) {
3610  i = (int)((*p_java2nrn_dmeth)(ho, s));
3611  }
3612 //printf("%s priority %d\n", hoc_object_name(ho), i);
3613  return i;
3614 }
3615 
3616 void JavaWindow::save_session(const char* fname, ostream& o) {
3617  // minimum save is, if ho is not NULL, to
3618  // load_java and create an object ocbox_ with the noarg constructor,
3619  // which is then unreffed.
3620  // after creation and before move/resize/hide and
3621  // unreffing, if the hoc_save_session
3622  // method exists, that is called with the session file name.
3623  if (!ho ) { return; }
3624  char buf[256];
3625  o << "/*Begin " << title << " */\n";
3626  sprintf(buf, "{load_java(\"%s\", \"%s\")}\n",
3627  (*p_java2nrn_classname)(ho),
3628  ho->ctemplate->sym->name);
3629  o << buf;
3630  sprintf(buf, "ocbox_ = new %s()\n", ho->ctemplate->sym->name);
3631  o << buf;
3632 
3633  // check for save_session method
3634  Symbol* s = hoc_table_lookup("hocSessionSave", ho->ctemplate->symtable);
3635  if (s) {
3636  // arguments are the session file name
3637  char* b2 = new char[strlen(fname)+1];
3638  strcpy(b2, fname);
3639  hoc_pushstr(&b2);
3640  char** cpp = (*p_java2nrn_smeth)(ho, s);
3641  hoc_strpop();
3642  delete [] b2;
3643 //printf("%s.hocSessionSave(\"%s\") returned |%s|\n", hoc_object_name(ho), fname, *cpp);
3644  o << *cpp;
3645  }
3646  sprintf(buf, "{PWManager[0].jwindow(ocbox_, %d, %d, %d, %d, %d)}\n",
3647  is_mapped?1:0, pl, pt, pw, ph);
3648  o << buf;
3649  o << "objref ocbox_\n";
3650  o << "/*End " << title << " */\n";
3651 }
3652 
3653 void* nrnjava_pwm_listen(const char* s, Object* ho) {
3654  JavaWindow* jw = new JavaWindow(s, ho);
3656  return jw;
3657 }
3658 
3659 // see src/nrnjava/PWMListener.java for the types
3660 void nrnjava_pwm_event(size_t ic, int type, int l, int t, int w, int h) {
3661  JavaWindow* jw = (JavaWindow*)ic;
3663  if (type >= 3 && type <= 6) {
3664  jw->pl = l;
3665  jw->pt = t;
3666  jw->pw = w;
3667  jw->ph = h;
3668  }
3669  switch(type) {
3670  case 1: // windowClosing
3671 //printf("windowClosing\n");
3672  jw->closing_ = true;
3673  break;
3674  case 2: // windowIconified
3675 //printf("windowIconified\n");
3676  jw->is_mapped = false;
3677  pwm->reconfigured(jw);
3678  jw->hide();
3679  break;
3680  case 3: // componentHidden
3681 //printf("componentHidden\n");
3682  if (jw->closing_) {
3683  jw->unref();
3684  pwm->remove(jw);
3685  delete jw;
3686  }else{
3687  jw->is_mapped = false;
3688  pwm->reconfigured(jw);
3689  }
3690  break;
3691  case 4: // componentMoved
3692  case 5: // componentResized
3693  jw->is_mapped = true;
3694  pwm->reconfigured(jw);
3695  break;
3696  case 6: // componentShown
3697 //printf("componentShown\n");
3698  jw->is_mapped = true;
3699  pwm->reconfigured(jw);
3700  jw->ref();
3701  break;
3702  }
3703 }
3704 
3705 #else
3706 
3707 #include <string.h>
3708 #include <stdio.h>
3709 #include <stdlib.h>
3710 #include <unistd.h>
3711 #include <InterViews/resource.h>
3712 #include "oc2iv.h"
3713 
3714 #endif //HAVE_IV
3715 
3717  char* tmpfile;
3718 #if MAC && !defined(carbon)
3719  FSSpec spec;
3720  tmpfile = new char[512];
3721  __temp_file_name(tmpfile, &spec);
3722 #else
3723  const char* tdir = getenv("TEMP");
3724  if (!tdir) {
3725  tdir = "/tmp";
3726  }
3727 #if defined(WIN32) && defined(__MWERKS__)
3728  char tname[L_tmpnam+1];
3729  tmpnam(tname);
3730  tmpfile = new char[strlen(tdir) + 1 + strlen(tname) + 1];
3731  sprintf(tmpfile, "%s/%s", tdir, tname);
3732 #else
3733  tmpfile = new char[strlen(tdir) + 1 + 9 + 1];
3734  sprintf(tmpfile, "%s/nrnXXXXXX", tdir);
3735 #if HAVE_MKSTEMP
3736  int fd;
3737  if ((fd = mkstemp(tmpfile)) == -1) {
3738  hoc_execerror("Could not create temporary file:", tmpfile);
3739  }
3740  close(fd);
3741 #else
3742  mktemp(tmpfile);
3743 #endif
3744 #endif
3745 #if defined(WIN32)
3746  tmpfile = hoc_back2forward(tmpfile);
3747 #endif
3748 #endif
3749  return tmpfile;
3750 }
o
Definition: seclist.cpp:180
void allot_x(const Allotment &)
Definition: geometry.h:282
static MenuItem * menu_item(const char *)
const char *(* p_java2nrn_classname)(Object *ho)
static ostream * idraw_stream
Definition: idraw.h:47
void xmove(int left, int top)
Definition: ivocmac.cpp:174
static void unref(Object *obj)
Definition: kschan.cpp:45
#define TelltaleGroup
Definition: _defines.h:295
virtual void update(Observable *)
double max(double a, double b)
Definition: geometry3d.cpp:22
static double pwman_hide(void *v)
Definition: pwman.cpp:521
virtual Glyph * component(GlyphIndex) const
#define Display
Definition: _defines.h:97
static Member_func members[]
Definition: pwman.cpp:856
static double pwman_snap(void *v)
Definition: pwman.cpp:685
short type
Definition: cabvars.h:10
static bool helpmode()
Definition: ivoc.h:66
void canvas(Canvas *)
static char * object_str(const char *symname, Object *=NULL)
Definition: oc2iv.cpp:14
void set(Canvas *, const Allocation &)
bool ok_to_write(const String &, Window *w=NULL)
virtual PrintableWindow * make_window(Coord left=-1, Coord bottom=-1, Coord width=-1, Coord height=-1)
static Member_ret_str_func s_memb[]
Definition: pwman.cpp:883
Coord x() const
Definition: geometry.h:290
void execute(Inst *p)
Definition: code.cpp:2651
char * hoc_back2forward(char *s)
Definition: mswinprt.cpp:193
void pwmimpl_redraw(Window *w)
carbon
Definition: ivocmac.cpp:153
#define TRY_GUI_REDIRECT_NO_RETURN(name, obj)
Definition: gui-redirect.h:44
#define WidgetKit
Definition: _defines.h:331
static double pwman_landscape(void *v)
Definition: pwman.cpp:834
virtual void execute()
static double pwman_deco(void *v)
Definition: pwman.cpp:845
int hoc_return_type_code
Definition: code.cpp:41
static double pwman_jwindow(void *v)
Definition: pwman.cpp:702
void psfilter(const char *filename)
int xleft() const
Definition: ivocmac.cpp:182
#define TRY_GUI_REDIRECT_ACTUAL_STR(name, obj)
Definition: gui-redirect.h:76
Definition: ivoc.h:36
#define g
Definition: passive0.cpp:23
void append(PrintableWindow *)
static double inside(void *)
Definition: mymath.cpp:21
#define Glyph
Definition: _defines.h:132
#define Coord
Definition: _defines.h:19
#define Brush
Definition: _defines.h:59
void
static int round(float)
void hoc_save_session()
Definition: ocnoiv1.cpp:155
size_t p
#define Color
Definition: _defines.h:74
virtual Coord x2() const
Definition: scenevie.h:318
static int first
Definition: fmenu.cpp:186
void xplace(int, int, bool map=true)
#define Scene
Definition: _defines.h:251
void reconfigured(PrintableWindow *)
void(* nrnjava_pwm_setwin)(void *, int, int, int)
static void help(const char *)
Definition: rect.h:38
void set_xy(Canvas *, Coord left, Coord bottom, Coord right, Coord top)
Definition: math.cpp:52
const char * pwm_session_filename()
static MenuItem * check_menu_item(const char *)
#define print
Definition: redef.h:109
#define Handler
Definition: _defines.h:146
int session_priority()
Definition: ocglyph.h:33
virtual Coord width_pw() const
#define v
Definition: md1redef.h:4
#define FileChooser
Definition: _defines.h:116
static void save_all(std::ostream &)
Coord y() const
Definition: geometry.h:291
const Requirement & x_requirement() const
Definition: geometry.h:249
virtual Glyph * glyph() const
Definition: apwindow.h:45
Coord begin() const
Definition: geometry.h:274
virtual void ref() const
Definition: resource.cpp:47
#define PolyGlyph
Definition: _defines.h:207
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
int system(const char *s)
Definition: mswinprt.cpp:281
int nrnignore
Definition: hoc.cpp:26
static void pr(N_Vector x)
#define TRY_GUI_REDIRECT_ACTUAL_DOUBLE(name, obj)
Definition: gui-redirect.h:66
virtual const char * name() const
void size(Coord x1, Coord y1, Coord x2, Coord y2)
#define e
Definition: passive0.cpp:24
void origin(Coord)
Definition: geometry.h:266
#define gargstr
Definition: hocdec.h:14
static double pwman_manager(void *v)
Definition: pwman.cpp:624
void type(const char *)
const char * string() const
Definition: string.h:139
virtual void save(std::ostream &)
char * ivoc_get_temp_file()
Definition: pwman.cpp:3716
#define declareTable(Table, Key, Value)
Definition: table.h:46
static double map(void *v)
Definition: mlinedit.cpp:46
virtual void map()
void hoc_ret()
Definition: ocbox.h:13
virtual Coord height_pw() const
static const Brush * default_brush()
void PWManager_reg()
Definition: pwman.cpp:888
#define Allotment
Definition: _defines.h:38
char * mktemp(char *)
Definition: ivocmac.cpp:27
void nrnjava_pwm_event(size_t, int, int, int, int, int)
static double pwman_printfile(void *v)
Definition: pwman.cpp:805
static N_Vector w_
#define Font
Definition: _defines.h:120
Coord bottom() const
Definition: geometry.h:298
void * nrnjava_pwm_listen(const char *, Object *)
static double pwman_scale(void *v)
Definition: pwman.cpp:742
void allot_y(const Allotment &)
Definition: geometry.h:283
virtual void reconfigured()
static double pwman_save(void *v)
Definition: pwman.cpp:643
Definition: ocbox.h:11
static double ref(void *v)
Definition: ocbox.cpp:377
int const size_t const size_t n
Definition: nrngsl.h:12
#define Menu
Definition: _defines.h:176
#define Printer
Definition: _defines.h:211
#define TRY_GUI_REDIRECT_DOUBLE(name, obj)
Definition: gui-redirect.h:54
const Requirement & y_requirement() const
Definition: geometry.h:250
static ostream * save_stream
Definition: ivoc.h:71
_CONST char * s
Definition: system.cpp:74
virtual Coord x1() const
Definition: scenevie.h:317
double(* nrnpy_object_to_double_)(Object *)
Definition: xmenu.cpp:14
Coord top() const
Definition: geometry.h:295
static std::ostream * ascii()
bool nrn_spec_dialog_pos(Coord &x, Coord &y)
true if Style &#39;dialog_spec_position: on&#39; and fills x,y with dialog_left_position and dialog_bottom_po...
static const char ** pwman_name(void *v)
Definition: pwman.cpp:537
void class2oc(const char *, void *(*cons)(Object *), void(*destruct)(void *), Member_func *, int(*checkpoint)(void **), Member_ret_obj_func *, Member_ret_str_func *)
Definition: hoc_oop.cpp:1581
void hoc_obj_unref(Object *obj)
Definition: hoc_oop.cpp:1998
static Rubberband * current()
Definition: rubband.h:50
#define printf
Definition: mwprefix.h:26
static N_Vector x_
#define IOS_OUT
Definition: ivstream.h:8
void alignment(float)
Definition: geometry.h:241
Coord left() const
Definition: geometry.h:297
int
Definition: nrnmusic.cpp:71
virtual Coord left_pw() const
void hoc_warning(const char *, const char *)
virtual void reconfigured()
void single_event_run()
Coord left() const
Definition: geometry.h:292
#define LayoutKit
Definition: _defines.h:161
static double pwman_close(void *v)
Definition: pwman.cpp:555
static const char * fname(const char *name)
Definition: nrnbbs.cpp:108
virtual void attach(Observer *)
Definition: observe.cpp:54
#define ENDGUI
Definition: hocdec.h:352
#define GlyphIndex
Definition: _defines.h:23
static void help(const char *)
Definition: hel2mos.cpp:104
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
void location(GlyphIndex, Coord &x, Coord &y) const
#define cnt
Definition: spt2queue.cpp:19
#define Canvas
Definition: _defines.h:65
void require_y(const Requirement &)
Definition: geometry.h:248
char * getenv(const char *s)
Definition: macprt.cpp:67
void move(GlyphIndex, Coord x, Coord y)
Definition: model.h:57
static void extend(Extension &, Coord)
Definition: mymath.h:89
static double pwman_iconify(void *v)
Definition: pwman.cpp:580
virtual void unref() const
Definition: resource.cpp:52
char * name
Definition: init.cpp:16
static N_Vector y_
static void * pwman_cons(Object *)
Definition: pwman.cpp:462
virtual void disconnect(Observable *)
void hoc_pwman_place()
Definition: ocnoiv1.cpp:148
static double pwman_leader(void *v)
Definition: pwman.cpp:606
void hoc_obj_ref(Object *obj)
Definition: hoc_oop.cpp:1980
Coord bottom() const
Definition: geometry.h:294
#define left
Definition: rbtqueue.cpp:45
virtual void move(const Event &e)
Definition: ocinput.h:19
#define Event
Definition: _defines.h:107
void hoc_print_session()
Definition: ocnoiv1.cpp:162
void xplace(int left, int top)
Definition: ivocmac.cpp:229
Coord right() const
Definition: geometry.h:299
static double resize(void *v)
bool ok_to_read(const String &, Window *w=NULL)
#define fil
Definition: coord.h:42
void clear()
static double pwman_count(void *v)
Definition: pwman.cpp:476
bool showing(GlyphIndex) const
virtual void map_notify()
int ifarg(int)
Definition: code.cpp:1562
void remove(PrintableWindow *)
virtual void dismiss()
static void prologue()
#define lookup
Definition: redef.h:90
static double pwman_window_place(void *v)
Definition: pwman.cpp:762
#define right
Definition: rbtqueue.cpp:46
#define TableIterator(Table)
Definition: table.h:38
void hoc_pushx(double)
void ivoc_bring_to_top(Window *w)
Definition: ivocmac.cpp:157
virtual Coord y2() const
Definition: scenevie.h:320
void require_x(const Requirement &)
Definition: geometry.h:247
static bool is_transient()
Definition: apwindow.h:50
#define TRY_GUI_REDIRECT_OBJ(name, obj)
Definition: gui-redirect.h:12
virtual Scene * scene() const
static FieldDialog * field_dialog_instance(const char *, Style *, Glyph *extra=NULL)
#define Transformer
Definition: _defines.h:316
void span(Coord)
Definition: geometry.h:269
Coord right() const
Definition: geometry.h:293
Coord top() const
Definition: geometry.h:300
static double save(void *v)
Definition: ocbox.cpp:340
void continue_dialog(const char *label, Window *w=NULL, Coord x=400., Coord y=400.)
Definition: hocdec.h:226
#define TRY_GUI_REDIRECT_ACTUAL_OBJ(name, obj)
Definition: gui-redirect.h:86
double(* p_java2nrn_dmeth)(Object *ho, Symbol *method)
Definition: hoc_oop.cpp:24
static double pwman_paper_place(void *v)
Definition: pwman.cpp:780
#define getarg
Definition: hocdec.h:15
virtual void remove(GlyphIndex)
#define Label
Definition: _defines.h:159
Symbol * hoc_table_lookup(const char *, Symlist *)
Definition: symbol.cpp:60
virtual ~PrintableWindowManager()
#define Rect
Definition: rect.h:5
virtual void pick(Canvas *, const Allocation &, int depth, Hit &)
Definition: scenevie.h:185
#define i
Definition: md1redef.h:12
#define c
char ** hoc_strpop()
Definition: code.cpp:868
virtual void detach(Observer *)
Definition: observe.cpp:63
#define Action
Definition: _defines.h:27
static PrintableWindowManager * current()
virtual void hide()
Definition: ivocmac.cpp:170
static PrintableWindow * leader()
Definition: apwindow.h:89
Definition: string.h:34
Item * title
Definition: model.cpp:40
virtual void snapshot(Printer *)
Allotment & x_allotment()
Definition: geometry.h:285
int hoc_copyfile(const char *src, const char *dest)
Definition: macprt.cpp:81
bool(* p_java2nrn_identity)(Object *o1, Object *o2)
bool boolean_dialog(const char *label, const char *accept, const char *cancel, Window *w=NULL, Coord x=400., Coord y=400.)
char buf[512]
Definition: init.cpp:13
#define Window
Definition: _defines.h:333
#define Style
Definition: _defines.h:281
static Object ** pwman_group(void *v)
Definition: pwman.cpp:666
static double pwman_map(void *v)
Definition: pwman.cpp:505
virtual GlyphIndex count() const
#define MenuItem
Definition: _defines.h:179
static OcGlyphContainer * intercept(OcGlyphContainer *)
void parents(bool)
int hoc_is_object_arg(int narg)
Definition: code.cpp:745
void hoc_pushstr(char **d)
Definition: code.cpp:665
Definition: ocbox.h:13
#define EventButton
Definition: _defines.h:21
virtual void replace_dismiss_action(WinDismiss *)
void merge_xy(Canvas *, Coord left, Coord bottom, Coord right, Coord top)
#define TelltaleState
Definition: _defines.h:296
virtual Coord y1() const
Definition: scenevie.h:319
Allotment & y_allotment()
Definition: geometry.h:286
#define Background
Definition: _defines.h:43
Object ** hoc_temp_objptr(Object *)
Definition: code.cpp:209
#define IFGUI
Definition: hocdec.h:351
double t
Definition: init.cpp:123
static double pwman_deiconify(void *v)
Definition: pwman.cpp:596
char ** hoc_temp_charptr(void)
Definition: code.cpp:625
int run(int argc, const char **argv)
void debugfile(const char *,...)
static PrintableWindowManager * current_
Definition: apwindow.h:146
size_t q
int close(int)
static void pwman_destruct(void *v)
Definition: pwman.cpp:472
Object ** hoc_objgetarg(int)
Definition: code.cpp:1568
#define WindowTable
Definition: _defines.h:336
static Member_ret_obj_func retobj_members[]
Definition: pwman.cpp:878
return NULL
Definition: cabcode.cpp:461
double chkarg(int, double low, double high)
Definition: code2.cpp:608
static void epilog()
virtual Glyph * print_glyph()
short index
Definition: cabvars.h:11
static double pwman_is_mapped(void *v)
Definition: pwman.cpp:488
void natural(Coord)
Definition: geometry.h:235
#define PixelCoord
Definition: _defines.h:25
int xtop() const
Definition: ivocmac.cpp:205
#define Hit
Definition: _defines.h:147
static double working(void *v)
Definition: ocbbs.cpp:208
virtual Coord bottom_pw() const