NEURON
utility.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #if HAVE_IV // to end of file
3 
4 #include <ivstream.h>
5 #include <string.h>
6 #include <stdio.h>
7 #include <errno.h>
8 
9 #include <InterViews/dialog.h>
10 #include <InterViews/session.h>
11 #include <InterViews/display.h>
12 #include <InterViews/action.h>
13 #include <InterViews/layout.h>
14 #include <InterViews/style.h>
15 #include <InterViews/hit.h>
16 #include <InterViews/event.h>
17 #include <IV-look/kit.h>
18 #include <IV-look/dialogs.h>
19 #include <OS/string.h>
20 
21 #define Input IOS_IN
22 #define Output IOS_OUT
23 #define Append IOS_APP|IOS_OUT
24 
25 #include "graph.h"
26 #include "utility.h"
27 #include "oc2iv.h"
28 #include "ivoc.h"
29 
30 extern Object** (*nrnpy_gui_helper_)(const char* name, Object* obj);
31 extern double (*nrnpy_object_to_double_)(Object*);
32 extern Object** (*nrnpy_gui_helper3_)(const char* name, Object* obj, int handle_strptr);
33 
34 bool nrn_spec_dialog_pos(Coord& x, Coord& y) {
35  Style* s = Session::instance()->style();
36  if (s->value_is_on("dialog_spec_position")) {
37  s->find_attribute("dialog_left_position", x);
38  s->find_attribute("dialog_bottom_position", y);
39  return true;
40  }
41  return false;
42 }
43 
44 bool oc_post_dialog(Dialog* d, Coord x, Coord y) {
45  if (nrn_spec_dialog_pos(x, y)) {
46  return d->post_at_aligned(x, y, 0.0, 0.0);
47  }
48  if (x != 400. || y != 400.) {
49  return d->post_at_aligned(x, y, .5,.5);
50  }else{
51  Display* dis = Session::instance()->default_display();
52  return d->post_at_aligned(dis->width()/2, dis->height()/2, .5,.5);
53  }
54 }
55 
56 bool ok_to_write(const String& s, Window* w) { return ok_to_write(s.string(), w);}
57 bool ok_to_read(const String& s, Window* w) { return ok_to_read(s.string(), w);}
58 
59 class OcGlyphDialog : public Dialog {
60 public:
61  OcGlyphDialog(Glyph*, Style*);
62  virtual ~OcGlyphDialog();
63  virtual void pick(Canvas*, const Allocation&, int depth, Hit&);
64 };
65 
66 /*static*/ class DialogAction : public Action {
67 public:
68  DialogAction(Dialog*, bool);
69  virtual ~DialogAction();
70  virtual void execute() { d_->dismiss(accept_); }
71 private:
72  Dialog* d_;
73  bool accept_;
74 };
75 DialogAction::DialogAction(Dialog* d, bool accept) {
76  accept_ = accept;
77  d_ = d;
78 }
79 DialogAction::~DialogAction(){
80  //printf("~DialogAction\n");
81 }
82 
83 bool boolean_dialog(const char* label, const char* accept,
84  const char* cancel, Window* w, Coord x, Coord y) {
85  WidgetKit& k = *WidgetKit::instance();
86  LayoutKit& l = *LayoutKit::instance();
87  PolyGlyph* vbox = l.vbox();
88  bool ok;
89  Dialog* d = new Dialog(
90  k.outset_frame(l.margin(vbox, 5)),
91  Session::instance()->style()
92  );
93  d->ref();
94  vbox->append(l.hcenter(k.inset_frame(l.margin(k.label(label), 10))));
95  vbox->append(
96  l.hcenter(
97  l.hbox(
98  k.push_button(accept, new DialogAction(d, true)),
99  l.hspace(10),
100  k.push_button(cancel, new DialogAction(d, false))
101  )
102  )
103  );
104  if (w) {
105  ok = d->post_for(w);
106  }else{
107  ok = oc_post_dialog(d, x, y);
108  }
109  d->unref();
110  return ok;
111 }
112 
113 void continue_dialog(const char* label, Window* w, Coord x, Coord y) {
114  WidgetKit& k = *WidgetKit::instance();
115  LayoutKit& l = *LayoutKit::instance();
116  PolyGlyph* vbox = l.vbox();
117  Dialog* d = new Dialog(
118  k.outset_frame(l.margin(vbox, 5)),
119  Session::instance()->style()
120  );
121  d->ref();
122  vbox->append(l.hcenter(k.inset_frame(l.margin(k.label(label), 10))));
123  vbox->append(
124  l.hcenter(
125  k.push_button("Continue", new DialogAction(d, true))
126  )
127  );
128  if (w) {
129  d->post_for(w);
130  }else{
131  oc_post_dialog(d, x, y);
132  }
133  d->unref();
134 }
135 
136 static bool ok_if_already_exists(const char* s, Window* w) {
137  char buf[256];
138  sprintf(buf, "%s already exists: Write?", s);
139  return boolean_dialog(buf, "Go Ahead", "Don't", w);
140 }
141 
142 static void open_fail(const char* s, Window* w, const char* io) {
143  char buf[256];
144  sprintf(buf, "Couldn't open %s for %sing", s, io);
145  continue_dialog(buf, w);
146 }
147 
148 bool ok_to_write(const char* s, Window* w) {
149  filebuf obuf;
150  if (obuf.open(s, Input)) {
151  obuf.close();
152  if (!ok_if_already_exists(s, w)) {
153  errno = 0;
154  return false;
155  }
156  }
157  if (obuf.open(s, Append)) {
158  obuf.close();
159  }else{
160  open_fail(s, w, "writ");
161  errno = 0;
162  return false;
163  }
164  errno = 0;
165  return true;
166 }
167 
168 bool ok_to_read(const char* s, Window* w) {
169  filebuf obuf;
170  if (obuf.open(s, Input)) {
171  obuf.close();
172  errno = 0;
173  return true;
174  }else{
175  open_fail(s, w, "read");
176  errno = 0;
177  return false;
178  }
179 }
180 
181 bool var_pair_chooser(const char* caption, float& x, float& y, Window* w,
182 Coord x2, Coord y2) {
183  char buf[200];
184  float x1=x, y1=y;
185  for (;;) {
186  sprintf(buf, "%g %g", x, y);
187  if (str_chooser(caption, buf, w, x2, y2)) {
188  if (sscanf(buf, "%f%f", &x1, &y1) == 2) {
189  x = x1; y = y1;
190  return true;
191  }else{
192 continue_dialog("Invalid entry: Enter pair of numbers separated by space.", w);
193  }
194  }else{
195  return false;
196  }
197  }
198 }
199 
200 bool str_chooser(const char* caption, char* buf, Window* w, Coord x, Coord y) {
201  WidgetKit& k = *WidgetKit::instance();
202  LayoutKit& l = *LayoutKit::instance();
203  Style* style = new Style(k.style());
204  style->attribute("caption", caption);
205  bool ok;
207  d->ref();
208  if (w) {
209  ok = d->post_for(w);
210  }else{
211  ok = oc_post_dialog(d, x,y);
212  }
213  if (ok) {
214  strcpy(buf, d->text()->string());
215  }
216  d->unref();
217  return ok;
218 }
219 
220 declareFieldEditorCallback(FieldDialog);
221 implementFieldEditorCallback(FieldDialog);
222 
224 }
225 
227  Resource::unref(fe_);
228 }
229 
230 bool FieldDialog::run() {
231  fe_->select(0, fe_->text()->length());
232  return Dialog::run();
233 }
234 void FieldDialog::dismiss(bool accept) {
235  if (accept) {
236  s_ = *fe_->text();
237  }else{
238  fe_->field(s_);
239  }
240  Dialog::dismiss(accept);
241 }
242 
243 FieldDialog* FieldDialog::field_dialog_instance(const char* str, Style* style,
244  Glyph* extra)
245 {
246  Glyph* g;
247  WidgetKit& widgets = *WidgetKit::instance();
248  DialogKit& dialogs = *DialogKit::instance();
249  LayoutKit& layout = *LayoutKit::instance();
250 
251  String caption("");
252  String accept("Accept");
253  String cancel("Cancel");
254  style->find_attribute("caption", caption);
255  style->find_attribute("accept", accept);
256  style->find_attribute("cancel", cancel);
257  PolyGlyph* hb = layout.hbox(5);
258  PolyGlyph* vb = layout.vbox(5);
259  g =
260  widgets.inset_frame(
261  layout.margin(
262  layout.flexible(vb, fil, 0),
263  10.0
264  )
265  );
266 
267  FieldDialog* fd = new FieldDialog(g, style);
268  FieldEditor* fe = dialogs.field_editor(str, style,
269  new FieldEditorCallback(FieldDialog)(
271  )
272  );
273 
274  fd->fe_ = fe;
275  Resource::ref(fe);
276  fd->s_ = *fe->text();
277 
278  vb->append(layout.flexible(widgets.label(caption)));
279  vb->append(layout.vglue(10));
280  vb->append(fd->fe_);
281  if (extra) {
282  vb->append(layout.vglue(10));
283  vb->append(extra);
284  }
285  vb->append(layout.vglue(10));
286  vb->append(hb);
287 
288  hb->append(layout.hglue(20, fil, 20));
289  hb->append(widgets.default_button(accept, new DialogAction(fd, true)));
290  hb->append(layout.hglue(5));
291  hb->append(widgets.push_button(cancel, new DialogAction(fd, false)));
292  hb->append(layout.hglue(20, fil, 20));
293 
294  return fd;
295 }
296 
297 void FieldDialog::accept(FieldEditor*) { dismiss(true); }
298 void FieldDialog::cancel(FieldEditor*) { dismiss(false); }
299 
300 
301 void hoc_boolean_dialog() {
302  bool b = false;
303  if (nrnpy_gui_helper_) {
304  Object** const result = nrnpy_gui_helper_("boolean_dialog", NULL);
305  if (result) {
306  hoc_ret();
308  return;
309  }
310  }
311 IFGUI
312  if (ifarg(3)) {
313  b = boolean_dialog(gargstr(1), gargstr(2), gargstr(3));
314  }else{
315  b = boolean_dialog(gargstr(1), "Yes", "No");
316  }
317 ENDGUI
318  hoc_ret();
319  hoc_pushx(double(b));
320 }
321 void hoc_continue_dialog() {
322  TRY_GUI_REDIRECT_DOUBLE("continue_dialog", NULL);
323 IFGUI
325 ENDGUI
326  hoc_ret();
327  hoc_pushx(1.);
328 }
329 void hoc_string_dialog() {
330  TRY_GUI_REDIRECT_DOUBLE_SEND_STRREF("string_dialog", NULL);
331  bool b = false;
332 IFGUI
333  char buf[256];
334  sprintf(buf, "%s", gargstr(2));
335  b = str_chooser(gargstr(1), buf);
336  if (b) {
337  hoc_assign_str(hoc_pgargstr(2), buf);
338  }
339 ENDGUI
340  hoc_ret();
341  hoc_pushx(double(b));
342 }
343 
344 
345 /*static*/ class LabelChooserAction : public Action {
346 public:
347  LabelChooserAction(GLabel*);
348  virtual ~LabelChooserAction();
349  void state(TelltaleState*);
350  virtual void execute();
351 private:
352  TelltaleState* ts_;
353  GLabel* gl_;
354 };
355 
356 bool Graph::label_chooser(const char* caption, char* buf, GLabel* gl, Coord x, Coord y) {
357  WidgetKit& k = *WidgetKit::instance();
358  LayoutKit& l = *LayoutKit::instance();
359  Style* style = new Style(k.style());
360  style->attribute("caption", caption);
361  bool ok;
362  LabelChooserAction* lca = new LabelChooserAction(gl);
363  Button* b = k.check_box("vfixed", lca);
364  lca->state(b->state());
365 
367 
368  d->ref();
369  ok = oc_post_dialog(d, x, y);
370  if (ok) {
371  strcpy(buf, d->text()->string());
372  }
373  d->unref();
374  return ok;
375 }
376 
377 LabelChooserAction::LabelChooserAction(GLabel* gl) {
378  gl_ = gl;
379  gl->ref();
380  ts_ = NULL;
381 }
382 LabelChooserAction::~LabelChooserAction() {
383  gl_->unref();
384  ts_->unref();
385 }
386 void LabelChooserAction::state(TelltaleState* t) {
387  t->ref();
388  ts_ = t;
389  if (gl_->fixed()) {
390  ts_->set(TelltaleState::is_chosen, false);
391  }else{
392  ts_->set(TelltaleState::is_chosen, true);
393  }
394 }
395 
397  if (ts_->test(TelltaleState::is_chosen)) {
398  if (gl_->fixed()) {
399  gl_->vfixed(gl_->scale());
400  }
401  }else{
402  if (!gl_->fixed()) {
403  gl_->fixed(gl_->scale());
404  }
405  }
406 }
407 
408 bool OcGlyph::dialog_dismiss(bool accept) {
409  if (d_) {
410  d_->dismiss(accept);
411  return true;
412  }
413  return false;
414 }
415 
416 bool OcGlyph::dialog(const char* label, const char* accept,
417  const char* cancel) {
418  WidgetKit& k = *WidgetKit::instance();
419  LayoutKit& l = *LayoutKit::instance();
420  PolyGlyph* vbox = l.vbox();
421  bool ok;
422  d_ = new OcGlyphDialog(
423  k.outset_frame(l.margin(vbox, 5)),
424  Session::instance()->style()
425  );
426  d_->ref();
427  vbox->append(l.hcenter(l.hflexible(l.margin(k.label(label), 10), fil, 0)));
428  vbox->append(l.hcenter(this));
429  vbox->append(
430  l.hcenter(
431  l.hflexible(
432  l.hbox(
433  k.push_button(accept, new DialogAction(d_, true)),
434  l.hspace(10),
435  k.push_button(cancel, new DialogAction(d_, false))
436  )
437  ,fil, 0
438  )
439  )
440  );
442  ok = oc_post_dialog(d_, 400., 400.);
444  d_->unref();
445  d_ = NULL;
446  return ok;
447 }
448 
449 OcGlyphDialog::OcGlyphDialog(Glyph* g, Style* s) : Dialog(g, s) {}
450 OcGlyphDialog::~OcGlyphDialog() {}
451 void OcGlyphDialog::pick(Canvas* c, const Allocation& a, int depth, Hit& h){
452  const Event* e = h.event();
453  EventType t = (e == NULL) ? Event::undefined : e->type();
454  switch (t) {
455  case Event::key:
456  if (e && inside(*e)) {
457  body()->pick(c, a, depth + 1, h);
458  }
459  break;
460  default:
461  Dialog::pick(c, a, depth, h);
462  }
463 }
464 #endif
#define Display
Definition: _defines.h:97
bool ok_to_write(const String &, Window *w=NULL)
void execute(Inst *p)
Definition: code.cpp:2651
#define WidgetKit
Definition: _defines.h:331
FieldDialog(Glyph *, Style *)
#define g
Definition: passive0.cpp:23
static double inside(void *)
Definition: mymath.cpp:21
#define Glyph
Definition: _defines.h:132
#define Coord
Definition: _defines.h:19
#define run
Definition: redef.h:125
virtual void cancel(FieldEditor *)
char ** hoc_pgargstr(int narg)
Definition: code.cpp:1580
virtual void ref() const
Definition: resource.cpp:47
static philox4x32_key_t k
Definition: nrnran123.cpp:11
#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)
#define TRY_GUI_REDIRECT_DOUBLE_SEND_STRREF(name, obj)
Definition: gui-redirect.h:96
#define e
Definition: passive0.cpp:24
Object **(* nrnpy_gui_helper_)(const char *name, Object *obj)
Definition: xmenu.cpp:13
void hoc_boolean_dialog()
Definition: ocnoiv1.cpp:109
#define gargstr
Definition: hocdec.h:14
virtual void accept(FieldEditor *)
const char * string() const
Definition: string.h:139
bool var_pair_chooser(const char *, float &x, float &y, Window *w=NULL, Coord x1=400., Coord y1=400.)
void hoc_ret()
void hoc_assign_str(char **cpp, const char *buf)
Definition: code.cpp:2337
CopyString s_
Definition: utility.h:33
static bool label_chooser(const char *, char *, GLabel *, Coord x=400., Coord y=400.)
double(* nrnpy_object_to_double_)(Object *)
Definition: xmenu.cpp:14
#define Dialog
Definition: _defines.h:94
#define TRY_GUI_REDIRECT_DOUBLE(name, obj)
Definition: gui-redirect.h:54
_CONST char * s
Definition: system.cpp:74
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...
void hoc_continue_dialog()
Definition: ocnoiv1.cpp:121
#define LayoutKit
Definition: _defines.h:161
#define ENDGUI
Definition: hocdec.h:352
#define Canvas
Definition: _defines.h:65
#define key
Definition: spt2queue.cpp:20
errno
Definition: system.cpp:98
virtual void unref() const
Definition: resource.cpp:52
char * name
Definition: init.cpp:16
#define FieldEditor
Definition: _defines.h:111
#define Event
Definition: _defines.h:107
bool ok_to_read(const String &, Window *w=NULL)
void hoc_string_dialog()
Definition: ocnoiv1.cpp:128
#define fil
Definition: coord.h:42
int ifarg(int)
Definition: code.cpp:1562
void hoc_pushx(double)
const String * text() const
Definition: utility.h:25
static FieldDialog * field_dialog_instance(const char *, Style *, Glyph *extra=NULL)
bool str_chooser(const char *, char *, Window *w=NULL, Coord x=400., Coord y=400.)
bool dialog_dismiss(bool b)
#define EventType
Definition: _defines.h:20
void continue_dialog(const char *label, Window *w=NULL, Coord x=400., Coord y=400.)
Definition: hocdec.h:226
#define c
#define Action
Definition: _defines.h:27
Definition: string.h:34
Definition: graph.h:329
FieldEditor * fe_
Definition: utility.h:32
virtual bool run()
char buf[512]
Definition: init.cpp:13
bool boolean_dialog(const char *label, const char *accept, const char *cancel, Window *w=NULL, Coord x=400., Coord y=400.)
#define Window
Definition: _defines.h:333
#define Style
Definition: _defines.h:281
virtual ~FieldDialog()
virtual void dismiss(bool accept)
#define TelltaleState
Definition: _defines.h:296
#define IFGUI
Definition: hocdec.h:351
double t
Definition: init.cpp:123
#define DialogKit
Definition: _defines.h:95
return NULL
Definition: cabcode.cpp:461
void handle_old_focus()
#define Button
Definition: _defines.h:62
#define Hit
Definition: _defines.h:147
virtual bool dialog(const char *label, const char *accept, const char *cancel)