TRootContextMenu.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TRootContextMenu.cxx 37924 2011-02-01 09:11:15Z bellenot $
00002 // Author: Fons Rademakers   12/02/98
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TRootContextMenu                                                     //
00015 //                                                                      //
00016 // This class provides an interface to context sensitive popup menus.   //
00017 // These menus pop up when the user hits the right mouse button, and    //
00018 // are destroyed when the menu pops downs.                              //
00019 // The picture below shows a canvas with a pop-up menu.                 //
00020 //                                                                      //
00021 //Begin_Html <img src="gif/hsumMenu.gif"> End_Html                      //
00022 //                                                                      //
00023 // The picture below shows a canvas with a pop-up menu and a dialog box.//
00024 //                                                                      //
00025 //Begin_Html <img src="gif/hsumDialog.gif"> End_Html                    //
00026 //                                                                      //
00027 //////////////////////////////////////////////////////////////////////////
00028 
00029 #include "TRootContextMenu.h"
00030 #include "TROOT.h"
00031 #include "TGClient.h"
00032 #include "TEnv.h"
00033 #include "TList.h"
00034 #include "TContextMenu.h"
00035 #include "TMethod.h"
00036 #include "TMethodArg.h"
00037 #include "TClass.h"
00038 #include "TVirtualX.h"
00039 #include "TCanvas.h"
00040 #include "TDataMember.h"
00041 #include "TToggle.h"
00042 #include "TRootDialog.h"
00043 #include "TDataType.h"
00044 #include "TCanvas.h"
00045 #include "TBrowser.h"
00046 #include "TRootCanvas.h"
00047 #include "TRootBrowser.h"
00048 #include "TClassMenuItem.h"
00049 #include "TObjectSpy.h"
00050 #include "KeySymbols.h"
00051 
00052 enum EContextMenu {
00053    kToggleStart       = 1000, // first id of toggle menu items
00054    kToggleListStart   = 2000, // first id of toggle list menu items
00055    kUserFunctionStart = 3000  // first id of user added functions/methods, etc...
00056 };
00057 
00058 
00059 ClassImp(TRootContextMenu)
00060 
00061 //______________________________________________________________________________
00062 TRootContextMenu::TRootContextMenu(TContextMenu *c, const char *)
00063     : TGPopupMenu(gClient->GetDefaultRoot()), TContextMenuImp(c)
00064 {
00065    // Create context menu.
00066 
00067    fDialog  = 0;
00068    fTrash = new TList;
00069 
00070    gROOT->GetListOfCleanups()->Add(this);
00071    // Context menu handles its own messages
00072    Associate(this);
00073 }
00074 
00075 //______________________________________________________________________________
00076 TRootContextMenu::~TRootContextMenu()
00077 {
00078    // Delete a context menu.
00079 
00080    gROOT->GetListOfCleanups()->Remove(this);
00081    delete fDialog;
00082    if (fTrash) fTrash->Delete();
00083    delete fTrash;
00084 }
00085 
00086 //______________________________________________________________________________
00087 void TRootContextMenu::DisplayPopup(Int_t x, Int_t y)
00088 {
00089    // Display context popup menu for currently selected object.
00090 
00091    if (fClient->IsEditable()) return;
00092 
00093    // delete menu items releated to previous object and reset menu size
00094    if (fEntryList) fEntryList->Delete();
00095    fCurrent = 0;
00096    if (fTrash)   fTrash->Delete();
00097    fMenuHeight = 6;
00098    fMenuWidth  = 8;
00099 
00100    // delete previous dialog
00101    if (fDialog) {
00102       delete fDialog;
00103       fDialog = 0;
00104    }
00105 
00106    // add menu items to popup menu
00107    CreateMenu(fContextMenu->GetSelectedObject());
00108 
00109    int    xx, yy, topx = 0, topy = 0;
00110    UInt_t w, h;
00111 
00112    if (fContextMenu->GetSelectedCanvas())
00113       gVirtualX->GetGeometry(fContextMenu->GetSelectedCanvas()->GetCanvasID(),
00114                         topx, topy, w, h);
00115 
00116    xx = topx + x + 1;
00117    yy = topy + y + 1;
00118 
00119    PlaceMenu(xx, yy, kFALSE, kTRUE);
00120    // add some space for the right-side '?' (help)
00121    fMenuWidth += 5;
00122    Resize(GetDefaultWidth()+5, GetDefaultHeight());
00123 }
00124 
00125 //______________________________________________________________________________
00126 TGPopupMenu * TRootContextMenu::FindHierarchy(const char *commentstring, TString & last_component)
00127 {
00128   // Decodes the Hierarchy="Level0/Level1/Level2/..." statement from the comment field
00129   // and returns the - if needed - created sub menu "Level0/Level1"
00130   // Returns the last component in last_component.
00131 
00132    TString cmd(commentstring);
00133    TString option;
00134    TString hierarchy;
00135    TGPopupMenu *currentMenu = 0;
00136 
00137    // search for arguments to the MENU statement
00138    // strcpy(cmd,commentstring);
00139    Ssiz_t opt_ptr;
00140    if ((opt_ptr=cmd.Index("*MENU={"))   != kNPOS ||
00141        (opt_ptr=cmd.Index("*SUBMENU={"))!= kNPOS ||
00142        (opt_ptr=cmd.Index("*TOGGLE={")) != kNPOS ) {
00143 
00144       Ssiz_t start = cmd.Index("{",opt_ptr) + 1;
00145       Ssiz_t end = cmd.Index("}",start);
00146       option = cmd(start,end - start);
00147 
00148       // Look for Hierarchy token
00149       TObjArray * array = option.Tokenize(";");
00150       TIter iter(array);
00151       TObject *obj;
00152       while((obj = iter())) {
00153          TString token(obj->GetName());
00154          if (token.Index("Hierarchy=\"") != kNPOS) {
00155             Ssiz_t tstart = token.Index("\"") + 1;
00156             Ssiz_t tend = token.Index("\"",tstart+1);
00157             if (tend == kNPOS) continue;
00158             hierarchy = token(tstart,tend - tstart);
00159          }
00160       }
00161       delete array;
00162    }
00163 
00164    // Build Hierarchy
00165    currentMenu = this;
00166    TObjArray * array = hierarchy.Tokenize("/");
00167    TIter iter(array);
00168    TObject *obj = iter();
00169    while(obj) {
00170       last_component = obj->GetName();
00171       obj = iter();
00172       if (obj) {
00173          TGMenuEntry *ptr;
00174          TIter next(currentMenu->GetListOfEntries());
00175          // Search for popup with corresponding name
00176          while ((ptr = (TGMenuEntry *) next()) &&
00177                 (ptr->GetType() != kMenuPopup ||
00178                 last_component.CompareTo(ptr->GetName()))) { }
00179          if (ptr)
00180             currentMenu = ptr->GetPopup();
00181          else {
00182             TGPopupMenu *r = new TGPopupMenu(gClient->GetDefaultRoot());
00183             // Alphabetical ordering
00184             TGMenuEntry *ptr2;
00185             TIter next2(currentMenu->GetListOfEntries());
00186             // Search for popup with corresponding name
00187             while ((ptr2 = (TGMenuEntry *) next2()) &&
00188                    (ptr2->GetType() != kMenuPopup  ||
00189                    last_component.CompareTo(ptr2->GetName()) > 0 )) { }
00190 
00191             currentMenu->AddPopup(last_component, r,ptr2);
00192             currentMenu = r;
00193             fTrash->Add(r);
00194             last_component = obj->GetName();
00195          }
00196       }
00197    }
00198 
00199    delete array;
00200    return currentMenu;
00201 }
00202 
00203 //______________________________________________________________________________
00204 void TRootContextMenu::AddEntrySorted(TGPopupMenu *currentMenu, const char *s, Int_t id, void *ud,
00205                                          const TGPicture *p , Bool_t sorted)
00206 {
00207    // Add a entry to current menu with alphabetical ordering.
00208 
00209    TGMenuEntry *ptr2 = 0;
00210    if (sorted) {
00211       TIter next(currentMenu->GetListOfEntries());
00212       // Search for popup with corresponding name
00213       while ((ptr2 = (TGMenuEntry *) next()) &&
00214              (ptr2->GetType() != kMenuEntry ||
00215              strcmp(ptr2->GetName(), s)<0 )) { }
00216    }
00217    currentMenu->AddEntry(s,id,ud,p,ptr2);
00218 }
00219 
00220 //______________________________________________________________________________
00221 void TRootContextMenu::CreateMenu(TObject *object)
00222 {
00223    // Create the context menu depending on the selected object.
00224 
00225    if (!object || fClient->IsEditable()) return;
00226 
00227    int entry = 0, toggle = kToggleStart, togglelist = kToggleListStart;
00228    int userfunction = kUserFunctionStart;
00229 
00230    // Add a title
00231    AddLabel(fContextMenu->CreatePopupTitle(object));
00232    AddSeparator();
00233 
00234    // Get list of menu items from the selected object's class
00235    TList *menuItemList = object->IsA()->GetMenuList();
00236 
00237    TClassMenuItem *menuItem;
00238    TIter nextItem(menuItemList);
00239 
00240    while ((menuItem = (TClassMenuItem*) nextItem())) {
00241       switch (menuItem->GetType()) {
00242          case TClassMenuItem::kPopupSeparator:
00243             {
00244             TGMenuEntry *last = (TGMenuEntry *)GetListOfEntries()->Last();
00245             if (last && last->GetType() != kMenuSeparator)
00246                AddSeparator();
00247             break;
00248             }
00249          case TClassMenuItem::kPopupStandardList:
00250             {
00251                // Standard list of class methods. Rebuild from scratch.
00252                // Get linked list of objects menu items (i.e. member functions
00253                // with the token *MENU in their comment fields.
00254                TList *methodList = new TList;
00255                object->IsA()->GetMenuItems(methodList);
00256 
00257                TMethod *method;
00258                TClass  *classPtr = 0;
00259                TIter next(methodList);
00260                Bool_t needSep = kFALSE;
00261 
00262                while ((method = (TMethod*) next())) {
00263                   if (classPtr != method->GetClass()) {
00264                      needSep = kTRUE;
00265                      classPtr = method->GetClass();
00266                   }
00267 
00268                   TDataMember *m;
00269                   EMenuItemKind menuKind = method->IsMenuItem();
00270                   TGPopupMenu *currentMenu = 0;
00271                   TString last_component;
00272 
00273                   switch (menuKind) {
00274                      case kMenuDialog:
00275                         // search for arguments to the MENU statement
00276                         currentMenu = FindHierarchy(method->GetCommentString(),last_component);
00277                         if (needSep && currentMenu == this) {
00278                            AddSeparator();
00279                            needSep = kFALSE;
00280                         }
00281                         AddEntrySorted(currentMenu,last_component.Length() ? last_component.Data() : method->GetName(), entry++, method,0,currentMenu != this);
00282                         break;
00283                      case kMenuSubMenu:
00284                         if ((m = method->FindDataMember())) {
00285 
00286                            // search for arguments to the MENU statement
00287                            currentMenu = FindHierarchy(method->GetCommentString(),last_component);
00288 
00289                            if (m->GetterMethod()) {
00290                               TGPopupMenu *r = new TGPopupMenu(gClient->GetDefaultRoot());
00291                               if (needSep && currentMenu == this) {
00292                                  AddSeparator();
00293                                  needSep = kFALSE;
00294                               }
00295                               if (last_component.Length()) {
00296                                  currentMenu->AddPopup(last_component, r);
00297                               } else {
00298                                  currentMenu->AddPopup(method->GetName(), r);
00299                               }
00300                               fTrash->Add(r);
00301                               TIter nxt(m->GetOptions());
00302                               TOptionListItem *it;
00303                               while ((it = (TOptionListItem*) nxt())) {
00304                                  char *name = it->fOptName;
00305                                  Long_t val = it->fValue;
00306 
00307                                  TToggle *t = new TToggle;
00308                                  t->SetToggledObject(object, method);
00309                                  t->SetOnValue(val);
00310                                  fTrash->Add(t);
00311 
00312                                  r->AddEntry(name, togglelist++, t);
00313                                  if (t->GetState())
00314                                     r->CheckEntry(togglelist-1);
00315                               }
00316                            } else {
00317                               if (needSep && currentMenu == this) {
00318                                  AddSeparator();
00319                                  needSep = kFALSE;
00320                               }
00321                               AddEntrySorted(currentMenu,last_component.Length() ? last_component.Data() : method->GetName(), entry++, method,0,currentMenu != this);
00322                            }
00323                         }
00324                         break;
00325 
00326                      case kMenuToggle:
00327                         {
00328                            TToggle *t = new TToggle;
00329                            t->SetToggledObject(object, method);
00330                            t->SetOnValue(1);
00331                            fTrash->Add(t);
00332                            // search for arguments to the MENU statement
00333                            currentMenu = FindHierarchy(method->GetCommentString(),last_component);
00334                            if (needSep && currentMenu == this) {
00335                               AddSeparator();
00336                               needSep = kFALSE;
00337                            }
00338                            AddEntrySorted(currentMenu,last_component.Length() ? last_component.Data() : method->GetName(), toggle++, t,0,currentMenu != this);
00339                            if (t->GetState()) currentMenu->CheckEntry(toggle-1);
00340                         }
00341                         break;
00342 
00343                      default:
00344                         break;
00345                   }
00346                }
00347                delete methodList;
00348             }
00349             break;
00350          case TClassMenuItem::kPopupUserFunction:
00351             {
00352                if (menuItem->IsToggle()) {
00353                   TMethod* method =
00354                         object->IsA()->GetMethodWithPrototype(menuItem->GetFunctionName(),menuItem->GetArgs());
00355                   TToggle *t = new TToggle;
00356                   t->SetToggledObject(object, method);
00357                   t->SetOnValue(1);
00358                   fTrash->Add(t);
00359 
00360                   AddEntry(method->GetName(), toggle++, t);
00361                   if (t->GetState()) CheckEntry(toggle-1);
00362                } else {
00363                   const char* menuItemTitle = menuItem->GetTitle();
00364                   if (strlen(menuItemTitle)==0) menuItemTitle = menuItem->GetFunctionName();
00365                   AddEntry(menuItemTitle,userfunction++,menuItem);
00366                }
00367             }
00368             break;
00369          default:
00370             break;
00371       }
00372    }
00373 }
00374 
00375 //______________________________________________________________________________
00376 void TRootContextMenu::Dialog(TObject *object, TMethod *method)
00377 {
00378    // Create dialog object with OK and Cancel buttons. This dialog
00379    // prompts for the arguments of "method".
00380 
00381    Dialog(object,(TFunction*)method);
00382 }
00383 
00384 //______________________________________________________________________________
00385 void TRootContextMenu::Dialog(TObject *object, TFunction *function)
00386 {
00387    // Create dialog object with OK and Cancel buttons. This dialog
00388    // prompts for the arguments of "function".
00389    // function may be a global function or a method
00390 
00391    Int_t selfobjpos;
00392 
00393    if (!function) return;
00394 
00395    // Position, if it exists, of the argument that correspond to the object itself
00396    if (fContextMenu->GetSelectedMenuItem())
00397       selfobjpos =  fContextMenu->GetSelectedMenuItem()->GetSelfObjectPos();
00398    else selfobjpos = -1;
00399 
00400    const TGWindow *w;
00401    if (fContextMenu->GetSelectedCanvas()) {
00402       TCanvas *c = (TCanvas *) fContextMenu->GetSelectedCanvas();
00403       // Embedded canvas has no canvasimp that is a TGFrame
00404       if (c->GetCanvasImp()->IsA()->InheritsFrom(TGFrame::Class())) {
00405          w = fClient->GetWindowById(gVirtualX->GetWindowID(c->GetCanvasID()));
00406          if (!w) w = (TRootCanvas *) c->GetCanvasImp();
00407       } else {
00408          w = gClient->GetDefaultRoot();
00409       }
00410    } else if (fContextMenu->GetBrowser()) {
00411       TBrowser *b = (TBrowser *) fContextMenu->GetBrowser();
00412       w = (TRootBrowser *) b->GetBrowserImp();
00413    } else {
00414       w = gClient->GetDefaultRoot();
00415    }
00416    fDialog = new TRootDialog(this, w, fContextMenu->CreateDialogTitle(object, function));
00417 
00418    // iterate through all arguments and create apropriate input-data objects:
00419    // inputlines, option menus...
00420    TMethodArg *argument = 0;
00421 
00422    TIter next(function->GetListOfMethodArgs());
00423    Int_t argpos = 0;
00424 
00425    while ((argument = (TMethodArg *) next())) {
00426       // Do not input argument for self object
00427       if (selfobjpos != argpos) {
00428          const char *argname    = fContextMenu->CreateArgumentTitle(argument);
00429          const char *type       = argument->GetTypeName();
00430          TDataType  *datatype   = gROOT->GetType(type);
00431          const char *charstar   = "char*";
00432          char        basictype[32];
00433 
00434          if (datatype) {
00435             strlcpy(basictype, datatype->GetTypeName(), 32);
00436          } else {
00437             TClass *cl = TClass::GetClass(type);
00438             if (strncmp(type, "enum", 4) && (cl && !(cl->Property() & kIsEnum)))
00439                Warning("Dialog", "data type is not basic type, assuming (int)");
00440             strlcpy(basictype, "int", 32);
00441          }
00442 
00443          if (strchr(argname, '*')) {
00444             strlcat(basictype, "*",32);
00445             if (!strncmp(type, "char", 4))
00446                type = charstar;
00447             else if (strstr(argname, "[default:")) {
00448                // skip arguments that are pointers (but not char *)
00449                // and have a default value
00450                argpos++;
00451                continue;
00452             }
00453          }
00454 
00455          TDataMember *m = argument->GetDataMember();
00456          if (m && object && m->GetterMethod(object->IsA())) {
00457 
00458             // Get the current value and form it as a text:
00459 
00460             char val[256];
00461 
00462             if (!strncmp(basictype, "char*", 5)) {
00463                char *tdefval;
00464                m->GetterMethod()->Execute(object, "", &tdefval);
00465                strlcpy(val, tdefval, sizeof(val));
00466             } else if (!strncmp(basictype, "float", 5) ||
00467                        !strncmp(basictype, "double", 6)) {
00468                Double_t ddefval;
00469                m->GetterMethod()->Execute(object, "", ddefval);
00470                snprintf(val,256, "%g", ddefval);
00471             } else if (!strncmp(basictype, "char", 4) ||
00472                        !strncmp(basictype, "bool", 4) ||
00473                        !strncmp(basictype, "int", 3)  ||
00474                        !strncmp(basictype, "long", 4) ||
00475                        !strncmp(basictype, "short", 5)) {
00476                Long_t ldefval;
00477                m->GetterMethod()->Execute(object, "", ldefval);
00478                snprintf(val,256, "%li", ldefval);
00479             }
00480 
00481             // Find out whether we have options ...
00482 
00483             TList *opt;
00484             if ((opt = m->GetOptions())) {
00485                Warning("Dialog", "option menu not yet implemented");
00486 #if 0
00487                TMotifOptionMenu *o= new TMotifOptionMenu(argname);
00488                TIter nextopt(opt);
00489                TOptionListItem *it = 0;
00490                while ((it = (TOptionListItem*) nextopt())) {
00491                   char *name  = it->fOptName;
00492                   char *label = it->fOptLabel;
00493                   Long_t value  = it->fValue;
00494                   if (value != -9999) {
00495                      char val[256];
00496                      snprintf(val,256, "%li", value);
00497                      o->AddItem(name, val);
00498                   }else
00499                      o->AddItem(name, label);
00500                }
00501                o->SetData(val);
00502                fDialog->Add(o);
00503 #endif
00504             } else {
00505                // we haven't got options - textfield ...
00506                fDialog->Add(argname, val, type);
00507             }
00508          } else {    // if m not found ...
00509 
00510             char val[256] = "";
00511             const char *tval = argument->GetDefault();
00512             if (tval && strlen(tval)) {
00513                // Remove leading and trailing quotes
00514                strlcpy(val, tval + (tval[0] == '"' ? 1 : 0), sizeof(val));
00515                if (val[strlen(val)-1] == '"')
00516                   val[strlen(val)-1]= 0;
00517             }
00518             fDialog->Add(argname, val, type);
00519          }
00520       }
00521       argpos++;
00522    }
00523 
00524    fDialog->Popup();
00525 }
00526 
00527 //______________________________________________________________________________
00528 void TRootContextMenu::DrawEntry(TGMenuEntry *entry)
00529 {
00530    // Draw context menu entry.
00531 
00532    int ty, offset;
00533    static int max_ascent = 0, max_descent = 0;
00534 
00535    TGPopupMenu::DrawEntry(entry);
00536    // draw the ? (help) in the right side when highlighting a menu entry
00537    if (entry->GetType() == kMenuEntry && (entry->GetStatus() & kMenuActiveMask)) {
00538       if (max_ascent == 0) {
00539          gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
00540       }
00541       offset = (entry->GetEh() - (max_ascent + max_descent)) / 2;
00542       ty = entry->GetEy() + max_ascent + offset - 1;
00543       TGHotString s("&?");
00544       s.Draw(fId, fSelGC, fMenuWidth-12, ty);
00545    }
00546 }
00547 
00548 //______________________________________________________________________________
00549 Bool_t TRootContextMenu::HandleButton(Event_t *event)
00550 {
00551    // Handle button event in the context menu.
00552 
00553    int   id;
00554    void *ud;
00555    if ((event->fType == kButtonRelease) && (event->fX >= (Int_t)(fMenuWidth-15)) &&
00556        (event->fX <= (Int_t)fMenuWidth)) {
00557       id = EndMenu(ud);
00558       if (fHasGrab) gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);  // ungrab
00559       if (ud) {
00560          // retrieve the highlighted function
00561          TFunction *function = 0;
00562          if (id < kToggleStart) {
00563             TMethod *m = (TMethod *)ud;
00564             function = (TFunction *)m;
00565          } else if (id >= kToggleStart && id < kUserFunctionStart) {
00566             TToggle *t = (TToggle *)ud;
00567             TMethodCall *mc = (TMethodCall *)t->GetSetter();
00568             function = (TFunction *)mc->GetMethod();
00569          } else {
00570             TClassMenuItem *mi = (TClassMenuItem *)ud;
00571             function = gROOT->GetGlobalFunctionWithPrototype(mi->GetFunctionName());
00572          }
00573          if (function)
00574             fContextMenu->SetMethod(function);
00575       }
00576       OnlineHelp();
00577       return kTRUE;
00578    }
00579    return TGPopupMenu::HandleButton(event);
00580 }
00581 
00582 //______________________________________________________________________________
00583 Bool_t TRootContextMenu::HandleCrossing(Event_t *event)
00584 {
00585    // Handle pointer crossing event in context menu.
00586 
00587    if (event->fType == kLeaveNotify) {
00588       // just to reset the mouse pointer...
00589       HandleMotion(event);
00590    }
00591    return TGPopupMenu::HandleCrossing(event);
00592 }
00593 
00594 //______________________________________________________________________________
00595 Bool_t TRootContextMenu::HandleMotion(Event_t *event)
00596 {
00597    // Handle pointer motion event in context menu.
00598 
00599    static int toggle = 0;
00600    static Cursor_t handCur = kNone, rightCur = kNone;
00601    static UInt_t mask = kButtonPressMask | kButtonReleaseMask | kPointerMotionMask;
00602 
00603    if (handCur == kNone)
00604       handCur    = gVirtualX->CreateCursor(kHand);
00605    if (rightCur == kNone)
00606       rightCur   = gVirtualX->CreateCursor(kArrowRight);
00607 
00608    if (event->fType == kLeaveNotify) {
00609       gVirtualX->ChangeActivePointerGrab(fId, mask, rightCur);
00610       toggle = 0;
00611       return kTRUE;
00612    }
00613    // change the cursot to a small hand when over the ? (help)
00614    if ((event->fX >= (Int_t)(fMenuWidth-15)) && (event->fX <= (Int_t)fMenuWidth) &&
00615        fCurrent && (fCurrent->GetType() == kMenuEntry)) {
00616       if (toggle == 0) {
00617          gVirtualX->ChangeActivePointerGrab(fId, mask, handCur);
00618          toggle = 1;
00619       }
00620    }
00621    else {
00622       if (toggle == 1) {
00623          gVirtualX->ChangeActivePointerGrab(fId, mask, rightCur);
00624          toggle = 0;
00625       }
00626    }
00627    return TGPopupMenu::HandleMotion(event);
00628 }
00629 
00630 //______________________________________________________________________________
00631 void TRootContextMenu::OnlineHelp()
00632 {
00633    // Open the online help matching the actual class/method.
00634 
00635    TString clname;
00636    TString cmd;
00637    TString url = gEnv->GetValue("Browser.StartUrl", "http://root.cern.ch/root/html/");
00638    if (url.EndsWith(".html", TString::kIgnoreCase)) {
00639       url.Remove(url.Last('/'));
00640    }
00641    if (!url.EndsWith("/")) {
00642       url += '/';
00643    }
00644    TObject *obj = fContextMenu->GetSelectedObject();
00645    if (obj) {
00646       clname = obj->ClassName();
00647       if (fContextMenu->GetSelectedMethod()) {
00648          TString smeth = fContextMenu->GetSelectedMethod()->GetName();
00649          TMethod *method = obj->IsA()->GetMethodAllAny(smeth.Data());
00650          if (method) clname = method->GetClass()->GetName();
00651          url += clname;
00652          url += ".html";
00653          url += "#";
00654          url += clname;
00655          url += ":";
00656          url += smeth.Data();
00657       }
00658       else {
00659          url += clname;
00660          url += ".html";
00661       }
00662       if (fDialog) delete fDialog;
00663       fDialog = 0;
00664       cmd = TString::Format("new TGHtmlBrowser(\"%s\", 0, 900, 300);", url.Data());
00665       gROOT->ProcessLine(cmd.Data());
00666    }
00667 }
00668 
00669 //______________________________________________________________________________
00670 Bool_t TRootContextMenu::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
00671 {
00672    // Handle context menu messages.
00673 
00674    TObjectSpy savedPad;
00675    if (GetContextMenu()->GetSelectedPad()) {
00676       savedPad.SetObject(gPad);
00677       gPad = GetContextMenu()->GetSelectedPad();
00678    }
00679 
00680    switch (GET_MSG(msg)) {
00681 
00682       case kC_COMMAND:
00683 
00684          switch (GET_SUBMSG(msg)) {
00685 
00686             case kCM_MENU:
00687 
00688                if (parm1 < kToggleStart) {
00689                   TMethod *m = (TMethod *) parm2;
00690                   GetContextMenu()->Action(m);
00691                } else if (parm1 >= kToggleStart && parm1 < kToggleListStart) {
00692                   TToggle *t = (TToggle *) parm2;
00693                   GetContextMenu()->Action(t);
00694                } else if (parm1 >= kToggleListStart && parm1<kUserFunctionStart) {
00695                   TToggle *t = (TToggle *) parm2;
00696                   if (t->GetState() == 0)
00697                      t->SetState(1);
00698                } else {
00699                   TClassMenuItem *mi = (TClassMenuItem*)parm2;
00700                   GetContextMenu()->Action(mi);
00701                }
00702                break;
00703 
00704             case kCM_BUTTON:
00705                if (parm1 == 1) {
00706                   const char *args = fDialog->GetParameters();
00707                   GetContextMenu()->Execute((char *)args);
00708                   delete fDialog;
00709                   fDialog = 0;
00710                }
00711                if (parm1 == 2) {
00712                   const char *args = fDialog->GetParameters();
00713                   GetContextMenu()->Execute((char *)args);
00714                }
00715                if (parm1 == 3) {
00716                   delete fDialog;
00717                   fDialog = 0;
00718                }
00719                if (parm1 == 4) {
00720                   OnlineHelp();
00721                }
00722                break;
00723 
00724             default:
00725                break;
00726          }
00727          break;
00728 
00729       case kC_TEXTENTRY:
00730 
00731          switch (GET_SUBMSG(msg)) {
00732 
00733             case kTE_ENTER:
00734                {
00735                   const char *args = fDialog->GetParameters();
00736                   GetContextMenu()->Execute((char *)args);
00737                   delete fDialog;
00738                   fDialog = 0;
00739                }
00740                break;
00741 
00742             default:
00743                break;
00744          }
00745          break;
00746 
00747       default:
00748          break;
00749    }
00750 
00751    if (savedPad.GetObject()) gPad = (TVirtualPad*) savedPad.GetObject();
00752 
00753    return kTRUE;
00754 }
00755 
00756 //______________________________________________________________________________
00757 void TRootContextMenu::RecursiveRemove(TObject *obj)
00758 {
00759    // Close the context menu if the object is deleted in the
00760    // RecursiveRemove() operation.
00761 
00762    void *ud;
00763    if (obj == fContextMenu->GetSelectedCanvas())
00764       fContextMenu->SetCanvas(0);
00765    if (obj == fContextMenu->GetSelectedPad())
00766       fContextMenu->SetPad(0);
00767    if (obj == fContextMenu->GetSelectedObject()) {
00768       // if the object being deleted is the one selected,
00769       // ungrab the mouse pointer and terminate (close) the menu
00770       fContextMenu->SetObject(0);
00771       if (fHasGrab) 
00772          gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
00773       EndMenu(ud);
00774    }
00775 }
00776 

Generated on Tue Jul 5 14:22:08 2011 for ROOT_528-00b_version by  doxygen 1.5.1