Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TRootDialog.cxx
Go to the documentation of this file.
1 // @(#)root/gui:$Id$
2 // Author: Fons Rademakers 20/02/98
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TRootDialog //
15 // //
16 // A TRootDialog is used to prompt for the arguments of an object's //
17 // member function. A TRootDialog is created via the context menu's //
18 // when selecting a member function taking arguments. //
19 // //
20 //////////////////////////////////////////////////////////////////////////
21 
22 #include "TRootDialog.h"
23 #include "TRootContextMenu.h"
24 #include "TContextMenu.h"
25 #include "TClassMenuItem.h"
26 #include "TList.h"
27 #include "TGLabel.h"
28 #include "TGTextEntry.h"
29 #include "TGButton.h"
30 #include "TObjString.h"
31 #include "KeySymbols.h"
32 
33 extern TGTextEntry *gBlinkingEntry;
34 
35 ClassImp(TRootDialog);
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Create a method argument prompt dialog.
39 
40 TRootDialog::TRootDialog(TRootContextMenu *cmenu, const TGWindow *main,
41  const char *title, Bool_t okB, Bool_t cancelB, Bool_t applyB,
42  Bool_t helpB) : TGTransientFrame(gClient->GetRoot(), main, 200, 100)
43 {
44  fMenu = cmenu;
45 
46  fOk = okB;
47  fCancel = cancelB;
48  fApply = applyB;
49  fHelp = helpB;
50 
51  fWidgets = new TList;
52 
53  fL1 = new TGLayoutHints(kLHintsTop | kLHintsCenterX, 0, 0, 5, 0);
54  fL2 = new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5);
55 
56  SetWindowName(title);
57  SetIconName(title);
58  SetEditDisabled(kEditDisable);
59 
60  AddInput(kKeyPressMask | kEnterWindowMask | kLeaveWindowMask);
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 /// Delete the dialog.
65 
66 TRootDialog::~TRootDialog()
67 {
68  fWidgets->Delete();
69  delete fWidgets;
70  delete fL1;
71  delete fL2;
72 }
73 
74 ////////////////////////////////////////////////////////////////////////////////
75 /// Add a label and text input field.
76 
77 void TRootDialog::Add(const char *argname, const char *value, const char *type)
78 {
79  TGLabel *l = new TGLabel(this, argname);
80  TString svalue(value);
81  // keep double backslashes (e.g. in case of LateX formatting, like \\gamma)
82  svalue.ReplaceAll("\\", "\\\\");
83  TGTextBuffer *b = new TGTextBuffer(20); b->AddText(0, svalue.Data());
84  TGTextEntry *t = new TGTextEntry(this, b);
85 
86  t->Connect("TabPressed()", "TRootDialog", this, "TabPressed()");
87 
88  t->Associate(fMenu);
89  t->Resize(260, t->GetDefaultHeight());
90  AddFrame(l, fL1);
91  AddFrame(t, fL2);
92 
93  fWidgets->Add(l);
94  fWidgets->Add(t); // TGTextBuffer will be deleted by TGTextEntry
95  fWidgets->Add(new TObjString(type));
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Get parameter string (called by contextmenu after OK or Apply has
100 /// been selected).
101 
102 const char *TRootDialog::GetParameters()
103 {
104  static TString params;
105  TString param;
106 
107  TObjString *str;
108  TObject *obj;
109 
110  Int_t selfobjpos;
111  if (fMenu->GetContextMenu()->GetSelectedMenuItem())
112  selfobjpos = fMenu->GetContextMenu()->GetSelectedMenuItem()->GetSelfObjectPos();
113  else
114  selfobjpos = -1;
115 
116  params.Clear();
117  TIter next(fWidgets);
118  Int_t nparam = 0;
119 
120  while ((obj = next())) { // first element is label, skip...
121  if (obj->IsA() != TGLabel::Class()) break;
122  obj = next(); // get either TGTextEntry or TGComboBox
123  str = (TObjString *) next(); // get type string
124 
125  nparam++;
126 
127  const char *type = str ? str->GetString().Data() : 0;
128  const char *data = 0;
129 
130  if (obj && obj->IsA() == TGTextEntry::Class())
131  data = ((TGTextEntry *) obj)->GetBuffer()->GetString();
132 
133  // TODO: Combobox...
134 
135  // if necessary, replace the selected object by it's address
136  if (selfobjpos == nparam-1) {
137  if (params.Length()) params += ",";
138  param = TString::Format("(TObject*)0x%lx",
139  (Long_t)fMenu->GetContextMenu()->GetSelectedObject());
140  params += param;
141  }
142 
143  if (params.Length()) params += ",";
144  if (type && data) {
145  if (!strncmp(type, "char*", 5))
146  param = TString::Format("\"%s\"", data);
147  else
148  param = TString::Format("(%s)%s", type, data);
149  } else
150  param = "0";
151 
152  params += param;
153  }
154 
155  // if selected object is the last argument, have to insert it here
156  if (selfobjpos == nparam) {
157  if (params.Length()) params += ",";
158  param = TString::Format("(TObject*)0x%lx",
159  (Long_t)fMenu->GetContextMenu()->GetSelectedObject());
160  params += param;
161  }
162 
163  return params.Data();
164 }
165 
166 ////////////////////////////////////////////////////////////////////////////////
167 /// Popup dialog.
168 
169 void TRootDialog::Popup()
170 {
171  //--- create the OK, Apply and Cancel buttons
172 
173  UInt_t nb = 0, width = 0, height = 0;
174 
175  TGHorizontalFrame *hf = new TGHorizontalFrame(this, 60, 20, kFixedWidth);
176  TGLayoutHints *l1 = new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 5, 5, 0, 0);
177 
178  // put hf as last in the list to be deleted
179  fWidgets->Add(l1);
180 
181  TGTextButton *b;
182  if (fOk) {
183  b = new TGTextButton(hf, "&OK", 1);
184  fWidgets->Add(b);
185  b->Associate(fMenu);
186  hf->AddFrame(b, l1);
187  height = b->GetDefaultHeight();
188  width = TMath::Max(width, b->GetDefaultWidth()); ++nb;
189  }
190  if (fApply) {
191  b = new TGTextButton(hf, "&Apply", 2);
192  fWidgets->Add(b);
193  b->Associate(fMenu);
194  hf->AddFrame(b, l1);
195  height = b->GetDefaultHeight();
196  width = TMath::Max(width, b->GetDefaultWidth()); ++nb;
197  }
198  if (fCancel) {
199  b = new TGTextButton(hf, "&Cancel", 3);
200  fWidgets->Add(b);
201  b->Associate(fMenu);
202  hf->AddFrame(b, l1);
203  height = b->GetDefaultHeight();
204  width = TMath::Max(width, b->GetDefaultWidth()); ++nb;
205  }
206  if (fHelp) {
207  b = new TGTextButton(hf, "Online &Help", 4);
208  fWidgets->Add(b);
209  b->Associate(fMenu);
210  hf->AddFrame(b, l1);
211  height = b->GetDefaultHeight();
212  width = TMath::Max(width, b->GetDefaultWidth()); ++nb;
213  }
214 
215  // place buttons at the bottom
216  l1 = new TGLayoutHints(kLHintsBottom | kLHintsCenterX, 0, 0, 5, 5);
217  fWidgets->Add(l1);
218  fWidgets->Add(hf);
219 
220  AddFrame(hf, l1);
221 
222  // keep the buttons centered and with the same width
223  hf->Resize((width + 20) * nb, height);
224 
225  // map all widgets and calculate size of dialog
226  MapSubwindows();
227 
228  width = GetDefaultWidth();
229  height = GetDefaultHeight();
230 
231  Resize(width, height);
232 
233  // position relative to the parent's window
234  CenterOnParent();
235 
236  // make the message box non-resizable
237  SetWMSize(width, height);
238  SetWMSizeHints(width, height, width, height, 0, 0);
239 
240  SetMWMHints(kMWMDecorAll | kMWMDecorResizeH | kMWMDecorMaximize |
241  kMWMDecorMinimize | kMWMDecorMenu,
242  kMWMFuncAll | kMWMFuncResize | kMWMFuncMaximize |
243  kMWMFuncMinimize,
244  kMWMInputModeless);
245 
246  MapWindow();
247  fClient->WaitFor(this);
248 }
249 
250 ////////////////////////////////////////////////////////////////////////////////
251 /// Called when closed via window manager action.
252 
253 void TRootDialog::CloseWindow()
254 {
255  // Send Cancel button message to context menu eventhandler
256  SendMessage(fMenu, MK_MSG(kC_COMMAND, kCM_BUTTON), 3, 0);
257 }
258 
259 ////////////////////////////////////////////////////////////////////////////////
260 /// Handle Tab keyboard navigation in this dialog.
261 
262 void TRootDialog::TabPressed()
263 {
264  Bool_t setNext = kFALSE;
265  TGTextEntry *entry;
266  TIter next(fWidgets);
267 
268  while ( TObject* obj = next() ) {
269  if ( obj->IsA() == TGTextEntry::Class() ) {
270  entry = (TGTextEntry*) obj;
271  if ( entry == gBlinkingEntry ) {
272  setNext = kTRUE;
273  } else if ( setNext ) {
274  entry->SetFocus();
275  entry->End();
276  return;
277  }
278  }
279  }
280 
281  next.Reset();
282  while ( TObject* obj = next() ) {
283  if ( obj->IsA() == TGTextEntry::Class() ) {
284  entry = (TGTextEntry*) obj;
285  entry->SetFocus();
286  entry->End();
287  return;
288  }
289  }
290 }
291 
292 ////////////////////////////////////////////////////////////////////////////////
293 /// The key press event handler in this dialog.
294 
295 Bool_t TRootDialog::HandleKey(Event_t* event)
296 {
297  char tmp[10];
298  UInt_t keysym;
299  gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
300  if ((EKeySym)keysym == kKey_Tab) {
301 
302  TGTextEntry *entry;
303  TIter next(fWidgets);
304 
305  while ( TObject* obj = next() ) {
306  if ( obj->IsA() == TGTextEntry::Class() ) {
307  entry = (TGTextEntry*) obj;
308  entry->TabPressed();
309  return kTRUE;
310  }
311  }
312  }
313 
314  return TGMainFrame::HandleKey(event);
315 }