8f2d33a65d3bb7670463649413eb85b6a2e93850
[u/mrichter/AliRoot.git] / EVE / EveBase / AliEveMacroExecutorWindow.cxx
1 // @(#)root/eve:$Id$
2 // Author: Matevz Tadel 2007
3
4 /**************************************************************************
5  * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6  * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
7  * full copyright notice.                                                 *
8  **************************************************************************/
9
10 #include "AliEveMacroExecutorWindow.h"
11 #include "AliEveMacroExecutor.h"
12 #include "AliEveMacro.h"
13 #include "AliEveEventManager.h"
14
15 #include <TGedEditor.h>
16 #include <TGLabel.h>
17 #include <TGListBox.h>
18 #include <TGTextEntry.h>
19 #include <Buttons.h>
20
21 #include <TPRegexp.h>
22
23 class AliEveMEWListBox : public TGListBox
24 {
25 public:
26   AliEveMEWListBox(const TGWindow* p = 0, Int_t id = -1) : TGListBox(p, id)
27   {
28     if (gfGC == 0)
29     {
30       const TGGC& old = TGTextLBEntry::GetDefaultGC();
31
32       gfFont = gClient->GetFontPool()->GetFont("-*-lucidatypewriter-*-*-*-*-12-*-*-*-*-*-iso8859-1");
33       gfGC   = gClient->GetGCPool()->GetGC((GCValues_t*) old.GetAttributes(), kTRUE);
34       gfGC->SetFont(gVirtualX->GetFontHandle(gfFont->GetFontStruct()));
35     }
36   }
37
38   using TGListBox::AddEntry;
39   virtual void AddEntry(const char* s, Int_t id)
40   {
41     static const Pixel_t gkBackground[] = { 0x00ffffff, 0xf5f7f8 };
42
43     TGTextLBEntry *lbe = new TGTextLBEntry(fLbc, new TGString(s), id,
44                                            gfGC->GetGC(), gfFont->GetFontStruct());
45     fItemVsize = TMath::Max(fItemVsize, lbe->GetDefaultHeight());
46     fLbc->AddEntry(lbe, new TGLayoutHints(kLHintsExpandX | kLHintsTop));
47     // Need to set it here as the above line sets it to white (for some strange reason).
48     lbe->SetBackgroundColor(gkBackground[id%2]);
49   }
50
51 protected:
52   static TGGC    *gfGC;
53   static TGFont  *gfFont;
54 };
55
56 TGGC   *AliEveMEWListBox::gfGC   = 0;
57 TGFont *AliEveMEWListBox::gfFont = 0;
58
59
60 class AliEveMEWEditor : public TGedEditor
61 {
62 protected:
63   AliEveMacroExecutorWindow* fMEW;
64
65 public:
66   AliEveMEWEditor(AliEveMacroExecutorWindow* w) : TGedEditor(0), fMEW(w) {}
67   virtual ~AliEveMEWEditor() {}
68   virtual void Update(TGedFrame* gframe=0)
69   {
70     TGedEditor::Update(gframe);
71     fMEW->PopulateMacros();
72   }
73   virtual void Refresh()
74   {
75     SetModel(fPad, fModel, kButton1Down);
76   }
77 };
78
79 //______________________________________________________________________________
80 // Full description of AliEveMacroExecutorWindow
81 //
82
83 ClassImp(AliEveMacroExecutorWindow)
84
85 //______________________________________________________________________________
86 AliEveMacroExecutorWindow::AliEveMacroExecutorWindow(AliEveMacroExecutor* master) :
87   TGMainFrame(gClient->GetRoot()), fM(master),
88   fMainFrame(0), fCtrlFrame(0), fListBox(0), fEditor(0),
89   fSelectTags(0)
90 {
91   // Constructor.
92
93   fMainFrame = new TGVerticalFrame(this);
94   AddFrame(fMainFrame, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
95
96   // TGHorizontalFrame *f = 0;
97   TGButton          *b = 0;
98   {
99     fCtrlFrame = MkHFrame(fMainFrame);
100     fCtrlFrame->Resize(400, 22);
101
102     b = new TGTextButton(fCtrlFrame, "Reload event");
103     fCtrlFrame->AddFrame(b);
104     b->Connect("Clicked()", "AliEveMacroExecutorWindow", this,
105                "DoReloadEvent()");
106
107     MkLabel(fCtrlFrame, "Select: ", 48);
108     fSelectTags = new TGTextEntry(fCtrlFrame);
109     fCtrlFrame->AddFrame(fSelectTags, new TGLayoutHints(kLHintsNormal));//|kLHintsExpandX));
110     fSelectTags->Connect("ReturnPressed()", "AliEveMacroExecutorWindow", this,
111                          "DoSelectTags()");
112     b = new TGTextButton(fCtrlFrame, "Select");
113     fCtrlFrame->AddFrame(b);
114     b->Connect("Clicked()", "AliEveMacroExecutorWindow", this,
115                "DoSelectTags()");
116
117     b = new TGTextButton(fCtrlFrame, "Enable all");
118     fCtrlFrame->AddFrame(b);
119     b->Connect("Clicked()", "AliEveMacroExecutorWindow", this,
120                "DoEnableAll()");
121
122     b = new TGTextButton(fCtrlFrame, "Disable all");
123     fCtrlFrame->AddFrame(b);
124     b->Connect("Clicked()", "AliEveMacroExecutorWindow", this,
125                "DoDisableAll()");
126   }
127
128   fListBox = new AliEveMEWListBox(fMainFrame);
129   fMainFrame->AddFrame(fListBox, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
130   fListBox->Resize(400, 400);
131   fListBox->Connect("Selected(Int_t)", "AliEveMacroExecutorWindow", this,
132                     "DoMacroSelected(Int_t)");
133
134   fMainFrame->SetEditDisabled(kEditEnable);
135   fMainFrame->SetEditable();
136   fEditor = new AliEveMEWEditor(this);
137   fEditor->SetGlobal(kFALSE);
138   fMainFrame->SetEditable(kEditDisable);
139   fMainFrame->SetEditable(kFALSE);
140   {
141     TGFrameElement *el = 0;
142     TIter next(fMainFrame->GetList());
143     while ((el = (TGFrameElement *) next())) {
144       if (el->fFrame == fEditor)
145         if (el->fLayout) {
146           el->fLayout->SetLayoutHints(kLHintsExpandX);
147           el->fLayout->SetPadLeft(1); el->fLayout->SetPadRight(1);
148           el->fLayout->SetPadTop(2);  el->fLayout->SetPadBottom(2);
149           break;
150         }
151     }
152   }
153   fEditor->Resize(400, 150);
154   fEditor->ChangeOptions(fEditor->GetOptions() | kFixedHeight);
155
156   Resize(400, 700);
157
158   SetCleanup(kDeepCleanup);
159   Layout();
160   MapSubwindows();
161   MapWindow();
162
163   AliEveEventManager::GetMaster()->Connect("NewEventLoaded()", "AliEveMacroExecutorWindow", this,
164                         "NewEventLoaded()");
165 }
166
167 AliEveMacroExecutorWindow::~AliEveMacroExecutorWindow()
168 {
169   // Destructor.
170
171   AliEveEventManager::GetMaster()->Disconnect("NewEventLoaded()", this);
172 }
173
174 /******************************************************************************/
175
176 void AliEveMacroExecutorWindow::PopulateMacros(Bool_t keep_selected)
177 {
178   // Populate list-box (or whatever will replace it) with all macros.
179   // prototype: no selection, sorting
180
181   // printf("AliEveMacroExecutorWindow::PopulateMacros()\n");
182
183   AliEveMacro* ex_sel = 0;
184   if (keep_selected && fListBox->GetSelected() != -1)
185     ex_sel = fBoxContents[fListBox->GetSelected()];
186
187   fListBox->RemoveAll();
188   fBoxContents.clear();
189
190   TPMERegexp *regexp = 0;
191   TString     select = fSelectTags->GetText();
192   if ( ! select.IsNull())
193   {
194     // "i" does not work (get pcre_exec error = -3 PCRE_ERROR_BADOPTION)
195     // same for 1 (the value of PCRE_CASELESS)
196     // using case-sensitive matching then ... must investigate in root
197     regexp = new TPMERegexp(select);
198   }
199
200   TIter next(fM->fMacros);
201   AliEveMacro *mac;
202   Int_t        id =  0;
203   Int_t    sel_id = -1;
204   while ((mac = (AliEveMacro*) next()))
205   {
206     if (regexp && regexp->Match(mac->GetTags()) == 0)
207       continue;
208     if (mac == ex_sel)
209       sel_id = id;
210
211     fListBox->AddEntry(mac->FormForDisplay(), id++);
212     fBoxContents.push_back(mac);
213   }
214
215   if (sel_id != -1)
216     fListBox->Select(sel_id);
217
218   fListBox->MapSubwindows();
219   fListBox->Layout();
220 }
221
222 void AliEveMacroExecutorWindow::SetActiveStateOfShownMacros(Bool_t active)
223 {
224   // Set active-state of all shown macros to active.
225   // Automatically refreshes the list and editor.
226
227   for (std::vector<AliEveMacro*>::iterator m = fBoxContents.begin(); m != fBoxContents.end(); ++m)
228     (*m)->SetActive(active);
229   PopulateMacros();
230   fEditor->Refresh();
231 }
232
233 /******************************************************************************/
234
235 void AliEveMacroExecutorWindow::NewEventLoaded()
236 {
237   // Slot called after a new event has been loaded
238
239   // !!! Once we have exit status from the macro, can update GUI showing this.
240 }
241
242 void AliEveMacroExecutorWindow::DoReloadEvent()
243 {
244   // Slot for reload-event.
245
246   AliEveEventManager::GetMaster()->GotoEvent(AliEveEventManager::GetMaster()->GetEventId());
247 }
248
249 void AliEveMacroExecutorWindow::DoSelectTags()
250 {
251   // Slot for select-tags.
252
253   PopulateMacros();
254 }
255
256 void AliEveMacroExecutorWindow::DoMacroSelected(Int_t mid)
257 {
258   // Slot for macro-selected.
259
260   fEditor->SetModel(0, fBoxContents[mid], kButton1Down);
261 }
262
263 /******************************************************************************/
264
265 TGHorizontalFrame* AliEveMacroExecutorWindow::MkHFrame(TGCompositeFrame* p)
266 {
267   // Make standard horizontal frame.
268
269   if (p == 0)
270     p = this;
271   TGHorizontalFrame* f = new TGHorizontalFrame(p);
272   p->AddFrame(f, new TGLayoutHints(kLHintsNormal|kLHintsExpandX));
273   return f;
274 }
275
276 TGLabel* AliEveMacroExecutorWindow::MkLabel(TGCompositeFrame* p, const char* txt, Int_t width,
277                                             Int_t lo, Int_t ro, Int_t to, Int_t bo)
278 {
279   // Make standard label.
280
281   TGLabel *l = new TGLabel(p, txt);
282   p->AddFrame(l, new TGLayoutHints(kLHintsNormal, lo,ro,to,bo));
283   l->SetTextJustify(kTextRight);
284   l->SetWidth(width);
285   l->ChangeOptions(l->GetOptions() | kFixedWidth);
286   return l;
287 }