Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TContextMenu.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Nenad Buncic 08/02/96
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 /** \class TContextMenu
13 \ingroup Base
14 
15 This class provides an interface to context sensitive popup menus.
16 These menus pop up when the user hits the right mouse button, and
17 are destroyed when the menu pops downs.
18 
19 Context Menus are automatically generated by ROOT using the
20 following convention: if the string `// *MENU*` is found in the
21 comment field of a member function. This function will be added to
22 the list of items in the menu.
23 
24 The picture below shows a canvas with a pop-up menu.
25 
26 \image html base_hsummenu.png
27 
28 The picture below shows a canvas with a pop-up menu and a dialog box.
29 
30 \image html base_hsumdialog.png
31 */
32 
33 // silence warning about some cast operations
34 #if defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ >= 4 && ((__GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ >= 1) || (__GNUC_MINOR__ >= 3)))) && !__INTEL_COMPILER
35 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
36 #endif
37 
38 #include "TROOT.h"
39 #include "TContextMenu.h"
40 #include "TVirtualPad.h"
41 #include "TGuiFactory.h"
42 #include "TMethod.h"
43 #include "TMethodArg.h"
44 #include "TObjArray.h"
45 #include "TObjString.h"
46 #include "TToggle.h"
47 #include "TClassMenuItem.h"
48 #include "TBrowser.h"
49 #include "TClass.h"
50 #include "TObjectSpy.h"
51 
52 ClassImp(TContextMenu);
53 
54 
55 ////////////////////////////////////////////////////////////////////////////////
56 /// Create a context menu.
57 
58 TContextMenu::TContextMenu(const char *name, const char *title)
59  : TNamed(name, title)
60 {
61  fSelectedObject = 0;
62  fCalledObject = 0;
63  fSelectedMethod = 0;
64  fBrowser = 0;
65  fSelectedPad = 0;
66  fSelectedCanvas = 0;
67  fSelectedMenuItem = 0;
68 
69  fContextMenuImp = gGuiFactory->CreateContextMenuImp(this, name, title);
70 }
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Destroy a context menu.
74 
75 TContextMenu::~TContextMenu()
76 {
77  delete fContextMenuImp;
78 
79  fSelectedMethod = 0;
80  fCalledObject = 0;
81  fSelectedObject = 0;
82  fSelectedMenuItem = 0;
83  fContextMenuImp = 0;
84 }
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// Action to be performed when this menu item is selected.
88 /// If the selected method requires arguments we popup an
89 /// automatically generated dialog, otherwise the method is
90 /// directly executed.
91 
92 void TContextMenu::Action(TObject *object, TMethod *method)
93 {
94  if (method) {
95  SetMethod( method );
96  SetSelectedMenuItem(0);
97  SetCalledObject(object);
98 
99  if (method->GetListOfMethodArgs()->First())
100  fContextMenuImp->Dialog(object, method);
101  else {
102  Execute(object, method, "");
103  }
104  }
105 
106  if (fBrowser) fBrowser->Refresh();
107 }
108 
109 ////////////////////////////////////////////////////////////////////////////////
110 /// Action to be performed when this menu item is selected.
111 /// If the selected method requires arguments we popup an
112 /// automatically generated dialog, otherwise the method is
113 /// directly executed.
114 
115 void TContextMenu::Action(TClassMenuItem *menuitem)
116 {
117  TObject* object;
118  TMethod* method = 0;
119 
120  SetSelectedMenuItem( menuitem );
121 
122  // Get the object to be called
123  if (menuitem->IsCallSelf()) object=fSelectedObject;
124  else object=menuitem->GetCalledObject();
125 
126  if (object) {
127  // If object deleted, remove from popup and return
128  if (!(object->TestBit(kNotDeleted))) {
129  menuitem->SetType(TClassMenuItem::kPopupSeparator);
130  menuitem->SetCall(0,"");
131  return;
132  }
133 
134  method = object->IsA()->GetMethodWithPrototype(menuitem->GetFunctionName(),menuitem->GetArgs());
135 
136  }
137 
138  // calling object, call the method directly
139  if (object) {
140  if (method) {
141  SetMethod(method);
142  SetCalledObject(object);
143 
144  if ((method->GetListOfMethodArgs()->First()
145  && menuitem->GetSelfObjectPos() < 0 ) ||
146  method->GetListOfMethodArgs()->GetSize() > 1)
147  fContextMenuImp->Dialog(object, method);
148  else {
149  if (menuitem->GetSelfObjectPos() < 0) {
150 #ifndef WIN32
151  Execute(object, method, "");
152 #else
153  // It is a workaround of the "Dead lock under Windows
154  char *cmd = Form("((TContextMenu *)0x%lx)->Execute((TObject *)0x%lx,"
155  "(TMethod *)0x%lx,\"\");",
156  (Long_t)this,(Long_t)object,(Long_t)method);
157  //Printf("%s", cmd);
158  gROOT->ProcessLine(cmd);
159  //Execute( object, method, (TObjArray *)NULL );
160 #endif
161  } else {
162 #ifndef WIN32
163  Execute(object, method, Form("(TObject*)0x%lx",(Long_t)fSelectedObject));
164 #else
165  // It is a workaround of the "Dead lock under Windows
166  char *cmd = Form("((TContextMenu *)0x%lx)->Execute((TObject *)0x%lx,"
167  "(TMethod *)0x%lx,(TObject*)0x%lx);",
168  (Long_t)this,(Long_t)object,(Long_t)method,
169  (Long_t)fSelectedObject);
170  //Printf("%s", cmd);
171  gROOT->ProcessLine(cmd);
172  //Execute( object, method, (TObjArray *)NULL );
173 #endif
174  }
175  }
176  }
177 
178  } else {
179  // Calling a standalone global function
180  TFunction* function = gROOT->GetGlobalFunctionWithPrototype(
181  menuitem->GetFunctionName());
182  //menuitem->GetArgs());
183  if (function) {
184  SetMethod(function);
185  SetCalledObject(0);
186  if ( (function->GetNargs() && menuitem->GetSelfObjectPos() < 0) ||
187  function->GetNargs() > 1) {
188  fContextMenuImp->Dialog(0,function);
189  } else {
190  char* cmd;
191  if (menuitem->GetSelfObjectPos() < 0) {
192  cmd = Form("%s();", menuitem->GetFunctionName());
193  } else {
194  cmd = Form("%s((TObject*)0x%lx);",
195  menuitem->GetFunctionName(), (Long_t)fSelectedObject);
196  }
197  gROOT->ProcessLine(cmd);
198  }
199  }
200  }
201 
202  if (fBrowser) fBrowser->Refresh();
203 }
204 
205 ////////////////////////////////////////////////////////////////////////////////
206 /// Action to be performed when this toggle menu item is selected.
207 
208 void TContextMenu::Action(TObject *object, TToggle *toggle)
209 {
210  if (object && toggle) {
211  TObjectSpy savePad;
212 
213  gROOT->SetSelectedPrimitive(object);
214  if (fSelectedPad && gPad) {
215  savePad.SetObject(gPad);
216  fSelectedPad->cd();
217  }
218  TObjectRefSpy fsp((TObject*&) fSelectedPad);
219  TObjectRefSpy fsc((TObject*&) fSelectedCanvas);
220 
221  gROOT->SetFromPopUp(kTRUE);
222  toggle->Toggle();
223  if (fSelectedCanvas && fSelectedCanvas->GetPadSave())
224  fSelectedCanvas->GetPadSave()->Modified();
225  if (fSelectedPad)
226  fSelectedPad->Modified();
227  gROOT->SetFromPopUp(kFALSE);
228 
229  if (savePad.GetObject())
230  ((TVirtualPad*)savePad.GetObject())->cd();
231 
232  if (fSelectedCanvas) {
233  fSelectedCanvas->Update();
234  if (fSelectedCanvas->GetPadSave())
235  fSelectedCanvas->GetPadSave()->Update();
236  }
237  }
238 
239  if (fBrowser) fBrowser->Refresh();
240 }
241 
242 ////////////////////////////////////////////////////////////////////////////////
243 /// Create string describing argument (for use in dialog box).
244 
245 const char *TContextMenu::CreateArgumentTitle(TMethodArg *argument)
246 {
247  static TString argTitle;
248 
249  if (argument) {
250  argTitle.Form("(%s) %s", argument->GetTitle(), argument->GetName());
251  if (argument->GetDefault() && *(argument->GetDefault())) {
252  argTitle += " [default: ";
253  argTitle += argument->GetDefault();
254  argTitle += "]";
255  }
256  } else
257  argTitle.Clear();
258 
259  return argTitle.Data();
260 }
261 
262 ////////////////////////////////////////////////////////////////////////////////
263 /// Create title for dialog box retrieving argument values.
264 
265 const char *TContextMenu::CreateDialogTitle(TObject *object, TFunction *method)
266 {
267  static TString methodTitle;
268 
269  if (object && method)
270  methodTitle.Form("%s::%s", object->ClassName(), method->GetName());
271  else if (!object && method)
272  methodTitle.Form("%s", method->GetName());
273  else
274  methodTitle.Clear();
275 
276  return methodTitle.Data();
277 }
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// Create title for popup menu.
281 
282 const char *TContextMenu::CreatePopupTitle(TObject *object)
283 {
284  static TString popupTitle;
285 
286  if (object) {
287  const char* clname = object->IsA()->GetContextMenuTitle();
288  if (!clname[0])
289  clname = object->ClassName();
290 
291  if (!*(object->GetName()) || !strcmp(object->GetName(), object->ClassName())) {
292  popupTitle.Form(" %s ", clname);
293  } else {
294  popupTitle.Form(" %s::%s ", clname, object->GetName());
295  }
296  if (popupTitle.Length() > 60) {
297  popupTitle.Remove(60);
298  popupTitle += "...";
299  }
300  } else
301  popupTitle.Clear();
302 
303  return popupTitle.Data();
304 }
305 
306 ////////////////////////////////////////////////////////////////////////////////
307 /// Execute method with specified arguments for specified object.
308 
309 void TContextMenu::Execute(TObject *object, TFunction *method, const char *params)
310 {
311  if (method) {
312  TObjectSpy savePad;
313 
314  gROOT->SetSelectedPrimitive(object);
315  if (fSelectedPad && gPad) {
316  savePad.SetObject(gPad);
317  fSelectedPad->cd();
318  }
319  TObjectRefSpy fsp((TObject*&) fSelectedPad);
320  TObjectRefSpy fsc((TObject*&) fSelectedCanvas);
321 
322  gROOT->SetFromPopUp(kTRUE);
323  if (object) {
324  object->Execute((char *) method->GetName(), params);
325  } else {
326  char *cmd = Form("%s(%s);", method->GetName(),params);
327  gROOT->ProcessLine(cmd);
328  }
329  if (fSelectedCanvas && fSelectedCanvas->GetPadSave())
330  fSelectedCanvas->GetPadSave()->Modified();
331  if (fSelectedPad)
332  fSelectedPad->Modified();
333  gROOT->SetFromPopUp(kFALSE);
334 
335  if (savePad.GetObject())
336  ((TVirtualPad*)savePad.GetObject())->cd();
337 
338  if (fSelectedCanvas) {
339  fSelectedCanvas->Update();
340  if (fSelectedCanvas->GetPadSave())
341  fSelectedCanvas->GetPadSave()->Update();
342  }
343  }
344 
345  if (fBrowser) fBrowser->Refresh();
346 }
347 
348 ////////////////////////////////////////////////////////////////////////////////
349 /// Execute method with specified arguments for specified object.
350 
351 void TContextMenu::Execute(TObject *object, TFunction *method, TObjArray *params)
352 {
353  if (method) {
354  TObjectSpy savePad;
355 
356  gROOT->SetSelectedPrimitive(object);
357  if (fSelectedPad && gPad) {
358  savePad.SetObject(gPad);
359  fSelectedPad->cd();
360  }
361  TObjectRefSpy fsp((TObject*&) fSelectedPad);
362  TObjectRefSpy fsc((TObject*&) fSelectedCanvas);
363 
364  gROOT->SetFromPopUp(kTRUE);
365  if (object) {
366  object->Execute((TMethod*)method, params);
367  } else {
368  TString args;
369  TIter next(params);
370  TObjString *s;
371  while ((s = (TObjString*) next())) {
372  if (!args.IsNull()) args += ",";
373  args += s->String();
374  }
375  char *cmd = Form("%s(%s);", method->GetName(), args.Data());
376  gROOT->ProcessLine(cmd);
377  }
378  if (fSelectedCanvas && fSelectedCanvas->GetPadSave())
379  fSelectedCanvas->GetPadSave()->Modified();
380  if (fSelectedPad)
381  fSelectedPad->Modified();
382  gROOT->SetFromPopUp(kFALSE);
383 
384  if (savePad.GetObject())
385  ((TVirtualPad*)savePad.GetObject())->cd();
386 
387  if (fSelectedCanvas) {
388  fSelectedCanvas->Update();
389  if (fSelectedCanvas->GetPadSave())
390  fSelectedCanvas->GetPadSave()->Update();
391  }
392  }
393  if (fBrowser) fBrowser->Refresh();
394 }
395 
396 ////////////////////////////////////////////////////////////////////////////////
397 /// Popup context menu at given location in canvas c and pad p for selected
398 /// object.
399 
400 void TContextMenu::Popup(Int_t x, Int_t y, TObject *obj, TVirtualPad *c, TVirtualPad *p)
401 {
402  SetBrowser(0);
403  SetObject(obj);
404  SetCanvas(c);
405  SetPad(p);
406 
407  DisplayPopUp(x,y);
408 }
409 
410 ////////////////////////////////////////////////////////////////////////////////
411 /// Popup context menu at given location in browser b for selected object.
412 
413 void TContextMenu::Popup(Int_t x, Int_t y, TObject *obj, TBrowser *b)
414 {
415  SetBrowser(b);
416  SetObject(obj);
417  SetCanvas(0);
418  SetPad(0);
419 
420  DisplayPopUp(x,y);
421 }