Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGedEditor.cxx
Go to the documentation of this file.
1 // @(#)root/ged:$Id$
2 // Author: Marek Biskup, Ilka Antcheva 02/08/2003
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 // //
15 // TGedEditor //
16 // //
17 // The main class of ROOT graphics editor. It manages the appearance //
18 // of objects editors according to the selected object in the canvas //
19 // (an object became selected after the user click on it using the //
20 // left-mouse button). //
21 // //
22 // Every object editor provides an object specific GUI and follows a //
23 // simple naming convention: it has as a name the object class name //
24 // concatinated with 'Editor' (e.g. for TGraph objects the object //
25 // editor is TGraphEditor). //
26 // //
27 // The ROOT graphics editor can be activated by selecting 'Editor' //
28 // from the View canvas menu, or SetLine/Fill/Text/MarkerAttributes //
29 // from the context menu. The algorithm in use is simple: according to //
30 // the selected object <obj> in the canvas it looks for a class name //
31 // <obj>Editor. If a class with this name exists, the editor verifies //
32 // that this class derives from the base editor class TGedFrame. //
33 // It makes an instance of the object editor, scans all object base //
34 // classes searching the corresponding object editors and makes an //
35 // instance of the base class editor too. Once the object editor is in //
36 // place, it sets the user interface elements according to the object //
37 // state and is ready for interactions. When a new object of a //
38 // different class is selected, a new object editor is loaded in the //
39 // editor frame. The old one is cached in memory for potential reuse. //
40 // //
41 // Any created canvas will be shown with the editor if you have a //
42 // .rootrc file in your working directory containing the the line: //
43 // Canvas.ShowEditor: true //
44 // //
45 // An created object can be set as selected in a macro by: //
46 // canvas->Selected(parent_pad_of_object, object, 1); //
47 // The first parameter can be the canvas itself or the pad containing //
48 // 'object'. //
49 // //
50 // Begin_Html //
51 /*
52 <img src="gif/TGedEditor.gif">
53 */
54 //End_Html
55 //////////////////////////////////////////////////////////////////////////
56 
57 #include "TGedEditor.h"
58 #include "TCanvas.h"
59 #include "TGCanvas.h"
60 #include "TGTab.h"
61 #include "TGedFrame.h"
62 #include "TGLabel.h"
63 #include "TROOT.h"
64 #include "TClass.h"
65 #include "TBaseClass.h"
66 
67 class TGedTabInfo : public TObject {
68  // Helper class for managing visibility and order of created tabs.
69 public:
70  TGTabElement *fElement;
71  TGCompositeFrame *fContainer;
72 
73  TGedTabInfo(TGTabElement* el, TGCompositeFrame* f) :
74  fElement(el), fContainer(f) {}
75 };
76 
77 
78 ClassImp(TGedEditor);
79 
80 TGedEditor* TGedEditor::fgFrameCreator = 0;
81 
82 ////////////////////////////////////////////////////////////////////////////////
83 /// Returns TGedEditor that currently creates TGedFrames.
84 
85 TGedEditor* TGedEditor::GetFrameCreator()
86 {
87  return fgFrameCreator;
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// Set the TGedEditor that currently creates TGedFrames.
92 
93 void TGedEditor::SetFrameCreator(TGedEditor* e)
94 {
95  fgFrameCreator = e;
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Constructor of graphics editor.
100 
101 TGedEditor::TGedEditor(TCanvas* canvas, UInt_t width, UInt_t height) :
102  TGMainFrame(gClient->GetRoot(), width, height),
103  fCan (0),
104  fTab (0),
105  fTabContainer (0),
106  fModel (0),
107  fPad (0),
108  fCanvas (0),
109  fClass (0),
110  fGlobal (kTRUE)
111 {
112  fCan = new TGCanvas(this, 170, 10, kFixedWidth);
113  AddFrame(fCan, new TGLayoutHints(kLHintsExpandY | kLHintsExpandX));
114 
115  fTab = new TGTab(fCan->GetViewPort(), 10, 10);
116  fTab->Associate(fCan);
117  fTab->SetCleanup(kDeepCleanup);
118  fCan->SetContainer(fTab);
119 
120  fTabContainer = GetEditorTab("Style");
121 
122  gROOT->GetListOfCleanups()->Add(this);
123 
124  SetCanvas(canvas);
125  if (fCanvas) {
126  UInt_t ch = fCanvas->GetWindowHeight();
127  if (ch)
128  Resize(GetWidth(), ch > 700 ? 700 : ch);
129  else
130  Resize(GetWidth(), fCanvas->GetWh()<450 ? 450 : fCanvas->GetWh() + 4);
131  } else {
132  Resize(width, height);
133  }
134 
135  MapSubwindows();
136  MapWindow();
137 }
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Editor destructor.
141 
142 TGedEditor::~TGedEditor()
143 {
144  Hide();
145 
146  if(fGlobal){
147  TQObject::Disconnect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)");
148  TQObject::Disconnect("TCanvas", "Closed()");
149  }
150 
151  // delete class editors
152  TIter next(fFrameMap.GetTable());
153  TPair* pair;
154  while ((pair = (TPair*) next())) {
155  if (pair->Value() != 0) {
156  TGedFrame* frame = (TGedFrame*) pair->Value();
157  delete frame;
158  }
159  }
160 
161  TGedTabInfo* ti;
162  TIter it1(&fCreatedTabs);
163  while ((ti = (TGedTabInfo*) it1())) {
164  fTab->AddFrame(ti->fElement,0);
165  fTab->AddFrame(ti->fContainer,0);
166  }
167 
168  delete fTab;
169  delete ((TGFrameElement*)fList->First())->fLayout;
170  delete fCan;
171 }
172 
173 ////////////////////////////////////////////////////////////////////////////////
174 /// Virtual method that is called on any change in the dependent frames.
175 /// This implementation simply calls fPad Modified()/Update().
176 
177 void TGedEditor::Update(TGedFrame* /*frame*/)
178 {
179  if (fPad) {
180  fPad->Modified();
181  fPad->Update();
182  }
183 }
184 
185 ////////////////////////////////////////////////////////////////////////////////
186 /// Find or create tab with name.
187 
188 TGCompositeFrame* TGedEditor::GetEditorTab(const char* name)
189 {
190  return GetEditorTabInfo(name)->fContainer;
191 }
192 
193 ////////////////////////////////////////////////////////////////////////////////
194 /// Find or create tab with name.
195 
196 TGedTabInfo* TGedEditor::GetEditorTabInfo(const char* name)
197 {
198  // look in list of created tabs
199  if ( ! fCreatedTabs.IsEmpty()) {
200  TIter next(&fCreatedTabs);
201  TGedTabInfo* ti;
202  while ((ti = (TGedTabInfo *) next())) {
203  if (*ti->fElement->GetText() == name)
204  return ti;
205  }
206  }
207 
208  // create tab
209  TGCompositeFrame* tc = fTab->AddTab(new TGString(name));
210 
211  // remove created frame end tab element from the fTab frame
212  TGTabElement *te = fTab->GetTabTab(fTab->GetNumberOfTabs() - 1);
213  fTab->RemoveFrame(tc);
214  fTab->RemoveFrame(te);
215 
216  // create a title frame for each tab
217  TGedFrame* nf = CreateNameFrame(tc, name);
218  if (nf) {
219  nf->SetGedEditor(this);
220  nf->SetModelClass(0);
221  tc->AddFrame(nf, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 2, 2, 2));
222  }
223  // add to list of created tabs
224  TGedTabInfo* ti = new TGedTabInfo(te, tc);
225  fCreatedTabs.Add(ti);
226 
227  return ti;
228 }
229 
230 ////////////////////////////////////////////////////////////////////////////////
231 /// Called when closed via WM close button. Calls Hide().
232 
233 void TGedEditor::CloseWindow()
234 {
235  Hide();
236 }
237 
238 ////////////////////////////////////////////////////////////////////////////////
239 /// Clears windows in editor tab.
240 /// Unmap and withdraw currently shown frames and thus prepare for
241 /// construction of a new class layout or destruction.
242 
243 void TGedEditor::ReinitWorkspace()
244 {
245  TIter next(&fVisibleTabs);
246  TGedTabInfo* ti;
247  while ((ti = (TGedTabInfo*)next())) {
248  TGTabElement *te = ti->fElement;
249  TGCompositeFrame *tc = ti->fContainer;
250 
251  fTab->RemoveFrame(te);
252  fTab->RemoveFrame(tc);
253 
254  TIter frames(tc->GetList());
255  frames(); // skip name-frame
256  TGFrameElement* fr;
257  while ((fr = (TGFrameElement *) frames()) != 0) {
258  TGFrame *f = fr->fFrame;
259  tc->RemoveFrame(f);
260  f->UnmapWindow();
261  te->UnmapWindow();
262  tc->UnmapWindow();
263  }
264  fVisibleTabs.Remove(ti);
265  }
266 }
267 
268 ////////////////////////////////////////////////////////////////////////////////
269 /// Set editor global.
270 
271 void TGedEditor::SetGlobal(Bool_t global)
272 {
273  fGlobal = global;
274  if (fGlobal) {
275  TQObject::Connect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)",
276  "TGedEditor", this, "GlobalSetModel(TVirtualPad *, TObject *, Int_t)");
277 
278  TQObject::Connect("TCanvas", "Closed()",
279  "TGedEditor", this, "GlobalClosed()");
280  }
281 }
282 
283 ////////////////////////////////////////////////////////////////////////////////
284 /// Delete global editor if no canvas exists.
285 
286 void TGedEditor::GlobalClosed()
287 {
288  if (gROOT->GetListOfCanvases()->IsEmpty())
289  TVirtualPadEditor::Terminate();
290 }
291 
292 ////////////////////////////////////////////////////////////////////////////////
293 /// Set canvas to global editor.
294 
295 void TGedEditor::GlobalSetModel(TVirtualPad *pad, TObject * obj, Int_t ev)
296 {
297  if ((ev != kButton1Down) || !IsMapped() ||
298  (obj && obj->InheritsFrom("TColorWheel")))
299  return;
300 
301  TCanvas* can = pad->GetCanvas();
302  // Do nothing if canvas is the same as before or
303  // local editor of the canvas is active.
304  if (!can || (can == fCanvas || can->GetShowEditor()))
305  return;
306 
307  Show();
308 }
309 
310 ////////////////////////////////////////////////////////////////////////////////
311 /// Connect this editor to the Selected signal of canvas 'c'.
312 
313 void TGedEditor::ConnectToCanvas(TCanvas *c)
314 {
315  c->Connect("Selected(TVirtualPad*,TObject*,Int_t)", "TGedEditor",
316  this, "SetModel(TVirtualPad*,TObject*,Int_t)");
317 }
318 
319 ////////////////////////////////////////////////////////////////////////////////
320 /// Disconnect this editor from the Selected signal of fCanvas.
321 
322 void TGedEditor::DisconnectFromCanvas()
323 {
324  if (fCanvas)
325  Disconnect(fCanvas, "Selected(TVirtualPad*,TObject*,Int_t)", this, "SetModel(TVirtualPad*,TObject*,Int_t)");
326 }
327 
328 ////////////////////////////////////////////////////////////////////////////////
329 /// Change connection to another canvas.
330 
331 void TGedEditor::SetCanvas(TCanvas *newcan)
332 {
333  if (fCanvas == newcan) return;
334 
335  DisconnectFromCanvas();
336  fCanvas = newcan;
337 
338  if (!newcan) return;
339 
340  SetWindowName(Form("%s_Editor", fCanvas->GetName()));
341  fPad = fCanvas->GetSelectedPad();
342  if (fPad == 0) fPad = fCanvas;
343  ConnectToCanvas(fCanvas);
344 }
345 
346 ////////////////////////////////////////////////////////////////////////////////
347 /// Activate object editors according to the selected object.
348 
349 void TGedEditor::SetModel(TVirtualPad* pad, TObject* obj, Int_t event, Bool_t force)
350 {
351  if ((event != kButton1Down) || (obj && obj->InheritsFrom("TColorWheel")))
352  return;
353 
354  if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kWatch);
355  gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kWatch));
356 
357  fPad = pad;
358  if (obj == 0) obj = fPad;
359 
360  // keep selected by name
361  TGTabElement* seltab = fTab->GetCurrentTab();
362 
363  Bool_t mapTabs = kFALSE;
364  if (fModel != obj || force) {
365  fModel = obj;
366  if (fModel == 0 || fModel->IsA() != fClass) {
367  ReinitWorkspace();
368  mapTabs = kTRUE;
369  // add Sytle tab to list of visible tabs
370  fVisibleTabs.Add(fCreatedTabs.First());
371  if (fModel) {
372  fClass = fModel->IsA();
373  // build a list of editors
374  ActivateEditor(fClass, kTRUE);
375  } else {
376  fClass = 0;
377  }
378 
379  // add class editors to fTabContainer
380  TGedFrame* gfr;
381  TIter ngf(&fGedFrames);
382  while ((gfr = (TGedFrame*) ngf()))
383  fTabContainer->AddFrame(gfr, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 2, 2, 2));
384 
385  fExclMap.Clear();
386  fGedFrames.Clear();
387 
388  // add visible tabs in fTab
389  TIter next(&fVisibleTabs);
390  TGedTabInfo* ti;
391  while ((ti = (TGedTabInfo *) next())) {
392  fTab->AddFrame(ti->fElement,0);
393  fTab->AddFrame(ti->fContainer,0);
394  }
395  }
396  ConfigureGedFrames(kTRUE);
397  } else {
398  ConfigureGedFrames(kFALSE);
399  } // end fModel != obj
400 
401  if (mapTabs) { // selected object is different class
402  TGedTabInfo* ti;
403  TIter next(&fVisibleTabs);
404  while ((ti = (TGedTabInfo *) next())) {
405  ti->fElement->MapWindow();
406  ti->fContainer->MapWindow();
407  }
408  if (seltab == 0 || fTab->SetTab(seltab->GetString(), kFALSE) == kFALSE)
409  fTab->SetTab(0, kFALSE);
410  }
411 
412  if (fGlobal)
413  Layout();
414  else
415  ((TGMainFrame*)GetMainFrame())->Layout();
416 
417  if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kPointer);
418  gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kPointer));
419 }
420 
421 ////////////////////////////////////////////////////////////////////////////////
422 /// Show editor.
423 
424 void TGedEditor::Show()
425 {
426  // gPad is setup properly in calling code for global and canvas editor.
427  if (gPad) SetCanvas(gPad->GetCanvas());
428 
429  if (fCanvas && fGlobal) {
430  SetModel(fCanvas->GetClickSelectedPad(), fCanvas->GetClickSelected(), kButton1Down);
431 
432  if (fCanvas->GetShowEditor())
433  fCanvas->ToggleEditor();
434 
435  UInt_t dw = fClient->GetDisplayWidth();
436  UInt_t cw = fCanvas->GetWindowWidth();
437  UInt_t ch = fCanvas->GetWindowHeight();
438  UInt_t cx = (UInt_t)fCanvas->GetWindowTopX();
439  UInt_t cy = (UInt_t)fCanvas->GetWindowTopY();
440  if (!ch)
441  cy = cy + 20; // embeded canvas protection
442 
443  Int_t gedx = 0, gedy = 0;
444 
445  if (cw + GetWidth() > dw) {
446  gedx = cx + cw - GetWidth();
447  gedy = ch - GetHeight();
448  } else {
449  if (cx > GetWidth())
450  gedx = cx - GetWidth() - 20;
451  else
452  gedx = cx + cw + 10;
453  gedy = cy - 20;
454  }
455  MoveResize(gedx, gedy, GetWidth(), ch > 700 ? 700 : ch);
456  SetWMPosition(gedx, gedy);
457  } else if (fCanvas) {
458  SetModel(fCanvas, fCanvas, kButton1Down);
459  }
460  MapWindow();
461  gVirtualX->RaiseWindow(GetId());
462 
463  if (!gROOT->GetListOfCleanups()->FindObject(this))
464  gROOT->GetListOfCleanups()->Add(this);
465 }
466 
467 ////////////////////////////////////////////////////////////////////////////////
468 /// Hide editor. The editor is put into non-active state.
469 
470 void TGedEditor::Hide()
471 {
472  UnmapWindow();
473  ReinitWorkspace();
474  fModel = 0; fClass = 0;
475  DisconnectFromCanvas();
476  fCanvas = 0; fPad = 0;
477  gROOT->GetListOfCleanups()->Remove(this);
478 }
479 
480 ////////////////////////////////////////////////////////////////////////////////
481 /// Remove references to fModel in case the fModel is being deleted.
482 /// Deactivate attribute frames if they point to obj.
483 
484 void TGedEditor::RecursiveRemove(TObject* obj)
485 {
486  if (obj == fPad) {
487  // printf("TGedEditor::RecursiveRemove: %s - pad deleted.\n", locglob);
488  SetModel(fCanvas, fCanvas, kButton1Down);
489  return;
490  }
491 
492  if (obj == fModel) {
493  // printf("TGedEditor::RecursiveRemove: %s - model deleted.\n", locglob);
494  SetModel(fPad, fPad, kButton1Down);
495  return;
496  }
497 }
498 
499 ////////////////////////////////////////////////////////////////////////////////
500 /// Searches for GedFrames for given class. In recursive mode look for class
501 /// editor in its list of bases.
502 
503 void TGedEditor::ActivateEditor(TClass* cl, Bool_t recurse)
504 {
505  TPair *pair = (TPair*) fFrameMap.FindObject(cl);
506  TClass *edClass = 0;
507  TGedFrame *frame = 0;
508 
509  if (pair == 0) {
510  edClass = TClass::GetClass(Form("%sEditor", cl->GetName()));
511 
512  if (edClass && edClass->InheritsFrom(TGedFrame::Class())) {
513  TGWindow *exroot = (TGWindow*) fClient->GetRoot();
514  fClient->SetRoot(fTabContainer);
515  fgFrameCreator = this;
516  frame = reinterpret_cast<TGedFrame*>(edClass->New());
517  frame->SetModelClass(cl);
518  fgFrameCreator = 0;
519  fClient->SetRoot(exroot);
520  }
521  fFrameMap.Add(cl, frame);
522  } else {
523  frame = (TGedFrame*)pair->Value();
524  }
525 
526  Bool_t exclfr = kFALSE;
527  Bool_t exclbases = kFALSE;
528 
529  if (frame) {
530  TPair* exclpair = (TPair*) fExclMap.FindObject(cl);
531  if (exclpair) {
532  exclfr = kTRUE;
533  exclbases = (exclpair->Value() != 0);
534  }
535 
536  if (!exclfr && frame->AcceptModel(fModel)){
537  // handle extra tabs in the gedframe
538  if (frame->GetExtraTabs()) {
539  TIter next(frame->GetExtraTabs());
540  TGedFrame::TGedSubFrame* subf;
541  while ((subf = (TGedFrame::TGedSubFrame*)next())) {
542  // locate the composite frame on created tabs
543  TGedTabInfo* ti = GetEditorTabInfo(subf->fName);
544  ti->fContainer->AddFrame(subf->fFrame, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
545  if (fVisibleTabs.FindObject(ti) == 0)
546  fVisibleTabs.Add(ti);
547  }
548  }
549  InsertGedFrame(frame);
550  }
551  }
552 
553  if (recurse && !exclbases) {
554  if (frame)
555  frame->ActivateBaseClassEditors(cl);
556  else
557  ActivateEditors(cl->GetListOfBases(), recurse);
558  }
559 }
560 
561 ////////////////////////////////////////////////////////////////////////////////
562 /// Searches GedFrames for classes in the given list.
563 
564 void TGedEditor::ActivateEditors(TList* bcl, Bool_t recurse)
565 {
566  TBaseClass *base;
567  TIter next(bcl);
568 
569  while ((base = (TBaseClass*) next())) {
570  ActivateEditor(base->GetClassPointer(), recurse);
571  }
572 }
573 
574 ////////////////////////////////////////////////////////////////////////////////
575 /// Exclude editor for class cl from current construction.
576 /// If recurse is true the base-class editors of cl are also excluded.
577 
578 void TGedEditor::ExcludeClassEditor(TClass* cl, Bool_t recurse)
579 {
580  TPair* pair = (TPair*) fExclMap.FindObject(cl);
581  if (pair) {
582  if (recurse && pair->Value() == 0)
583  pair->SetValue((TObject*)(Long_t)1); // hack, reuse TObject as Bool_t
584  } else {
585  fExclMap.Add(cl, (TObject*)(Long_t)(recurse ? 1 : 0));
586  }
587 }
588 
589 ////////////////////////////////////////////////////////////////////////////////
590 /// Insert GedFrame in fGedFrames list according to priorities.
591 
592 void TGedEditor::InsertGedFrame(TGedFrame* f)
593 {
594  // printf("%s %s insert gedframe %s \n", fModel->GetName(), fModel->IsA()->GetName(),f->GetModelClass()->GetName());
595  TObjLink* lnk = fGedFrames.FirstLink();
596  if (lnk == 0) {
597  fGedFrames.Add(f);
598  return;
599  }
600  TGedFrame* cf;
601  while (lnk) {
602  cf = (TGedFrame*) lnk->GetObject();
603  if (f->GetPriority() < cf->GetPriority()) {
604  fGedFrames.AddBefore(lnk, f);
605  return;
606  }
607  lnk = lnk->Next();
608  }
609  fGedFrames.Add(f);
610 }
611 
612 ////////////////////////////////////////////////////////////////////////////////
613 /// Call SetModel in class editors.
614 
615 void TGedEditor::ConfigureGedFrames(Bool_t objChanged)
616 {
617  TGFrameElement *el;
618 
619  // Call SetModel on TGedNameFrames (first in the container list)
620  // and map extra-tabs.
621  TIter vistabs(&fVisibleTabs);
622  vistabs(); // skip Style tab
623  TGedTabInfo* ti;
624  while ((ti = (TGedTabInfo *) vistabs())) {
625  TIter fr(ti->fContainer->GetList());
626  el = (TGFrameElement*) fr();
627  if (el) {
628  ((TGedFrame*) el->fFrame)->SetModel(fModel);
629  if (objChanged) {
630  do {
631  el->fFrame->MapSubwindows();
632  el->fFrame->Layout();
633  el->fFrame->MapWindow();
634  } while((el = (TGFrameElement *) fr()));
635  }
636  }
637  ti->fContainer->Layout();
638  }
639 
640  TIter next(fTabContainer->GetList());
641  while ((el = (TGFrameElement *) next())) {
642  if ((el->fFrame)->InheritsFrom(TGedFrame::Class())) {
643  if (objChanged) {
644  el->fFrame->MapSubwindows();
645  ((TGedFrame *)(el->fFrame))->SetModel(fModel);
646  el->fFrame->Layout();
647  el->fFrame->MapWindow();
648  } else {
649  ((TGedFrame *)(el->fFrame))->SetModel(fModel);
650  }
651  }
652  }
653  fTabContainer->Layout();
654 }
655 
656 ////////////////////////////////////////////////////////////////////////////////
657 /// Virtual function for creation of top name-frame in each tab.
658 
659 TGedFrame* TGedEditor::CreateNameFrame(const TGWindow* parent, const char* /*tab_name*/)
660 {
661  return new TGedNameFrame(parent);
662 }
663 
664 ////////////////////////////////////////////////////////////////////////////////
665 /// Print contents of fFrameMap.
666 
667 void TGedEditor::PrintFrameStat()
668 {
669  printf("TGedEditor::PrintFrameStat()\n");
670  Int_t sum = 0;
671  TIter next(fFrameMap.GetTable());
672  TPair* pair;
673  while ((pair = (TPair*) next())) {
674  if (pair->Value() != 0) {
675  TClass* cl = (TClass*) pair->Key();
676  printf("TGedFrame created for %s \n", cl->GetName());
677  sum ++;
678  }
679  }
680  printf("SUMMARY: %d editors stored in the local map.\n", sum);
681 }