Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGFrame.cxx
Go to the documentation of this file.
1 // @(#)root/gui:$Id$
2 // Author: Fons Rademakers 03/01/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  This source is based on Xclass95, a Win95-looking GUI toolkit.
14  Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
15 
16  Xclass95 is free software; you can redistribute it and/or
17  modify it under the terms of the GNU Library General Public
18  License as published by the Free Software Foundation; either
19  version 2 of the License, or (at your option) any later version.
20 
21 **************************************************************************/
22 
23 //////////////////////////////////////////////////////////////////////////
24 // //
25 // TGFrame, TGCompositeFrame, TGVerticalFrame, TGHorizontalFrame, //
26 // TGMainFrame, TGTransientFrame and TGGroupFrame //
27 // //
28 // The frame classes describe the different "dressed" GUI windows. //
29 // //
30 // The TGFrame class is a subclasses of TGWindow, and is used as base //
31 // class for some simple widgets (buttons, labels, etc.). //
32 // It provides: //
33 // - position & dimension fields //
34 // - an 'options' attribute (see constant above) //
35 // - a generic event handler //
36 // - a generic layout mechanism //
37 // - a generic border //
38 // //
39 // The TGCompositeFrame class is the base class for composite widgets //
40 // (menu bars, list boxes, etc.). //
41 // It provides: //
42 // - a layout manager //
43 // - a frame container (TList *) //
44 // //
45 // The TGVerticalFrame and TGHorizontalFrame are composite frame that //
46 // layout their children in vertical or horizontal way. //
47 // //
48 // The TGMainFrame class defines top level windows that interact with //
49 // the system Window Manager. //
50 // //
51 // The TGTransientFrame class defines transient windows that typically //
52 // are used for dialogs windows. //
53 // //
54 // The TGGroupFrame is a composite frame with a border and a title. //
55 // It is typically used to group a number of logically related widgets //
56 // visually together. //
57 // //
58 //Begin_Html
59 /*
60 <img src="gif/tgcompositeframe_classtree.gif">
61 */
62 //End_Html
63 //////////////////////////////////////////////////////////////////////////
64 
65 #include "TError.h"
66 #include "TGFrame.h"
67 #include "TGResourcePool.h"
68 #include "TGPicture.h"
69 #include "TList.h"
70 #include "TApplication.h"
71 #include "TTimer.h"
72 #include "Riostream.h"
73 #include "TClass.h"
74 
75 #include "TObjString.h"
76 #include "TObjArray.h"
77 #include "TBits.h"
78 #include "TColor.h"
79 #include "TROOT.h"
80 #include "KeySymbols.h"
81 #include "TGFileDialog.h"
82 #include "TGMsgBox.h"
83 #include "TSystem.h"
84 #include "TVirtualDragManager.h"
85 #include "TGuiBuilder.h"
86 #include "TQConnection.h"
87 #include "TGButton.h"
88 #include "TGSplitter.h"
89 #include "TGDNDManager.h"
90 #include "TImage.h"
91 #include "TObjectSpy.h"
92 
93 
94 Bool_t TGFrame::fgInit = kFALSE;
95 Pixel_t TGFrame::fgDefaultFrameBackground = 0;
96 Pixel_t TGFrame::fgDefaultSelectedBackground = 0;
97 Pixel_t TGFrame::fgWhitePixel = 0;
98 Pixel_t TGFrame::fgBlackPixel = 0;
99 const TGGC *TGFrame::fgBlackGC = 0;
100 const TGGC *TGFrame::fgWhiteGC = 0;
101 const TGGC *TGFrame::fgHilightGC = 0;
102 const TGGC *TGFrame::fgShadowGC = 0;
103 const TGGC *TGFrame::fgBckgndGC = 0;
104 Time_t TGFrame::fgLastClick = 0;
105 UInt_t TGFrame::fgLastButton = 0;
106 Int_t TGFrame::fgDbx = 0;
107 Int_t TGFrame::fgDby = 0;
108 Window_t TGFrame::fgDbw = 0;
109 UInt_t TGFrame::fgUserColor = 0;
110 
111 const TGFont *TGGroupFrame::fgDefaultFont = 0;
112 const TGGC *TGGroupFrame::fgDefaultGC = 0;
113 
114 TGLayoutHints *TGCompositeFrame::fgDefaultHints = 0;
115 
116 static const char *gSaveMacroTypes[] = {
117  "ROOT macros", "*.C",
118  "GIF", "*.gif",
119  "PNG", "*.png",
120  "JPEG", "*.jpg",
121  "TIFF", "*.tiff",
122  "XPM", "*.xpm",
123  "All files", "*",
124  0, 0
125 };
126 
127 TList *gListOfHiddenFrames = new TList();
128 
129 ClassImp(TGFrame);
130 ClassImp(TGCompositeFrame);
131 ClassImp(TGVerticalFrame);
132 ClassImp(TGHorizontalFrame);
133 ClassImp(TGMainFrame);
134 ClassImp(TGTransientFrame);
135 ClassImp(TGGroupFrame);
136 ClassImp(TGHeaderFrame);
137 
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Create a TGFrame object. Options is an OR of the EFrameTypes.
141 
142 TGFrame::TGFrame(const TGWindow *p, UInt_t w, UInt_t h,
143  UInt_t options, Pixel_t back)
144  : TGWindow(p, 0, 0, w, h, 0, 0, 0, 0, 0, options)
145 {
146  if (!fgInit && gClient) {
147  TGFrame::GetDefaultFrameBackground();
148  TGFrame::GetDefaultSelectedBackground();
149  TGFrame::GetWhitePixel();
150  TGFrame::GetBlackPixel();
151  TGFrame::GetBlackGC();
152  TGFrame::GetWhiteGC();
153  TGFrame::GetHilightGC();
154  TGFrame::GetShadowGC();
155  TGFrame::GetBckgndGC();
156  fgInit = kTRUE;
157  }
158 
159  SetWindowAttributes_t wattr;
160 
161  fDNDState = 0;
162  fBackground = back;
163  fOptions = options;
164  fWidth = w; fHeight = h; fX = fY = fBorderWidth = 0;
165  fMinWidth = 0;
166  fMinHeight = 0;
167  fMaxWidth = kMaxUInt;
168  fMaxHeight = kMaxUInt;
169  fFE = 0;
170 
171  if (fOptions & (kSunkenFrame | kRaisedFrame))
172  fBorderWidth = (gClient->GetStyle() > 1) ? 1 : (fOptions & kDoubleBorder) ? 2 : 1;
173 
174  wattr.fMask = kWABackPixel | kWAEventMask;
175  wattr.fBackgroundPixel = back;
176  wattr.fEventMask = kExposureMask;
177  if (fOptions & kMainFrame) {
178  wattr.fEventMask |= kStructureNotifyMask;
179  gVirtualX->ChangeWindowAttributes(fId, &wattr);
180  //if (fgDefaultBackgroundPicture)
181  // SetBackgroundPixmap(fgDefaultBackgroundPicture->GetPicture());
182  } else {
183  gVirtualX->ChangeWindowAttributes(fId, &wattr);
184  //if (!(fOptions & kOwnBackground))
185  // SetBackgroundPixmap(kParentRelative);
186  }
187  fEventMask = (UInt_t) wattr.fEventMask;
188 
189  if ((fOptions & kDoubleBorder) && (gClient->GetStyle() > 1))
190  ChangeOptions(fOptions ^ kDoubleBorder);
191 
192  SetWindowName();
193 }
194 
195 ////////////////////////////////////////////////////////////////////////////////
196 /// Create a frame using an externally created window. For example
197 /// to register the root window (called by TGClient), or a window
198 /// created via TVirtualX::InitWindow() (id is obtained with
199 /// TVirtualX::GetWindowID()).
200 
201 TGFrame::TGFrame(TGClient *c, Window_t id, const TGWindow *parent)
202  : TGWindow(c, id, parent)
203 {
204  if (!fgInit && gClient) {
205  TGFrame::GetDefaultFrameBackground();
206  TGFrame::GetDefaultSelectedBackground();
207  TGFrame::GetWhitePixel();
208  TGFrame::GetBlackPixel();
209  TGFrame::GetBlackGC();
210  TGFrame::GetWhiteGC();
211  TGFrame::GetHilightGC();
212  TGFrame::GetShadowGC();
213  TGFrame::GetBckgndGC();
214  fgInit = kTRUE;
215  }
216 
217  WindowAttributes_t attributes;
218  // Initialize some values - needed for batch mode!
219  attributes.fX = 0;
220  attributes.fY = 0;
221  attributes.fWidth = 100;
222  attributes.fHeight = 100;
223  attributes.fBorderWidth = 4;
224  attributes.fYourEventMask = 0;
225  gVirtualX->GetWindowAttributes(id, attributes);
226 
227  fDNDState = 0;
228  fX = attributes.fX;
229  fY = attributes.fY;
230  fWidth = attributes.fWidth;
231  fHeight = attributes.fHeight;
232  fBorderWidth = attributes.fBorderWidth;
233  fEventMask = (UInt_t) attributes.fYourEventMask;
234  fBackground = 0;
235  fOptions = 0;
236  fMinWidth = 0;
237  fMinHeight = 0;
238  fMaxWidth = kMaxUInt;
239  fMaxHeight = kMaxUInt;
240  fFE = 0;
241 
242  SetWindowName();
243 }
244 
245 ////////////////////////////////////////////////////////////////////////////////
246 /// Destructor.
247 
248 TGFrame::~TGFrame()
249 {
250 }
251 
252 ////////////////////////////////////////////////////////////////////////////////
253 /// Delete window. Use single shot timer to call final delete method.
254 /// We use this indirect way since deleting the window in its own
255 /// execution "thread" can cause side effects because frame methods
256 /// can still be called while the window object has already been deleted.
257 
258 void TGFrame::DeleteWindow()
259 {
260  if (gDNDManager) {
261  if (gDNDManager->GetMainFrame() == this)
262  gDNDManager->SetMainFrame(0);
263  }
264  if (!TestBit(kDeleteWindowCalled)) {
265  // coverity[returned_null]
266  // coverity[dereference]
267  TTimer::SingleShot(150, IsA()->GetName(), this, "ReallyDelete()");
268  }
269  SetBit(kDeleteWindowCalled);
270 }
271 
272 ////////////////////////////////////////////////////////////////////////////////
273 /// Change frame background color.
274 
275 void TGFrame::ChangeBackground(Pixel_t back)
276 {
277  fBackground = back;
278  gVirtualX->SetWindowBackground(fId, back);
279  fClient->NeedRedraw(this);
280 }
281 
282 ////////////////////////////////////////////////////////////////////////////////
283 /// Return frame foreground color.
284 
285 Pixel_t TGFrame::GetForeground() const
286 {
287  return fgBlackPixel;
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Set background color (override from TGWindow base class).
292 /// Same effect as ChangeBackground().
293 
294 void TGFrame::SetBackgroundColor(Pixel_t back)
295 {
296  fBackground = back;
297  TGWindow::SetBackgroundColor(back);
298 }
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 /// Change frame options. Options is an OR of the EFrameTypes.
302 
303 void TGFrame::ChangeOptions(UInt_t options)
304 {
305  if ((options & (kDoubleBorder | kSunkenFrame | kRaisedFrame)) !=
306  (fOptions & (kDoubleBorder | kSunkenFrame | kRaisedFrame))) {
307  if (!InheritsFrom(TGGroupFrame::Class())) {
308  if (options & (kSunkenFrame | kRaisedFrame))
309  fBorderWidth = (gClient->GetStyle() > 1) ? 1 : (fOptions & kDoubleBorder) ? 2 : 1;
310  else
311  fBorderWidth = 0;
312  }
313  }
314 
315  fOptions = options;
316 }
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 /// Add events specified in the emask to the events the frame should handle.
320 
321 void TGFrame::AddInput(UInt_t emask)
322 {
323  fEventMask |= emask;
324  gVirtualX->SelectInput(fId, fEventMask);
325 }
326 
327 ////////////////////////////////////////////////////////////////////////////////
328 /// Remove events specified in emask from the events the frame should handle.
329 
330 void TGFrame::RemoveInput(UInt_t emask)
331 {
332  fEventMask &= ~emask;
333  gVirtualX->SelectInput(fId, fEventMask);
334 }
335 
336 ////////////////////////////////////////////////////////////////////////////////
337 /// Draw 3D rectangle on the frame border.
338 
339 void TGFrame::Draw3dRectangle(UInt_t type, Int_t x, Int_t y,
340  UInt_t w, UInt_t h)
341 {
342  switch (type) {
343  case kSunkenFrame:
344  gVirtualX->DrawLine(fId, GetShadowGC()(), x, y, x+w-2, y);
345  gVirtualX->DrawLine(fId, GetShadowGC()(), x, y, x, y+h-2);
346  gVirtualX->DrawLine(fId, GetHilightGC()(), x, y+h-1, x+w-1, y+h-1);
347  gVirtualX->DrawLine(fId, GetHilightGC()(), x+w-1, y+h-1, x+w-1, y);
348  break;
349 
350  case kSunkenFrame | kDoubleBorder:
351  if (gClient->GetStyle() < 2) {
352  gVirtualX->DrawLine(fId, GetShadowGC()(), x, y, x+w-2, y);
353  gVirtualX->DrawLine(fId, GetShadowGC()(), x, y, x, y+h-2);
354  gVirtualX->DrawLine(fId, GetBlackGC()(), x+1, y+1, x+w-3, y+1);
355  gVirtualX->DrawLine(fId, GetBlackGC()(), x+1, y+1, x+1, y+h-3);
356  gVirtualX->DrawLine(fId, GetHilightGC()(), x, y+h-1, x+w-1, y+h-1);
357  gVirtualX->DrawLine(fId, GetHilightGC()(), x+w-1, y+h-1, x+w-1, y);
358  gVirtualX->DrawLine(fId, GetBckgndGC()(), x+1, y+h-2, x+w-2, y+h-2);
359  gVirtualX->DrawLine(fId, GetBckgndGC()(), x+w-2, y+1, x+w-2, y+h-2);
360  }
361  else {
362  gVirtualX->DrawLine(fId, GetShadowGC()(), x, y, x+w-2, y);
363  gVirtualX->DrawLine(fId, GetShadowGC()(), x, y, x, y+h-2);
364  gVirtualX->DrawLine(fId, GetHilightGC()(), x, y+h-1, x+w-1, y+h-1);
365  gVirtualX->DrawLine(fId, GetHilightGC()(), x+w-1, y+h-1, x+w-1, y);
366  }
367  break;
368 
369  case kRaisedFrame:
370  gVirtualX->DrawLine(fId, GetHilightGC()(), x, y, x+w-2, y);
371  gVirtualX->DrawLine(fId, GetHilightGC()(), x, y, x, y+h-2);
372  gVirtualX->DrawLine(fId, GetShadowGC()(), x, y+h-1, x+w-1, y+h-1);
373  gVirtualX->DrawLine(fId, GetShadowGC()(), x+w-1, y+h-1, x+w-1, y);
374  break;
375 
376  case kRaisedFrame | kDoubleBorder:
377  if (gClient->GetStyle() < 2) {
378  gVirtualX->DrawLine(fId, GetHilightGC()(), x, y, x+w-2, y);
379  gVirtualX->DrawLine(fId, GetHilightGC()(), x, y, x, y+h-2);
380  gVirtualX->DrawLine(fId, GetBckgndGC()(), x+1, y+1, x+w-3, y+1);
381  gVirtualX->DrawLine(fId, GetBckgndGC()(), x+1, y+1, x+1, y+h-3);
382  gVirtualX->DrawLine(fId, GetShadowGC()(), x+1, y+h-2, x+w-2, y+h-2);
383  gVirtualX->DrawLine(fId, GetShadowGC()(), x+w-2, y+h-2, x+w-2, y+1);
384  gVirtualX->DrawLine(fId, GetBlackGC()(), x, y+h-1, x+w-1, y+h-1);
385  gVirtualX->DrawLine(fId, GetBlackGC()(), x+w-1, y+h-1, x+w-1, y);
386  }
387  else {
388  gVirtualX->DrawLine(fId, GetHilightGC()(), x, y, x+w-2, y);
389  gVirtualX->DrawLine(fId, GetHilightGC()(), x, y, x, y+h-2);
390  gVirtualX->DrawLine(fId, GetShadowGC()(), x, y+h-1, x+w-1, y+h-1);
391  gVirtualX->DrawLine(fId, GetShadowGC()(), x+w-1, y+h-1, x+w-1, y);
392  }
393  break;
394 
395  default:
396  break;
397  }
398 }
399 
400 ////////////////////////////////////////////////////////////////////////////////
401 /// Draw frame border.
402 
403 void TGFrame::DrawBorder()
404 {
405  Draw3dRectangle(fOptions & (kSunkenFrame | kRaisedFrame | kDoubleBorder),
406  0, 0, fWidth, fHeight);
407 }
408 
409 ////////////////////////////////////////////////////////////////////////////////
410 /// Redraw the frame.
411 
412 void TGFrame::DoRedraw()
413 {
414  gVirtualX->ClearArea(fId, fBorderWidth, fBorderWidth,
415  fWidth - (fBorderWidth << 1), fHeight - (fBorderWidth << 1));
416 
417  // border will only be drawn if we have a 3D option hint
418  // (kRaisedFrame or kSunkenFrame)
419  DrawBorder();
420 }
421 
422 ////////////////////////////////////////////////////////////////////////////////
423 /// This event is generated when the frame is resized.
424 
425 Bool_t TGFrame::HandleConfigureNotify(Event_t *event)
426 {
427  if ((event->fWidth != fWidth) || (event->fHeight != fHeight)) {
428  fWidth = event->fWidth;
429  fHeight = event->fHeight;
430  Layout();
431  }
432  return kTRUE;
433 }
434 
435 ////////////////////////////////////////////////////////////////////////////////
436 /// Handle all frame events. Events are dispatched to the specific
437 /// event handlers.
438 
439 Bool_t TGFrame::HandleEvent(Event_t *event)
440 {
441  if (gDragManager && !fClient->IsEditDisabled() &&
442  gDragManager->HandleEvent(event)) return kTRUE;
443 
444  TObjectSpy deleteCheck(this);
445 
446  switch (event->fType) {
447 
448  case kExpose:
449  HandleExpose(event);
450  break;
451 
452  case kConfigureNotify:
453  while (gVirtualX->CheckEvent(fId, kConfigureNotify, *event))
454  ;
455  // protection
456  if ((event->fWidth < 32768) && (event->fHeight < 32768)){
457  ProcessedConfigure(event); // emit signal
458  HandleConfigureNotify(event);
459  }
460  break;
461 
462  case kGKeyPress:
463  case kKeyRelease:
464  HandleKey(event);
465  break;
466 
467  case kFocusIn:
468  case kFocusOut:
469  HandleFocusChange(event);
470  break;
471 
472  case kButtonPress:
473  {
474  Int_t dbl_clk = kFALSE;
475 
476  if ((event->fTime - fgLastClick < 350) &&
477  (event->fCode == fgLastButton) &&
478  (TMath::Abs(event->fXRoot - fgDbx) < 6) &&
479  (TMath::Abs(event->fYRoot - fgDby) < 6) &&
480  (event->fWindow == fgDbw))
481  dbl_clk = kTRUE;
482 
483  fgLastClick = event->fTime;
484  fgLastButton = event->fCode;
485  fgDbx = event->fXRoot;
486  fgDby = event->fYRoot;
487  fgDbw = event->fWindow;
488 
489  if (dbl_clk) {
490  if ((event->fState & kKeyControlMask) &&
491  !GetEditDisabled() && gGuiBuilder) {
492  StartGuiBuilding(!IsEditable());
493  return kTRUE;
494  }
495 
496  if (!HandleDoubleClick(event)) {
497  HandleButton(event);
498  }
499  } else {
500  HandleButton(event);
501  }
502  }
503  break;
504 
505  case kButtonDoubleClick:
506  {
507  fgLastClick = event->fTime;
508  fgLastButton = event->fCode;
509  fgDbx = event->fXRoot;
510  fgDby = event->fYRoot;
511  fgDbw = event->fWindow;
512 
513  HandleDoubleClick(event);
514  }
515  break;
516 
517  case kButtonRelease:
518  HandleButton(event);
519  break;
520 
521  case kEnterNotify:
522  case kLeaveNotify:
523  HandleCrossing(event);
524  break;
525 
526  case kMotionNotify:
527  while (gVirtualX->CheckEvent(fId, kMotionNotify, *event))
528  ;
529  HandleMotion(event);
530  break;
531 
532  case kClientMessage:
533  HandleClientMessage(event);
534  break;
535 
536  case kSelectionNotify:
537  HandleSelection(event);
538  break;
539 
540  case kSelectionRequest:
541  HandleSelectionRequest(event);
542  break;
543 
544  case kSelectionClear:
545  HandleSelectionClear(event);
546  break;
547 
548  case kColormapNotify:
549  HandleColormapChange(event);
550  break;
551 
552  default:
553  //Warning("HandleEvent", "unknown event (%#x) for (%#x)", event->fType, fId);
554  break;
555  }
556 
557  if (deleteCheck.GetObject())
558  ProcessedEvent(event); // emit signal
559 
560  return kTRUE;
561 }
562 
563 ////////////////////////////////////////////////////////////////////////////////
564 /// std::cout << fWidth << "x" << fHeight << std::endl;
565 
566 TGDimension TGFrame::GetDefaultSize() const
567 {
568  return TGDimension(fWidth, fHeight);
569 }
570 
571 
572 ////////////////////////////////////////////////////////////////////////////////
573 /// Move frame.
574 
575 void TGFrame::Move(Int_t x, Int_t y)
576 {
577  if (x != fX || y != fY) {
578  TGWindow::Move(x, y);
579  fX = x; fY = y;
580  }
581 }
582 
583 ////////////////////////////////////////////////////////////////////////////////
584 /// Resize the frame.
585 /// If w=0 && h=0 - Resize to default size
586 
587 void TGFrame::Resize(UInt_t w, UInt_t h)
588 {
589  if (w != fWidth || h != fHeight) {
590  TGDimension siz(0,0);
591  siz = GetDefaultSize();
592  fWidth = w ? w : siz.fWidth;
593  fHeight = h ? h : siz.fHeight;
594  TGWindow::Resize(fWidth, fHeight);
595  Layout();
596  }
597 }
598 
599 ////////////////////////////////////////////////////////////////////////////////
600 /// Resize the frame.
601 
602 void TGFrame::Resize(TGDimension size)
603 {
604  Resize(size.fWidth, size.fHeight);
605 }
606 
607 ////////////////////////////////////////////////////////////////////////////////
608 /// Move and/or resize the frame.
609 /// If w=0 && h=0 - Resize to default size
610 
611 void TGFrame::MoveResize(Int_t x, Int_t y, UInt_t w, UInt_t h)
612 {
613  // we do it anyway as we don't know if it's only a move or only a resize
614  TGDimension siz(0,0);
615  siz = GetDefaultSize();
616  fWidth = w ? w : siz.fWidth;
617  fHeight = h ? h : siz.fHeight;
618  fX = x; fY = y;
619  TGWindow::MoveResize(x, y, fWidth, fHeight);
620  Layout();
621 }
622 
623 ////////////////////////////////////////////////////////////////////////////////
624 /// Send message (i.e. event) to window w. Message is encoded in one long
625 /// as message type and up to two long parameters.
626 
627 void TGFrame::SendMessage(const TGWindow *w, Long_t msg, Long_t parm1, Long_t parm2)
628 {
629  Event_t event;
630 
631  if (w) {
632  event.fType = kClientMessage;
633  event.fFormat = 32;
634  event.fHandle = gROOT_MESSAGE;
635 
636  event.fWindow = w->GetId();
637  event.fUser[0] = msg;
638  event.fUser[1] = parm1;
639  event.fUser[2] = parm2;
640  event.fUser[3] = 0;
641  event.fUser[4] = 0;
642 
643  gVirtualX->SendEvent(w->GetId(), &event);
644  }
645 }
646 
647 ////////////////////////////////////////////////////////////////////////////////
648 /// Handle a client message. Client messages are the ones sent via
649 /// TGFrame::SendMessage (typically by widgets).
650 
651 Bool_t TGFrame::HandleClientMessage(Event_t *event)
652 {
653  if (gDNDManager) {
654  gDNDManager->HandleClientMessage(event);
655  }
656  if (event->fHandle == gROOT_MESSAGE) {
657  ProcessMessage(event->fUser[0], event->fUser[1], event->fUser[2]);
658  }
659  return kTRUE;
660 }
661 
662 ////////////////////////////////////////////////////////////////////////////////
663 /// Get default frame background.
664 
665 ULong_t TGFrame::GetDefaultFrameBackground()
666 {
667  static Bool_t init = kFALSE;
668  if (!init && gClient) {
669  fgDefaultFrameBackground = gClient->GetResourcePool()->GetFrameBgndColor();
670  init = kTRUE;
671  }
672  return fgDefaultFrameBackground;
673 }
674 
675 ////////////////////////////////////////////////////////////////////////////////
676 /// Get default selected frame background.
677 
678 ULong_t TGFrame::GetDefaultSelectedBackground()
679 {
680  static Bool_t init = kFALSE;
681  if (!init && gClient) {
682  fgDefaultSelectedBackground = gClient->GetResourcePool()->GetSelectedBgndColor();
683  init = kTRUE;
684  }
685  return fgDefaultSelectedBackground;
686 }
687 
688 ////////////////////////////////////////////////////////////////////////////////
689 /// Get white pixel value.
690 
691 ULong_t TGFrame::GetWhitePixel()
692 {
693  static Bool_t init = kFALSE;
694  if (!init && gClient) {
695  fgWhitePixel = gClient->GetResourcePool()->GetWhiteColor();
696  init = kTRUE;
697  }
698  return fgWhitePixel;
699 }
700 
701 ////////////////////////////////////////////////////////////////////////////////
702 /// Get black pixel value.
703 
704 ULong_t TGFrame::GetBlackPixel()
705 {
706  static Bool_t init = kFALSE;
707  if (!init && gClient) {
708  fgBlackPixel = gClient->GetResourcePool()->GetBlackColor();
709  init = kTRUE;
710  }
711  return fgBlackPixel;
712 }
713 
714 ////////////////////////////////////////////////////////////////////////////////
715 /// Get black graphics context.
716 
717 const TGGC &TGFrame::GetBlackGC()
718 {
719  if (!fgBlackGC && gClient)
720  fgBlackGC = gClient->GetResourcePool()->GetBlackGC();
721  return *fgBlackGC;
722 }
723 
724 ////////////////////////////////////////////////////////////////////////////////
725 /// Get white graphics context.
726 
727 const TGGC &TGFrame::GetWhiteGC()
728 {
729  if (!fgWhiteGC && gClient)
730  fgWhiteGC = gClient->GetResourcePool()->GetWhiteGC();
731  return *fgWhiteGC;
732 }
733 
734 ////////////////////////////////////////////////////////////////////////////////
735 /// Get highlight color graphics context.
736 
737 const TGGC &TGFrame::GetHilightGC()
738 {
739  if (!fgHilightGC && gClient)
740  fgHilightGC = gClient->GetResourcePool()->GetFrameHiliteGC();
741  return *fgHilightGC;
742 }
743 
744 ////////////////////////////////////////////////////////////////////////////////
745 /// Get shadow color graphics context.
746 
747 const TGGC &TGFrame::GetShadowGC()
748 {
749  if (!fgShadowGC && gClient)
750  fgShadowGC = gClient->GetResourcePool()->GetFrameShadowGC();
751  return *fgShadowGC;
752 }
753 
754 ////////////////////////////////////////////////////////////////////////////////
755 /// Get background color graphics context.
756 
757 const TGGC &TGFrame::GetBckgndGC()
758 {
759  if (!fgBckgndGC && gClient)
760  fgBckgndGC = gClient->GetResourcePool()->GetFrameBckgndGC();
761  return *fgBckgndGC;
762 }
763 
764 ////////////////////////////////////////////////////////////////////////////////
765 /// Get time of last mouse click.
766 
767 Time_t TGFrame::GetLastClick()
768 {
769  return fgLastClick;
770 }
771 
772 ////////////////////////////////////////////////////////////////////////////////
773 /// Print window id.
774 
775 void TGFrame::Print(Option_t *option) const
776 {
777  TString opt = option;
778  if (opt.Contains("tree")) {
779  TGWindow::Print(option);
780  return;
781  }
782 
783  std::cout << option << ClassName() << ":\tid=" << fId << " parent=" << fParent->GetId();
784  std::cout << " x=" << fX << " y=" << fY;
785  std::cout << " w=" << fWidth << " h=" << fHeight << std::endl;
786 }
787 
788 ////////////////////////////////////////////////////////////////////////////////
789 /// SetDragType
790 
791 void TGFrame::SetDragType(Int_t)
792 {
793 }
794 
795 ////////////////////////////////////////////////////////////////////////////////
796 /// SetDropType
797 
798 void TGFrame::SetDropType(Int_t)
799 {
800 }
801 
802 ////////////////////////////////////////////////////////////////////////////////
803 /// Returns drag source type.
804 /// If frame is not "draggable" - return zero
805 
806 Int_t TGFrame::GetDragType() const
807 {
808  return fClient->IsEditable();
809 }
810 
811 ////////////////////////////////////////////////////////////////////////////////
812 /// Returns drop target type.
813 /// If frame cannot accept drop - return zero
814 
815 Int_t TGFrame::GetDropType() const
816 {
817  return 0;
818 }
819 
820 ////////////////////////////////////////////////////////////////////////////////
821 /// Go into GUI building mode.
822 
823 void TGFrame::StartGuiBuilding(Bool_t on)
824 {
825  if (GetEditDisabled()) return;
826  if (!gDragManager) gDragManager = TVirtualDragManager::Instance();
827  if (!gDragManager) return;
828 
829  TGCompositeFrame *comp = 0;
830 
831  if (InheritsFrom(TGCompositeFrame::Class())) {
832  comp = (TGCompositeFrame *)this;
833  } else if (fParent->InheritsFrom(TGCompositeFrame::Class())) {
834  comp = (TGCompositeFrame*)fParent;
835  }
836  if (comp) comp->SetEditable(on);
837 }
838 
839 ////////////////////////////////////////////////////////////////////////////////
840 /// Create a composite frame. A composite frame has in addition to a TGFrame
841 /// also a layout manager and a list of child frames.
842 
843 TGCompositeFrame::TGCompositeFrame(const TGWindow *p, UInt_t w, UInt_t h,
844  UInt_t options, Pixel_t back) : TGFrame(p, w, h, options, back)
845 {
846  fLayoutManager = 0;
847  fList = new TList;
848  fLayoutBroken = kFALSE;
849  fMustCleanup = kNoCleanup;
850  fMapSubwindows = fParent->IsMapSubwindows();
851  if (!fgDefaultHints)
852  fgDefaultHints = new TGLayoutHints;
853 
854  if (fOptions & kHorizontalFrame)
855  SetLayoutManager(new TGHorizontalLayout(this));
856  else
857  SetLayoutManager(new TGVerticalLayout(this));
858 
859  SetWindowName();
860 }
861 
862 ////////////////////////////////////////////////////////////////////////////////
863 /// Create a frame using an externally created window. For example
864 /// to register the root window (called by TGClient), or a window
865 /// created via TVirtualX::InitWindow() (id is obtained with TVirtualX::GetWindowID()).
866 
867 TGCompositeFrame::TGCompositeFrame(TGClient *c, Window_t id, const TGWindow *parent)
868  : TGFrame(c, id, parent)
869 {
870  fLayoutManager = 0;
871  fList = new TList;
872  fLayoutBroken = kFALSE;
873  fMustCleanup = kNoCleanup;
874  fMapSubwindows = fParent->IsMapSubwindows();
875  if (!fgDefaultHints)
876  fgDefaultHints = new TGLayoutHints;
877 
878  SetLayoutManager(new TGVerticalLayout(this));
879 
880  SetWindowName();
881 }
882 
883 ////////////////////////////////////////////////////////////////////////////////
884 /// Delete a composite frame.
885 
886 TGCompositeFrame::~TGCompositeFrame()
887 {
888  if (fMustCleanup != kNoCleanup) {
889  Cleanup();
890  } else {
891  TGFrameElement *el = 0;
892  TIter next(fList);
893 
894  while ((el = (TGFrameElement *) next())) {
895  fList->Remove(el);
896  delete el;
897  }
898  }
899 
900  delete fList;
901  delete fLayoutManager;
902  fList = 0;
903  fLayoutManager = 0;
904 }
905 
906 ////////////////////////////////////////////////////////////////////////////////
907 /// Return kTRUE if frame is being edited.
908 
909 Bool_t TGCompositeFrame::IsEditable() const
910 {
911  return (fClient->GetRoot() == (TGWindow*)this);
912 }
913 
914 ////////////////////////////////////////////////////////////////////////////////
915 /// Switch ON/OFF edit mode.
916 /// If edit mode is ON it is possible:
917 ///
918 /// 1. embed other ROOT GUI application (a la ActiveX)
919 ///
920 /// For example:
921 /// TGMainFrame *m = new TGMainFrame(gClient->GetRoot(), 500, 500);
922 /// m->SetEditable();
923 /// gSystem->Load("$ROOTSYS/test/Aclock"); // load Aclock demo
924 /// Aclock a;
925 /// gROOT->Macro("$ROOTSYS/tutorials/gui/guitest.C");
926 /// m->SetEditable(0);
927 /// m->MapWindow();
928 ///
929 
930 void TGCompositeFrame::SetEditable(Bool_t on)
931 {
932  if (on && ((fEditDisabled & kEditDisable) ||
933  (fEditDisabled & kEditDisableLayout))) return;
934 
935  if (on) {
936  fClient->SetRoot(this);
937  } else {
938  fClient->SetRoot(0);
939  }
940  if (gDragManager) gDragManager->SetEditable(on);
941 }
942 
943 ////////////////////////////////////////////////////////////////////////////////
944 /// Cleanup and delete all objects contained in this composite frame.
945 /// This will delete all objects added via AddFrame().
946 /// CAUTION: all objects (frames and layout hints) must be unique, i.e.
947 /// cannot be shared.
948 
949 void TGCompositeFrame::Cleanup()
950 {
951  if (!fList) return;
952 
953  TGFrameElement *el;
954  TIter next(fList);
955 
956  while ((el = (TGFrameElement *) next())) {
957  if (el->fFrame) {
958  el->fFrame->SetFrameElement(0);
959  if (!gVirtualX->InheritsFrom("TGX11") && !gVirtualX->InheritsFrom("TGCocoa"))
960  el->fFrame->DestroyWindow();
961  delete el->fFrame;
962  }
963 
964  if (el->fLayout && (el->fLayout != fgDefaultHints) &&
965  (el->fLayout->References() > 0)) {
966  el->fLayout->RemoveReference();
967  if (!el->fLayout->References()) {
968  el->fLayout->fFE = 0;
969  delete el->fLayout;
970  }
971  }
972  fList->Remove(el);
973  delete el;
974  }
975 }
976 
977 ////////////////////////////////////////////////////////////////////////////////
978 /// Set the layout manager for the composite frame.
979 /// The layout manager is adopted by the frame and will be deleted
980 /// by the frame.
981 
982 void TGCompositeFrame::SetLayoutManager(TGLayoutManager *l)
983 {
984  if (l) {
985  delete fLayoutManager;
986  fLayoutManager = l;
987  } else
988  Error("SetLayoutManager", "no layout manager specified");
989 }
990 
991 ////////////////////////////////////////////////////////////////////////////////
992 /// Set broken layout. No Layout method is called.
993 
994 void TGCompositeFrame::SetLayoutBroken(Bool_t on)
995 {
996  fLayoutBroken = on;
997 }
998 
999 ////////////////////////////////////////////////////////////////////////////////
1000 /// Set edit disable flag for this frame and subframes
1001 ///
1002 /// - if (on & kEditDisable) - disable edit for this frame and all subframes.
1003 
1004 void TGCompositeFrame::SetEditDisabled(UInt_t on)
1005 {
1006  fEditDisabled = on;
1007  UInt_t set = on & kEditDisable;
1008 
1009  // propagate only kEditDisable
1010  if (set == kEditDisable) {
1011 
1012  TGFrameElement *el;
1013  TIter next(fList);
1014  while ((el = (TGFrameElement *) next())) {
1015  if (el->fFrame) {
1016  el->fFrame->SetEditDisabled(set);
1017  }
1018  }
1019  }
1020 }
1021 
1022 ////////////////////////////////////////////////////////////////////////////////
1023 /// Change composite frame options. Options is an OR of the EFrameTypes.
1024 
1025 void TGCompositeFrame::ChangeOptions(UInt_t options)
1026 {
1027  TGFrame::ChangeOptions(options);
1028 
1029  if (options & kHorizontalFrame)
1030  SetLayoutManager(new TGHorizontalLayout(this));
1031  else if (options & kVerticalFrame)
1032  SetLayoutManager(new TGVerticalLayout(this));
1033 }
1034 
1035 ////////////////////////////////////////////////////////////////////////////////
1036 /// Turn on automatic cleanup of child frames in dtor.
1037 ///
1038 /// if mode = kNoCleanup - no automatic cleanup
1039 /// if mode = kLocalCleanup - automatic cleanup in this composite frame only
1040 /// if mode = kDeepCleanup - automatic deep cleanup in this composite frame
1041 /// and all child composite frames (hierarchical)
1042 ///
1043 /// Attention!
1044 /// Hierarchical cleaning is dangerous and must be used with caution.
1045 /// There are many GUI components (in ROOT and in user code) which do not
1046 /// use Clean method in destructor ("custom deallocation").
1047 /// Adding such component to GUI container which is using hierarchical
1048 /// cleaning will produce seg. violation when container is deleted.
1049 /// The reason is double deletion: first whem Clean method is invoked,
1050 /// then at "custom deallocation".
1051 /// We are going to correct all ROOT code to make it to be
1052 /// consitent with hierarchical cleaning scheeme.
1053 
1054 void TGCompositeFrame::SetCleanup(Int_t mode)
1055 {
1056  if (mode == fMustCleanup)
1057  return;
1058 
1059  fMustCleanup = mode;
1060 
1061  if (fMustCleanup == kDeepCleanup) {
1062  TGFrameElement *el;
1063  TIter next(fList);
1064 
1065  while ((el = (TGFrameElement *) next())) {
1066  if (el->fFrame->InheritsFrom(TGCompositeFrame::Class())) {
1067  el->fFrame->SetCleanup(kDeepCleanup);
1068  }
1069  }
1070  }
1071 }
1072 
1073 ////////////////////////////////////////////////////////////////////////////////
1074 /// Find frame-element holding frame f.
1075 
1076 TGFrameElement* TGCompositeFrame::FindFrameElement(TGFrame *f) const
1077 {
1078  if (!fList) return 0;
1079 
1080  TGFrameElement *el;
1081  TIter next(fList);
1082 
1083  while ((el = (TGFrameElement *) next()))
1084  if (el->fFrame == f)
1085  return el;
1086 
1087  return 0;
1088 }
1089 
1090 ////////////////////////////////////////////////////////////////////////////////
1091 /// Add frame to the composite frame using the specified layout hints.
1092 /// If no hints are specified default hints TGLayoutHints(kLHintsNormal,0,0,0,0)
1093 /// will be used. Most of the time, however, you will want to provide
1094 /// specific hints. User specified hints can be reused many times
1095 /// and need to be destroyed by the user. The added frames cannot not be
1096 /// added to different composite frames but still need to be deleted by
1097 /// the user.
1098 
1099 void TGCompositeFrame::AddFrame(TGFrame *f, TGLayoutHints *l)
1100 {
1101  TGFrameElement *nw = new TGFrameElement(f, l ? l : fgDefaultHints);
1102  fList->Add(nw);
1103 
1104  // in case of recusive cleanup, propagate cleanup setting to all
1105  // child composite frames
1106  if (fMustCleanup == kDeepCleanup)
1107  f->SetCleanup(kDeepCleanup);
1108 }
1109 
1110 ////////////////////////////////////////////////////////////////////////////////
1111 /// Remove all frames from composite frame.
1112 
1113 void TGCompositeFrame::RemoveAll()
1114 {
1115  if (!fList) return;
1116 
1117  TGFrameElement *el;
1118  TIter next(fList);
1119 
1120  while ((el = (TGFrameElement *) next())) {
1121  fList->Remove(el);
1122  if (el->fLayout) el->fLayout->RemoveReference();
1123 // el->fFrame->SetFrameElement(0);
1124  delete el;
1125  }
1126 }
1127 
1128 ////////////////////////////////////////////////////////////////////////////////
1129 /// Remove frame from composite frame.
1130 
1131 void TGCompositeFrame::RemoveFrame(TGFrame *f)
1132 {
1133  TGFrameElement *el = FindFrameElement(f);
1134 
1135  if (el) {
1136  fList->Remove(el);
1137  if (el->fLayout) el->fLayout->RemoveReference();
1138  f->SetFrameElement(0);
1139  delete el;
1140  }
1141 }
1142 
1143 ////////////////////////////////////////////////////////////////////////////////
1144 /// Map all sub windows that are part of the composite frame.
1145 
1146 void TGCompositeFrame::MapSubwindows()
1147 {
1148  if (!fMapSubwindows) {
1149  //MapWindow();
1150  return;
1151  }
1152 
1153  TGWindow::MapSubwindows();
1154 
1155  if (!fList) return;
1156 
1157  TGFrameElement *el;
1158  TIter next(fList);
1159 
1160  while ((el = (TGFrameElement *) next())) {
1161  if (el->fFrame) {
1162  el->fFrame->MapSubwindows();
1163  TGFrameElement *fe = el->fFrame->GetFrameElement();
1164  if (fe) fe->fState |= kIsVisible;
1165  }
1166  }
1167 }
1168 
1169 ////////////////////////////////////////////////////////////////////////////////
1170 /// Hide sub frame.
1171 
1172 void TGCompositeFrame::HideFrame(TGFrame *f)
1173 {
1174  TGFrameElement *el = FindFrameElement(f);
1175 
1176  if (el) {
1177  el->fState = 0;
1178  el->fFrame->UnmapWindow();
1179  Layout();
1180  }
1181 }
1182 
1183 ////////////////////////////////////////////////////////////////////////////////
1184 /// Show sub frame.
1185 
1186 void TGCompositeFrame::ShowFrame(TGFrame *f)
1187 {
1188  TGFrameElement *el = FindFrameElement(f);
1189 
1190  if (el) {
1191  el->fState = 1;
1192  el->fFrame->MapWindow();
1193  Layout();
1194  }
1195 }
1196 
1197 ////////////////////////////////////////////////////////////////////////////////
1198 /// Get state of sub frame.
1199 
1200 Int_t TGCompositeFrame::GetState(TGFrame *f) const
1201 {
1202  TGFrameElement *el = FindFrameElement(f);
1203 
1204  if (el)
1205  return el->fState;
1206  else
1207  return 0;
1208 }
1209 
1210 ////////////////////////////////////////////////////////////////////////////////
1211 /// Get state of sub frame.
1212 
1213 Bool_t TGCompositeFrame::IsVisible(TGFrame *f) const
1214 {
1215  TGFrameElement *el = FindFrameElement(f);
1216 
1217  if (el)
1218  return (el->fState & kIsVisible);
1219  else
1220  return kFALSE;
1221 }
1222 
1223 ////////////////////////////////////////////////////////////////////////////////
1224 /// Get state of sub frame.
1225 
1226 Bool_t TGCompositeFrame::IsArranged(TGFrame *f) const
1227 {
1228  TGFrameElement *el = FindFrameElement(f);
1229 
1230  if (el)
1231  return (el->fState & kIsArranged);
1232  else
1233  return kFALSE;
1234 }
1235 
1236 ////////////////////////////////////////////////////////////////////////////////
1237 /// Layout the elements of the composite frame.
1238 
1239 void TGCompositeFrame::Layout()
1240 {
1241  if (IsLayoutBroken()) return;
1242  fLayoutManager->Layout();
1243 }
1244 
1245 ////////////////////////////////////////////////////////////////////////////////
1246 /// Print all frames in this composite frame.
1247 
1248 void TGCompositeFrame::Print(Option_t *option) const
1249 {
1250  TString opt = option;
1251  if (opt.Contains("tree")) {
1252  TGWindow::Print(option);
1253  return;
1254  }
1255 
1256  TGFrameElement *el;
1257  TIter next(fList);
1258  TString tab = option;
1259 
1260  TGFrame::Print(tab.Data());
1261  tab += " ";
1262  while ((el = (TGFrameElement*)next())) {
1263  el->fFrame->Print(tab.Data());
1264  }
1265 }
1266 
1267 ////////////////////////////////////////////////////////////////////////////////
1268 /// Change background color for this frame and all subframes.
1269 
1270 void TGCompositeFrame::ChangeSubframesBackground(Pixel_t back)
1271 {
1272  TGFrame::ChangeBackground(back);
1273  TGFrameElement *el;
1274 
1275  TIter next(fList);
1276 
1277  while ((el = (TGFrameElement*)next())) {
1278  el->fFrame->SetBackgroundColor(back);
1279  if (el->fFrame->InheritsFrom(TGCompositeFrame::Class())) {
1280  ((TGCompositeFrame*)el->fFrame)->ChangeSubframesBackground(back);
1281  }
1282  fClient->NeedRedraw(el->fFrame);
1283  }
1284  fClient->NeedRedraw(this);
1285 }
1286 
1287 ////////////////////////////////////////////////////////////////////////////////
1288 /// Get frame located at specified point.
1289 
1290 TGFrame *TGCompositeFrame::GetFrameFromPoint(Int_t x, Int_t y)
1291 {
1292  if (!Contains(x, y)) return 0;
1293 
1294  if (!fList) return this;
1295 
1296  TGFrame *f;
1297  TGFrameElement *el;
1298  TIter next(fList);
1299 
1300  while ((el = (TGFrameElement *) next())) {
1301  //if (el->fFrame->IsVisible()) { //for this need to move IsVisible to TGFrame
1302  if (el->fState & kIsVisible) {
1303  f = el->fFrame->GetFrameFromPoint(x - el->fFrame->GetX(),
1304  y - el->fFrame->GetY());
1305  if (f) return f;
1306  }
1307  }
1308  return this;
1309 }
1310 
1311 ////////////////////////////////////////////////////////////////////////////////
1312 /// Translate coordinates to child frame.
1313 
1314 Bool_t TGCompositeFrame::TranslateCoordinates(TGFrame *child, Int_t x, Int_t y,
1315  Int_t &fx, Int_t &fy)
1316 {
1317  if (child == this) {
1318  fx = x;
1319  fy = y;
1320  return kTRUE;
1321  }
1322 
1323  if (!Contains(x, y)) return kFALSE;
1324 
1325  if (!fList) return kFALSE;
1326 
1327  TGFrameElement *el;
1328  TIter next(fList);
1329 
1330  while ((el = (TGFrameElement *) next())) {
1331  if (el->fFrame == child) {
1332  fx = x - el->fFrame->GetX();
1333  fy = y - el->fFrame->GetY();
1334  return kTRUE;
1335  } else if (el->fFrame->IsComposite()) {
1336  if (((TGCompositeFrame *)el->fFrame)->TranslateCoordinates(child,
1337  x - el->fFrame->GetX(), y - el->fFrame->GetY(), fx, fy))
1338  return kTRUE;
1339  }
1340  }
1341  return kFALSE;
1342 }
1343 
1344 ////////////////////////////////////////////////////////////////////////////////
1345 /// Handle drag enter event.
1346 
1347 Bool_t TGCompositeFrame::HandleDragEnter(TGFrame *)
1348 {
1349  if (fClient && fClient->IsEditable() &&
1350  (fId != fClient->GetRoot()->GetId())) {
1351 
1352  // the dragged frame cannot be droppped
1353  if (fEditDisabled & (kEditDisable | kEditDisableLayout)) return kFALSE;
1354 
1355  //
1356  if (IsEditable()) {
1357  return kTRUE;
1358  }
1359 
1360  Float_t r, g, b;
1361  TColor::Pixel2RGB(fBackground, r, g, b);
1362  r *= 1.12;
1363  g *= 1.13;
1364  b *= 1.12;
1365  Pixel_t back = TColor::RGB2Pixel(r, g, b);
1366  gVirtualX->SetWindowBackground(fId, back);
1367  DoRedraw();
1368  return kTRUE;
1369  }
1370 
1371  return kFALSE;
1372 }
1373 
1374 ////////////////////////////////////////////////////////////////////////////////
1375 /// Handle drag leave event.
1376 
1377 Bool_t TGCompositeFrame::HandleDragLeave(TGFrame *)
1378 {
1379  if (fClient && fClient->IsEditable() &&
1380  (fId != fClient->GetRoot()->GetId())) {
1381 
1382  if (fEditDisabled & (kEditDisable | kEditDisableLayout)) return kFALSE;
1383 
1384  gVirtualX->SetWindowBackground(fId, fBackground);
1385  DoRedraw();
1386  return kTRUE;
1387  }
1388 
1389  return kFALSE;
1390 }
1391 
1392 ////////////////////////////////////////////////////////////////////////////////
1393 /// Handle drag motion event.
1394 
1395 Bool_t TGCompositeFrame::HandleDragMotion(TGFrame *)
1396 {
1397  return kFALSE;
1398 }
1399 
1400 ////////////////////////////////////////////////////////////////////////////////
1401 /// Handle drop event.
1402 
1403 Bool_t TGCompositeFrame::HandleDragDrop(TGFrame *frame, Int_t x, Int_t y,
1404  TGLayoutHints *lo)
1405 {
1406  if (fClient && fClient->IsEditable() && frame && (x >= 0) && (y >= 0) &&
1407  (x + frame->GetWidth() <= fWidth) && (y + frame->GetHeight() <= fHeight)) {
1408 
1409  if (fEditDisabled & (kEditDisable | kEditDisableLayout)) return kFALSE;
1410 
1411  frame->ReparentWindow(this, x, y);
1412  AddFrame(frame, lo);
1413  frame->MapWindow();
1414  SetEditable(kTRUE);
1415  return kTRUE;
1416  }
1417 
1418  return kFALSE;
1419 }
1420 
1421 
1422 ////////////////////////////////////////////////////////////////////////////////
1423 /// Create a top level main frame. A main frame interacts
1424 /// with the window manager.
1425 
1426 TGMainFrame::TGMainFrame(const TGWindow *p, UInt_t w, UInt_t h,
1427  UInt_t options) : TGCompositeFrame(p, w, h, options | kMainFrame)
1428 {
1429  // WMDeleteNotify causes the system to send a kClientMessage to the
1430  // window with fFormat=32 and fUser[0]=gWM_DELETE_WINDOW when window
1431  // closed via WM
1432 
1433  gVirtualX->WMDeleteNotify(fId);
1434 
1435  fBindList = new TList;
1436 
1437  fMWMValue = 0;
1438  fMWMFuncs = 0;
1439  fMWMInput = 0;
1440  fWMX = -1;
1441  fWMY = -1;
1442  fWMWidth = (UInt_t) -1;
1443  fWMHeight = (UInt_t) -1;
1444  fWMMinWidth = (UInt_t) -1;
1445  fWMMinHeight = (UInt_t) -1;
1446  fWMMaxWidth = (UInt_t) -1;
1447  fWMMaxHeight = (UInt_t) -1;
1448  fWMWidthInc = (UInt_t) -1;
1449  fWMHeightInc = (UInt_t) -1;
1450  fWMInitState = (EInitialState) 0;
1451 
1452  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_s),
1453  kKeyControlMask, kTRUE);
1454  if (p == fClient->GetDefaultRoot()) {
1455  fMWMValue = kMWMDecorAll;
1456  fMWMFuncs = kMWMFuncAll;
1457  fMWMInput = kMWMInputModeless;
1458  gVirtualX->SetMWMHints(fId, fMWMValue, fMWMFuncs, fMWMInput);
1459  }
1460  // if parent is editing/embedable add this frame to the parent
1461  if (fClient->IsEditable() && (p == fClient->GetRoot())) {
1462  TGCompositeFrame *frame;
1463  if (p && p->InheritsFrom(TGCompositeFrame::Class())) {
1464  frame = (TGCompositeFrame*)p;
1465  frame->AddFrame(this, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
1466 
1467  // used during paste operation
1468  if (gDragManager && gDragManager->IsPasting()) {
1469  gDragManager->SetPasteFrame(this);
1470  }
1471  }
1472  }
1473  //AddInput(kButtonPressMask); // to allow Drag and Drop
1474  // Create Drag&Drop Manager and define a few DND types
1475  fDNDTypeList = new Atom_t[3];
1476  fDNDTypeList[0] = gVirtualX->InternAtom("application/root", kFALSE);
1477  fDNDTypeList[1] = gVirtualX->InternAtom("text/uri-list", kFALSE);
1478  fDNDTypeList[2] = 0;
1479  if (!gDNDManager)
1480  new TGDNDManager(this, fDNDTypeList);
1481  SetWindowName();
1482 }
1483 
1484 ////////////////////////////////////////////////////////////////////////////////
1485 /// TGMainFrame destructor.
1486 
1487 TGMainFrame::~TGMainFrame()
1488 {
1489  delete [] fDNDTypeList;
1490  if (fBindList) {
1491  fBindList->Delete();
1492  delete fBindList;
1493  }
1494 }
1495 
1496 ////////////////////////////////////////////////////////////////////////////////
1497 /// Opens dialog window allowing user to save the frame contents
1498 /// as a ROOT macro or as an image.
1499 /// Returns kTRUE if something was saved.
1500 ///
1501 /// This is bound to Ctrl-S by default.
1502 
1503 Bool_t TGMainFrame::SaveFrameAsCodeOrImage()
1504 {
1505  static TString dir(".");
1506  static Bool_t overwr = kFALSE;
1507 
1508  Bool_t repeat_save;
1509  do {
1510  repeat_save = kFALSE;
1511 
1512  TGFileInfo fi;
1513  TGMainFrame *main = (TGMainFrame*)GetMainFrame();
1514  fi.fFileTypes = gSaveMacroTypes;
1515  fi.fIniDir = StrDup(dir);
1516  fi.fOverwrite = overwr;
1517  new TGFileDialog(fClient->GetDefaultRoot(), this, kFDSave, &fi);
1518  if (!fi.fFilename) return kFALSE;
1519  dir = fi.fIniDir;
1520  overwr = fi.fOverwrite;
1521  TString fname = gSystem->UnixPathName(fi.fFilename);
1522  if (fname.EndsWith(".C"))
1523  main->SaveSource(fname.Data(), "");
1524  else {
1525  TImage::EImageFileTypes gtype = TImage::kUnknown;
1526  if (fname.EndsWith("gif")) {
1527  gtype = TImage::kGif;
1528  } else if (fname.EndsWith(".png")) {
1529  gtype = TImage::kPng;
1530  } else if (fname.EndsWith(".jpg")) {
1531  gtype = TImage::kJpeg;
1532  } else if (fname.EndsWith(".tiff")) {
1533  gtype = TImage::kTiff;
1534  } else if (fname.EndsWith(".xpm")) {
1535  gtype = TImage::kXpm;
1536  }
1537  if (gtype != TImage::kUnknown) {
1538  Int_t saver = gErrorIgnoreLevel;
1539  gErrorIgnoreLevel = kFatal;
1540  TImage *img = TImage::Create();
1541  RaiseWindow();
1542  img->FromWindow(GetId());
1543  img->WriteImage(fname, gtype);
1544  gErrorIgnoreLevel = saver;
1545  delete img;
1546  }
1547  else {
1548  Int_t retval;
1549  new TGMsgBox(fClient->GetDefaultRoot(), this, "Error...",
1550  TString::Format("file (%s) cannot be saved with this extension",
1551  fname.Data()), kMBIconExclamation,
1552  kMBRetry | kMBCancel, &retval);
1553  repeat_save = (retval == kMBRetry);
1554  }
1555  }
1556  } while (repeat_save);
1557 
1558  return kTRUE;
1559 }
1560 
1561 ////////////////////////////////////////////////////////////////////////////////
1562 /// Handle keyboard events.
1563 
1564 Bool_t TGMainFrame::HandleKey(Event_t *event)
1565 {
1566  if (fBindList) {
1567 
1568  TIter next(fBindList);
1569  TGMapKey *m;
1570  TGFrame *w = 0;
1571 
1572  while ((m = (TGMapKey *) next())) {
1573  if (m->fKeyCode == event->fCode) {
1574  w = (TGFrame *) m->fWindow;
1575  if (w->HandleKey(event)) return kTRUE;
1576  }
1577  }
1578  }
1579 
1580  if ((event->fType == kGKeyPress) && (event->fState & kKeyControlMask)) {
1581  UInt_t keysym;
1582  char str[2];
1583  gVirtualX->LookupString(event, str, sizeof(str), keysym);
1584 
1585  if ((keysym & ~0x20) == kKey_S) { // case insensitive ctrl-s
1586  return SaveFrameAsCodeOrImage();
1587  }
1588  }
1589  return kFALSE;
1590 }
1591 
1592 ////////////////////////////////////////////////////////////////////////////////
1593 /// Bind key to a window.
1594 
1595 Bool_t TGMainFrame::BindKey(const TGWindow *w, Int_t keycode, Int_t modifier) const
1596 {
1597  TList *list = fBindList;
1598  Handle_t id = fId;
1599 
1600  if (fClient->IsEditable()) {
1601  TGMainFrame *main = (TGMainFrame*)GetMainFrame();
1602  list = main->GetBindList();
1603  id = main->GetId();
1604  }
1605 
1606  if (list) {
1607  TGMapKey *m = new TGMapKey(keycode, (TGWindow *)w);
1608  list->Add(m);
1609  gVirtualX->GrabKey(id, keycode, modifier, kTRUE);
1610  return kTRUE;
1611  }
1612  return kFALSE;
1613 }
1614 
1615 ////////////////////////////////////////////////////////////////////////////////
1616 /// Remove key binding.
1617 
1618 void TGMainFrame::RemoveBind(const TGWindow *, Int_t keycode, Int_t modifier) const
1619 {
1620  if (fBindList) {
1621  TIter next(fBindList);
1622  TGMapKey *m;
1623  while ((m = (TGMapKey *) next())) {
1624  if (m->fKeyCode == (UInt_t) keycode) {
1625  fBindList->Remove(m);
1626  delete m;
1627  gVirtualX->GrabKey(fId, keycode, modifier, kFALSE);
1628  return;
1629  }
1630  }
1631  }
1632 }
1633 
1634 ////////////////////////////////////////////////////////////////////////////////
1635 /// Handle mouse button events.
1636 
1637 Bool_t TGMainFrame::HandleButton(Event_t *event)
1638 {
1639  if (event->fType == kButtonRelease) {
1640  if (gDNDManager->IsDragging()) gDNDManager->Drop();
1641  }
1642  return TGCompositeFrame::HandleButton(event);
1643 }
1644 
1645 
1646 ////////////////////////////////////////////////////////////////////////////////
1647 /// Handle mouse motion events.
1648 
1649 Bool_t TGMainFrame::HandleMotion(Event_t *event)
1650 {
1651  if (gDNDManager && gDNDManager->IsDragging()) {
1652  gDNDManager->Drag(event->fXRoot, event->fYRoot,
1653  TGDNDManager::GetDNDActionCopy(), event->fTime);
1654  }
1655  return TGCompositeFrame::HandleMotion(event);
1656 }
1657 
1658 ////////////////////////////////////////////////////////////////////////////////
1659 /// Handle primary selection event.
1660 
1661 Bool_t TGMainFrame::HandleSelection(Event_t *event)
1662 {
1663  if ((Atom_t)event->fUser[1] == TGDNDManager::GetDNDSelection()) {
1664  if (gDNDManager)
1665  return gDNDManager->HandleSelection(event);
1666  }
1667  return TGCompositeFrame::HandleSelection(event);
1668 }
1669 
1670 ////////////////////////////////////////////////////////////////////////////////
1671 /// Handle selection request event.
1672 
1673 Bool_t TGMainFrame::HandleSelectionRequest(Event_t *event)
1674 {
1675  if ((Atom_t)event->fUser[1] == TGDNDManager::GetDNDSelection()) {
1676  if (gDNDManager)
1677  return gDNDManager->HandleSelectionRequest(event);
1678  }
1679  return TGCompositeFrame::HandleSelectionRequest(event);
1680 }
1681 
1682 ////////////////////////////////////////////////////////////////////////////////
1683 /// Handle client messages sent to this frame.
1684 
1685 Bool_t TGMainFrame::HandleClientMessage(Event_t *event)
1686 {
1687  TGCompositeFrame::HandleClientMessage(event);
1688 
1689  if ((event->fFormat == 32) && ((Atom_t)event->fUser[0] == gWM_DELETE_WINDOW) &&
1690  (event->fHandle != gROOT_MESSAGE)) {
1691  Emit("CloseWindow()");
1692  if (TestBit(kNotDeleted) && !TestBit(kDontCallClose))
1693  CloseWindow();
1694  }
1695  return kTRUE;
1696 }
1697 
1698 ////////////////////////////////////////////////////////////////////////////////
1699 /// Send close message to self. This method should be called from
1700 /// a button to close this window.
1701 
1702 void TGMainFrame::SendCloseMessage()
1703 {
1704  Event_t event;
1705 
1706  event.fType = kClientMessage;
1707  event.fFormat = 32;
1708  event.fHandle = gWM_DELETE_WINDOW;
1709 
1710  event.fWindow = GetId();
1711  event.fUser[0] = (Long_t) gWM_DELETE_WINDOW;
1712  event.fUser[1] = 0;
1713  event.fUser[2] = 0;
1714  event.fUser[3] = 0;
1715  event.fUser[4] = 0;
1716 
1717  gVirtualX->SendEvent(GetId(), &event);
1718 }
1719 
1720 ////////////////////////////////////////////////////////////////////////////////
1721 /// Close and delete main frame. We get here in response to ALT+F4 or
1722 /// a window manager close command. To terminate the application when this
1723 /// happens override this method and call gApplication->Terminate(0) or
1724 /// make a connection to this signal (if after the slot this method
1725 /// should not be called call DontCallClose() in the slot).
1726 /// By default the window will be deleted.
1727 
1728 void TGMainFrame::CloseWindow()
1729 {
1730  DeleteWindow();
1731 }
1732 
1733 ////////////////////////////////////////////////////////////////////////////////
1734 /// Typically call this method in the slot connected to the CloseWindow()
1735 /// signal to prevent the calling of the default or any derived CloseWindow()
1736 /// methods to prevent premature or double deletion of this window.
1737 
1738 void TGMainFrame::DontCallClose()
1739 {
1740  SetBit(kDontCallClose);
1741 }
1742 
1743 ////////////////////////////////////////////////////////////////////////////////
1744 /// Set window name. This is typically done via the window manager.
1745 
1746 void TGMainFrame::SetWindowName(const char *name)
1747 {
1748  if (!name) {
1749  TGWindow::SetWindowName();
1750  } else {
1751  fWindowName = name;
1752  gVirtualX->SetWindowName(fId, (char *)name);
1753  }
1754 }
1755 
1756 ////////////////////////////////////////////////////////////////////////////////
1757 /// Set window icon name. This is typically done via the window manager.
1758 
1759 void TGMainFrame::SetIconName(const char *name)
1760 {
1761  fIconName = name;
1762  gVirtualX->SetIconName(fId, (char *)name);
1763 }
1764 
1765 ////////////////////////////////////////////////////////////////////////////////
1766 /// Set window icon pixmap by name. This is typically done via the window
1767 /// manager. Icon can be in any image format supported by TImage, e.g.
1768 /// GIF, XPM, PNG, JPG .. or even PS, PDF (see EImageFileTypes in TImage.h
1769 /// for the full list of supported formats).
1770 ///
1771 /// For example,
1772 /// main_frame->SetIconPixmap("/home/root/icons/bld_rgb.png");
1773 
1774 const TGPicture *TGMainFrame::SetIconPixmap(const char *iconName)
1775 {
1776  fIconPixmap = iconName;
1777  const TGPicture *iconPic = fClient->GetPicture(iconName);
1778  if (iconPic) {
1779  Pixmap_t pic = iconPic->GetPicture();
1780  gVirtualX->SetIconPixmap(fId, pic);
1781  return iconPic;
1782  } else
1783  return 0;
1784 }
1785 
1786 ////////////////////////////////////////////////////////////////////////////////
1787 /// Set window icon by xpm array. That allows to have icons
1788 /// builtin to the source code.
1789 ///
1790 /// For example,
1791 /// #include "/home/root/icons/bld_rgb.xpm"
1792 /// //bld_rgb.xpm contains char *bld_rgb[] array
1793 /// main_frame->SetIconPixmap(bld_rgb);
1794 
1795 void TGMainFrame::SetIconPixmap(char **xpm_array)
1796 {
1797  TImage *img = TImage::Create();
1798  if (!img) return;
1799  img->SetImageBuffer(xpm_array, TImage::kXpm);
1800  Pixmap_t pic = img->GetPixmap();
1801  if (pic) {
1802  gVirtualX->SetIconPixmap(fId, pic);
1803  } else {
1804  Warning("SetIconPixmap", "Failed to set window icon from xpm array.");
1805  }
1806  delete img;
1807 }
1808 
1809 ////////////////////////////////////////////////////////////////////////////////
1810 /// Set the windows class and resource name. Used to get the right
1811 /// resources from the resource database. However, ROOT applications
1812 /// will typically use the .rootrc file for this.
1813 
1814 void TGMainFrame::SetClassHints(const char *className, const char *resourceName)
1815 {
1816  fClassName = className;
1817  fResourceName = resourceName;
1818  gVirtualX->SetClassHints(fId, (char *)className, (char *)resourceName);
1819 }
1820 
1821 ////////////////////////////////////////////////////////////////////////////////
1822 /// Set decoration style for MWM-compatible wm (mwm, ncdwm, fvwm?).
1823 
1824 void TGMainFrame::SetMWMHints(UInt_t value, UInt_t funcs, UInt_t input)
1825 {
1826  if (fClient->IsEditable() && (fParent == fClient->GetRoot())) return;
1827 
1828  fMWMValue = value;
1829  fMWMFuncs = funcs;
1830  fMWMInput = input;
1831  gVirtualX->SetMWMHints(fId, value, funcs, input);
1832 }
1833 
1834 ////////////////////////////////////////////////////////////////////////////////
1835 /// Give the window manager a window position hint.
1836 
1837 void TGMainFrame::SetWMPosition(Int_t x, Int_t y)
1838 {
1839  if (fClient->IsEditable() && (fParent == fClient->GetRoot())) return;
1840 
1841  fWMX = x;
1842  fWMY = y;
1843  gVirtualX->SetWMPosition(fId, x, y);
1844 }
1845 
1846 ////////////////////////////////////////////////////////////////////////////////
1847 /// Give the window manager a window size hint.
1848 
1849 void TGMainFrame::SetWMSize(UInt_t w, UInt_t h)
1850 {
1851  if (fClient->IsEditable() && (fParent == fClient->GetRoot())) return;
1852 
1853  fWMWidth = w;
1854  fWMHeight = h;
1855  gVirtualX->SetWMSize(fId, w, h);
1856 }
1857 
1858 ////////////////////////////////////////////////////////////////////////////////
1859 /// Give the window manager minimum and maximum size hints. Also
1860 /// specify via winc and hinc the resize increments.
1861 
1862 void TGMainFrame::SetWMSizeHints(UInt_t wmin, UInt_t hmin,
1863  UInt_t wmax, UInt_t hmax,
1864  UInt_t winc, UInt_t hinc)
1865 {
1866  if (fClient->IsEditable() && (fParent == fClient->GetRoot())) return;
1867 
1868  fMinWidth = fWMMinWidth = wmin;
1869  fMinHeight = fWMMinHeight = hmin;
1870  fMaxWidth = fWMMaxWidth = wmax;
1871  fMaxHeight = fWMMaxHeight = hmax;
1872  fWMWidthInc = winc;
1873  fWMHeightInc = hinc;
1874  gVirtualX->SetWMSizeHints(fId, wmin, hmin, wmax, hmax, winc, hinc);
1875 }
1876 
1877 ////////////////////////////////////////////////////////////////////////////////
1878 /// Set the initial state of the window. Either kNormalState or kIconicState.
1879 
1880 void TGMainFrame::SetWMState(EInitialState state)
1881 {
1882  if (fClient->IsEditable() && (fParent == fClient->GetRoot())) return;
1883 
1884  fWMInitState = state;
1885  gVirtualX->SetWMState(fId, state);
1886 }
1887 
1888 
1889 ////////////////////////////////////////////////////////////////////////////////
1890 /// Create a transient window. A transient window is typically used for
1891 /// dialog boxes.
1892 
1893 TGTransientFrame::TGTransientFrame(const TGWindow *p, const TGWindow *main,
1894  UInt_t w, UInt_t h, UInt_t options)
1895  : TGMainFrame(p, w, h, options | kTransientFrame)
1896 {
1897  fMain = main;
1898  if (!fMain && gClient)
1899  fMain = gClient->GetRoot();
1900 
1901  if (fMain) {
1902  gVirtualX->SetWMTransientHint(fId, fMain->GetId());
1903  }
1904 }
1905 
1906 ////////////////////////////////////////////////////////////////////////////////
1907 /// Position transient frame centered relative to the parent frame.
1908 /// If fMain is 0 (i.e. TGTransientFrame is acting just like a
1909 /// TGMainFrame) and croot is true, the window will be centered on
1910 /// the root window, otherwise no action is taken and the default
1911 /// wm placement will be used.
1912 
1913 void TGTransientFrame::CenterOnParent(Bool_t croot, EPlacement pos)
1914 {
1915  Int_t x=0, y=0, ax, ay;
1916  Window_t wdummy;
1917 
1918  UInt_t dw = fClient->GetDisplayWidth();
1919  UInt_t dh = fClient->GetDisplayHeight();
1920 
1921  if (fMain) {
1922 
1923  switch (pos) {
1924  case kCenter:
1925  x = (Int_t)(((TGFrame *) fMain)->GetWidth() - fWidth) >> 1;
1926  y = (Int_t)(((TGFrame *) fMain)->GetHeight() - fHeight) >> 1;
1927  break;
1928  case kRight:
1929  x = (Int_t)(((TGFrame *) fMain)->GetWidth() - (fWidth >> 1));
1930  y = (Int_t)(((TGFrame *) fMain)->GetHeight() - fHeight) >> 1;
1931  break;
1932  case kLeft:
1933  x = (Int_t)(-1 * (Int_t)(fWidth >> 1));
1934  y = (Int_t)(((TGFrame *) fMain)->GetHeight() - fHeight) >> 1;
1935  break;
1936  case kTop:
1937  x = (Int_t)(((TGFrame *) fMain)->GetWidth() - fWidth) >> 1;
1938  y = (Int_t)(-1 * (Int_t)(fHeight >> 1));
1939  break;
1940  case kBottom:
1941  x = (Int_t)(((TGFrame *) fMain)->GetWidth() - fWidth) >> 1;
1942  y = (Int_t)(((TGFrame *) fMain)->GetHeight() - (fHeight >> 1));
1943  break;
1944  case kTopLeft:
1945  x = (Int_t)(-1 * (Int_t)(fWidth >> 1));
1946  y = (Int_t)(-1 * (Int_t)(fHeight >> 1));
1947  break;
1948  case kTopRight:
1949  x = (Int_t)(((TGFrame *) fMain)->GetWidth() - (fWidth >> 1));
1950  y = (Int_t)(-1 * (Int_t)(fHeight >> 1));
1951  break;
1952  case kBottomLeft:
1953  x = (Int_t)(-1 * (Int_t)(fWidth >> 1));
1954  y = (Int_t)(((TGFrame *) fMain)->GetHeight() - (fHeight >> 1));
1955  break;
1956  case kBottomRight:
1957  x = (Int_t)(((TGFrame *) fMain)->GetWidth() - (fWidth >> 1));
1958  y = (Int_t)(((TGFrame *) fMain)->GetHeight() - (fHeight >> 1));
1959  break;
1960  }
1961 
1962  gVirtualX->TranslateCoordinates(fMain->GetId(), GetParent()->GetId(),
1963  x, y, ax, ay, wdummy);
1964  if (!gVirtualX->InheritsFrom("TGWin32")) {
1965  if (ax < 10)
1966  ax = 10;
1967  else if (ax + fWidth + 10 > dw)
1968  ax = dw - fWidth - 10;
1969 
1970  if (ay < 20)
1971  ay = 20;
1972  else if (ay + fHeight + 50 > dh)
1973  ay = dh - fHeight - 50;
1974  }
1975 
1976  } else if (croot) {
1977 
1978  switch (pos) {
1979  case kCenter:
1980  x = (dw - fWidth) >> 1;
1981  y = (dh - fHeight) >> 1;
1982  break;
1983  case kRight:
1984  x = dw - (fWidth >> 1);
1985  y = (dh - fHeight) >> 1;
1986  break;
1987  case kLeft:
1988  x = -1 * (Int_t)(fWidth >> 1);
1989  y = (dh - fHeight) >> 1;
1990  break;
1991  case kTop:
1992  x = (dw - fWidth) >> 1;
1993  y = -1 * (Int_t)(fHeight >> 1);
1994  break;
1995  case kBottom:
1996  x = (dw - fWidth) >> 1;
1997  y = dh - (fHeight >> 1);
1998  break;
1999  case kTopLeft:
2000  x = -1 * (Int_t)(fWidth >> 1);
2001  y = -1 * (Int_t)(fHeight >> 1);
2002  break;
2003  case kTopRight:
2004  x = dw - (fWidth >> 1);
2005  y = -1 * (Int_t)(fHeight >> 1);
2006  break;
2007  case kBottomLeft:
2008  x = -1 * (Int_t)(fWidth >> 1);
2009  y = dh - (fHeight >> 1);
2010  break;
2011  case kBottomRight:
2012  x = dw - (fWidth >> 1);
2013  y = dh - (fHeight >> 1);
2014  break;
2015  }
2016 
2017  ax = x;
2018  ay = y;
2019 
2020  } else {
2021 
2022  return;
2023 
2024  }
2025 
2026  Move(ax, ay);
2027  SetWMPosition(ax, ay);
2028 }
2029 
2030 ////////////////////////////////////////////////////////////////////////////////
2031 /// Create a group frame. The title will be adopted and deleted by the
2032 /// group frame.
2033 
2034 TGGroupFrame::TGGroupFrame(const TGWindow *p, TGString *title,
2035  UInt_t options, GContext_t norm,
2036  FontStruct_t font, Pixel_t back) :
2037  TGCompositeFrame(p, 1, 1, options, back)
2038 {
2039  fText = title;
2040  fFontStruct = font;
2041  fNormGC = norm;
2042  fTitlePos = kLeft;
2043  fHasOwnFont = kFALSE;
2044 
2045  int max_ascent, max_descent;
2046  gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
2047  fBorderWidth = max_ascent + max_descent + 1;
2048 }
2049 
2050 ////////////////////////////////////////////////////////////////////////////////
2051 /// Create a group frame.
2052 
2053 TGGroupFrame::TGGroupFrame(const TGWindow *p, const char *title,
2054  UInt_t options, GContext_t norm,
2055  FontStruct_t font, Pixel_t back) :
2056  TGCompositeFrame(p, 1, 1, options, back)
2057 {
2058  fText = new TGString(!p && !title ? GetName() : title);
2059  fFontStruct = font;
2060  fNormGC = norm;
2061  fTitlePos = kLeft;
2062  fHasOwnFont = kFALSE;
2063 
2064  int max_ascent, max_descent;
2065  gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
2066  fBorderWidth = max_ascent + max_descent + 1;
2067 
2068  SetWindowName();
2069 }
2070 
2071 ////////////////////////////////////////////////////////////////////////////////
2072 /// Delete a group frame.
2073 
2074 TGGroupFrame::~TGGroupFrame()
2075 {
2076  if (fHasOwnFont) {
2077  TGGCPool *pool = fClient->GetGCPool();
2078  TGGC *gc = pool->FindGC(fNormGC);
2079  pool->FreeGC(gc);
2080  }
2081  delete fText;
2082 }
2083 
2084 ////////////////////////////////////////////////////////////////////////////////
2085 /// Returns default size.
2086 
2087 TGDimension TGGroupFrame::GetDefaultSize() const
2088 {
2089  UInt_t tw = gVirtualX->TextWidth(fFontStruct, fText->GetString(),
2090  fText->GetLength()) + 24;
2091 
2092  TGDimension dim = TGCompositeFrame::GetDefaultSize();
2093 
2094  return tw>dim.fWidth ? TGDimension(tw, dim.fHeight) : dim;
2095 }
2096 
2097 ////////////////////////////////////////////////////////////////////////////////
2098 /// Redraw the group frame. Need special DoRedraw() since we need to
2099 /// redraw with fBorderWidth=0.
2100 
2101 void TGGroupFrame::DoRedraw()
2102 {
2103  gVirtualX->ClearArea(fId, 0, 0, fWidth, fHeight);
2104 
2105  DrawBorder();
2106 }
2107 
2108 
2109 ////////////////////////////////////////////////////////////////////////////////
2110 /// Changes text color.
2111 /// If local is true color is changed locally, otherwise - globally.
2112 
2113 void TGGroupFrame::SetTextColor(Pixel_t color, Bool_t local)
2114 {
2115  TGGCPool *pool = fClient->GetResourcePool()->GetGCPool();
2116  TGGC *gc = pool->FindGC(fNormGC);
2117 
2118  if (gc && local) {
2119  gc = pool->GetGC((GCValues_t*)gc->GetAttributes(), kTRUE); // copy
2120  fHasOwnFont = kTRUE;
2121  }
2122  if (gc) {
2123  gc->SetForeground(color);
2124  fNormGC = gc->GetGC();
2125  }
2126  fClient->NeedRedraw(this);
2127 }
2128 
2129 ////////////////////////////////////////////////////////////////////////////////
2130 /// Changes text font.
2131 /// If local is true font is changed locally - otherwise globally.
2132 
2133 void TGGroupFrame::SetTextFont(FontStruct_t font, Bool_t local)
2134 {
2135  FontH_t v = gVirtualX->GetFontHandle(font);
2136  if (!v) return;
2137 
2138  fFontStruct = font;
2139 
2140  TGGCPool *pool = fClient->GetResourcePool()->GetGCPool();
2141  TGGC *gc = pool->FindGC(fNormGC);
2142 
2143  if (gc && local) {
2144  gc = pool->GetGC((GCValues_t*)gc->GetAttributes(), kTRUE); // copy
2145  fHasOwnFont = kTRUE;
2146  }
2147  if (gc) {
2148  gc->SetFont(v);
2149  fNormGC = gc->GetGC();
2150  }
2151  fClient->NeedRedraw(this);
2152 }
2153 
2154 ////////////////////////////////////////////////////////////////////////////////
2155 /// Changes text font specified by name.
2156 /// If local is true font is changed locally - otherwise globally.
2157 
2158 void TGGroupFrame::SetTextFont(const char *fontName, Bool_t local)
2159 {
2160  TGFont *font = fClient->GetFont(fontName);
2161 
2162  if (font) {
2163  SetTextFont(font->GetFontStruct(), local);
2164  }
2165 }
2166 
2167 ////////////////////////////////////////////////////////////////////////////////
2168 /// Returns kTRUE if text attributes are unique,
2169 /// returns kFALSE if text attributes are shared (global).
2170 
2171 Bool_t TGGroupFrame::HasOwnFont() const
2172 {
2173  return fHasOwnFont;
2174 }
2175 
2176 ////////////////////////////////////////////////////////////////////////////////
2177 /// Draw border of around the group frame.
2178 ///
2179 /// if frame is kRaisedFrame - a frame border is of "wall style",
2180 /// otherwise of "groove style".
2181 
2182 void TGGroupFrame::DrawBorder()
2183 {
2184  Int_t x, y, l, t, r, b, gl, gr, sep, max_ascent, max_descent;
2185 
2186  UInt_t tw = gVirtualX->TextWidth(fFontStruct, fText->GetString(), fText->GetLength());
2187  gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
2188 
2189  l = 0;
2190  t = (max_ascent + max_descent + 2) >> 1;
2191  r = fWidth - 1;
2192  // next three lines are for backward compatibility in case of horizontal layout
2193  // coverity[returned_null]
2194  // coverity[dereference]
2195  TGLayoutManager * lm = GetLayoutManager();
2196  if ((lm->InheritsFrom(TGHorizontalLayout::Class())) ||
2197  (lm->InheritsFrom(TGMatrixLayout::Class())))
2198  b = fHeight - 1;
2199  else
2200  b = fHeight - t;
2201 
2202  sep = 3;
2203  UInt_t rr = 5 + (sep << 1) + tw;
2204 
2205  switch (fTitlePos) {
2206  case kRight:
2207  gl = fWidth>rr ? Int_t(fWidth - rr) : 5 + sep;
2208  break;
2209  case kCenter:
2210  gl = fWidth>tw ? Int_t((fWidth - tw)>>1) - sep : 5 + sep;
2211  break;
2212  case kLeft:
2213  default:
2214  gl = 5 + sep;
2215  }
2216  gr = gl + tw + (sep << 1);
2217 
2218  switch (fOptions & (kSunkenFrame | kRaisedFrame)) {
2219  case kRaisedFrame:
2220  gVirtualX->DrawLine(fId, GetHilightGC()(), l, t, gl, t);
2221  gVirtualX->DrawLine(fId, GetShadowGC()(), l+1, t+1, gl, t+1);
2222 
2223  gVirtualX->DrawLine(fId, GetHilightGC()(), gr, t, r-1, t);
2224  gVirtualX->DrawLine(fId, GetShadowGC()(), gr, t+1, r-2, t+1);
2225 
2226  gVirtualX->DrawLine(fId, GetHilightGC()(), r-1, t, r-1, b-1);
2227  gVirtualX->DrawLine(fId, GetShadowGC()(), r, t, r, b);
2228 
2229  gVirtualX->DrawLine(fId, GetHilightGC()(), r-1, b-1, l, b-1);
2230  gVirtualX->DrawLine(fId, GetShadowGC()(), r, b, l, b);
2231 
2232  gVirtualX->DrawLine(fId, GetHilightGC()(), l, b-1, l, t);
2233  gVirtualX->DrawLine(fId, GetShadowGC()(), l+1, b-2, l+1, t+1);
2234  break;
2235  case kSunkenFrame:
2236  default:
2237  gVirtualX->DrawLine(fId, GetShadowGC()(), l, t, gl, t);
2238  gVirtualX->DrawLine(fId, GetHilightGC()(), l+1, t+1, gl, t+1);
2239 
2240  gVirtualX->DrawLine(fId, GetShadowGC()(), gr, t, r-1, t);
2241  gVirtualX->DrawLine(fId, GetHilightGC()(), gr, t+1, r-2, t+1);
2242 
2243  gVirtualX->DrawLine(fId, GetShadowGC()(), r-1, t, r-1, b-1);
2244  gVirtualX->DrawLine(fId, GetHilightGC()(), r, t, r, b);
2245 
2246  gVirtualX->DrawLine(fId, GetShadowGC()(), r-1, b-1, l, b-1);
2247  gVirtualX->DrawLine(fId, GetHilightGC()(), r, b, l, b);
2248 
2249  gVirtualX->DrawLine(fId, GetShadowGC()(), l, b-1, l, t);
2250  gVirtualX->DrawLine(fId, GetHilightGC()(), l+1, b-2, l+1, t+1);
2251  break;
2252  }
2253 
2254  x = gl + sep;
2255  y = 1;
2256 
2257  fText->Draw(fId, fNormGC, x, y + max_ascent);
2258 }
2259 
2260 ////////////////////////////////////////////////////////////////////////////////
2261 /// Set or change title of the group frame. Titlte TGString is adopted
2262 /// by the TGGroupFrame.
2263 
2264 void TGGroupFrame::SetTitle(TGString *title)
2265 {
2266  if (!title) {
2267  Warning("SetTitle", "title cannot be 0, try \"\"");
2268  title = new TGString("");
2269  }
2270 
2271  delete fText;
2272 
2273  fText = title;
2274  fClient->NeedRedraw(this);
2275 }
2276 
2277 ////////////////////////////////////////////////////////////////////////////////
2278 /// Set or change title of the group frame.
2279 
2280 void TGGroupFrame::SetTitle(const char *title)
2281 {
2282  if (!title) {
2283  Error("SetTitle", "title cannot be 0, try \"\"");
2284  return;
2285  }
2286 
2287  SetTitle(new TGString(title));
2288 }
2289 
2290 ////////////////////////////////////////////////////////////////////////////////
2291 /// Return default font structure in use.
2292 
2293 FontStruct_t TGGroupFrame::GetDefaultFontStruct()
2294 {
2295  if (!fgDefaultFont && gClient)
2296  fgDefaultFont = gClient->GetResourcePool()->GetDefaultFont();
2297  return fgDefaultFont->GetFontStruct();
2298 }
2299 
2300 ////////////////////////////////////////////////////////////////////////////////
2301 /// Return default graphics context in use.
2302 
2303 const TGGC &TGGroupFrame::GetDefaultGC()
2304 {
2305  if (!fgDefaultGC && gClient)
2306  fgDefaultGC = gClient->GetResourcePool()->GetFrameGC();
2307  return *fgDefaultGC;
2308 }
2309 
2310 ////////////////////////////////////////////////////////////////////////////////
2311 /// Header Frame constructor.
2312 
2313 TGHeaderFrame::TGHeaderFrame(const TGWindow *p, UInt_t w, UInt_t h,
2314  UInt_t options, Pixel_t back) :
2315  TGHorizontalFrame(p, w, h, options | kVerticalFrame, back)
2316 {
2317  fSplitCursor = kNone;
2318  fSplitCursor = gVirtualX->CreateCursor(kArrowHor);
2319  fOverSplitter = false;
2320  fOverButton = -1;
2321  fLastButton = -1;
2322  fNColumns = 1;
2323  fColHeader = 0;
2324  fSplitHeader = 0;
2325 
2326  gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
2327  kButtonPressMask | kButtonReleaseMask,
2328  kNone, kNone);
2329  AddInput(kPointerMotionMask);
2330 }
2331 
2332 ////////////////////////////////////////////////////////////////////////////////
2333 /// Set columns information in the header frame.
2334 
2335 void TGHeaderFrame::SetColumnsInfo(Int_t nColumns, TGTextButton **colHeader,
2336  TGVFileSplitter **splitHeader)
2337 {
2338  fNColumns = nColumns;
2339  fColHeader = colHeader;
2340  fSplitHeader = splitHeader;
2341 }
2342 
2343 ////////////////////////////////////////////////////////////////////////////////
2344 /// Handle mouse button event in header frame.
2345 
2346 Bool_t TGHeaderFrame::HandleButton(Event_t* event)
2347 {
2348  if ( event->fY > 0 &&
2349  event->fY <= (Int_t) this->GetHeight() ) {
2350  for (Int_t i = 1; i < fNColumns; ++i ) {
2351  if ( event->fX < fColHeader[i]->GetX() &&
2352  event->fX >= fColHeader[i-1]->GetX() ) {
2353  if ( fOverSplitter ) {
2354  if ( event->fX <= fColHeader[i-1]->GetX() + 5 )
2355  fSplitHeader[i-2]->HandleButton(event);
2356  else
2357  fSplitHeader[i-1]->HandleButton(event);
2358  } else {
2359  if ( event->fType == kButtonPress ) {
2360  fLastButton = i - 1;
2361  } else {
2362  fLastButton = -1;
2363  }
2364  event->fX -= fColHeader[i-1]->GetX();
2365  fColHeader[i-1]->HandleButton(event);
2366  }
2367  break;
2368  }
2369  }
2370  }
2371 
2372  return kTRUE;
2373 }
2374 
2375 ////////////////////////////////////////////////////////////////////////////////
2376 /// Handle double click mouse event in header frame.
2377 
2378 Bool_t TGHeaderFrame::HandleDoubleClick(Event_t *event)
2379 {
2380  if ( event->fY > 0 &&
2381  event->fY <= (Int_t) this->GetHeight() ) {
2382  for (Int_t i = 1; i < fNColumns; ++i ) {
2383  if ( event->fX < fColHeader[i]->GetX() &&
2384  event->fX >= fColHeader[i-1]->GetX() ) {
2385  if ( fOverSplitter ) {
2386  if ( event->fX <= fColHeader[i-1]->GetX() + 5 )
2387  fSplitHeader[i-2]->HandleDoubleClick(event);
2388  else
2389  fSplitHeader[i-1]->HandleDoubleClick(event);
2390  } else {
2391  event->fX -= fColHeader[i-1]->GetX();
2392  fColHeader[i-1]->HandleDoubleClick(event);
2393  }
2394  break;
2395  }
2396  }
2397  }
2398 
2399  return kTRUE;
2400 }
2401 
2402 ////////////////////////////////////////////////////////////////////////////////
2403 /// Handle mouse motion events in header frame.
2404 
2405 Bool_t TGHeaderFrame::HandleMotion(Event_t* event)
2406 {
2407  if ( event->fY > 0 &&
2408  event->fY <= (Int_t) this->GetHeight() ) {
2409  Bool_t inMiddle = false;
2410 
2411  for (Int_t i = 1; i < fNColumns; ++i ) {
2412  if ( event->fX > fColHeader[i]->GetX() - 5 &&
2413  event->fX < fColHeader[i]->GetX() + 5 ) {
2414  inMiddle = true;
2415  }
2416  if ( event->fX < fColHeader[i]->GetX() &&
2417  event->fX >= fColHeader[i-1]->GetX() ) {
2418  fOverButton = i - 1;
2419  }
2420  }
2421  fOverSplitter = inMiddle;
2422  if ( fOverSplitter ) {
2423  gVirtualX->SetCursor(fId, fSplitCursor);
2424  }
2425  else {
2426  gVirtualX->SetCursor(fId, kNone);
2427  }
2428  }
2429  return kTRUE;
2430 }
2431 
2432 ////////////////////////////////////////////////////////////////////////////////
2433 /// Save a user color in a C++ macro file - used in SavePrimitive().
2434 
2435 void TGFrame::SaveUserColor(std::ostream &out, Option_t *option)
2436 {
2437  char quote = '"';
2438 
2439  if (gROOT->ClassSaved(TGFrame::Class())) {
2440  out << std::endl;
2441  } else {
2442  // declare a color variable to reflect required user changes
2443  out << std::endl;
2444  out << " ULong_t ucolor; // will reflect user color changes" << std::endl;
2445  }
2446  ULong_t ucolor;
2447  if (option && !strcmp(option, "slider"))
2448  ucolor = GetDefaultFrameBackground();
2449  else
2450  ucolor = GetBackground();
2451  if ((ucolor != fgUserColor) || (ucolor == GetWhitePixel())) {
2452  const char *ucolorname = TColor::PixelAsHexString(ucolor);
2453  out << " gClient->GetColorByName(" << quote << ucolorname << quote
2454  << ",ucolor);" << std::endl;
2455  fgUserColor = ucolor;
2456  }
2457 }
2458 
2459 ////////////////////////////////////////////////////////////////////////////////
2460 /// Returns a frame option string - used in SavePrimitive().
2461 
2462 TString TGFrame::GetOptionString() const
2463 {
2464  TString options;
2465 
2466  if (!GetOptions()) {
2467  options = "kChildFrame";
2468  } else {
2469  if (fOptions & kMainFrame) {
2470  if (options.Length() == 0) options = "kMainFrame";
2471  else options += " | kMainFrame";
2472  }
2473  if (fOptions & kVerticalFrame) {
2474  if (options.Length() == 0) options = "kVerticalFrame";
2475  else options += " | kVerticalFrame";
2476  }
2477  if (fOptions & kHorizontalFrame) {
2478  if (options.Length() == 0) options = "kHorizontalFrame";
2479  else options += " | kHorizontalFrame";
2480  }
2481  if (fOptions & kSunkenFrame) {
2482  if (options.Length() == 0) options = "kSunkenFrame";
2483  else options += " | kSunkenFrame";
2484  }
2485  if (fOptions & kRaisedFrame) {
2486  if (options.Length() == 0) options = "kRaisedFrame";
2487  else options += " | kRaisedFrame";
2488  }
2489  if (fOptions & kDoubleBorder) {
2490  if (options.Length() == 0) options = "kDoubleBorder";
2491  else options += " | kDoubleBorder";
2492  }
2493  if (fOptions & kFitWidth) {
2494  if (options.Length() == 0) options = "kFitWidth";
2495  else options += " | kFitWidth";
2496  }
2497  if (fOptions & kFixedWidth) {
2498  if (options.Length() == 0) options = "kFixedWidth";
2499  else options += " | kFixedWidth";
2500  }
2501  if (fOptions & kFitHeight) {
2502  if (options.Length() == 0) options = "kFitHeight";
2503  else options += " | kFitHeight";
2504  }
2505  if (fOptions & kFixedHeight) {
2506  if (options.Length() == 0) options = "kFixedHeight";
2507  else options += " | kFixedHeight";
2508  }
2509  if (fOptions & kOwnBackground) {
2510  if (options.Length() == 0) options = "kOwnBackground";
2511  else options += " | kOwnBackground";
2512  }
2513  if (fOptions & kTransientFrame) {
2514  if (options.Length() == 0) options = "kTransientFrame";
2515  else options += " | kTransientFrame";
2516  }
2517  if (fOptions & kTempFrame) {
2518  if (options.Length() == 0) options = "kTempFrame";
2519  else options += " | kTempFrame";
2520  }
2521  }
2522  return options;
2523 }
2524 
2525 ////////////////////////////////////////////////////////////////////////////////
2526 /// Returns MWM decoration hints as a string - used in SavePrimitive().
2527 
2528 TString TGMainFrame::GetMWMvalueString() const
2529 {
2530  TString hints;
2531 
2532  if (fMWMValue) {
2533  if (fMWMValue & kMWMDecorAll) {
2534  if (hints.Length() == 0) hints = "kMWMDecorAll";
2535  else hints += " | kMWMDecorAll";
2536  }
2537  if (fMWMValue & kMWMDecorBorder) {
2538  if (hints.Length() == 0) hints = "kMWMDecorBorder";
2539  else hints += " | kMWMDecorBorder";
2540  }
2541  if (fMWMValue & kMWMDecorResizeH) {
2542  if (hints.Length() == 0) hints = "kMWMDecorResizeH";
2543  else hints += " | kMWMDecorResizeH";
2544  }
2545  if (fMWMValue & kMWMDecorTitle) {
2546  if (hints.Length() == 0) hints = "kMWMDecorTitle";
2547  else hints += " | kMWMDecorTitle";
2548  }
2549  if (fMWMValue & kMWMDecorMenu) {
2550  if (hints.Length() == 0) hints = "kMWMDecorMenu";
2551  else hints += " | kMWMDecorMenu";
2552  }
2553  if (fMWMValue & kMWMDecorMinimize) {
2554  if (hints.Length() == 0) hints = "kMWMDecorMinimize";
2555  else hints += " | kMWMDecorMinimize";
2556  }
2557  if (fMWMValue & kMWMDecorMaximize) {
2558  if (hints.Length() == 0) hints = "kMWMDecorMaximize";
2559  else hints += " | kMWMDecorMaximize";
2560  }
2561  }
2562  return hints;
2563 }
2564 
2565 ////////////////////////////////////////////////////////////////////////////////
2566 /// Returns MWM function hints as a string - used in SavePrimitive().
2567 
2568 TString TGMainFrame::GetMWMfuncString() const
2569 {
2570  TString hints;
2571 
2572  if (fMWMFuncs) {
2573 
2574  if (fMWMFuncs & kMWMFuncAll) {
2575  if (hints.Length() == 0) hints = "kMWMFuncAll";
2576  else hints += " | kMWMFuncAll";
2577  }
2578  if (fMWMFuncs & kMWMFuncResize) {
2579  if (hints.Length() == 0) hints = "kMWMFuncResize";
2580  else hints += " | kMWMFuncResize";
2581  }
2582  if (fMWMFuncs & kMWMFuncMove) {
2583  if (hints.Length() == 0) hints = "kMWMFuncMove";
2584  else hints += " | kMWMFuncMove";
2585  }
2586  if (fMWMFuncs & kMWMFuncMinimize) {
2587  if (hints.Length() == 0) hints = "kMWMFuncMinimize";
2588  else hints += " | kMWMFuncMinimize";
2589  }
2590  if (fMWMFuncs & kMWMFuncMaximize) {
2591  if (hints.Length() == 0) hints = "kMWMFuncMaximize";
2592  else hints += " | kMWMFuncMaximize";
2593  }
2594  if (fMWMFuncs & kMWMFuncClose) {
2595  if (hints.Length() == 0) hints = "kMWMFuncClose";
2596  else hints += " | kMWMFuncClose";
2597  }
2598  }
2599  return hints;
2600 }
2601 
2602 ////////////////////////////////////////////////////////////////////////////////
2603 /// Returns MWM input mode hints as a string - used in SavePrimitive().
2604 
2605 TString TGMainFrame::GetMWMinpString() const
2606 {
2607  TString hints;
2608 
2609  if (fMWMInput == 0) hints = "kMWMInputModeless";
2610 
2611  if (fMWMInput == 1) hints = "kMWMInputPrimaryApplicationModal";
2612 
2613  if (fMWMInput == 2) hints = "kMWMInputSystemModal";
2614 
2615  if (fMWMInput == 3) hints = "kMWMInputFullApplicationModal";
2616 
2617  return hints;
2618 }
2619 
2620 ////////////////////////////////////////////////////////////////////////////////
2621 /// Auxilary protected method used to save subframes.
2622 
2623 void TGCompositeFrame::SavePrimitiveSubframes(std::ostream &out, Option_t *option /*= ""*/)
2624 {
2625  if (fLayoutBroken)
2626  out << " " << GetName() << "->SetLayoutBroken(kTRUE);" << std::endl;
2627 
2628  if (!fList) return;
2629 
2630  char quote = '"';
2631 
2632  TGFrameElement *el;
2633  static TGHSplitter *hsplit = 0;
2634  static TGVSplitter *vsplit = 0;
2635  TList *signalslist;
2636  TList *connlist;
2637  TQConnection *conn;
2638  TString signal_name, slot_name;
2639 
2640  TIter next(fList);
2641 
2642  while ((el = (TGFrameElement *) next())) {
2643 
2644  // Don't save hidden (unmapped) frames having a parent different
2645  // than this frame. Solves a problem with shared frames
2646  // (e.g. shared menus in the new Browser)
2647  if ((!(el->fState & kIsVisible)) && (el->fFrame->GetParent() != this))
2648  continue;
2649 
2650  // Remember if the frame to be saved is a TG(H,V)Splitter
2651  // See comments below and in TG[H/V]Splitter::SavePrimitive()
2652  if (el->fFrame->InheritsFrom("TGVSplitter")) {
2653  vsplit = (TGVSplitter *)el->fFrame;
2654  if (vsplit->GetLeft())
2655  vsplit = 0;
2656  }
2657  else if (el->fFrame->InheritsFrom("TGHSplitter")) {
2658  hsplit = (TGHSplitter *)el->fFrame;
2659  if (hsplit->GetAbove())
2660  hsplit = 0;
2661  }
2662  el->fFrame->SavePrimitive(out, option);
2663  out << " " << GetName() << "->AddFrame(" << el->fFrame->GetName();
2664  el->fLayout->SavePrimitive(out, option);
2665  out << ");"<< std::endl;
2666  if (IsLayoutBroken()) {
2667  out << " " << el->fFrame->GetName() << "->MoveResize(";
2668  out << el->fFrame->GetX() << "," << el->fFrame->GetY() << ",";
2669  out << el->fFrame->GetWidth() << "," << el->fFrame->GetHeight();
2670  out << ");" << std::endl;
2671  }
2672  // TG(H,V)Splitter->SetFrame(theframe) can only be saved _AFTER_
2673  // having saved "theframe", when "theframe" is either at right
2674  // or below the splitter (that means after the splitter in the
2675  // list of frames), otherwise "theframe" would be undefined
2676  // (aka used before to be created)...
2677  if (vsplit && el->fFrame == vsplit->GetFrame()) {
2678  out << " " << vsplit->GetName() << "->SetFrame(" << vsplit->GetFrame()->GetName();
2679  if (vsplit->GetLeft()) out << ",kTRUE);" << std::endl;
2680  else out << ",kFALSE);"<< std::endl;
2681  vsplit = 0;
2682  }
2683  if (hsplit && el->fFrame == hsplit->GetFrame()) {
2684  out << " " << hsplit->GetName() << "->SetFrame(" << hsplit->GetFrame()->GetName();
2685  if (hsplit->GetAbove()) out << ",kTRUE);" << std::endl;
2686  else out << ",kFALSE);"<< std::endl;
2687  hsplit = 0;
2688  }
2689 
2690  if (!(el->fState & kIsVisible)) {
2691  gListOfHiddenFrames->Add(el->fFrame);
2692  }
2693 
2694  // saving signals/slots
2695  signalslist = (TList*)el->fFrame->GetListOfSignals();
2696  if (!signalslist) continue;
2697  connlist = (TList*)signalslist->Last();
2698  if (connlist) {
2699  conn = (TQConnection*)connlist->Last();
2700  if (conn) {
2701  signal_name = connlist->GetName();
2702  slot_name = conn->GetName();
2703  Int_t eq = slot_name.First('=');
2704  Int_t rb = slot_name.First(')');
2705  if (eq != -1)
2706  slot_name.Remove(eq, rb-eq);
2707  out << " " << el->fFrame->GetName() << "->Connect(" << quote << signal_name
2708  << quote << ", 0, 0, " << quote << slot_name << quote << ");" << std::endl;
2709 
2710  TList *lsl = (TList *)gROOT->GetListOfSpecials()->FindObject("ListOfSlots");
2711  if (lsl) {
2712  TObjString *slotel = (TObjString *)lsl->FindObject(slot_name);
2713  if (!slotel)
2714  lsl->Add(new TObjString(slot_name));
2715  }
2716  }
2717  }
2718  }
2719  out << std::endl;
2720 }
2721 
2722 ////////////////////////////////////////////////////////////////////////////////
2723 /// Save a composite frame widget as a C++ statement(s) on output stream out.
2724 
2725 void TGCompositeFrame::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2726 {
2727  if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
2728 
2729  if (!strcmp(GetName(),"")) {
2730  SetName(Form("fCompositeframe%d",fgCounter));
2731  fgCounter++;
2732  }
2733 
2734  out << std::endl << " // composite frame" << std::endl;
2735  out << " TGCompositeFrame *";
2736  out << GetName() << " = new TGCompositeFrame(" << fParent->GetName()
2737  << "," << GetWidth() << "," << GetHeight();
2738 
2739  if (fBackground == GetDefaultFrameBackground()) {
2740  if (!GetOptions()) {
2741  out << ");" << std::endl;
2742  } else {
2743  out << "," << GetOptionString() <<");" << std::endl;
2744  }
2745  } else {
2746  out << "," << GetOptionString() << ",ucolor);" << std::endl;
2747  }
2748  if (option && strstr(option, "keep_names"))
2749  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
2750 
2751  // setting layout manager if it differs from the composite frame type
2752  // coverity[returned_null]
2753  // coverity[dereference]
2754  TGLayoutManager *lm = GetLayoutManager();
2755  if ((GetOptions() & kHorizontalFrame) &&
2756  (lm->InheritsFrom(TGHorizontalLayout::Class()))) {
2757  ;
2758  } else if ((GetOptions() & kVerticalFrame) &&
2759  (lm->InheritsFrom(TGVerticalLayout::Class()))) {
2760  ;
2761  } else {
2762  out << " " << GetName() <<"->SetLayoutManager(";
2763  lm->SavePrimitive(out, option);
2764  out << ");"<< std::endl;
2765  }
2766 
2767  SavePrimitiveSubframes(out, option);
2768 }
2769 
2770 ////////////////////////////////////////////////////////////////////////////////
2771 /// Save the GUI main frame widget in a C++ macro file.
2772 
2773 void TGMainFrame::SaveSource(const char *filename, Option_t *option)
2774 {
2775  // iteration over all active classes to exclude the base ones
2776  TString opt = option;
2777  TBits *bc = new TBits();
2778  TClass *c1, *c2, *c3;
2779  UInt_t k = 0; // will mark k-bit of TBits if the class is a base class
2780 
2781  TIter nextc1(gROOT->GetListOfClasses());
2782  //gROOT->GetListOfClasses()->ls(); // valid. test
2783  while((c1 = (TClass *)nextc1())) {
2784 
2785  // resets bit TClass::kClassSaved for all classes
2786  c1->ResetBit(TClass::kClassSaved);
2787 
2788  TIter nextc2(gROOT->GetListOfClasses());
2789  while ((c2 = (TClass *)nextc2())) {
2790  if (c1==c2) continue;
2791  else {
2792  c3 = c2->GetBaseClass(c1);
2793  if (c3 != 0) {
2794  bc->SetBitNumber(k, kTRUE);
2795  break;
2796  }
2797  }
2798  }
2799  k++;
2800  }
2801 
2802  TList *ilist = new TList(); // will contain include file names without '.h'
2803  ilist->SetName("ListOfIncludes");
2804  gROOT->GetListOfSpecials()->Add(ilist);
2805  k=0;
2806 
2807  // completes list of include file names
2808  TIter nextdo(gROOT->GetListOfClasses());
2809  while ((c2 = (TClass *)nextdo())) {
2810  // for used GUI header files
2811  if (bc->TestBitNumber(k) == 0 && c2->InheritsFrom(TGObject::Class()) == 1) {
2812  // for any used ROOT header files activate the line below, comment the line above
2813  //if (bc->TestBitNumber(k) == 0) {
2814  const char *iname;
2815  iname = c2->GetDeclFileName();
2816  if (iname[0] && strstr(iname,".h")) {
2817  const char *lastsl = strrchr(iname,'/');
2818  if (lastsl) iname = lastsl + 1;
2819  char *tname = new char[strlen(iname)+1];
2820  Int_t i=0;
2821  while (*iname != '.') {
2822  tname[i] = *iname;
2823  i++; iname++;
2824  }
2825  tname[i] = 0; //tname = include file name without '.h'
2826 
2827  TObjString *iel = (TObjString *)ilist->FindObject(tname);
2828  if (!iel) {
2829  ilist->Add(new TObjString(tname));
2830  }
2831  // Weird, but when saving a canvas, the following two classes
2832  // may be missing if the toolbar has not been displayed...
2833  if (strstr(tname, "TRootCanvas")) {
2834  if (!ilist->FindObject("TGDockableFrame"))
2835  ilist->Add(new TObjString("TGDockableFrame"));
2836  if (!ilist->FindObject("TG3DLine"))
2837  ilist->Add(new TObjString("TG3DLine"));
2838  }
2839  delete [] tname;
2840  }
2841  k++; continue;
2842  }
2843  k++;
2844  }
2845 
2846  char quote = '"';
2847  std::ofstream out;
2848 
2849  TString ff = filename && strlen(filename) ? filename : "Rootappl.C";
2850 
2851  // Computes the main method name.
2852  const char *fname = gSystem->BaseName(ff.Data());
2853  Int_t lenfname = strlen(fname);
2854  char *sname = new char[lenfname+1];
2855 
2856  Int_t i = 0;
2857  while ((*fname != '.') && (i < lenfname)) {
2858  sname[i] = *fname;
2859  i++; fname++;
2860  }
2861  if (i == lenfname)
2862  ff += ".C";
2863  sname[i] = 0;
2864 
2865  out.open(ff.Data(), std::ios::out);
2866  if (!out.good()) {
2867  Error("SaveSource", "cannot open file: %s", ff.Data());
2868  delete [] sname;
2869  return;
2870  }
2871 
2872  // writes include files in C++ macro
2873  TObjString *inc;
2874  ilist = (TList *)gROOT->GetListOfSpecials()->FindObject("ListOfIncludes");
2875 
2876  if (!ilist) {
2877  delete [] sname;
2878  return;
2879  }
2880 
2881  // write macro header, date/time stamp as string, and the used Root version
2882  TDatime t;
2883  out <<"// Mainframe macro generated from application: "<< gApplication->Argv(0) << std::endl;
2884  out <<"// By ROOT version "<< gROOT->GetVersion() <<" on "<<t.AsSQLString()<< std::endl;
2885  out << std::endl;
2886 
2887  TIter nexti(ilist);
2888  while((inc = (TObjString *)nexti())) {
2889  out << "#ifndef ROOT_" << inc->GetString() << std::endl;
2890  out << "#include " << quote << inc->GetString() << ".h" << quote << std::endl;
2891  out << "#endif" << std::endl;
2892  if (strstr(inc->GetString(),"TRootEmbeddedCanvas")) {
2893  out << "#ifndef ROOT_TCanvas" << std::endl;
2894  out << "#include " << quote << "TCanvas.h" << quote << std::endl;
2895  out << "#endif" << std::endl;
2896  }
2897  }
2898  out << std::endl << "#include " << quote << "Riostream.h" << quote << std::endl;
2899  // deletes created ListOfIncludes
2900  gROOT->GetListOfSpecials()->Remove(ilist);
2901  ilist->Delete();
2902  delete ilist;
2903  delete bc;
2904 
2905  // writes the macro entry point equal to the fname
2906  out << std::endl;
2907  out << "void " << sname << "()" << std::endl;
2908  out <<"{"<< std::endl;
2909  delete [] sname;
2910 
2911  gListOfHiddenFrames->Clear();
2912 
2913  // saivng slots
2914  TList *lSlots = new TList;
2915  lSlots->SetName("ListOfSlots");
2916  gROOT->GetListOfSpecials()->Add(lSlots);
2917 
2918  TGMainFrame::SavePrimitive(out, option);
2919 
2920  if (strlen(fClassName) || strlen(fResourceName)) {
2921  out << " " << GetName() << "->SetClassHints(" << quote << fClassName
2922  << quote << "," << quote << fResourceName << quote << ");" << std::endl;
2923  }
2924 
2925  GetMWMHints(fMWMValue, fMWMFuncs, fMWMInput);
2926  if (fMWMValue || fMWMFuncs || fMWMInput) {
2927  out << " " << GetName() << "->SetMWMHints(";
2928  out << GetMWMvalueString() << "," << std::endl;
2929  out << " ";
2930  out << GetMWMfuncString() << "," << std::endl;
2931  out << " ";
2932  out << GetMWMinpString() << ");"<< std::endl;
2933  }
2934 
2935 /// GetWMPosition(fWMX, fWMY);
2936 /// if ((fWMX != -1) || (fWMY != -1)) {
2937 /// out <<" "<<GetName()<<"->SetWMPosition("<<fWMX<<","<<fWMY<<");"<<std::endl;
2938 /// } // does not work - fixed via Move() below...
2939 
2940  GetWMSize(fWMWidth, fWMHeight);
2941  if (fWMWidth != UInt_t(-1) || fWMHeight != UInt_t(-1)) {
2942  out <<" "<<GetName()<<"->SetWMSize("<<fWMWidth<<","<<fWMHeight<<");"<<std::endl;
2943  }
2944 
2945  GetWMSizeHints(fWMMinWidth, fWMMinHeight, fWMMaxWidth, fWMMaxHeight, fWMWidthInc, fWMHeightInc);
2946  if (fWMMinWidth != UInt_t(-1) || fWMMinHeight != UInt_t(-1) ||
2947  fWMMaxWidth != UInt_t(-1) || fWMMaxHeight != UInt_t(-1) ||
2948  fWMWidthInc != UInt_t(-1) || fWMHeightInc != UInt_t(-1)) {
2949  out <<" "<<GetName()<<"->SetWMSizeHints("<<fWMMinWidth<<","<<fWMMinHeight
2950  <<","<<fWMMaxWidth<<","<<fWMMaxHeight
2951  <<","<<fWMWidthInc<<","<<fWMHeightInc <<");"<<std::endl;
2952  }
2953 
2954  out << " " <<GetName()<< "->MapSubwindows();" << std::endl;
2955 
2956  TIter nexth(gListOfHiddenFrames);
2957  TGFrame *fhidden;
2958  while ((fhidden = (TGFrame*)nexth())) {
2959  out << " " <<fhidden->GetName()<< "->UnmapWindow();" << std::endl;
2960  }
2961 
2962  out << std::endl;
2963  gListOfHiddenFrames->Clear();
2964 
2965  Bool_t usexy = kFALSE;
2966  // coverity[returned_null]
2967  // coverity[dereference]
2968  TGLayoutManager * lm = GetLayoutManager();
2969  if (lm->InheritsFrom("TGXYLayout"))
2970  usexy = kTRUE;
2971 
2972  if (!usexy)
2973  out << " " <<GetName()<< "->Resize("<< GetName()<< "->GetDefaultSize());" << std::endl;
2974  else
2975  out << " " <<GetName()<< "->Resize("<< GetWidth()<<","<<GetHeight()<<");"<<std::endl;
2976 
2977  out << " " <<GetName()<< "->MapWindow();" <<std::endl;
2978 
2979  GetWMPosition(fWMX, fWMY);
2980  if ((fWMX != -1) || (fWMY != -1)) {
2981  out <<" "<<GetName()<<"->Move("<<fWMX<<","<<fWMY<<");"<<std::endl;
2982  }
2983 
2984  // needed in case the frame was resized
2985  // otherwhice the frame became bigger showing all hidden widgets (layout algorithm)
2986  if (!usexy) out << " " <<GetName()<< "->Resize("<< GetWidth()<<","<<GetHeight()<<");"<<std::endl;
2987  out << "} " << std::endl;
2988 
2989  // writing slots
2990  TList *sl = (TList *)gROOT->GetListOfSpecials()->FindObject("ListOfSlots");
2991  if (sl) {
2992  TIter nextsl(sl);
2993  TObjString *slobj;
2994  Int_t pnumber = 1;
2995 
2996  while ((slobj = (TObjString*) nextsl())) {
2997  TString s = slobj->GetString();
2998  TString p = "";
2999  Int_t lb, rb, eq;
3000  lb = s.First('(');
3001  rb = s.First(')');
3002  eq = s.First('=');
3003  out << std::endl;
3004 
3005  if (rb - lb > 1 && eq == -1) {
3006  p = TString::Format(" par%d", pnumber);
3007  s.Insert(rb, p);
3008  pnumber++;
3009  out << "void " << s << std::endl;
3010  out << "{" << std::endl;
3011  s = slobj->GetString();
3012  s[rb] = ' ';
3013  out << " std::cout << " << quote << "Slot " << s << quote
3014  << " <<" << p << " << " << quote << ")" << quote
3015  << " << std::endl; " << std::endl;
3016  } else {
3017  if (eq != -1) {
3018  s.Remove(eq, rb-eq);
3019  out << "void " << s << std::endl;
3020  out << "{" << std::endl;
3021  out << " std::cout << " << quote << "Slot " << s
3022  << quote << " << std::endl; " << std::endl;
3023  } else {
3024  out << "void " << slobj->GetString() << std::endl;
3025  out << "{" << std::endl;
3026  out << " std::cout << " << quote << "Slot " << slobj->GetString()
3027  << quote << " << std::endl; " << std::endl;
3028  }
3029  }
3030  out << "}" << std::endl;
3031  }
3032  gROOT->GetListOfSpecials()->Remove(sl);
3033  sl->Delete();
3034  delete sl;
3035  }
3036  out.close();
3037 
3038  if (!opt.Contains("quiet"))
3039  printf(" C++ macro file %s has been generated\n", gSystem->BaseName(ff.Data()));
3040 
3041  // reset bit TClass::kClassSaved for all classes
3042  nextc1.Reset();
3043  while((c1=(TClass*)nextc1())) {
3044  c1->ResetBit(TClass::kClassSaved);
3045  }
3046 }
3047 
3048 ////////////////////////////////////////////////////////////////////////////////
3049 /// Save a main frame widget as a C++ statement(s) on output stream out.
3050 
3051 void TGMainFrame::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
3052 {
3053  if (fParent != gClient->GetDefaultRoot()) { // frame is embedded
3054  fOptions &= ~kMainFrame;
3055  TGCompositeFrame::SavePrimitive(out, option);
3056  fOptions |= kMainFrame;
3057  return;
3058  }
3059 
3060  char quote = '"';
3061 
3062  out << std::endl << " // main frame" << std::endl;
3063  out << " TGMainFrame *";
3064  out << GetName() << " = new TGMainFrame(gClient->GetRoot(),10,10," // layout alg.
3065  << GetOptionString() << ");" <<std::endl;
3066  if (option && strstr(option, "keep_names"))
3067  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
3068 
3069  // setting layout manager if it differs from the main frame type
3070  // coverity[returned_null]
3071  // coverity[dereference]
3072  TGLayoutManager * lm = GetLayoutManager();
3073  if ((GetOptions() & kHorizontalFrame) &&
3074  (lm->InheritsFrom(TGHorizontalLayout::Class()))) {
3075  ;
3076  } else if ((GetOptions() & kVerticalFrame) &&
3077  (lm->InheritsFrom(TGVerticalLayout::Class()))) {
3078  ;
3079  } else {
3080  out << " " << GetName() <<"->SetLayoutManager(";
3081  lm->SavePrimitive(out, option);
3082  out << ");"<< std::endl;
3083  }
3084 
3085  SavePrimitiveSubframes(out, option);
3086 
3087  if (strlen(fWindowName)) {
3088  out << " " << GetName() << "->SetWindowName(" << quote << GetWindowName()
3089  << quote << ");" << std::endl;
3090  }
3091  if (strlen(fIconName)) {
3092  out <<" "<<GetName()<< "->SetIconName("<<quote<<GetIconName()<<quote<<");"<<std::endl;
3093  }
3094  if (strlen(fIconPixmap)) {
3095  out << " " << GetName() << "->SetIconPixmap(" << quote << GetIconPixmap()
3096  << quote << ");" << std::endl;
3097  }
3098 }
3099 
3100 ////////////////////////////////////////////////////////////////////////////////
3101 /// Save a horizontal frame widget as a C++ statement(s) on output stream out.
3102 
3103 void TGHorizontalFrame::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
3104 {
3105  if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
3106 
3107  out << std::endl << " // horizontal frame" << std::endl;
3108  out << " TGHorizontalFrame *";
3109  out << GetName() << " = new TGHorizontalFrame(" << fParent->GetName()
3110  << "," << GetWidth() << "," << GetHeight();
3111 
3112  if (fBackground == GetDefaultFrameBackground()) {
3113  if (!GetOptions()) {
3114  out << ");" << std::endl;
3115  } else {
3116  out << "," << GetOptionString() <<");" << std::endl;
3117  }
3118  } else {
3119  out << "," << GetOptionString() << ",ucolor);" << std::endl;
3120  }
3121  if (option && strstr(option, "keep_names"))
3122  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
3123 
3124  // setting layout manager if it differs from the main frame type
3125  // coverity[returned_null]
3126  // coverity[dereference]
3127  TGLayoutManager * lm = GetLayoutManager();
3128  if ((GetOptions() & kHorizontalFrame) &&
3129  (lm->InheritsFrom(TGHorizontalLayout::Class()))) {
3130  ;
3131  } else if ((GetOptions() & kVerticalFrame) &&
3132  (lm->InheritsFrom(TGVerticalLayout::Class()))) {
3133  ;
3134  } else {
3135  out << " " << GetName() <<"->SetLayoutManager(";
3136  lm->SavePrimitive(out, option);
3137  out << ");"<< std::endl;
3138  }
3139 
3140  SavePrimitiveSubframes(out, option);
3141 }
3142 
3143 ////////////////////////////////////////////////////////////////////////////////
3144 /// Save a vertical frame widget as a C++ statement(s) on output stream out.
3145 
3146 void TGVerticalFrame::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
3147 {
3148  if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
3149 
3150  out << std::endl << " // vertical frame" << std::endl;
3151  out << " TGVerticalFrame *";
3152  out << GetName() << " = new TGVerticalFrame(" << fParent->GetName()
3153  << "," << GetWidth() << "," << GetHeight();
3154 
3155  if (fBackground == GetDefaultFrameBackground()) {
3156  if (!GetOptions()) {
3157  out <<");" << std::endl;
3158  } else {
3159  out << "," << GetOptionString() <<");" << std::endl;
3160  }
3161  } else {
3162  out << "," << GetOptionString() << ",ucolor);" << std::endl;
3163  }
3164  if (option && strstr(option, "keep_names"))
3165  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
3166 
3167  // setting layout manager if it differs from the main frame type
3168  // coverity[returned_null]
3169  // coverity[dereference]
3170  TGLayoutManager * lm = GetLayoutManager();
3171  if ((GetOptions() & kHorizontalFrame) &&
3172  (lm->InheritsFrom(TGHorizontalLayout::Class()))) {
3173  ;
3174  } else if ((GetOptions() & kVerticalFrame) &&
3175  (lm->InheritsFrom(TGVerticalLayout::Class()))) {
3176  ;
3177  } else {
3178  out << " " << GetName() <<"->SetLayoutManager(";
3179  lm->SavePrimitive(out, option);
3180  out << ");"<< std::endl;
3181  }
3182 
3183  SavePrimitiveSubframes(out, option);
3184 }
3185 
3186 ////////////////////////////////////////////////////////////////////////////////
3187 /// Save a frame widget as a C++ statement(s) on output stream out.
3188 
3189 void TGFrame::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
3190 {
3191  if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
3192 
3193  out << " TGFrame *";
3194  out << GetName() << " = new TGFrame("<< fParent->GetName()
3195  << "," << GetWidth() << "," << GetHeight();
3196 
3197  if (fBackground == GetDefaultFrameBackground()) {
3198  if (!GetOptions()) {
3199  out <<");" << std::endl;
3200  } else {
3201  out << "," << GetOptionString() <<");" << std::endl;
3202  }
3203  } else {
3204  out << "," << GetOptionString() << ",ucolor);" << std::endl;
3205  }
3206  if (option && strstr(option, "keep_names"))
3207  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
3208 }
3209 
3210 ////////////////////////////////////////////////////////////////////////////////
3211 /// Save a group frame widget as a C++ statement(s) on output stream out.
3212 
3213 void TGGroupFrame::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
3214 {
3215  char quote = '"';
3216 
3217  // font + GC
3218  option = GetName()+5; // unique digit id of the name
3219  TString parGC, parFont;
3220  // coverity[returned_null]
3221  // coverity[dereference]
3222  parFont.Form("%s::GetDefaultFontStruct()",IsA()->GetName());
3223  // coverity[returned_null]
3224  // coverity[dereference]
3225  parGC.Form("%s::GetDefaultGC()()",IsA()->GetName());
3226 
3227  if ((GetDefaultFontStruct() != fFontStruct) || (GetDefaultGC()() != fNormGC)) {
3228  TGFont *ufont = gClient->GetResourcePool()->GetFontPool()->FindFont(fFontStruct);
3229  if (ufont) {
3230  ufont->SavePrimitive(out, option);
3231  parFont.Form("ufont->GetFontStruct()");
3232  }
3233 
3234  TGGC *userGC = gClient->GetResourcePool()->GetGCPool()->FindGC(fNormGC);
3235  if (userGC) {
3236  userGC->SavePrimitive(out, option);
3237  parGC.Form("uGC->GetGC()");
3238  }
3239  }
3240 
3241  if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
3242 
3243  out << std::endl << " // " << quote << GetTitle() << quote << " group frame" << std::endl;
3244  out << " TGGroupFrame *";
3245  out << GetName() <<" = new TGGroupFrame("<<fParent->GetName()
3246  << "," << quote << GetTitle() << quote;
3247 
3248  if (fBackground == GetDefaultFrameBackground()) {
3249  if (fFontStruct == GetDefaultFontStruct()) {
3250  if (fNormGC == GetDefaultGC()()) {
3251  if (GetOptions() & kVerticalFrame) {
3252  out <<");" << std::endl;
3253  } else {
3254  out << "," << GetOptionString() <<");" << std::endl;
3255  }
3256  } else {
3257  out << "," << GetOptionString() << "," << parGC.Data() <<");" << std::endl;
3258  }
3259  } else {
3260  out << "," << GetOptionString() << "," << parGC.Data() << "," << parFont.Data() << ");" << std::endl;
3261  }
3262  } else {
3263  out << "," << GetOptionString() << "," << parGC.Data() << "," << parFont.Data() << ",ucolor);" << std::endl;
3264  }
3265  if (option && strstr(option, "keep_names"))
3266  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
3267 
3268  if (GetTitlePos() != -1)
3269  out << " " << GetName() <<"->SetTitlePos(";
3270  if (GetTitlePos() == 0)
3271  out << "TGGroupFrame::kCenter);" << std::endl;
3272  if (GetTitlePos() == 1)
3273  out << "TGGroupFrame::kRight);" << std::endl;
3274 
3275  SavePrimitiveSubframes(out, option);
3276 
3277  // setting layout manager
3278  out << " " << GetName() <<"->SetLayoutManager(";
3279  // coverity[returned_null]
3280  // coverity[dereference]
3281  GetLayoutManager()->SavePrimitive(out, option);
3282  out << ");"<< std::endl;
3283 
3284  out << " " << GetName() <<"->Resize(" << GetWidth() << ","
3285  << GetHeight() << ");" << std::endl;
3286 }
3287 
3288 
3289 ////////////////////////////////////////////////////////////////////////////////
3290 /// Save the GUI tranzient frame widget in a C++ macro file.
3291 
3292 void TGTransientFrame::SaveSource(const char *filename, Option_t *option)
3293 {
3294  // iterate over all active classes to exclude the base ones
3295 
3296  TString opt = option;
3297  TBits *bc = new TBits();
3298  TClass *c1, *c2, *c3;
3299  UInt_t k = 0; // will mark k-bit of TBits if the class is a base class
3300 
3301  TIter nextc1(gROOT->GetListOfClasses());
3302  while((c1 = (TClass *)nextc1())) {
3303 
3304  // resets bit TClass::kClassSaved for all classes
3305  c1->ResetBit(TClass::kClassSaved);
3306 
3307  TIter nextc2(gROOT->GetListOfClasses());
3308  while ((c2 = (TClass *)nextc2())) {
3309  if (c1==c2) continue;
3310  else {
3311  c3 = c2->GetBaseClass(c1);
3312  if (c3 != 0) {
3313  bc->SetBitNumber(k, kTRUE);
3314  break;
3315  }
3316  }
3317  }
3318  k++;
3319  }
3320 
3321  TList *ilist = new TList(); // will contain include file names without '.h'
3322  ilist->SetName("ListOfIncludes");
3323  gROOT->GetListOfSpecials()->Add(ilist);
3324  k=0;
3325 
3326  // completes list of include file names
3327  TIter nextdo(gROOT->GetListOfClasses());
3328  while ((c2 = (TClass *)nextdo())) {
3329  // to have only used GUI header files
3330  if (bc->TestBitNumber(k) == 0 && c2->InheritsFrom(TGObject::Class()) == 1) {
3331  // for any used ROOT header files activate the line below, comment the line above
3332  //if (bc->TestBitNumber(k) == 0) {
3333  const char *iname;
3334  iname = c2->GetDeclFileName();
3335  if (iname[0] && strstr(iname,".h")) {
3336  const char *lastsl = strrchr(iname,'/');
3337  if (lastsl) iname = lastsl + 1;
3338  char *tname = new char[strlen(iname)+1];
3339  Int_t i=0;
3340  while (*iname != '.') {
3341  tname[i] = *iname;
3342  i++; iname++;
3343  }
3344  tname[i] = 0; //tname = include file name without '.h'
3345 
3346  TObjString *iel = (TObjString *)ilist->FindObject(tname);
3347  if (!iel) {
3348  ilist->Add(new TObjString(tname));
3349  }
3350  delete [] tname;
3351  }
3352  k++; continue;
3353  }
3354  k++;
3355  }
3356 
3357  char quote = '"';
3358  std::ofstream out;
3359 
3360  TString ff = filename && strlen(filename) ? filename : "Rootdlog.C";
3361 
3362  // Computes the main method name.
3363  const char *fname = gSystem->BaseName(ff.Data());
3364  Int_t lenfname = strlen(fname);
3365  char *sname = new char[lenfname+1];
3366 
3367  Int_t i = 0;
3368  while ((*fname != '.') && (i < lenfname)) {
3369  sname[i] = *fname;
3370  i++; fname++;
3371  }
3372  if (i == lenfname)
3373  ff += ".C";
3374  sname[i] = 0;
3375 
3376  out.open(ff.Data(), std::ios::out);
3377  if (!out.good()) {
3378  Error("SaveSource", "cannot open file: %s", ff.Data());
3379  delete [] sname;
3380  return;
3381  }
3382 
3383  // writes include files in C++ macro
3384  TObjString *inc;
3385  ilist = (TList *)gROOT->GetListOfSpecials()->FindObject("ListOfIncludes");
3386 
3387  if (!ilist) {
3388  delete [] sname;
3389  return;
3390  }
3391 
3392  // write macro header, date/time stamp as string, and the used Root version
3393  TDatime t;
3394  out <<"// Dialog macro generated from application: "<< gApplication->Argv(0) << std::endl;
3395  out <<"// By ROOT version "<< gROOT->GetVersion() <<" on "<<t.AsSQLString()<< std::endl;
3396  out << std::endl;
3397 
3398  out << "#if !defined( __CINT__) || defined (__MAKECINT__)" << std::endl << std::endl;
3399 
3400  TIter nexti(ilist);
3401  while((inc = (TObjString *)nexti())) {
3402  out <<"#ifndef ROOT_"<< inc->GetString() << std::endl;
3403  out <<"#include "<< quote << inc->GetString() <<".h"<< quote << std::endl;
3404  out <<"#endif" << std::endl;
3405  if (strstr(inc->GetString(),"TRootEmbeddedCanvas")) {
3406  out <<"#ifndef ROOT_TCanvas"<< std::endl;
3407  out <<"#include "<< quote <<"TCanvas.h"<< quote << std::endl;
3408  out <<"#endif" << std::endl;
3409  }
3410  }
3411  out << std::endl << "#include " << quote << "Riostream.h" << quote << std::endl;
3412  out << std::endl << "#endif" << std::endl;
3413  // deletes created ListOfIncludes
3414  gROOT->GetListOfSpecials()->Remove(ilist);
3415  ilist->Delete();
3416  delete ilist;
3417  delete bc;
3418 
3419  // writes the macro entry point equal to the fname
3420  out << std::endl;
3421  out << "void " << sname << "()" << std::endl;
3422  delete [] sname;
3423 
3424  // Save GUI widgets as a C++ macro in a file
3425  out <<"{"<< std::endl;
3426 
3427  gListOfHiddenFrames->Clear();
3428 
3429  // saivng slots
3430  TList *lSlots = new TList;
3431  lSlots->SetName("ListOfSlots");
3432  gROOT->GetListOfSpecials()->Add(lSlots);
3433 
3434  TGTransientFrame::SavePrimitive(out, option);
3435 
3436  if (strlen(fClassName) || strlen(fResourceName)) {
3437  out<<" "<<GetName()<< "->SetClassHints("<<quote<<fClassName<<quote
3438  <<"," <<quote<<fResourceName<<quote
3439  <<");"<<std::endl;
3440  }
3441 
3442  GetMWMHints(fMWMValue, fMWMFuncs, fMWMInput);
3443  if (fMWMValue || fMWMFuncs || fMWMInput) {
3444  out << " " << GetName() << "->SetMWMHints(";
3445  out << GetMWMvalueString() << "," << std::endl;
3446  out << " ";
3447  out << GetMWMfuncString() << "," << std::endl;
3448  out << " ";
3449  out << GetMWMinpString() << ");"<< std::endl;
3450  }
3451 
3452  GetWMPosition(fWMX, fWMY);
3453  if ((fWMX != -1) || (fWMY != -1)) {
3454  out <<" "<<GetName()<<"->SetWMPosition("<<fWMX<<","<<fWMY<<");"<<std::endl;
3455  }
3456 
3457  GetWMSize(fWMWidth, fWMHeight);
3458  if (fWMWidth != UInt_t(-1) || fWMHeight != UInt_t(-1)) {
3459  out <<" "<<GetName()<<"->SetWMSize("<<fWMWidth<<","<<fWMHeight<<");"<<std::endl;
3460  }
3461 
3462  GetWMSizeHints(fWMMinWidth,fWMMinHeight,fWMMaxWidth,fWMMaxHeight,fWMWidthInc,fWMHeightInc);
3463  if (fWMMinWidth != UInt_t(-1) || fWMMinHeight != UInt_t(-1) ||
3464  fWMMaxWidth != UInt_t(-1) || fWMMaxHeight != UInt_t(-1) ||
3465  fWMWidthInc != UInt_t(-1) || fWMHeightInc != UInt_t(-1)) {
3466 
3467  out <<" "<<GetName()<<"->SetWMSizeHints("<<fWMMinWidth<<","<<fWMMinHeight
3468  <<","<<fWMMaxWidth<<","<<fWMMaxHeight <<","<<fWMWidthInc<<","<<fWMHeightInc
3469  <<");"<<std::endl;
3470  }
3471 
3472  GetWMPosition(fWMX, fWMY);
3473  if ((fWMX != -1) || (fWMY != -1)) {
3474  out <<" "<<GetName()<<"->Move("<<fWMX<<","<<fWMY<<");"<<std::endl;
3475  }
3476 
3477  out << " " <<GetName()<< "->MapSubwindows();" << std::endl;
3478 
3479  TIter nexth(gListOfHiddenFrames);
3480  TGFrame *fhidden;
3481  while ((fhidden = (TGFrame*)nexth())) {
3482  out << " " <<fhidden->GetName()<< "->UnmapWindow();" << std::endl;
3483  }
3484  out << std::endl;
3485  gListOfHiddenFrames->Clear();
3486 
3487  Bool_t usexy = kFALSE;
3488  // coverity[returned_null]
3489  // coverity[dereference]
3490  TGLayoutManager * lm = GetLayoutManager();
3491  if (lm->InheritsFrom("TGXYLayout"))
3492  usexy = kTRUE;
3493 
3494  if (!usexy)
3495  out << " " <<GetName()<< "->Resize("<< GetName()<< "->GetDefaultSize());" << std::endl;
3496  else
3497  out << " " <<GetName()<< "->Resize("<< GetWidth()<<","<<GetHeight()<<");"<<std::endl;
3498 
3499  out << " " <<GetName()<< "->MapWindow();" <<std::endl;
3500  if (!usexy) out << " " <<GetName()<< "->Resize();" << std::endl;
3501  out << "} " << std::endl;
3502 
3503  // writing slots
3504  TList *sl = (TList *)gROOT->GetListOfSpecials()->FindObject("ListOfSlots");
3505  if (sl) {
3506  TIter nextsl(sl);
3507  TObjString *slobj;
3508  Int_t pnumber = 1;
3509 
3510  while ((slobj = (TObjString*) nextsl())) {
3511  TString s = slobj->GetString();
3512  TString p = "";
3513  Int_t lb, rb, eq;
3514  lb = s.First('(');
3515  rb = s.First(')');
3516  eq = s.First('=');
3517  out << std::endl;
3518 
3519  if (rb - lb > 1 && eq == -1) {
3520  p = TString::Format(" par%d", pnumber);
3521  s.Insert(rb, p);
3522  pnumber++;
3523  out << "void " << s << std::endl;
3524  out << "{" << std::endl;
3525  s = slobj->GetString();
3526  s[rb] = ' ';
3527  out << " std::cout << " << quote << "Slot " << s << quote
3528  << " <<" << p << " << " << quote << ")" << quote
3529  << " << std::endl; " << std::endl;
3530  } else {
3531  if (eq != -1) {
3532  s.Remove(eq, rb-eq);
3533  out << "void " << s << std::endl;
3534  out << "{" << std::endl;
3535  out << " std::cout << " << quote << "Slot " << s
3536  << quote << " << std::endl; " << std::endl;
3537  } else {
3538  out << "void " << slobj->GetString() << std::endl;
3539  out << "{" << std::endl;
3540  out << " std::cout << " << quote << "Slot " << slobj->GetString()
3541  << quote << " << std::endl; " << std::endl;
3542  }
3543  }
3544  out << "}" << std::endl;
3545  }
3546  gROOT->GetListOfSpecials()->Remove(sl);
3547  sl->Delete();
3548  delete sl;
3549  }
3550 
3551  out.close();
3552 
3553  if (!opt.Contains("quiet"))
3554  printf(" C++ macro file %s has been generated\n", gSystem->BaseName(ff.Data()));
3555 
3556  // reset bit TClass::kClassSaved for all classes
3557  nextc1.Reset();
3558  while((c1=(TClass*)nextc1())) {
3559  c1->ResetBit(TClass::kClassSaved);
3560  }
3561 }
3562 
3563 ////////////////////////////////////////////////////////////////////////////////
3564 /// Save a transient frame widget as a C++ statement(s) on output stream out.
3565 
3566 void TGTransientFrame::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
3567 {
3568  char quote = '"';
3569 
3570  out << std::endl << " // transient frame" << std::endl;
3571  out << " TGTransientFrame *";
3572  out << GetName()<<" = new TGTransientFrame(gClient->GetRoot(),0"
3573  << "," << GetWidth() << "," << GetHeight() << "," << GetOptionString() <<");" << std::endl;
3574 
3575  if (option && strstr(option, "keep_names"))
3576  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
3577 
3578  // setting layout manager if it differs from transient frame type
3579  // coverity[returned_null]
3580  // coverity[dereference]
3581  TGLayoutManager * lm = GetLayoutManager();
3582  if ((GetOptions() & kHorizontalFrame) &&
3583  (lm->InheritsFrom(TGHorizontalLayout::Class()))) {
3584  ;
3585  } else if ((GetOptions() & kVerticalFrame) &&
3586  (lm->InheritsFrom(TGVerticalLayout::Class()))) {
3587  ;
3588  } else {
3589  out << " " << GetName() <<"->SetLayoutManager(";
3590  lm->SavePrimitive(out, option);
3591  out << ");"<< std::endl;
3592  }
3593 
3594  SavePrimitiveSubframes(out, option);
3595 
3596  if (strlen(fWindowName)) {
3597  out << " " << GetName() << "->SetWindowName(" << quote << GetWindowName()
3598  << quote << ");" << std::endl;
3599  }
3600  if (strlen(fIconName)) {
3601  out <<" "<<GetName()<< "->SetIconName("<<quote<<GetIconName()<<quote<<");"<<std::endl;
3602  }
3603  if (strlen(fIconPixmap)) {
3604  out << " " << GetName() << "->SetIconPixmap(" << quote << GetIconPixmap()
3605  << quote << ");" << std::endl;
3606  }
3607 }