ParameterSetEditDialog.cxx
Go to the documentation of this file.
1 ///
2 /// \file ParameterSetEditDialog.cxx
3 /// \brief Pop-up window for editing parameter sets
4 /// \author messier@indiana.edu
5 ///
7 #include <iostream>
8 #include <sstream>
9 #include "TROOT.h"
10 #include "TGTab.h"
11 #include "TGButton.h"
12 #include "TGCanvas.h"
13 #include "TGTableLayout.h"
14 #include "TGLayout.h"
15 #include "TGFrame.h"
16 #include "TGTextEntry.h"
17 #include "TGListBox.h"
18 #include "TGDoubleSlider.h"
19 #include "fhiclcpp/ParameterSet.h"
22 
24 
25 using namespace evdb;
26 
27 // Window and row sizes in units of pixels
28 static const unsigned int kWidth = 500*11/10;
29 static const unsigned int kHeight = 500*11/10;
30 static const unsigned int kRowW = kWidth-150;
31 static const unsigned int kRowH = 18;
32 
33 //
34 // Flags to help us decide what sort of parameter we need to build a
35 // GUI for.
36 //
37 static const int kSINGLE_VALUED_PARAM = 1<<0; // Expect single value
38 static const int kVECTOR_PARAM = 1<<1; // Expect multiple values
39 //static const int kVECTOR_OF_VECTOR_PARAM = 1<<2; // Expect multiple values - never used
40 static const int kHAVE_GUI_TAGS = 1<<3; // GUI tags are present
41 static const int kNO_GUI_TAGS = 1<<4; // GUI tags are not present
42 static const int kINTEGER_PARAM = 1<<5; // Force the value to be int
43 static const int kPARAMETER_SET_PARAM = 1<<6; // Value is a parameter set itself
44 //
45 // The short letter codes for the various GUI objects supported. Also
46 // provide a list of all possible tags.
47 //
48 #define GUITAG static const std::string
49 GUITAG kTEXT_ENTRY = "te"; // A text edit box
50 GUITAG kLIST_BOX_SINGLE = "lbs"; // A list box, single choice allowed
51 GUITAG kLIST_BOX_MULTI = "lbm"; // A list box, multuiple choices allowed
52 GUITAG kRADIO_BUTTONS = "rb"; // Radio buttons
53 GUITAG kCHECK_BOX = "cb"; // Check boxes
54 GUITAG kSLIDER = "sl"; // Slider bar
55 GUITAG kSLIDER_INT = "sli"; // Slider bar, limit to integers
56 #undef GUITAG
57 static const std::vector<std::string> gsGUITAG = {
62  kCHECK_BOX,
63  kSLIDER,
65 };
66 
67 //======================================================================
68 //
69 // ParameterSetEditRow methods
70 //
72  TGHorizontalFrame* lhs,
73  TGHorizontalFrame* rhs,
74  const fhicl::ParameterSet& ps,
75  const std::string& key) :
76  fFrame(frame),
77  fRightLH(0),
78  fLeftLH(0),
79  fLabel(0),
80  fTextEntry(0),
81  fListBox(0),
82  fSlider(0),
83  fKEY(key)
84 {
85  //
86  // Extract information about the parameter for which we are building
87  // the GUI
88  //
89  std::string tag; // What sort of frame to build?
90  std::vector<std::string> values; // What is the current value?
91  this->UnpackParameter(ps, key, fParamFlags, tag, fChoice, values, fGUI, fDOC);
92  if (values.empty()){
93  // What happened here? We'll crash if we continue though, so bail out.
94  return;
95  }
96 
98  fValue = "[";
99  for (unsigned int i=0; i<values.size(); ++i) {
100  fValue += values[i];
101  if (i+1<values.size()) fValue += ",";
102  else fValue += "]";
103  }
104  }
106  fValue = "{";
107  fValue += values[0];
108  fValue += "}";
109  }
110  else {
111  fValue = values[0];
112  }
113 
114  fLeftLH = new TGLayoutHints(kLHintsLeft, 1,1,0,0);
115  fRightLH = new TGLayoutHints(kLHintsRight,1,1,0,0);
116 
117  fLabel = new TGTextButton(lhs,
118  key.c_str(),
119  -1,
120  TGButton::GetDefaultGC()(),
121  TGTextButton::GetDefaultFontStruct(),
122  0);
123  lhs->AddFrame(fLabel);
124  fLabel->SetToolTipText(fDOC.c_str());
125  fLabel->SetTextJustify(kTextRight);
126 
127  if (tag==kTEXT_ENTRY) {
128  this->SetupTextEntry(rhs, fParamFlags, values);
129  }
130  if (tag==kLIST_BOX_SINGLE) {
131  this->SetupListBox(rhs, fChoice, values, false);
132  }
133  if (tag==kLIST_BOX_MULTI) {
134  this->SetupListBox(rhs, fChoice, values, true);
135  }
136  if (tag==kRADIO_BUTTONS) {
137  this->SetupRadioButtons(rhs, fChoice, values);
138  }
139  if (tag==kCHECK_BOX) {
140  this->SetupCheckButton(rhs, fChoice, values);
141  }
142  if (tag==kSLIDER) {
143  this->SetupSlider(rhs, fChoice, values);
144  }
145  if (tag==kSLIDER_INT) {
147  this->SetupSlider(rhs, fChoice, values);
148  }
149 }
150 
151 //......................................................................
152 
154 {
155  unsigned int i;
156  for (i=0; i<fCheckButton.size(); ++i) {
157  if (fCheckButton[i]) delete fCheckButton[i];
158  }
159  for (i=0; i<fRadioButton.size(); ++i) {
160  if (fRadioButton[i]) delete fRadioButton[i];
161  }
162  if (fSlider) delete fSlider;
163  if (fListBox) delete fListBox;
164  if (fTextEntry) delete fTextEntry;
165  if (fLeftLH) delete fLeftLH;
166  if (fRightLH) delete fRightLH;
167  if (fLabel) delete fLabel;
168 }
169 
170 //......................................................................
171 
173  const std::string& key,
174  unsigned int& flag,
175  std::string& tag,
176  std::vector<std::string>& choice,
177  std::vector<std::string>& value,
178  std::string& gui,
179  std::string& doc)
180 {
181  std::string guikey = key; guikey += ".gui";
182  std::string dockey = key; dockey += ".doc";
183 
184  flag = 0;
185 
186  //
187  // Try to extract GUI tags
188  //
189  try {
190  gui = p.get< std::string >(guikey);
191  doc = p.get< std::string >(dockey);
192  flag |= kHAVE_GUI_TAGS;
193  }
194  catch (...) {
195  //
196  // If they aren't there, try extracting it as a normal
197  // parameter. Default to providing the user with a text entry box.
198  //
199  gui = kTEXT_ENTRY;
200  doc = "See .fcl file for documentation...";
201  flag |= kNO_GUI_TAGS;
202  }
203 
204  //
205  // Parse out the GUI string to find out what type of frame to build
206  // and the choices we should present to the user
207  //
208  ParseGUItag(gui, tag, choice);
209 
210  //
211  // Now extract the assigned value(s) of the parameter
212  //
213  // The key is either just the key, or in the case of GUI-enabled
214  // parameters the key name with ".val" appended
215  //
216  std::string valkey = key;
217  if ( flag&kHAVE_GUI_TAGS ) valkey += ".val";
218  //
219  // Try first to extract a single value.
220  //
221  try {
222  std::string v = p.get<std::string>(valkey);
223  value.push_back(v);
224  flag |= kSINGLE_VALUED_PARAM;
225  }
226  catch (...) {
227  //
228  // If that fails, try extracting multiple values
229  //
230  try {
231  value = p.get< std::vector<std::string> >(valkey);
232  flag |= kVECTOR_PARAM;
233  if (value.size()==0) value.push_back("");
234  }
235  catch (...) {
236  //
237  // Yikes - vector of vectors, perhaps?
238  //
239  try {
240  std::vector< std::vector <std::string> > vv;
241  vv = p.get<std::vector<std::vector<std::string> > >(valkey);
242  //
243  // Vectors of vectors are treated as vectors of
244  // std::strings. The strings assigned to the values are
245  // strings that FHICL will parse as vectors. So, this:
246  //
247  // [ [0,0], [1,1] ]
248  //
249  // is represented as:
250  //
251  // value.size()=2, value[0]="[0,0]", value[1]="[1,1]"
252  //
253  unsigned int i, j;
254  flag |= kVECTOR_PARAM;
255  for (i=0; i<vv.size(); ++i) {
256  std::string s;
257  s += "[";
258  for (j=0; j<vv[i].size(); ++j) {
259  s += vv[i][j];
260  if (j+2<vv[i].size()) s += ",";
261  else s += "]";
262  }
263  value.push_back(s);
264  }
265  if (vv.size()==0) value.push_back("[[]]");
266  }
267  catch (...) {
268  // what about another fhicl::ParameterSet?
269  try{
271  flag |= kPARAMETER_SET_PARAM;
272  value.push_back(v.to_string());
273  }
274  catch(...){
275  //
276  // If that fails we are very stuck. Print a message and fail.
277  //
278  LOG_ERROR("ParameterSetEditDialog") << "Failed to parse " << key
279  << "\n" << p.to_string();
280  }
281  }
282  }
283  }
284 }
285 
286 //......................................................................
287 //
288 // Parse out what we can from the "gui" tag. Expected format is:
289 // "frame_tag:choice1,choice2,choice3"
290 //
292  std::string& frame,
293  std::vector<std::string>& choice)
294 {
295  //
296  // Get the frame name. Should be piece just before the ":"
297  //
298  choice.clear();
299  size_t icolon = guitag.find(':');
300  if (icolon == std::string::npos) frame = guitag;
301  else frame = guitag.substr(0,icolon);
302  if (!IsLegalGUItag(frame)) frame = kTEXT_ENTRY;
303 
304  //
305  // Get the list of choices. Should be comma separated.
306  //
307  size_t icomma = icolon;
308  size_t spos, epos;
309  while (icomma!=std::string::npos) {
310  spos = icomma+1;
311  epos = guitag.find(',',spos);
312  std::string s = guitag.substr(spos,epos-spos);
313  choice.push_back(s);
314  icomma = epos;
315  }
316 }
317 
318 //......................................................................
319 
321 {
322  for(unsigned int i=0; i<gsGUITAG.size(); ++i) {
323  if (s==gsGUITAG[i]) return true;
324  }
325  LOG_ERROR("ParameterSetEditDialog") << s << " is not a legal GUI tag.";
326  return false;
327 }
328 
329 //......................................................................
330 
331 void ParameterSetEditRow::SetupTextEntry(TGCompositeFrame* f,
332  unsigned int flags,
333  const std::vector<std::string>& value)
334 {
335  static TColor* c = gROOT->GetColor(41);
336 
337  fTextEntry = new TGTextEntry(f);
338  f->AddFrame(fTextEntry);
339  fTextEntry->SetTextColor(c);
340 
341  fTextEntry->Connect("ReturnPressed()",
342  "evdb::ParameterSetEditRow",
343  this,
344  "TextEntryReturnPressed()");
345 
346  std::string buff;
347  if (flags&kVECTOR_PARAM) buff += "[";
348  if (flags&kPARAMETER_SET_PARAM) buff += "{";
349  for (unsigned int i=0; i<value.size(); ++i) {
350  buff += value[i];
351  if ((i+1)!=value.size()) buff += ",";
352  }
353  if (flags&kVECTOR_PARAM) buff += "]";
354  if (flags&kPARAMETER_SET_PARAM) buff += "}";
355  fTextEntry->SetText(buff.c_str(), 0);
356  fTextEntry->Resize(kRowW,kRowH);
357 }
358 
359 //......................................................................
360 
361 void ParameterSetEditRow::SetupListBox(TGCompositeFrame* f,
362  const std::vector<std::string>& choice,
363  const std::vector<std::string>& value,
364  bool ismulti)
365 {
366  fListBox = new TGListBox(f);
367  f->AddFrame(fListBox);
368  if (ismulti) fListBox->SetMultipleSelections();
369 
370  for (size_t i=0; i<choice.size(); ++i) {
371  fListBox->AddEntry(choice[i].c_str(), i);
372  for (size_t j=0; j<value.size(); ++j) {
373  if (value[j]==choice[i]) fListBox->Select(i);
374  }
375  }
376 
377  fListBox->Connect("SelectionChanged()",
378  "evdb::ParameterSetEditRow",
379  this,
380  "ListBoxSelectionChanged()");
381  fListBox->Connect("Selected(Int_t)",
382  "evdb::ParameterSetEditRow",
383  this,
384  "ListBoxSelected(int)");
385 
386  size_t h = kRowH*choice.size();
387  if (h>3*kRowH) h = 3*kRowH;
388  fListBox->Resize(kRowW,h);
389 }
390 
391 //......................................................................
392 
394  const std::vector<std::string>& choice,
395  const std::vector<std::string>& value)
396 {
397  unsigned int v = atoi(value[0].c_str());
398 
399  for (size_t i=0; i<choice.size(); ++i) {
400  TGRadioButton* b = new TGRadioButton(f, choice[i].c_str(), i);
401  f->AddFrame(b);
402 
403  b->SetTextJustify(kTextLeft);
404  b->Connect("Clicked()",
405  "evdb::ParameterSetEditRow",
406  this,
407  "RadioButtonClicked()");
408 
409  if (i==v) b->SetState(kButtonDown);
410 
411  fRadioButton.push_back(b);
412  }
413 }
414 
415 //......................................................................
416 
418  const std::vector<std::string>& choice,
419  const std::vector<std::string>& value)
420 {
421  unsigned int mask;
422  unsigned int v = atoi(value[0].c_str());
423  for (size_t i=0; i<choice.size(); ++i) {
424  TGCheckButton* b = new TGCheckButton(f, choice[i].c_str(), i);
425  f->AddFrame(b);
426  b->Connect("Clicked()",
427  "evdb::ParameterSetEditRow",
428  this,
429  "CheckButtonClicked()");
430 
431  mask = (0x1)<<i;
432  if (v&mask) b->SetState(kButtonDown);
433 
434  fCheckButton.push_back(b);
435  }
436 }
437 //......................................................................
438 void ParameterSetEditRow::SetupSlider(TGCompositeFrame* f,
439  const std::vector<std::string>& choice,
440  const std::vector<std::string>& value)
441 {
442  fTextEntry = new TGTextEntry(f);
443  f->AddFrame(fTextEntry);
444 
445  std::string t;
446  if (value.size()==1) { t = value[0]; }
447  if (value.size()==2) {
448  t = "["; t += value[0]; t += ","; t += value[1]; t += "]";
449  }
450  fTextEntry->SetText(t.c_str());
451 
452  fTextEntry->Connect("ReturnPressed()",
453  "evdb::ParameterSetEditRow",
454  this,
455  "TextEntryReturnPressed()");
456 
457  fSlider = new TGDoubleHSlider(f, 100, kDoubleScaleBoth);
458  f->AddFrame(fSlider);
459 
460  float min = atof(choice[0].c_str());
461  float max = atof(choice[1].c_str());
462 
463  float pos1 = 0;
464  float pos2 = 0;
465  if (value.size()==1) {
466  pos1 = atof(value[0].c_str());
467  pos2 = pos1;
468  }
469  if (value.size()==2) {
470  pos1 = atof(value[0].c_str());
471  pos2 = atof(value[1].c_str());
472  }
473 
474  fSlider->SetRange(min, max);
475  fSlider->SetPosition(pos1, pos2);
476 
477  fSlider->Connect("PositionChanged()",
478  "evdb::ParameterSetEditRow",
479  this,
480  "SliderPositionChanged()");
481 
482  fTextEntry->Resize(kRowW*1/5, kRowH);
483  fSlider-> Resize(kRowW*4/5,10*kRowH);
484 }
485 
486 //......................................................................
487 
489 {
490  if (fTextEntry==0) return;
491 
492  const char* text = fTextEntry->GetBuffer()->GetString();
493 
494  static TColor* c = gROOT->GetColor(1);
495  fTextEntry->SetTextColor(c);
496 
497  //
498  // If we also have a slider connected to this frame, make sure its
499  // state is updated
500  //
501  if (fSlider) {
502  int n=0;
503  float f1=0, f2=0;
504  n = sscanf(text, "[%f, %f]", &f1, &f2);
505  if (n!=2) {
506  n = sscanf(text, "%f", &f1);
507  f2 = f1;
508  }
509  fSlider->SetPosition(f1, f2);
510  }
511  fValue = text;
512  fFrame->Modified();
513 }
514 
515 //......................................................................
516 
518 {
519  //
520  // Only need to handle list boxes where multiple selections are
521  // allowed here.
522  //
523  if (fListBox->GetMultipleSelections()==0) return;
524 
525  fValue = "[";
526  TList selections;
527  fListBox->GetSelectedEntries(&selections);
528  TGLBEntry* sel;
529  bool isfirst = true;
530  for (unsigned int i=0;;++i) {
531  sel = (TGLBEntry*)selections.At(i);
532  if (sel==0) break;
533  if (!isfirst) fValue += ",";
534  fValue += fChoice[sel->EntryId()];
535  isfirst = false;
536  }
537  fValue += "]";
538  fFrame->Modified();
539 }
540 
541 //......................................................................
542 
544 {
545  //
546  // Only handle single selection list boxes here
547  //
548  if (fListBox->GetMultipleSelections()) return;
549  fValue = fChoice[id];
550  fFrame->Modified();
551 }
552 //......................................................................
553 
555 {
556  unsigned int value = 0;
557  TGButton* b = (TGButton*)gTQSender;
558  int id = b->WidgetId();
559  for (size_t i=0; i<fRadioButton.size(); ++i) {
560  if (fRadioButton[i]->WidgetId() != id) {
561  fRadioButton[i]->SetState(kButtonUp);
562  }
563  else value = i;
564  }
565  char buff[256];
566  sprintf(buff, "%d", value);
567  fValue = buff;
568  fFrame->Modified();
569 }
570 
571 //......................................................................
572 
574 {
575  int value = 0;
576  for (unsigned int i=0; i<fCheckButton.size(); ++i) {
577  if (fCheckButton[i]->IsDown()) value |= 1<<i;
578  }
579  char buff[256];
580  sprintf(buff, "%d", value);
581  fValue = buff;
582  fFrame->Modified();
583 }
584 
585 //......................................................................
586 
588 {
589  char buff[1024];
590  float mn, mx, ave;
591  fSlider->GetPosition(mn, mx);
592 
593  ave = 0.5*(mn+mx);
594 
595  if (fParamFlags & kINTEGER_PARAM) {
596  int mni = rint(mn);
597  int mxi = rint(mx);
598  int avei = rint(ave);
599  if (fParamFlags & kVECTOR_PARAM) {
600  sprintf(buff, "[%d, %d]",mni,mxi);
601  }
602  else {
603  sprintf(buff, "%d",avei);
604  }
605  }
606  else {
607  if (fParamFlags & kVECTOR_PARAM) {
608  sprintf(buff, "[%.1f, %.1f]",mn,mx);
609  }
610  else {
611  sprintf(buff, "%.1f",ave);
612  }
613  }
614  fTextEntry->SetText(buff);
615  fValue = buff;
616  fFrame->Modified();
617 }
618 
619 //......................................................................
620 
622 {
623  if (fTextEntry) {
624  if (fValue != fTextEntry->GetBuffer()->GetString()) {
625  this->TextEntryReturnPressed();
626  }
627  }
628 }
629 
630 //......................................................................
631 
633 {
634  std::ostringstream s;
635  if (fParamFlags & kNO_GUI_TAGS) {
636  s << fKEY << ":" << fValue << " ";
637  }
638  else {
639  s << fKEY
640  << ": { "
641  << "val:" << fValue << " "
642  << "gui:\"" << fGUI << "\" "
643  << "doc:\"" << fDOC << "\" "
644  << "}";
645  }
646  return s.str();
647 }
648 
649 //======================================================================
650 //
651 // ParameterSetEditFrame methods
652 //
654  unsigned int psetid) :
655  fParameterSetID(psetid),
656  fIsModified(false)
657 {
658  unsigned int i, j;
659 
660  fCanvas = new TGCanvas(mother, kWidth-6, kHeight-50);
661  fCanvasH = new TGLayoutHints(kLHintsExpandX|kLHintsExpandY);
662  mother->AddFrame(fCanvas, fCanvasH);
663 
664  fContainer = new TGCompositeFrame(fCanvas->GetViewPort());
665  fCanvas->SetContainer(fContainer);
666 
667  //
668  // Locate the parameter set connected to this frame
669  //
670  const ServiceTable& st = ServiceTable::Instance();
671  const fhicl::ParameterSet& pset = st.GetParameterSet(psetid);
672  std::vector<std::string> key = pset.get_names();
673  unsigned int nkey = key.size();
674 
675  //
676  // Count the number of "non system" parameters - each of these will
677  // need an row in the dialog window.
678  //
679  unsigned int nparam = 0;
680  for (i=0; i<nkey; ++i) {
681  if (!((key[i]=="service_type") ||
682  (key[i]=="module_type") ||
683  (key[i]=="module_label"))) {
684  ++nparam;
685  }
686  }
687 
688  //
689  // Build the layout
690  //
691  fLayout = new TGTableLayout(fContainer, nparam, 2);
692  fContainer->SetLayoutManager(fLayout);
693 
694  for (i=0, j=0; i<nkey; ++i) {
695  if (!((key[i]=="service_type") ||
696  (key[i]=="module_type") ||
697  (key[i]=="module_label"))) {
698 
699  TGHorizontalFrame* lhs = new TGHorizontalFrame(fContainer);
700  TGHorizontalFrame* rhs = new TGHorizontalFrame(fContainer);
701 
702  TGTableLayoutHints* lhsh = new TGTableLayoutHints(0,1,j,j+1);
703  TGTableLayoutHints* rhsh = new TGTableLayoutHints(1,2,j,j+1);
704 
705  fContainer->AddFrame(lhs, lhsh);
706  fContainer->AddFrame(rhs, rhsh);
707 
708  fLHS. push_back(lhs);
709  fRHS. push_back(rhs);
710  fLHSHints.push_back(lhsh);
711  fRHSHints.push_back(rhsh);
712 
713  fRow.push_back(new ParameterSetEditRow(this, lhs, rhs, pset, key[i]));
714  ++j;
715  }
716  }
717 
718  fCanvas->Connect("ProcessedEvent(Event_t*)", "evdb::ParameterSetEditFrame",
719  this,
720  "HandleMouseWheel(Event_t*)");
721 
722  fCanvas->Resize();
723 }
724 
725 //......................................................................
726 
728 {
729  unsigned int i;
730  for (i=0; i<fRow.size(); ++i) delete fRow[i];
731  for (i=0; i<fRHSHints.size(); ++i) delete fRHSHints[i];
732  for (i=0; i<fLHSHints.size(); ++i) delete fLHSHints[i];
733  for (i=0; i<fRHS.size(); ++i) delete fRHS[i];
734  for (i=0; i<fLHS.size(); ++i) delete fLHS[i];
735  delete fLayout;
736  //
737  // Parent takes care of delete for fContainer, I think. Anyhow,
738  // trying to delete it causes a seg fault.
739  //
740  // delete fContainer;
741  delete fCanvasH;
742  delete fCanvas;
743 }
744 
745 //......................................................................
747 {
748  // Handle mouse wheel to scroll.
749  if (event->fType != kButtonPress && event->fType != kButtonRelease)
750  return;
751 
752  Int_t page = 0;
753  if (event->fCode == kButton4 || event->fCode == kButton5) {
754  if (!fCanvas) return;
755  if (fCanvas->GetContainer()->GetHeight())
756  page = Int_t(Float_t(fCanvas->GetViewPort()->GetHeight() *
757  fCanvas->GetViewPort()->GetHeight()) /
758  fCanvas->GetContainer()->GetHeight());
759  }
760 
761  if (event->fCode == kButton4) {
762  //scroll up
763  Int_t newpos = fCanvas->GetVsbPosition() - page;
764  if (newpos < 0) newpos = 0;
765  fCanvas->SetVsbPosition(newpos);
766  }
767  if (event->fCode == kButton5) {
768  // scroll down
769  Int_t newpos = fCanvas->GetVsbPosition() + page;
770  fCanvas->SetVsbPosition(newpos);
771  }
772 
773  return;
774 }
775 
776 //......................................................................
778 
779 //......................................................................
781 {
782  unsigned int i;
783  for (i=0; i<fRow.size(); ++i) fRow[i]->Finalize();
784 }
785 
786 //......................................................................
787 
789 {
790  unsigned int i;
791  std::ostringstream s;
792  for (i=0; i<fRow.size(); ++i) {
793  s << fRow[i]->AsFHICL() << "\n";
794  }
795  return s.str();
796 }
797 
798 //======================================================================
799 //
800 // ParameterSetEditDialog methods
801 //
803  TGTransientFrame(gClient->GetRoot(), gClient->GetRoot(), 4, 4)
804 {
805  fTGTab = new TGTab(this);
806  this->AddFrame(fTGTab);
807 
808  fButtons = new TGHorizontalFrame(this);
809  this->AddFrame(fButtons);
810 
811  fApply = new TGTextButton(fButtons, " Apply ");
812  fCancel = new TGTextButton(fButtons, " Cancel ");
813  fDone = new TGTextButton(fButtons, " Done ");
814 
815  fButtons->AddFrame(fApply);
816  fButtons->AddFrame(fCancel);
817  fButtons->AddFrame(fDone);
818 
819  fApply-> Connect("Clicked()","evdb::ParameterSetEditDialog",this,"Apply()");
820  fCancel->Connect("Clicked()","evdb::ParameterSetEditDialog",this,"Cancel()");
821  fDone-> Connect("Clicked()","evdb::ParameterSetEditDialog",this,"Done()");
822 
823  //
824  // Loop over all the parameter sets and build tabs for them
825  //
826  const ServiceTable& st = ServiceTable::Instance();
827  assert(psetid < st.fServices.size());
828  int which = st.fServices[psetid].fCategory;
829 
830  unsigned int i;
831  unsigned int top=0, indx=0;
832  for (i=0; i<st.fServices.size(); ++i) {
833  if (st.fServices[i].fCategory==which) {
834  if (i==psetid) top = indx;
835  std::string tabnm = this->TabName(st.fServices[i].fName);
836  TGCompositeFrame* f = fTGTab->AddTab(tabnm.c_str());
837  fFrames.push_back(new ParameterSetEditFrame(f, i));
838  ++indx;
839  }
840  }
841  fTGTab->SetTab(top);
842 
843  switch (which) {
844  case kDRAWING_SERVICE:
845  this->SetWindowName("Drawing Services");
846  break;
847  case kEXPERIMENT_SERVICE:
848  this->SetWindowName("Experiment Services");
849  break;
850  default:
851  this->SetWindowName("Services Configuration");
852  }
853 
854  this->MapSubwindows();
855  this->Resize(kWidth,kHeight);
856  this->MapWindow();
857 }
858 
859 //......................................................................
860 
862 {
863  unsigned int i;
864  for (i=0; i<fFrames.size(); ++i) delete fFrames[i];
865  delete fDone;
866  delete fCancel;
867  delete fApply;
868  delete fButtons;
869  delete fTGTab;
870 }
871 
872 //......................................................................
873 
875 {
876  //
877  // We're not in control of the event loop so what we can do is write
878  // the new configuration to the ServiceTable. The main driver will
879  // pick it up, apply it, and wipe it clean when a reload / next
880  // event is triggered.
881  //
882  unsigned int i;
884  for (i=0; i<fFrames.size(); ++i) {
885  if (fFrames[i]->fIsModified) {
886  unsigned int psetid = fFrames[i]->fParameterSetID;
887 
888  fFrames[i]->Finalize();
889  std::string p = fFrames[i]->AsFHICL();
890 
891  p += "service_type:";
892  p += st.fServices[psetid].fName;
893 
894  st.fServices[psetid].fParamSet = p;
895 
896  }
897  }
899 }
900 
901 //......................................................................
902 
903 void ParameterSetEditDialog::Cancel() { this->SendCloseMessage(); }
904 
905 //......................................................................
906 
908 {
909  this->Apply();
910  this->SendCloseMessage();
911 }
912 
913 //......................................................................
914 
915 void ParameterSetEditDialog::CloseWindow() { delete this; }
916 
917 //......................................................................
918 //
919 // Remove any redundant text from the tab name
920 //
922 {
923  size_t n = 0;
924 
925  n = s.find("DrawingOptions");
926  if (n!=std::string::npos) return s.substr(0,n);
927 
928  return s;
929 }
930 
931 ////////////////////////////////////////////////////////////////////////
::xsd::cxx::tree::id< char, ncname > id
Definition: Database.h:165
static constexpr int kDRAWING_SERVICE
Definition: ServiceTable.h:19
std::vector< TGRadioButton * > fRadioButton
static void Set(int which)
Definition: NavState.cxx:24
void SetupListBox(TGCompositeFrame *f, const std::vector< std::string > &choice, const std::vector< std::string > &value, bool ismulti)
static const unsigned int kHeight
static ServiceTable & Instance()
::xsd::cxx::tree::flags flags
Definition: Database.h:214
std::vector< ParameterSetEditRow * > fRow
Collection of Services used in the event display.
Definition: ServiceTable.h:36
const char * p
Definition: xmltok.h:285
GUITAG kRADIO_BUTTONS
TGLayoutHints * fRightLH
Align to right.
GUITAG kLIST_BOX_SINGLE
Float_t f2
static const int kSINGLE_VALUED_PARAM
Manage all things related to colors for the event display.
Definition: Display3DPad.h:11
GUITAG kLIST_BOX_MULTI
ParameterSetEditFrame * fFrame
The parent frame.
void SetupSlider(TGCompositeFrame *f, const std::vector< std::string > &choice, const std::vector< std::string > &value)
std::vector< std::string > fChoice
const XML_Char * s
Definition: expat.h:262
void SetupTextEntry(TGCompositeFrame *f, unsigned int flags, const std::vector< std::string > &value)
static constexpr int kEXPERIMENT_SERVICE
Definition: ServiceTable.h:20
TGLayoutHints * fLeftLH
Align to left.
GUITAG kCHECK_BOX
std::vector< TGTableLayoutHints * > fRHSHints
static const int kNO_GUI_TAGS
static const unsigned int kRowH
std::vector< TGHorizontalFrame * > fLHS
const XML_Char int const XML_Char * value
Definition: expat.h:331
static const int kINTEGER_PARAM
#define GUITAG
static const std::vector< std::string > gsGUITAG
T get(std::string const &key) const
Definition: ParameterSet.h:231
base_types push_back(int_type())
static const int kPARAMETER_SET_PARAM
Float_t f1
const double j
Definition: BetheBloch.cxx:29
std::vector< std::string > get_names() const
static void ParseGUItag(const std::string &guitag, std::string &frame, std::vector< std::string > &choice)
A frame for editing a single paramter set.
static const unsigned int kRowW
Pop-up window for editing parameter sets.
static void UnpackParameter(const fhicl::ParameterSet &ps, const std::string &key, unsigned int &flags, std::string &tag, std::vector< std::string > &choice, std::vector< std::string > &value, std::string &gui, std::string &doc)
std::vector< TGTableLayoutHints * > fLHSHints
static float min(const float a, const float b, const float c)
Definition: absgeo.cxx:45
std::vector< ServiceTableEntry > fServices
Definition: ServiceTable.h:50
static const int kVECTOR_PARAM
static const int kHAVE_GUI_TAGS
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
std::vector< TGHorizontalFrame * > fRHS
A single row for editing a single parameter in a set.
GUITAG kSLIDER
std::vector< ParameterSetEditFrame * > fFrames
void SetupRadioButtons(TGCompositeFrame *f, const std::vector< std::string > &choice, const std::vector< std::string > &value)
fhicl::ParameterSet const & GetParameterSet(unsigned int i) const
const hit & b
Definition: hits.cxx:21
ParameterSetEditRow(ParameterSetEditFrame *frame, TGHorizontalFrame *lhs, TGHorizontalFrame *rhs, const fhicl::ParameterSet &ps, const std::string &key)
GUITAG kTEXT_ENTRY
assert(nhit_max >=nhit_nbins)
static bool IsLegalGUItag(const std::string &s)
GUITAG kSLIDER_INT
void SetupCheckButton(TGCompositeFrame *f, const std::vector< std::string > &choice, const std::vector< std::string > &value)
ParameterSetEditDialog(unsigned int psetid)
static const unsigned int kWidth
Interface to services and their configurations.
T max(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:68
std::vector< TGCheckButton * > fCheckButton
#define LOG_ERROR(stream)
Definition: Messenger.h:129
TGeoVolume * top
Definition: make_fe_box.C:9
std::string to_string() const
Definition: ParameterSet.h:137
ParameterSetEditFrame(TGCompositeFrame *mother, unsigned int psetid)
TGTextButton * fLabel
Label on the left.
std::string TabName(const std::string &s)