00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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,
00054 kToggleListStart = 2000,
00055 kUserFunctionStart = 3000
00056 };
00057
00058
00059 ClassImp(TRootContextMenu)
00060
00061
00062 TRootContextMenu::TRootContextMenu(TContextMenu *c, const char *)
00063 : TGPopupMenu(gClient->GetDefaultRoot()), TContextMenuImp(c)
00064 {
00065
00066
00067 fDialog = 0;
00068 fTrash = new TList;
00069
00070 gROOT->GetListOfCleanups()->Add(this);
00071
00072 Associate(this);
00073 }
00074
00075
00076 TRootContextMenu::~TRootContextMenu()
00077 {
00078
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
00090
00091 if (fClient->IsEditable()) return;
00092
00093
00094 if (fEntryList) fEntryList->Delete();
00095 fCurrent = 0;
00096 if (fTrash) fTrash->Delete();
00097 fMenuHeight = 6;
00098 fMenuWidth = 8;
00099
00100
00101 if (fDialog) {
00102 delete fDialog;
00103 fDialog = 0;
00104 }
00105
00106
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
00121 fMenuWidth += 5;
00122 Resize(GetDefaultWidth()+5, GetDefaultHeight());
00123 }
00124
00125
00126 TGPopupMenu * TRootContextMenu::FindHierarchy(const char *commentstring, TString & last_component)
00127 {
00128
00129
00130
00131
00132 TString cmd(commentstring);
00133 TString option;
00134 TString hierarchy;
00135 TGPopupMenu *currentMenu = 0;
00136
00137
00138
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
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
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
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
00184 TGMenuEntry *ptr2;
00185 TIter next2(currentMenu->GetListOfEntries());
00186
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
00208
00209 TGMenuEntry *ptr2 = 0;
00210 if (sorted) {
00211 TIter next(currentMenu->GetListOfEntries());
00212
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
00224
00225 if (!object || fClient->IsEditable()) return;
00226
00227 int entry = 0, toggle = kToggleStart, togglelist = kToggleListStart;
00228 int userfunction = kUserFunctionStart;
00229
00230
00231 AddLabel(fContextMenu->CreatePopupTitle(object));
00232 AddSeparator();
00233
00234
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
00252
00253
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
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
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
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
00379
00380
00381 Dialog(object,(TFunction*)method);
00382 }
00383
00384
00385 void TRootContextMenu::Dialog(TObject *object, TFunction *function)
00386 {
00387
00388
00389
00390
00391 Int_t selfobjpos;
00392
00393 if (!function) return;
00394
00395
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
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
00419
00420 TMethodArg *argument = 0;
00421
00422 TIter next(function->GetListOfMethodArgs());
00423 Int_t argpos = 0;
00424
00425 while ((argument = (TMethodArg *) next())) {
00426
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
00449
00450 argpos++;
00451 continue;
00452 }
00453 }
00454
00455 TDataMember *m = argument->GetDataMember();
00456 if (m && object && m->GetterMethod(object->IsA())) {
00457
00458
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
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
00506 fDialog->Add(argname, val, type);
00507 }
00508 } else {
00509
00510 char val[256] = "";
00511 const char *tval = argument->GetDefault();
00512 if (tval && strlen(tval)) {
00513
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
00531
00532 int ty, offset;
00533 static int max_ascent = 0, max_descent = 0;
00534
00535 TGPopupMenu::DrawEntry(entry);
00536
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
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);
00559 if (ud) {
00560
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
00586
00587 if (event->fType == kLeaveNotify) {
00588
00589 HandleMotion(event);
00590 }
00591 return TGPopupMenu::HandleCrossing(event);
00592 }
00593
00594
00595 Bool_t TRootContextMenu::HandleMotion(Event_t *event)
00596 {
00597
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
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
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
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
00760
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
00769
00770 fContextMenu->SetObject(0);
00771 if (fHasGrab)
00772 gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
00773 EndMenu(ud);
00774 }
00775 }
00776