TGuiBldDragManager.cxx

Go to the documentation of this file.
00001 // @(#)root/guibuilder:$Id: TGuiBldDragManager.cxx 36155 2010-10-07 14:04:45Z rdm $
00002 // Author: Valeriy Onuchin   12/09/04
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 
00013 #include "TGuiBldDragManager.h"
00014 #include "TGuiBldEditor.h"
00015 #include "TRootGuiBuilder.h"
00016 
00017 #include "TTimer.h"
00018 #include "TList.h"
00019 #include "TClass.h"
00020 #include "TSystem.h"
00021 #include "TROOT.h"
00022 #include "TColor.h"
00023 #include "TImage.h"
00024 
00025 #include "TError.h"
00026 #include "TClassMenuItem.h"
00027 #include "TMethod.h"
00028 #include "TBaseClass.h"
00029 #include "TMethodArg.h"
00030 #include "TToggle.h"
00031 #include "TDataType.h"
00032 #include "TObjString.h"
00033 #include "TInterpreter.h"
00034 
00035 #include "KeySymbols.h"
00036 #include "TGResourcePool.h"
00037 #include "TGMenu.h"
00038 #include "TGFileDialog.h"
00039 #include "TGMsgBox.h"
00040 #include "TRandom.h"
00041 #include "TGButton.h"
00042 #include "TGMdi.h"
00043 #include "TGTextEntry.h"
00044 #include "TGDockableFrame.h"
00045 #include "TGColorDialog.h"
00046 #include "TGFontDialog.h"
00047 #include "TGComboBox.h"
00048 #include "TGCanvas.h"
00049 #include "TGLabel.h"
00050 #include "TGProgressBar.h"
00051 #include "TGScrollBar.h"
00052 #include "TGTextEntry.h"
00053 
00054 #undef DEBUG_LOCAL
00055 
00056 //_____________________________________________________________________________
00057 //
00058 // TGuiBldDragManager
00059 //
00060 // Drag and drop manager used by the ROOT GUI Builder.
00061 //_____________________________________________________________________________
00062 
00063 ClassImp(TGuiBldDragManager)
00064 
00065 static UInt_t gGridStep = 8;
00066 static TGuiBldDragManager *gGuiBldDragManager = 0;
00067 TGColorDialog *TGuiBldDragManager::fgGlobalColorDialog = 0;
00068 TGFontDialog *TGuiBldDragManager::fgGlobalFontDialog = 0;
00069 
00070 static const char *gSaveMacroTypes[] = {
00071    "Macro files", "*.C",
00072    "All files",   "*",
00073    0,             0
00074 };
00075 
00076 static const char *gImageTypes[] = {
00077    "All files", "*",
00078    "XPM",     "*.xpm",
00079    "GIF",     "*.gif",
00080    "PNG",     "*.png",
00081    "JPEG",    "*.jpg",
00082    "TARGA",   "*.tga",
00083    "BMP",     "*.bmp",
00084    "ICO",     "*.ico",
00085    "XCF",     "*.xcf",
00086    "CURSORS", "*.cur",
00087    "PPM",     "*.ppm",
00088    "PNM",     "*.pnm",
00089    "XBM",     "*.xbm",
00090    "TIFF",    "*.tiff",
00091    "Enacapsulated PostScript", "*.eps",
00092    "PostScript", "*.ps",
00093    "PDF",        "*.pdf",
00094    "ASImage XML","*.xml",
00095     0,             0
00096 };
00097 
00098 
00099 ////////////////////////////////////////////////////////////////////////////////
00100 
00101 
00102 class TGuiBldMenuDialog : public TGTransientFrame {
00103 
00104 friend class TGuiBldDragManager;
00105 
00106 public:
00107    TGButton       *fOK;       // OK button
00108    //TGButton     *fApply;    // apply button
00109    TGButton       *fCancel;   // cancel button
00110    TObject        *fObject;   // selected object/frame
00111    TMethod        *fMethod;   // method to be applied
00112    TGLayoutHints  *fL1;       // internally used layout hints
00113    TGLayoutHints  *fL2;       // internally used layout hints
00114    TList          *fWidgets;  // list of widgets
00115 
00116 public:
00117    virtual ~TGuiBldMenuDialog();
00118    TGuiBldMenuDialog(const TGWindow *main, TObject *obj, TMethod *method);
00119 
00120    const char *GetParameters();
00121    void CloseWindow();
00122    void ConnectButtonSignals();
00123    void Build();
00124    void Popup();
00125    void ApplyMethod();
00126    void Add(const char *argname, const char *value, const char *type);
00127 
00128 };
00129 
00130 static TGuiBldMenuDialog *gMenuDialog = 0;
00131 
00132 
00133 //______________________________________________________________________________
00134 TGuiBldMenuDialog::TGuiBldMenuDialog(const TGWindow *main, TObject *obj, TMethod *method) :
00135     TGTransientFrame(gClient->GetDefaultRoot(), main, 200, 100)
00136 {
00137    // ctor.
00138 
00139    fObject = obj;
00140    fMethod = method;
00141    if (!obj) return; // zombie
00142 
00143    fWidgets = new TList();
00144 
00145    fL1 = new TGLayoutHints(kLHintsTop | kLHintsCenterX, 0, 0, 5, 0);
00146    fL2 = new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5);
00147 
00148    TString title = obj->ClassName();
00149    title += "::";
00150    title += method->GetName();
00151 
00152    Build();
00153    ConnectButtonSignals();
00154 
00155    SetWindowName(title);
00156    SetIconName(title);
00157    SetEditDisabled(kEditDisable);
00158 
00159    //TRootGuiBuilder::PropagateBgndColor(this, TRootGuiBuilder::GetBgnd());
00160 }
00161 
00162 //______________________________________________________________________________
00163 TGuiBldMenuDialog::~TGuiBldMenuDialog()
00164 {
00165    // dtor.
00166 
00167    fWidgets->Delete();
00168    delete fWidgets;
00169    delete fL1;
00170    delete fL2;
00171 }
00172 
00173 //______________________________________________________________________________
00174 void TGuiBldMenuDialog::ConnectButtonSignals()
00175 {
00176    // Connect buttons signals
00177 
00178    fOK->Connect("Pressed()", "TGuiBldDragManager", gGuiBldDragManager, "DoDialogOK()");
00179    //fApply->Connect("Pressed()", "TGuiBldDragManager", gGuiBldDragManager, "DoDialogApply()");
00180    fCancel->Connect("Pressed()", "TGuiBldDragManager", gGuiBldDragManager, "DoDialogCancel()");
00181 }
00182 
00183 //______________________________________________________________________________
00184 void TGuiBldMenuDialog::ApplyMethod()
00185 {
00186    // execute method for obejct with input args
00187 
00188    const char *params = GetParameters();
00189    fObject->Execute(fMethod->GetName(), params);
00190 }
00191 
00192 //______________________________________________________________________________
00193 const char *TGuiBldMenuDialog::GetParameters()
00194 {
00195    // Return input parameters as single string.
00196 
00197    static char params[1024];
00198    char param[256];
00199 
00200    TObjString   *str;
00201    TObject      *obj;
00202 
00203    Int_t selfobjpos;
00204 //   if (fMenu->GetContextMenu()->GetSelectedMenuItem())
00205 //      selfobjpos = fMenu->GetContextMenu()->GetSelectedMenuItem()->GetSelfObjectPos();
00206 //   else
00207    selfobjpos = -1;
00208 
00209    params[0] = 0;
00210    TIter next(fWidgets);
00211    Int_t nparam = 0;
00212 
00213    while ((obj = next())) {        // first element is label, skip...
00214       if (obj->IsA() != TGLabel::Class()) break;
00215       obj = next();                // get either TGTextEntry or TGComboBox
00216       str = (TObjString *) next(); // get type string
00217 
00218       nparam++;
00219 
00220       const char *type = str->GetString().Data();
00221       const char *data = 0;
00222 
00223       if (obj->IsA() == TGTextEntry::Class())
00224          data = ((TGTextEntry *) obj)->GetBuffer()->GetString();
00225 
00226       // TODO: Combobox...
00227 
00228       // if necessary, replace the selected object by it's address
00229       if (selfobjpos == nparam-1) {
00230          if (params[0]) strlcat(params, ",", 1024-strlen(params));
00231          snprintf(param, 255, "(TObject*)0x%lx", (Long_t)fObject);
00232          strlcat(params, param, 1024-strlen(params));
00233       }
00234 
00235       if (params[0]) strlcat(params, ",", 1024-strlen(params));
00236       if (data) {
00237          if (!strncmp(type, "char*", 5))
00238             snprintf(param, 255, "\"%s\"", data);
00239          else
00240             strlcpy(param, data, sizeof(param));
00241       } else
00242          strlcpy(param, "0", sizeof(param));
00243 
00244       strlcat(params, param, 1024-strlen(params));
00245    }
00246 
00247    // if selected object is the last argument, have to insert it here
00248    if (selfobjpos == nparam) {
00249       if (params[0]) strlcat(params, ",", 1024-strlen(params));
00250       snprintf(param, 255, "(TObject*)0x%lx", (Long_t)fObject);
00251       strlcat(params, param, 1024-strlen(params));
00252    }
00253 
00254    return params;
00255 }
00256 
00257 //______________________________________________________________________________
00258 static TString CreateArgumentTitle(TMethodArg *argument)
00259 {
00260    // Create a string describing method argument.
00261 
00262    static TString ret;
00263 
00264    if (argument) {
00265       ret.Form("(%s)  %s", argument->GetTitle(), argument->GetName());
00266       if (argument->GetDefault() && *(argument->GetDefault())) {
00267          ret += "  [default: ";
00268          ret += argument->GetDefault();
00269          ret += "]";
00270       }
00271    }
00272 
00273    return ret;
00274 }
00275 
00276 //______________________________________________________________________________
00277 void TGuiBldMenuDialog::Add(const char *argname, const char *value, const char *type)
00278 {
00279    // Add a label and text input field.
00280 
00281    TGLabel      *l = new TGLabel(this, argname);
00282    TGTextBuffer *b = new TGTextBuffer(20);
00283    b->AddText(0, value);
00284    TGTextEntry  *t = new TGTextEntry(this, b);
00285 
00286    t->Connect("ReturnPressed()", "TGuiBldDragManager", gGuiBldDragManager, "DoDialogOK()");
00287    t->Resize(260, t->GetDefaultHeight());
00288    AddFrame(l, fL1);
00289    AddFrame(t, fL2);
00290 
00291    fWidgets->Add(l);
00292    fWidgets->Add(t);
00293    fWidgets->Add(new TObjString(type));
00294 }
00295 
00296 //______________________________________________________________________________
00297 void TGuiBldMenuDialog::CloseWindow()
00298 {
00299    // Close window
00300 
00301    gGuiBldDragManager->DoDialogCancel();
00302 }
00303 
00304 //______________________________________________________________________________
00305 void TGuiBldMenuDialog::Build()
00306 {
00307    // Build dialog
00308 
00309    TMethodArg *argument = 0;
00310    Int_t selfobjpos = -1;
00311 
00312    TIter next(fMethod->GetListOfMethodArgs());
00313    Int_t argpos = 0;
00314 
00315    while ((argument = (TMethodArg *) next())) {
00316       // Do not input argument for self object
00317       if (selfobjpos != argpos) {
00318          const char *argname    = CreateArgumentTitle(argument).Data();
00319          const char *type       = argument->GetTypeName();
00320          TDataType  *datatype   = gROOT->GetType(type);
00321          const char *charstar   = "char*";
00322          char        basictype[32];
00323 
00324          if (datatype) {
00325             strlcpy(basictype, datatype->GetTypeName(), sizeof(basictype));
00326          } else {
00327             TClass *cl = TClass::GetClass(type);
00328             if (strncmp(type, "enum", 4) && (cl && !(cl->Property() & kIsEnum)))
00329                Warning("Dialog", "data type is not basic type, assuming (int)");
00330             strlcpy(basictype, "int", sizeof(basictype));
00331          }
00332 
00333          if (strchr(argname, '*')) {
00334             strlcat(basictype, "*", 32-strlen(basictype));
00335             type = charstar;
00336          }
00337 
00338          TDataMember *m = argument->GetDataMember();
00339          if (m && m->GetterMethod(fObject->IsA())) {
00340 
00341             // Get the current value and form it as a text:
00342             char val[256];
00343 
00344             if (!strncmp(basictype, "char*", 5)) {
00345                char *tdefval;
00346                m->GetterMethod()->Execute(fObject, "", &tdefval);
00347                strlcpy(val, tdefval, sizeof(val));
00348             } else if (!strncmp(basictype, "float", 5) ||
00349                        !strncmp(basictype, "double", 6)) {
00350                Double_t ddefval;
00351                m->GetterMethod()->Execute(fObject, "", ddefval);
00352                snprintf(val, 255, "%g", ddefval);
00353             } else if (!strncmp(basictype, "char", 4) ||
00354                        !strncmp(basictype, "bool", 4) ||
00355                        !strncmp(basictype, "int", 3)  ||
00356                        !strncmp(basictype, "long", 4) ||
00357                        !strncmp(basictype, "short", 5)) {
00358                Long_t ldefval;
00359                m->GetterMethod()->Execute(fObject, "", ldefval);
00360                snprintf(val, 255, "%li", ldefval);
00361             }
00362 
00363             // Find out whether we have options ...
00364 
00365             TList *opt;
00366             if ((opt = m->GetOptions())) {
00367                Warning("Dialog", "option menu not yet implemented");
00368 
00369             } else {
00370                // we haven't got options - textfield ...
00371                Add(argname, val, type);
00372             }
00373          } else {    // if m not found ...
00374 
00375             char val[256] = "";
00376             const char *tval = argument->GetDefault();
00377             if (tval) strlcpy(val, tval, sizeof(val));
00378             Add(argname, val, type);
00379          }
00380       }
00381       argpos++;
00382    }
00383 
00384    // add OK, Apply, Cancel buttons
00385    TGHorizontalFrame *hf = new TGHorizontalFrame(this, 60, 20, kFixedWidth);
00386    TGLayoutHints     *l1 = new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 5, 5, 0, 0);
00387    UInt_t  width = 0, height = 0;
00388 
00389    fWidgets->Add(l1);
00390 
00391    fOK = new TGTextButton(hf, "&OK", 1);
00392    hf->AddFrame(fOK, l1);
00393    fWidgets->Add(fOK);
00394    height = fOK->GetDefaultHeight();
00395    width  = TMath::Max(width, fOK->GetDefaultWidth());
00396 
00397 /*
00398    fApply = new TGTextButton(hf, "&Apply", 2);
00399    hf->AddFrame(fApply, l1);
00400    fWidgets->Add(fApply);
00401    height = fApply->GetDefaultHeight();
00402    width  = TMath::Max(width, fApply->GetDefaultWidth());
00403 */
00404 
00405    fCancel = new TGTextButton(hf, "&Cancel", 3);
00406    hf->AddFrame(fCancel, l1);
00407    fWidgets->Add(fCancel);
00408    height = fCancel->GetDefaultHeight();
00409    width  = TMath::Max(width, fCancel->GetDefaultWidth());
00410 
00411    // place buttons at the bottom
00412    l1 = new TGLayoutHints(kLHintsBottom | kLHintsCenterX, 0, 0, 5, 5);
00413    AddFrame(hf, l1);
00414    fWidgets->Add(l1);
00415    fWidgets->Add(hf);
00416 
00417    hf->Resize((width + 20) * 3, height);
00418 
00419    // map all widgets and calculate size of dialog
00420    MapSubwindows();
00421 }
00422 
00423 //______________________________________________________________________________
00424 void TGuiBldMenuDialog::Popup()
00425 {
00426    // Popup dialog.
00427 
00428    UInt_t width  = GetDefaultWidth();
00429    UInt_t height = GetDefaultHeight();
00430 
00431    Resize(width, height);
00432 
00433    Window_t wdummy;
00434    Int_t x = (Int_t)((TGFrame*)fMain)->GetWidth();
00435    Int_t y = (Int_t)((TGFrame*)fMain)->GetHeight();
00436    gVirtualX->TranslateCoordinates(fMain->GetId(), fClient->GetDefaultRoot()->GetId(),
00437                                    x, y, x, y, wdummy);
00438 
00439    x += 10;
00440    y += 10;
00441 
00442    // make the message box non-resizable
00443    SetWMSize(width, height);
00444    SetWMSizeHints(width, height, width, height, 0, 0);
00445 
00446    SetMWMHints(kMWMDecorAll | kMWMDecorResizeH  | kMWMDecorMaximize |
00447                               kMWMDecorMinimize | kMWMDecorMenu,
00448                kMWMFuncAll  | kMWMFuncResize    | kMWMFuncMaximize |
00449                               kMWMFuncMinimize,
00450                kMWMInputModeless);
00451 
00452    Move(x, y);
00453    SetWMPosition(x, y);
00454    MapRaised();
00455    fClient->WaitFor(this);
00456 }
00457 
00458 
00459 ///////////////////////// auxilary static functions ///////////////////////////
00460 //______________________________________________________________________________
00461 static Window_t GetWindowFromPoint(Int_t x, Int_t y)
00462 {
00463    // Helper. Return a window located at point x,y (in screen coordinates)
00464 
00465    Window_t src, dst, child;
00466    Window_t ret = 0;
00467    Int_t xx = x;
00468    Int_t yy = y;
00469 
00470    if (!gGuiBldDragManager || gGuiBldDragManager->IsStopped() ||
00471        !gClient->IsEditable()) return 0;
00472 
00473    dst = src = child = gVirtualX->GetDefaultRootWindow();
00474 
00475    while (child && dst) {
00476       src = dst;
00477       dst = child;
00478       gVirtualX->TranslateCoordinates(src, dst, xx, yy, xx, yy, child);
00479       ret = dst;
00480    }
00481    return ret;
00482 }
00483 
00484 //______________________________________________________________________________
00485 static void layoutFrame(TGFrame *frame)
00486 {
00487    // Helper to layout
00488 
00489    if (!frame || !frame->InheritsFrom(TGCompositeFrame::Class())) {
00490       return;
00491    }
00492 
00493    TGCompositeFrame *comp = (TGCompositeFrame*)frame;
00494 
00495    if (comp->GetLayoutManager()) {
00496       comp->GetLayoutManager()->Layout();
00497    } else {
00498       comp->Layout();
00499    }
00500    gClient->NeedRedraw(comp);
00501 
00502    TIter next(comp->GetList());
00503    TGFrameElement *fe;
00504 
00505    while ((fe = (TGFrameElement*)next())) {
00506       layoutFrame(fe->fFrame);
00507       gClient->NeedRedraw(fe->fFrame);
00508    }
00509 }
00510 
00511 //______________________________________________________________________________
00512 static void GuiBldErrorHandler(Int_t /*level*/, Bool_t /*abort*/,
00513                                  const char * /*location*/, const char * /*msg*/)
00514 {
00515    // Our own error handler (not used yet)
00516 
00517 }
00518 
00519 ////////////////////////////////////////////////////////////////////////////////
00520 class TGuiBldDragManagerGrid {
00521 
00522 public:
00523    static UInt_t   fgStep;
00524    static ULong_t  fgPixel;
00525    static TGGC    *fgBgnd;
00526 
00527    Pixmap_t    fPixmap;
00528    TGWindow   *fWindow;
00529    Int_t       fWinId;
00530 
00531    TGuiBldDragManagerGrid();
00532    ~TGuiBldDragManagerGrid();
00533    void  Draw();
00534    void  SetStep(UInt_t step);
00535    void  InitPixmap();
00536    void  InitBgnd();
00537 };
00538 
00539 UInt_t   TGuiBldDragManagerGrid::fgStep = gGridStep;
00540 ULong_t  TGuiBldDragManagerGrid::fgPixel = 0;
00541 TGGC    *TGuiBldDragManagerGrid::fgBgnd = 0;
00542 
00543 //______________________________________________________________________________
00544 TGuiBldDragManagerGrid::TGuiBldDragManagerGrid()
00545 {
00546    // Create a grid background for the selected window
00547 
00548    fPixmap = 0;
00549    fWindow = 0;
00550    fWinId = 0;
00551 
00552    if (!fgBgnd) {
00553       InitBgnd();
00554    }
00555    SetStep(fgStep);
00556 }
00557 
00558 //______________________________________________________________________________
00559 TGuiBldDragManagerGrid::~TGuiBldDragManagerGrid()
00560 {
00561    // ctor.
00562 
00563    fWindow = gClient->GetWindowById(fWinId);
00564 
00565    if (fWindow) {
00566       fWindow->SetBackgroundPixmap(0);
00567       fWindow->SetBackgroundColor(((TGFrame*)fWindow)->GetBackground());
00568       gClient->NeedRedraw(fWindow, kTRUE);
00569    }
00570    if (fPixmap) {
00571       gVirtualX->DeletePixmap(fPixmap);
00572    }
00573 
00574    fPixmap = 0;
00575    fWindow = 0;
00576    fWinId = 0;
00577 }
00578 
00579 //______________________________________________________________________________
00580 void TGuiBldDragManagerGrid::SetStep(UInt_t step)
00581 {
00582    // Set the grid step
00583 
00584    if (!gClient || !gClient->IsEditable()) {
00585       return;
00586    }
00587 
00588    fWindow = (TGWindow*)gClient->GetRoot();
00589    fWinId = fWindow->GetId();
00590    fgStep = step;
00591    InitPixmap();
00592 
00593 }
00594 
00595 //______________________________________________________________________________
00596 void TGuiBldDragManagerGrid::InitBgnd()
00597 {
00598    // Create grid background.
00599 
00600    if (fgBgnd) {
00601       return;
00602    }
00603 
00604    fgBgnd = new TGGC(TGFrame::GetBckgndGC());
00605 
00606    Float_t r, g, b;
00607 
00608    r = 232./255;
00609    g = 232./255;
00610    b = 226./255;
00611 
00612    fgPixel = TColor::RGB2Pixel(r, g, b);
00613    fgBgnd->SetForeground(fgPixel);
00614 }
00615 
00616 //______________________________________________________________________________
00617 void TGuiBldDragManagerGrid::InitPixmap()
00618 {
00619    // Create grid background pixmap
00620 
00621    if (fPixmap) {
00622       gVirtualX->DeletePixmap(fPixmap);
00623    }
00624 
00625    fPixmap = gVirtualX->CreatePixmap(gClient->GetDefaultRoot()->GetId(), fgStep, fgStep);
00626    gVirtualX->FillRectangle(fPixmap, fgBgnd->GetGC(), 0, 0, fgStep, fgStep);
00627 
00628    if(fgStep > 2) {
00629       gVirtualX->FillRectangle(fPixmap, TGFrame::GetShadowGC()(),
00630                                fgStep - 1, fgStep - 1, 1, 1);
00631    }
00632 }
00633 
00634 //______________________________________________________________________________
00635 void TGuiBldDragManagerGrid::Draw()
00636 {
00637    // Draw grid over editted frame.
00638 
00639    if (!gClient || !gClient->IsEditable()) {
00640       return;
00641    }
00642 
00643    fWindow = gClient->GetWindowById(fWinId);
00644 
00645    if (fWindow && (fWindow != gClient->GetRoot())) {
00646       fWindow->SetBackgroundPixmap(0);
00647       fWindow->SetBackgroundColor(((TGFrame*)fWindow)->GetBackground());
00648       gClient->NeedRedraw(fWindow);
00649    }
00650 
00651    if (!fPixmap) {
00652       InitPixmap();
00653    }
00654 
00655    fWindow = (TGWindow*)gClient->GetRoot();
00656    fWinId = fWindow->GetId();
00657    fWindow->SetBackgroundPixmap(fPixmap);
00658 
00659    gClient->NeedRedraw(fWindow);
00660 }
00661 
00662 
00663 ////////////////////////////////////////////////////////////////////////////////
00664 class TGuiBldDragManagerRepeatTimer : public TTimer {
00665 
00666 private:
00667    TGuiBldDragManager *fManager;   // back pointer
00668 
00669 public:
00670    TGuiBldDragManagerRepeatTimer(TGuiBldDragManager *m, Long_t ms) :
00671                                  TTimer(ms, kTRUE) { fManager = m; }
00672    Bool_t Notify() { fManager->HandleTimer(this); Reset(); return kFALSE; }
00673 };
00674 
00675 
00676 ////////////////////////////////////////////////////////////////////////////////
00677 class TGGrabRect : public TGFrame {
00678 
00679 private:
00680    Pixmap_t    fPixmap;
00681    ECursor     fType;
00682 
00683 public:
00684    TGGrabRect(Int_t type);
00685    ~TGGrabRect() {}
00686 
00687    Bool_t HandleButton(Event_t *ev);
00688    ECursor GetType() const { return fType; }
00689 };
00690 
00691 //______________________________________________________________________________
00692 TGGrabRect::TGGrabRect(Int_t type) :
00693       TGFrame(gClient->GetDefaultRoot(), 8, 8, kTempFrame)
00694 {
00695    // ctor.
00696 
00697    fType = kTopLeft;
00698 
00699    switch (type) {
00700       case 0:
00701          fType = kTopLeft;
00702          break;
00703       case 1:
00704          fType = kTopSide;
00705          break;
00706       case 2:
00707          fType = kTopRight;
00708          break;
00709       case 3:
00710          fType = kBottomLeft;
00711          break;
00712       case 4:
00713          fType = kLeftSide;
00714          break;
00715       case 5:
00716          fType = kRightSide;
00717          break;
00718       case 6:
00719          fType = kBottomSide;
00720          break;
00721       case 7:
00722          fType = kBottomRight;
00723          break;
00724    }
00725 
00726    SetWindowAttributes_t attr;
00727    attr.fMask             = kWAOverrideRedirect | kWASaveUnder;
00728    attr.fOverrideRedirect = kTRUE;
00729    attr.fSaveUnder        = kTRUE;
00730 
00731    gVirtualX->ChangeWindowAttributes(fId, &attr);
00732 
00733    fPixmap = gVirtualX->CreatePixmap(gVirtualX->GetDefaultRootWindow(), 8, 8);
00734    const TGGC *bgc = TRootGuiBuilder::GetPopupHlghtGC();
00735 //fClient->GetResourcePool()->GetSelectedBckgndGC();
00736    TGGC *gc = new TGGC(TGFrame::GetBckgndGC());
00737 
00738    Pixel_t back;
00739    fClient->GetColorByName("black", back);
00740    gc->SetBackground(back);
00741    gc->SetForeground(back);
00742 
00743    gVirtualX->FillRectangle(fPixmap, bgc->GetGC(), 0, 0, 7, 7);
00744    gVirtualX->DrawRectangle(fPixmap, gc->GetGC(), 0, 0, 7, 7);
00745 //   gVirtualX->DrawRectangle(fPixmap, fClient->GetResourcePool()->GetSelectedBckgndGC()->GetGC(), 1, 1, 5, 5);
00746 
00747    AddInput(kButtonPressMask);
00748    SetBackgroundPixmap(fPixmap);
00749 
00750    gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(fType));
00751 }
00752 
00753 //______________________________________________________________________________
00754 Bool_t TGGrabRect::HandleButton(Event_t *ev)
00755 {
00756    // Handle button press event.
00757 
00758    gGuiBldDragManager->CheckDragResize(ev);
00759    return kTRUE;
00760 }
00761 
00762 ////////////////////////////////////////////////////////////////////////////////
00763 class TGAroundFrame : public TGFrame {
00764 
00765 public:
00766    TGAroundFrame();
00767    ~TGAroundFrame() {}
00768 };
00769 
00770 //______________________________________________________________________________
00771 TGAroundFrame::TGAroundFrame() : TGFrame(gClient->GetDefaultRoot(), 1, 1,
00772                                          kTempFrame | kOwnBackground)
00773 {
00774    // ctor.
00775 
00776    SetWindowAttributes_t attr;
00777    attr.fMask             = kWAOverrideRedirect | kWASaveUnder;
00778    attr.fOverrideRedirect = kTRUE;
00779    attr.fSaveUnder        = kTRUE;
00780 
00781    gVirtualX->ChangeWindowAttributes(fId, &attr);
00782    ULong_t blue;
00783    fClient->GetColorByName("blue", blue);
00784    SetBackgroundColor(blue);
00785 }
00786 
00787 
00788 ////////////////////////////////////////////////////////////////////////////////
00789 class TGuiBldDragManagerPimpl {
00790 
00791 friend class TGuiBldDragManager;
00792 
00793 private:
00794    TGuiBldDragManager     *fManager;   // drag and drop manager
00795    TTimer            *fRepeatTimer;    // repeat rate timer (when mouse stays pressed)
00796    TGFrame           *fGrab;           // grabbed/selected frame
00797    TGLayoutHints     *fGrabLayout;     // layout of grabbed frame
00798    TGFrame           *fSaveGrab;       // used during context menu handling
00799    TGFrame           *fClickFrame;     // last clicked frame
00800    TGuiBldDragManagerGrid *fGrid;      //
00801    ECursor            fResizeType;     // defines resize type
00802    Int_t              fX0, fY0;        // initial drag position in pixels
00803    Int_t              fX, fY;          // current drag position in pixels
00804    Int_t              fXf, fYf;        // offset of inititial position inside frame
00805    Int_t              fGrabX, fGrabY;  //
00806    const TGWindow    *fGrabParent;     // parent of the grabbed/seleceted frame
00807    Int_t              fLastPopupAction;//
00808    Bool_t             fReplaceOn;
00809    TGGrabRect        *fGrabRect[8];    // small rectangles drawn over grabbed/selected frame
00810    TGFrame           *fAroundFrame[4]; // red lines drawn over layouted frame
00811    Bool_t             fGrabRectHidden;
00812    TGFrameElement    *fGrabListPosition;
00813    Bool_t             fButtonPressed;  //
00814    Bool_t             fCompacted;   //
00815    TGFrame           *fPlane; // highlighted plain composite frame when mose is moving
00816    TGFrame           *fSpacePressedFrame; // frame which was grabbed via spacebar pressed
00817    Bool_t             fPlacePopup; // kTRUE is menu fo frame was placed
00818    TList             *fFrameMenuTrash; // trash list
00819    TGFrame           *fMenuObject;     // object/frame for which context menu is created
00820 
00821 public:
00822    TGuiBldDragManagerPimpl(TGuiBldDragManager *m) {
00823       fManager = m;
00824       fRepeatTimer = new TGuiBldDragManagerRepeatTimer(m, 100);
00825 
00826       int i = 0;
00827       for (i = 0; i <8; i++) {
00828          fGrabRect[i] = new TGGrabRect(i);
00829       }
00830       for (i = 0; i <4; i++) {
00831          fAroundFrame[i] = new TGAroundFrame();
00832       }
00833 
00834       fFrameMenuTrash = new TList();
00835 
00836       ResetParams();
00837    }
00838    void ResetParams() {
00839       fGrab = 0;
00840       fSaveGrab = 0;
00841       fClickFrame = 0;
00842       fGrid = 0;
00843       fX0 = fY0 = fX = fY = fXf = fYf = fGrabX = fGrabY = 0;
00844       fGrabParent = 0;
00845       fResizeType = kPointer;
00846       fLastPopupAction = kNoneAct;
00847       fReplaceOn = kFALSE;
00848       fGrabLayout = 0;
00849       fGrabRectHidden = kFALSE;
00850       fGrabListPosition = 0;
00851       fButtonPressed = kFALSE;
00852       fCompacted = kFALSE;
00853       fPlane = 0;
00854       fSpacePressedFrame = 0;
00855       fPlacePopup = kFALSE;
00856       fFrameMenuTrash->Delete();
00857       fMenuObject = 0;
00858    }
00859 
00860    ~TGuiBldDragManagerPimpl() {
00861       int i;
00862       for (i = 0; i <8; i++) {
00863          delete fGrabRect[i];
00864       }
00865       for (i = 0; i <4; i++) {
00866          delete fAroundFrame[i];
00867       }
00868 
00869       delete fRepeatTimer;
00870       delete fGrab;
00871       fFrameMenuTrash->Delete();
00872       delete fFrameMenuTrash;
00873 
00874       if (fPlane) {
00875          fPlane->ChangeOptions(fPlane->GetOptions() & ~kRaisedFrame);
00876          gClient->NeedRedraw(fPlane, kTRUE);
00877          fPlane = 0;
00878       }
00879    }
00880 };
00881 
00882 
00883 ////////////////////////////////////////////////////////////////////////////////
00884 TGuiBldDragManager::TGuiBldDragManager() : TVirtualDragManager() ,
00885                     TGFrame(gClient->GetDefaultRoot(), 1, 1)
00886 {
00887    // Constructor. Create "fantom window".
00888 
00889    SetWindowAttributes_t attr;
00890    attr.fMask             = kWAOverrideRedirect | kWASaveUnder;
00891    attr.fOverrideRedirect = kTRUE;
00892    attr.fSaveUnder        = kTRUE;
00893 
00894    gVirtualX->ChangeWindowAttributes(fId, &attr);
00895 
00896    gGuiBldDragManager = this;
00897    fPimpl = new TGuiBldDragManagerPimpl(this);
00898 
00899    fSelectionIsOn = kFALSE;
00900    fFrameMenu     = 0;
00901    fLassoMenu     = 0;
00902    fEditor        = 0;
00903    fBuilder       = 0;
00904    fLassoDrawn    = kFALSE;
00905    fDropStatus    = kFALSE;
00906    fStop          = kTRUE;
00907    fSelected      = 0;
00908    fListOfDialogs = 0;
00909 
00910    Reset1();
00911    CreateListOfDialogs();
00912 
00913    TString tmpfile = gSystem->TempDirectory();
00914    char *s = gSystem->ConcatFileName(tmpfile.Data(),
00915                TString::Format("RootGuiBldClipboard%d.C", gSystem->GetPid()));
00916    fPasteFileName = s;
00917    delete [] s;
00918 
00919    s = gSystem->ConcatFileName(tmpfile.Data(),
00920                TString::Format("RootGuiBldTmpFile%d.C", gSystem->GetPid()));
00921    fTmpBuildFile = s;
00922    delete [] s;
00923 
00924    fName = "Gui Builder Drag Manager";
00925    SetWindowName(fName.Data());
00926 
00927    // let's try to solve the problems by myself
00928    SetErrorHandler(GuiBldErrorHandler);
00929 
00930    fClient->UnregisterWindow(this);
00931 }
00932 
00933 //______________________________________________________________________________
00934 TGuiBldDragManager::~TGuiBldDragManager()
00935 {
00936    // Destructor
00937 
00938    SetEditable(kFALSE);
00939 
00940    delete fPimpl;
00941 
00942    delete fBuilder;
00943    fBuilder = 0;
00944 
00945 //   delete fEditor;
00946 //   fEditor = 0;
00947 
00948    delete fFrameMenu;
00949    fFrameMenu =0;
00950 
00951    delete fLassoMenu;
00952    fLassoMenu = 0;
00953 
00954    if (!gSystem->AccessPathName(fPasteFileName.Data())) {
00955       gSystem->Unlink(fPasteFileName.Data());
00956    }
00957 
00958    delete fListOfDialogs;
00959 
00960    gGuiBldDragManager = 0;
00961 }
00962 
00963 //______________________________________________________________________________
00964 void TGuiBldDragManager::Reset1()
00965 {
00966    // Reset some parameters
00967 
00968    TVirtualDragManager::Init();
00969    fTargetId = 0;
00970    fPimpl->fPlacePopup = kFALSE;
00971    SetCursorType(kPointer);
00972 }
00973 
00974 //______________________________________________________________________________
00975 void TGuiBldDragManager::CreateListOfDialogs()
00976 {
00977    // Create a list of dialog methods
00978 
00979    fListOfDialogs = new TList();
00980 
00981    TList *methodList = IsA()->GetListOfMethods();
00982    TIter next(methodList);
00983    TString str;
00984    TMethod *method;
00985 
00986    while ((method = (TMethod*) next())) {
00987       str = method->GetCommentString();
00988       if (str.Contains("*DIALOG")) {
00989          fListOfDialogs->Add(method);
00990       }
00991    }
00992 }
00993 
00994 //______________________________________________________________________________
00995 void TGuiBldDragManager::Snap2Grid()
00996 {
00997    // Draw grid on editable frame and restore background on previuosly editted one
00998 
00999    if (fStop) {
01000       return;
01001    }
01002 
01003    delete fPimpl->fGrid;
01004 
01005    fPimpl->fGrid = new TGuiBldDragManagerGrid();
01006    fPimpl->fGrid->Draw();
01007 }
01008 
01009 //______________________________________________________________________________
01010 UInt_t TGuiBldDragManager::GetGridStep()
01011 {
01012    // Return the grid step
01013 
01014    return fPimpl->fGrid ? fPimpl->fGrid->fgStep : 1;
01015 }
01016 
01017 //______________________________________________________________________________
01018 void TGuiBldDragManager::SetGridStep(UInt_t step)
01019 {
01020    // Set the grid step
01021 
01022    fPimpl->fGrid->SetStep(step);
01023 }
01024 
01025 //______________________________________________________________________________
01026 Bool_t TGuiBldDragManager::IgnoreEvent(Event_t *event)
01027 {
01028    // Return kTRUE if event is rejected for processing by drag manager
01029 
01030    if (fStop || !fClient || !fClient->IsEditable()) return kTRUE;
01031    if (event->fType == kClientMessage) return kFALSE;
01032    if (event->fType == kDestroyNotify) return kFALSE;
01033 
01034    TGWindow *w = fClient->GetWindowById(event->fWindow);
01035 
01036    if (w) {
01037       if (IsEditDisabled(w)) {
01038          w = GetEditableParent((TGFrame*)w);
01039          return !w;
01040       }
01041    } else {
01042       return kTRUE;
01043    }
01044    return kFALSE;
01045 }
01046 
01047 //______________________________________________________________________________
01048 TGFrame* TGuiBldDragManager::InEditable(Window_t id)
01049 {
01050    // Return a pointer to the parent window (which is being editted)
01051 
01052    if (fStop || !id) {
01053       return 0;
01054    }
01055 
01056    Window_t preparent = id;
01057    Window_t parent = (Window_t)gVirtualX->GetParent(id);
01058 
01059    while (!parent || (parent != fClient->GetDefaultRoot()->GetId())) {
01060       if (parent == fClient->GetRoot()->GetId()) {
01061          TGWindow *w = fClient->GetWindowById(preparent);
01062          return (w ? (TGFrame*)w : 0);
01063       }
01064       preparent = parent;
01065       parent = gVirtualX->GetParent(parent);
01066    }
01067    return 0;
01068 }
01069 
01070 //______________________________________________________________________________
01071 TGCompositeFrame *TGuiBldDragManager::FindCompositeFrame(Window_t id)
01072 {
01073    // Find the first composite parent of window
01074 
01075    if (fStop || !id) {
01076       return 0;
01077    }
01078 
01079    Window_t parent = id;
01080 
01081    while (!parent || (parent != fClient->GetDefaultRoot()->GetId())) {
01082       TGWindow *w = fClient->GetWindowById(parent);
01083       if (w) {
01084          if (w->InheritsFrom(TGCompositeFrame::Class())) {
01085             return (TGCompositeFrame*)w;
01086          }
01087       }
01088       parent = gVirtualX->GetParent(parent);
01089    }
01090    return 0;
01091 }
01092 
01093 //______________________________________________________________________________
01094 void TGuiBldDragManager::SetCursorType(Int_t cur)
01095 {
01096    // Set cursor for selcted/grabbed frame.
01097 
01098    if (fStop) {
01099       return;
01100    }
01101 
01102    static UInt_t gid = 0;
01103    static UInt_t rid = 0;
01104 
01105    if (fPimpl->fGrab && (gid != fPimpl->fGrab->GetId())) {
01106       gVirtualX->SetCursor(fPimpl->fGrab->GetId(),
01107                            gVirtualX->CreateCursor((ECursor)cur));
01108       gid = fPimpl->fGrab->GetId();
01109    }
01110    if (fClient->IsEditable() && (rid != fClient->GetRoot()->GetId())) {
01111       gVirtualX->SetCursor(fClient->GetRoot()->GetId(),
01112                            gVirtualX->CreateCursor((ECursor)cur));
01113       rid = fClient->GetRoot()->GetId();
01114    }
01115 }
01116 
01117 //______________________________________________________________________________
01118 Bool_t TGuiBldDragManager::CheckDragResize(Event_t *event)
01119 {
01120    // Check resize type event.
01121 
01122    if (fStop) {
01123       return kFALSE;
01124    }
01125 
01126    Bool_t ret = kFALSE;
01127    fPimpl->fResizeType = kPointer;
01128 
01129    for (int i = 0; i < 8; i++) {
01130       if (fPimpl->fGrabRect[i]->GetId() == event->fWindow) {
01131          fPimpl->fResizeType = fPimpl->fGrabRect[i]->GetType();
01132          ret = kTRUE;
01133       }
01134    }
01135 
01136    if ((event->fType == kButtonPress) && (fPimpl->fResizeType != kPointer)) {
01137       fDragType = kDragResize;
01138       ret = kTRUE;
01139    }
01140 
01141    SetCursorType(ret ? fPimpl->fResizeType : kPointer);
01142    return ret;
01143 }
01144 
01145 //______________________________________________________________________________
01146 void TGuiBldDragManager::DoRedraw()
01147 {
01148    // Redraw the editted window
01149 
01150    if (fStop || !fClient || !fClient->IsEditable()) {
01151       return;
01152    }
01153 
01154    TGWindow *root = (TGWindow*)fClient->GetRoot();
01155 
01156    fClient->NeedRedraw(root, kTRUE);
01157 
01158    if (fBuilder) {
01159       fClient->NeedRedraw(fBuilder, kTRUE);
01160    }
01161 }
01162 
01163 //______________________________________________________________________________
01164 void TGuiBldDragManager::SwitchEditable(TGFrame *frame)
01165 {
01166    // Switch editable
01167 
01168    if (fStop || !frame) {
01169       return;
01170    }
01171 
01172    TGCompositeFrame *comp = 0;
01173 
01174    if (frame->InheritsFrom(TGCompositeFrame::Class()) && CanChangeLayout(frame)) {
01175       comp = (TGCompositeFrame *)frame;
01176    } else if (frame->GetParent()->InheritsFrom(TGCompositeFrame::Class())) {
01177       comp = (TGCompositeFrame *)frame->GetParent();
01178    }
01179 
01180    if (!comp) {
01181       return;
01182    }
01183 
01184    TString str = comp->ClassName();
01185    str += "::";
01186    str += comp->GetName();
01187 
01188    if (IsEditDisabled(comp)) {
01189       if (fBuilder) {
01190          str += " cannot be editted.";
01191          fBuilder->UpdateStatusBar(str.Data());
01192       }
01193       return;
01194    }
01195 
01196    if (frame != comp) {
01197       SelectFrame(frame);
01198    }
01199 
01200    if (comp->IsEditable()) {
01201       return;
01202    }
01203 
01204    RaiseMdiFrame(comp);
01205    comp->SetEditable(kTRUE);
01206 }
01207 
01208 //______________________________________________________________________________
01209 void TGuiBldDragManager::SelectFrame(TGFrame *frame, Bool_t add)
01210 {
01211    // Grab/Select frame
01212 
01213    if (fStop || !frame || (frame->GetParent() == fClient->GetDefaultRoot()) ||
01214        !fClient->IsEditable()) {
01215       return;
01216    }
01217 
01218    TString str = frame->ClassName();
01219    str += "::";
01220    str += frame->GetName();
01221 
01222    if (IsGrabDisabled(frame)) {
01223       if (fBuilder) {
01224          str += "can not be selected";
01225          fBuilder->UpdateStatusBar(str.Data());
01226       }
01227       return;
01228    }
01229 
01230    // do not grab mdi frames (quick hack)
01231    if (fBuilder && frame->InheritsFrom(TGMdiFrame::Class())) {
01232       return;
01233    }
01234 
01235 
01236    static Int_t x, x0, y, y0, xx, yy;
01237    Window_t c;
01238 
01239    RaiseMdiFrame(FindMdiFrame(frame));
01240    frame->MapRaised();
01241 
01242    if (!add) {
01243 
01244       fDragType = (fDragType != kDragCopy ) ?  kDragMove : fDragType;
01245 
01246       gVirtualX->TranslateCoordinates(frame->GetId(),
01247                                       fClient->GetDefaultRoot()->GetId(),
01248                                       0, 0, x0, y0, c);
01249 
01250       x = x0 + frame->GetWidth();
01251       y = y0 + frame->GetHeight();
01252 
01253       if (fBuilder) {
01254          str += " selected";
01255          str += (IsEditDisabled(frame) || IsFixedLayout(frame)  ? ". This frame cannot be editted." :
01256                  " ");
01257          str += " Press SpaceBar to unselect the frame.";
01258          if (IsFixedSize(frame)) str += " This frame cannot be resized.";
01259 
01260          fBuilder->UpdateStatusBar(str.Data());
01261       }
01262 
01263    } else { //shift mask is on
01264 
01265       gVirtualX->TranslateCoordinates(frame->GetId(),
01266                                       fClient->GetDefaultRoot()->GetId(),
01267                                       0, 0, xx, yy, c);
01268 
01269       fDragType = kDragLasso;
01270       fPimpl->fX0 = x0 = TMath::Min(x0, xx);
01271       fPimpl->fX = x = TMath::Max(x, xx + (Int_t)frame->GetWidth());
01272       fPimpl->fY0 = y0 = TMath::Min(y0, yy);
01273       fPimpl->fY = y = TMath::Max(y, yy + (Int_t)frame->GetHeight());
01274 
01275       DrawLasso();
01276    }
01277 
01278    fFrameUnder = fPimpl->fGrab = frame;
01279    fPimpl->fGrab->RequestFocus();
01280 
01281    // quick hack. the special case for TGCanvases
01282    if (frame->InheritsFrom(TGCanvas::Class())) {
01283       fSelected = ((TGCanvas*)frame)->GetContainer();
01284 
01285       if (!IsEditDisabled(fSelected)) {
01286          fSelected->SetEditable(kTRUE);
01287          if (fBuilder && fBuilder->GetAction()) {
01288             PlaceFrame((TGFrame*)fBuilder->ExecuteAction(), 0);
01289          }
01290       }
01291    } else {
01292       fSelected = fPimpl->fGrab;
01293    }
01294    ChangeSelected(fPimpl->fGrab);
01295 
01296    SetCursorType(kMove);
01297 
01298    SetLassoDrawn(kFALSE);
01299    DrawGrabRectangles(fPimpl->fGrab);
01300 }
01301 
01302 //______________________________________________________________________________
01303 void TGuiBldDragManager::ChangeSelected(TGFrame *fr)
01304 {
01305    // Inform outside wold that selected frame was changed
01306 
01307    if (fStop) {
01308       return;
01309    }
01310 
01311    TGFrame *sel = fr;
01312 
01313    if (fBuilder && (sel == fBuilder->GetMdiMain()->GetCurrent())) {
01314       sel = 0;
01315    }
01316 
01317    if (!fr) {
01318       UngrabFrame();
01319    }
01320 
01321    if (fEditor) {
01322       fEditor->ChangeSelected(sel);
01323    }
01324 
01325    if (fBuilder) {
01326       fBuilder->ChangeSelected(sel);
01327       //fBuilder->Update();
01328    }
01329 }
01330 
01331 //______________________________________________________________________________
01332 void TGuiBldDragManager::GrabFrame(TGFrame *frame)
01333 {
01334    // grab frame (see SelectFrame)
01335 
01336    if (fStop || !frame || !fClient->IsEditable()) {
01337       return;
01338    }
01339 
01340    fPimpl->fGrabParent = frame->GetParent();
01341    fPimpl->fGrabX = frame->GetX();
01342    fPimpl->fGrabY = frame->GetY();
01343 
01344    Window_t c;
01345 
01346    gVirtualX->TranslateCoordinates(frame->GetId(),
01347                                    fClient->GetDefaultRoot()->GetId(),
01348                                    0, 0, fPimpl->fX0, fPimpl->fY0, c);
01349 
01350    fPimpl->fX = fPimpl->fX0;
01351    fPimpl->fY = fPimpl->fY0;
01352 
01353    if (frame->GetFrameElement() && frame->GetFrameElement()->fLayout) {
01354       fPimpl->fGrabLayout = frame->GetFrameElement()->fLayout;
01355    }
01356 
01357    if (fPimpl->fGrabParent && frame->GetFrameElement() &&
01358        fPimpl->fGrabParent->InheritsFrom(TGCompositeFrame::Class())) {
01359       TList *li = ((TGCompositeFrame*)fPimpl->fGrabParent)->GetList();
01360       fPimpl->fGrabListPosition = (TGFrameElement*)li->Before(frame->GetFrameElement());
01361       ((TGCompositeFrame*)fPimpl->fGrabParent)->RemoveFrame(frame);
01362    }
01363 
01364    SetWindowAttributes_t attr;
01365    attr.fMask             = kWAOverrideRedirect | kWASaveUnder;
01366    attr.fOverrideRedirect = kTRUE;
01367    attr.fSaveUnder        = kTRUE;
01368 
01369    gVirtualX->ChangeWindowAttributes(frame->GetId(), &attr);
01370 
01371    frame->UnmapWindow();
01372    frame->ReparentWindow(fClient->GetDefaultRoot(), fPimpl->fX0, fPimpl->fY0);
01373    gVirtualX->Update(1);
01374    frame->Move(fPimpl->fX0, fPimpl->fY0);
01375    frame->MapRaised();
01376 
01377    if (fBuilder) {
01378       //fBuilder->Update();
01379       TString str = frame->ClassName();
01380       str += "::";
01381       str += frame->GetName();
01382       str += " is grabbed";
01383 
01384       fBuilder->UpdateStatusBar(str.Data());
01385    }
01386 }
01387 
01388 //______________________________________________________________________________
01389 void TGuiBldDragManager::UngrabFrame()
01390 {
01391    // Ungrab/Unselect selected/grabbed frame.
01392 
01393    if (fStop || !fPimpl->fGrab) {
01394       return;
01395    }
01396 
01397    SetCursorType(kPointer);
01398    HideGrabRectangles();
01399 
01400    DoRedraw();
01401 
01402    if (fBuilder) {
01403       //fBuilder->Update();
01404       TString str = fPimpl->fGrab->ClassName();
01405       str += "::";
01406       str += fPimpl->fGrab->GetName();
01407       str += " ungrabbed";
01408       fBuilder->UpdateStatusBar(str.Data());
01409    }
01410    fSelected = fPimpl->fGrab = 0;
01411 }
01412 
01413 //______________________________________________________________________________
01414 static Bool_t IsParentOfGrab(Window_t id, const TGWindow *grab)
01415 {
01416    // Helper for IsPointVisible
01417 
01418    const TGWindow *parent = grab;
01419 
01420    while (parent && (parent != gClient->GetDefaultRoot())) {
01421       if (parent->GetId() == id) {
01422          return kTRUE;
01423       }
01424       parent = parent->GetParent();
01425    }
01426 
01427    return kFALSE;
01428 }
01429 
01430 //______________________________________________________________________________
01431 Bool_t TGuiBldDragManager::IsPointVisible(Int_t xi, Int_t yi)
01432 {
01433    // Helper function for IsSelectedWindow method
01434 
01435    Window_t w = gVirtualX->GetDefaultRootWindow();
01436    Window_t src, dst, child;
01437    Int_t x = xi;
01438    Int_t y = yi;
01439    Bool_t ret = kFALSE;
01440 
01441    gVirtualX->TranslateCoordinates(fPimpl->fGrab->GetId(), w, x, y, x, y, child);
01442 
01443    dst = src = child = w;
01444 
01445    while (child) {
01446       src = dst;
01447       dst = child;
01448       gVirtualX->TranslateCoordinates(src, dst, x, y, x, y, child);
01449 
01450       if (IsParentOfGrab(child, fPimpl->fGrab)) {
01451          return kTRUE;
01452       }
01453    }
01454 
01455    return ret;
01456 }
01457 
01458 //______________________________________________________________________________
01459 Bool_t TGuiBldDragManager::IsSelectedVisible()
01460 {
01461    // Return kTRUE if grabbed/selected frame is not overlapped by other windows.
01462 
01463    if (fStop || !fPimpl->fGrab || !fClient->IsEditable()) {
01464       return kFALSE;
01465    }
01466 
01467    if (fBuilder) {
01468       TGMdiFrame *mdi = fBuilder->FindEditableMdiFrame(fPimpl->fGrab);
01469       if (mdi && (mdi != fBuilder->GetMdiMain()->GetCurrent())) {
01470          return kFALSE;
01471       }
01472    }
01473 
01474    // popup menu was placed
01475    if (fPimpl->fPlacePopup) {
01476       return kTRUE;
01477    }
01478 
01479    static Long64_t was = gSystem->Now();
01480    static Bool_t visible = kFALSE;
01481 
01482    Long64_t now = gSystem->Now();
01483 
01484    if (now-was < 100) {
01485       return visible;
01486    }
01487    was = now;
01488 
01489    visible = kFALSE;
01490 
01491    if (!IsPointVisible(2, 2)) {
01492       return visible;
01493    }
01494 
01495    if (!IsPointVisible(2, fPimpl->fGrab->GetHeight()-2)) {
01496       return visible;
01497    }
01498 
01499    if (!IsPointVisible(fPimpl->fGrab->GetWidth()-2, 2)) {
01500       return visible;
01501    }
01502 
01503    if (!IsPointVisible(fPimpl->fGrab->GetWidth()-2,
01504                        fPimpl->fGrab->GetHeight()-2)) {
01505       return visible;
01506    }
01507 
01508    visible = kTRUE;
01509 
01510    return visible;
01511 }
01512 
01513 //______________________________________________________________________________
01514 void TGuiBldDragManager::DrawGrabRectangles(TGWindow *win)
01515 {
01516    // Draw small grab rectangles around grabbed/selected/frame
01517 
01518    if (fStop) {
01519       return;
01520    }
01521 
01522    TGFrame *frame = win ? (TGFrame *)win : fPimpl->fGrab;
01523 
01524    if (!frame || !fClient->IsEditable() || fPimpl->fPlacePopup) {
01525       return;
01526    }
01527 
01528    Window_t w = gVirtualX->GetDefaultRootWindow();
01529    Window_t c; Int_t x, y;
01530 
01531    gVirtualX->TranslateCoordinates(frame->GetId(), w,  0, 0, x, y, c);
01532 
01533    if (frame->InheritsFrom(TGCompositeFrame::Class()) &&
01534        CanChangeLayout(frame) && !frame->IsLayoutBroken()) {
01535       fPimpl->fAroundFrame[0]->MoveResize(x-3, y-3, frame->GetWidth()+6, 2);
01536       fPimpl->fAroundFrame[0]->MapRaised();
01537       fPimpl->fAroundFrame[1]->MoveResize(x+frame->GetWidth()+3, y-3, 2, frame->GetHeight()+6);
01538       fPimpl->fAroundFrame[1]->MapRaised();
01539       fPimpl->fAroundFrame[2]->MoveResize(x-3, y+frame->GetHeight()+2, frame->GetWidth()+6, 2);
01540       fPimpl->fAroundFrame[2]->MapRaised();
01541       fPimpl->fAroundFrame[3]->MoveResize(x-3, y-3, 2, frame->GetHeight()+6);
01542       fPimpl->fAroundFrame[3]->MapRaised();
01543    } else {
01544       for (int i = 0; i < 4; i++) fPimpl->fAroundFrame[i]->UnmapWindow();
01545    }
01546 
01547    // draw rectangles
01548    DrawGrabRect(0, x - 6, y - 6);
01549    DrawGrabRect(1, x + frame->GetWidth()/2 - 3, y - 6);
01550    DrawGrabRect(2, x + frame->GetWidth(), y - 6);
01551    DrawGrabRect(3, x - 6, y + frame->GetHeight());
01552    DrawGrabRect(4, x - 6, y + frame->GetHeight()/2 - 3);
01553    DrawGrabRect(5, x + frame->GetWidth(), y + frame->GetHeight()/2 - 3);
01554    DrawGrabRect(6, x + frame->GetWidth()/2 - 3, y + frame->GetHeight());
01555    DrawGrabRect(7, x + frame->GetWidth(), y + frame->GetHeight());
01556 
01557    fPimpl->fGrabRectHidden = kFALSE;
01558 }
01559 
01560 //______________________________________________________________________________
01561 void TGuiBldDragManager::DrawGrabRect(Int_t i, Int_t x, Int_t y)
01562 {
01563    // Helper method to draw grab rectangle at position x,y
01564 
01565    if (fStop) {
01566       return;
01567    }
01568 
01569    fPimpl->fGrabRect[i]->Move(x, y);
01570    fPimpl->fGrabRect[i]->MapRaised();
01571 }
01572 
01573 //______________________________________________________________________________
01574 void TGuiBldDragManager::HighlightCompositeFrame(Window_t win)
01575 {
01576    // Raise composite frame when mouse is moving over it.
01577    // That allows to highlight position of "plain" composite frames.
01578 
01579    static Window_t gw = 0;
01580 
01581    if (fStop || !win || (win == gw)) {
01582       return;
01583    }
01584 
01585    TGWindow *w = fClient->GetWindowById(win);
01586 
01587    if (!w || (w == fPimpl->fPlane) || w->GetEditDisabled() || w->IsEditable() ||
01588        !w->InheritsFrom(TGCompositeFrame::Class())) {
01589       return;
01590    }
01591 
01592    TGFrame *frame = (TGFrame*)w;
01593    UInt_t opt = frame->GetOptions();
01594 
01595    if ((opt & kRaisedFrame) || (opt & kSunkenFrame)) {
01596       return;
01597    }
01598 
01599    gw = win;
01600    if (fPimpl->fPlane) {
01601       fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
01602       fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
01603    }
01604    fPimpl->fPlane = frame;
01605    fPimpl->fPlane->ChangeOptions(opt | kRaisedFrame);
01606    fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
01607 
01608    if (fBuilder) {
01609       TString str = frame->ClassName();
01610       str += "::";
01611       str += frame->GetName();
01612       fBuilder->UpdateStatusBar(str.Data());
01613    }
01614 }
01615 
01616 //______________________________________________________________________________
01617 Bool_t TGuiBldDragManager::HandleTimer(TTimer *t)
01618 {
01619    // The main event loop is  originated here
01620    // It repeadeatly queries pointer state and position on the screen.
01621    // From this info an Event_t structure is built.
01622 
01623    return HandleTimerEvent(0, t);
01624 }
01625 
01626 //______________________________________________________________________________
01627 Bool_t TGuiBldDragManager::HandleTimerEvent(Event_t *e, TTimer *t)
01628 {
01629    // Handle timer events or events coming from the recorder.
01630 
01631    static Int_t gy = 0;
01632    static Int_t gx = 0;
01633    static UInt_t gstate = 0;
01634    static Window_t gw = 0;
01635 
01636    Bool_t ret = kTRUE;
01637 
01638    // if nothing is editted stop timer and reset everything
01639    if (!fClient || !fClient->IsEditable()) {
01640       SetEditable(kFALSE);
01641       return kFALSE;
01642    }
01643    if (!IsSelectedVisible()) {
01644       HideGrabRectangles();
01645    }
01646    if (e) {
01647       if (fPimpl->fRepeatTimer) {
01648          // we are replaying events from the recorder...
01649          fPimpl->fRepeatTimer->Reset();
01650          fPimpl->fRepeatTimer->Remove();
01651       }
01652       if (e->fType == kButtonPress)
01653          return HandleButtonPress(e);
01654       else if (e->fType == kButtonRelease)
01655          return HandleButtonRelease(e);
01656       else if (e->fState & kButton1Mask)
01657          return HandleMotion(e);
01658       return kTRUE;
01659    }
01660    Window_t dum;
01661    Event_t ev;
01662    ev.fCode = kButton1;
01663    ev.fType = kMotionNotify;
01664    ev.fState = 0;
01665 
01666    gVirtualX->QueryPointer(gVirtualX->GetDefaultRootWindow(), dum, dum,
01667                            ev.fXRoot, ev.fYRoot, ev.fX, ev.fY, ev.fState);
01668 
01669    ev.fWindow = GetWindowFromPoint(ev.fXRoot, ev.fYRoot);
01670 
01671    if (ev.fWindow && (gw == ev.fWindow) && (gstate == ev.fState) &&
01672        (ev.fYRoot == gy) && (ev.fXRoot == gx)) {
01673       return kFALSE;
01674    }
01675 
01676    gw = ev.fWindow;
01677    gstate = ev.fState;
01678    ev.fState &= ~16;    // ignore "num lock" pressed
01679    ev.fState &= ~2;     // ignore "caps lock" pressed
01680 
01681    if (!fDragging && !fMoveWaiting && !fPimpl->fButtonPressed &&
01682        ((ev.fState == kButton1Mask) || (ev.fState == kButton3Mask) ||
01683         (ev.fState == (kButton1Mask | kKeyShiftMask)) ||
01684         (ev.fState == (kButton1Mask | kKeyControlMask)))) {
01685 
01686       if (ev.fState & kButton1Mask) ev.fCode = kButton1;
01687       if (ev.fState & kButton3Mask) ev.fCode = kButton3;
01688 
01689       ev.fType = kButtonPress;
01690       t->SetTime(40);
01691 
01692       if (fPimpl->fPlane && fClient->GetWindowById(fPimpl->fPlane->GetId())) {
01693          fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
01694          fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
01695       } else {
01696          fPimpl->fPlane = 0;
01697       }
01698 
01699       ret = HandleButtonPress(&ev);
01700       TimerEvent(&ev);
01701       return ret;
01702    }
01703 
01704    if ((fDragging || fMoveWaiting) && (!ev.fState || (ev.fState == kKeyShiftMask)) &&
01705        fPimpl->fButtonPressed) {
01706 
01707       ev.fType = kButtonRelease;
01708       t->SetTime(100);
01709 
01710       ret = HandleButtonRelease(&ev);
01711       TimerEvent(&ev);
01712       return ret;
01713    }
01714 
01715    fPimpl->fButtonPressed = (ev.fState & kButton1Mask) ||
01716                             (ev.fState & kButton2Mask) ||
01717                             (ev.fState & kButton3Mask);
01718 
01719    if ((ev.fYRoot == gy) && (ev.fXRoot == gx)) return kFALSE;
01720 
01721    gy = ev.fYRoot;
01722    gx = ev.fXRoot;
01723 
01724    if (!fMoveWaiting && !fDragging && !ev.fState) {
01725       if (!CheckDragResize(&ev) && fClient->GetWindowById(ev.fWindow)) {
01726          HighlightCompositeFrame(ev.fWindow);
01727       }
01728    } else if (ev.fState & kButton1Mask) {
01729       HandleMotion(&ev);
01730       TimerEvent(&ev);
01731    }
01732    return ret;
01733 }
01734 
01735 //______________________________________________________________________________
01736 Bool_t TGuiBldDragManager::RecognizeGesture(Event_t *event, TGFrame *frame)
01737 {
01738    // Recognize what was done when mouse button pressed
01739 
01740    if (fStop) {
01741       return kFALSE;
01742    }
01743 
01744    if (((event->fCode != kButton1) && (event->fCode != kButton3)) ||
01745        !frame || !fClient->IsEditable()) {
01746       return kFALSE;
01747    }
01748 
01749    TGFrame *context_fr = 0;
01750    Bool_t mdi = kFALSE;
01751 
01752    // hack for editable mdi frames
01753    if (frame->IsEditable() && frame->InheritsFrom(TGMdiFrame::Class())) {
01754       context_fr = frame;
01755       mdi = kTRUE;
01756    }
01757 
01758    // handle context menu
01759    if (event->fCode == kButton3) {
01760       if (!fPimpl->fSpacePressedFrame) {
01761          if (!mdi) {
01762             SelectFrame(frame);
01763             context_fr = fSelected;
01764          }
01765       } else {
01766          context_fr = fPimpl->fSpacePressedFrame;
01767       }
01768 
01769       HandleButon3Pressed(event, context_fr);
01770       return kTRUE;
01771    }
01772 
01773    fDragType = kDragNone;
01774 
01775    if (!fSelectionIsOn) {
01776       fPimpl->fX0 = event->fXRoot;
01777       fPimpl->fY0 = event->fYRoot;
01778    }
01779 
01780    //HideGrabRectangles();
01781    fPimpl->fClickFrame = frame;
01782 
01783    if (fBuilder && fBuilder->IsExecutable() &&
01784        frame->InheritsFrom(TGCompositeFrame::Class())) {
01785       UngrabFrame();
01786       frame->SetEditable(kTRUE);
01787       fSource = 0;
01788       fDragType = kDragLasso;
01789       goto out;
01790    }
01791 
01792    if (event->fState & kKeyShiftMask) {
01793       // drag grabbed frame with shift key pressed should create a copy of grabbed frame
01794       // move a copy of editable and selected frame
01795       if (frame == fPimpl->fGrab) {
01796          fSource = frame;
01797          fDragType = kDragCopy;
01798          gVirtualX->SetCursor(frame->GetId(), gVirtualX->CreateCursor(kMove));
01799          goto out;
01800       }
01801 
01802       // otherwise do lasso selection
01803       if (!fSelectionIsOn) {
01804          fSelectionIsOn = kTRUE;
01805       } else {
01806          fPimpl->fX = event->fXRoot;
01807          fPimpl->fY = event->fYRoot;
01808          fDragType = kDragLasso;
01809          DrawLasso();
01810          return kTRUE;
01811       }
01812    }
01813 
01814    CheckDragResize(event);
01815 
01816    if (frame->IsEditable()) {
01817       fSource = 0;
01818 
01819       if (fDragType != kDragResize) {
01820 
01821          // move editable and selected frame
01822          if (frame == fPimpl->fGrab) {
01823             fSource = frame;
01824             fDragType = kDragMove;
01825             gVirtualX->SetCursor(frame->GetId(), gVirtualX->CreateCursor(kMove));
01826             goto out;
01827          }
01828 
01829          fDragType = kDragLasso;
01830       }
01831    } else if ((fDragType != kDragResize) && !fPimpl->fSpacePressedFrame) {
01832 
01833       // special case of TGCanvas
01834       if (!fPimpl->fGrab && frame->InheritsFrom(TGCanvas::Class()))  {
01835          TGFrame *cont = ((TGCanvas*)frame)->GetContainer();
01836 
01837          if (!cont->IsEditable()) {
01838             cont->SetEditable(kTRUE);
01839             fDragType = kDragLasso;
01840             goto out;
01841          }
01842       }
01843 
01844       fSource = frame;
01845       SelectFrame(frame, event->fState & kKeyShiftMask);
01846    }
01847 
01848    if ((fDragType == kDragNone) && !fPimpl->fSpacePressedFrame) {
01849       SwitchEditable(frame);
01850       fSource = 0;
01851 
01852       // try again
01853       CheckDragResize(event);
01854 
01855       if (fDragType == kDragNone) {
01856          return kFALSE;
01857       }
01858    }
01859 
01860 out:
01861    Window_t c;
01862 
01863    gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
01864                                    frame->GetId(),
01865                                    event->fXRoot, event->fYRoot,
01866                                    fPimpl->fXf, fPimpl->fYf, c);
01867    fPimpl->fX = event->fXRoot;
01868    fPimpl->fY = event->fYRoot;
01869 
01870    fMoveWaiting = kTRUE;
01871    DoRedraw();
01872 
01873    return kTRUE;
01874 }
01875 
01876 //______________________________________________________________________________
01877 void TGuiBldDragManager::HandleButon3Pressed(Event_t *event, TGFrame *frame)
01878 {
01879    // Handle 3d mouse pressed (popup context menu)
01880 
01881    if (fStop || !frame) {
01882       return;
01883    }
01884 
01885    if (fClient->GetWaitForEvent() == kUnmapNotify) {
01886       return;
01887    }
01888 
01889    if (frame == fSelected) {
01890       Menu4Frame(frame, event->fXRoot, event->fYRoot);
01891    } else if (frame->IsEditable())  {
01892       if (fLassoDrawn) {
01893          Menu4Lasso(event->fXRoot, event->fYRoot);
01894       } else {
01895          Menu4Frame(frame, event->fXRoot, event->fYRoot);
01896       }
01897    } else {
01898       TGFrame *base = InEditable(frame->GetId());
01899       if (base) {
01900          //SelectFrame(base);
01901          Menu4Frame(base, event->fXRoot, event->fYRoot);
01902       } else {
01903          Menu4Frame(frame, event->fXRoot, event->fYRoot);
01904       }
01905    }
01906 }
01907 
01908 //______________________________________________________________________________
01909 Bool_t TGuiBldDragManager::HandleButton(Event_t *event)
01910 {
01911    // Handle button event occured in some ROOT frame
01912 
01913    if (fStop) {
01914       return kFALSE;
01915    }
01916 
01917    if (event->fCode != kButton3) {
01918       CloseMenus();
01919    }
01920 
01921    if (event->fType == kButtonPress) {
01922       return HandleButtonPress(event);
01923    } else {
01924       return HandleButtonRelease(event);
01925    }
01926 }
01927 
01928 //______________________________________________________________________________
01929 Bool_t TGuiBldDragManager::HandleConfigureNotify(Event_t *event)
01930 {
01931    // Resize events
01932 
01933    if (fStop) {
01934       return kFALSE;
01935    }
01936 
01937    TGWindow *w = fClient->GetWindowById(event->fWindow);
01938 
01939    if (!w) {
01940       return kFALSE;
01941    }
01942 
01943    fPimpl->fCompacted = kFALSE;
01944    return kFALSE;
01945 }
01946 
01947 //______________________________________________________________________________
01948 Bool_t TGuiBldDragManager::HandleExpose(Event_t *event)
01949 {
01950    // Handle repaint event
01951 
01952    if (fStop) {
01953       return kFALSE;
01954    }
01955 
01956    static Long64_t was = gSystem->Now();
01957    static Window_t win = 0;
01958    Long64_t now = gSystem->Now();
01959 
01960    if (event->fCount || (win == event->fWindow) || (now-was < 50) || fDragging) {
01961       if (fDragging) {
01962          HideGrabRectangles();
01963       }
01964       return kFALSE;
01965    }
01966 
01967    if (gMenuDialog) {
01968       HideGrabRectangles();
01969       gMenuDialog->RaiseWindow();
01970       return kFALSE;
01971    }
01972 
01973    if (fLassoDrawn) {
01974       DrawLasso();
01975    } else {
01976       if (IsSelectedVisible()) {
01977          DrawGrabRectangles();
01978       }
01979    }
01980 
01981    win = event->fWindow;
01982    was = now;
01983 
01984    return kFALSE;
01985 }
01986 
01987 //______________________________________________________________________________
01988 Bool_t TGuiBldDragManager::HandleEvent(Event_t *event)
01989 {
01990    // Handle all events.
01991 
01992    if (fStop) {
01993       return kFALSE;
01994    }
01995 
01996    if (IgnoreEvent(event)) {
01997       return kFALSE;
01998    }
01999 
02000    switch (event->fType) {
02001 
02002       case kExpose:
02003          return HandleExpose(event);
02004 
02005       case kConfigureNotify:
02006          while (gVirtualX->CheckEvent(fId, kConfigureNotify, *event))
02007             ;
02008          return HandleConfigureNotify(event);
02009 
02010       case kGKeyPress:
02011       case kKeyRelease:
02012          return HandleKey(event);
02013 
02014       case kFocusIn:
02015       case kFocusOut:
02016          //HandleFocusChange(event);
02017          break;
02018 
02019       case kButtonPress:
02020          {
02021             Int_t dbl_clk = kFALSE;
02022 
02023             static Window_t gDbw = 0;
02024             static Long_t gLastClick = 0;
02025             static UInt_t gLastButton = 0;
02026             static Int_t gDbx = 0;
02027             static Int_t gDby = 0;
02028 
02029             if ((event->fTime - gLastClick < 350) &&
02030                 (event->fCode == gLastButton) &&
02031                 (TMath::Abs(event->fXRoot - gDbx) < 6) &&
02032                 (TMath::Abs(event->fYRoot - gDby) < 6) &&
02033                 (event->fWindow == gDbw)) {
02034                dbl_clk = kTRUE;
02035             }
02036 
02037             if (dbl_clk) {
02038                if (event->fState & kKeyControlMask) {
02039                   HandleAction(kEndEditAct);
02040                   return kTRUE;
02041                } else if (!(event->fState & 0xFF)) {
02042                   TGFrame *w = (TGFrame*)fClient->GetWindowById(event->fWindow);
02043 
02044                   if (w && (w->GetEditDisabled() & kEditDisableBtnEnable)) {
02045                      return w->HandleDoubleClick(event);
02046                   }
02047                   if (SaveFrame(fTmpBuildFile.Data())) {
02048                      gROOT->Macro(fTmpBuildFile.Data());
02049                   }
02050                   // an easy way to start editting
02051                   if (fBuilder) fBuilder->HandleMenu(kGUIBLD_FILE_START);
02052                   return kTRUE;
02053                }
02054             } else {
02055                gDbw = event->fWindow;
02056                gLastClick = event->fTime;
02057                gLastButton = event->fCode;
02058                gDbx = event->fXRoot;
02059                gDby = event->fYRoot;
02060 
02061                Bool_t ret = HandleButtonPress(event);
02062                return ret;
02063             }
02064 
02065             return kFALSE;
02066          }
02067 
02068       case kButtonRelease:
02069          return HandleButtonRelease(event);
02070 
02071       case kEnterNotify:
02072       case kLeaveNotify:
02073          //HandleCrossing(event);
02074          break;
02075 
02076       case kMotionNotify:
02077          while (gVirtualX->CheckEvent(fId, kMotionNotify, *event))
02078             ;
02079          return HandleMotion(event);
02080 
02081       case kClientMessage:
02082          return HandleClientMessage(event);
02083 
02084       case kDestroyNotify:
02085          return HandleDestroyNotify(event);
02086 
02087       case kSelectionNotify:
02088          //HandleSelection(event);
02089          break;
02090 
02091       case kSelectionRequest:
02092          //HandleSelectionRequest(event);
02093          break;
02094 
02095       case kSelectionClear:
02096          //HandleSelectionClear(event);
02097          break;
02098 
02099       case kColormapNotify:
02100          //HandleColormapChange(event);
02101          break;
02102 
02103       default:
02104          //Warning("HandleEvent", "unknown event (%#x) for (%#x)", event->fType, fId);
02105          break;
02106    }
02107 
02108    return kFALSE;
02109 }
02110 
02111 //______________________________________________________________________________
02112 Bool_t TGuiBldDragManager::HandleDoubleClick(Event_t *)
02113 {
02114    // Mouse double click handler (never should happen)
02115 
02116    if (fStop) {
02117       return kFALSE;
02118    }
02119 
02120    return kFALSE;
02121 }
02122 
02123 //______________________________________________________________________________
02124 TGFrame *TGuiBldDragManager::GetBtnEnableParent(TGFrame *fr)
02125 {
02126    // Return a parent which can handle button evevents.
02127 
02128    TGWindow *parent = fr;
02129 
02130    while (parent && (parent != fClient->GetDefaultRoot())) {
02131       if (parent->GetEditDisabled() & kEditDisableBtnEnable) {
02132          return (TGFrame*)parent;
02133       }
02134       parent = (TGWindow*)parent->GetParent();
02135    }
02136    return 0;
02137 }
02138 
02139 //______________________________________________________________________________
02140 void TGuiBldDragManager::UnmapAllPopups()
02141 {
02142    // Unmap all popups
02143 
02144    TList *li = fClient->GetListOfPopups();
02145    if (!li->GetEntries()) {
02146       return;
02147    }
02148 
02149    TGPopupMenu *pup;
02150    TIter next(li);
02151 
02152    while ((pup = (TGPopupMenu*)next())) {
02153       pup->UnmapWindow();
02154       fClient->ResetWaitFor(pup);
02155    }
02156    gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
02157 }
02158 
02159 //______________________________________________________________________________
02160 Bool_t TGuiBldDragManager::HandleButtonPress(Event_t *event)
02161 {
02162    // Handle button press event
02163 
02164    if (fStop) {
02165       return kFALSE;
02166    }
02167 
02168    fPimpl->fButtonPressed = kTRUE;
02169    fPimpl->fPlacePopup = kFALSE;
02170 
02171    if (fPimpl->fPlane) {
02172       fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
02173       fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
02174    }
02175 
02176    if (gMenuDialog) { // keep editor on the top
02177       gMenuDialog->RaiseWindow();
02178    }
02179 
02180    // keep undocked toolbar on the top
02181    //(but under win32 key handling will be broken : todo)
02182    if (gVirtualX->InheritsFrom("TGX11") && fBuilder &&
02183        fBuilder->GetToolDock()->IsUndocked()) {
02184       fBuilder->GetToolDock()->GetUndocked()->RaiseWindow();
02185    }
02186 
02187    // keep color dialog on the top
02188    if (fgGlobalColorDialog && fgGlobalColorDialog->IsMapped()) {
02189       fgGlobalColorDialog->RaiseWindow();
02190       return kFALSE;
02191    }
02192 
02193    if ( ((event->fCode != kButton1) && (event->fCode != kButton3)) ||
02194         (event->fType != kButtonPress) || IgnoreEvent(event)) {
02195       return kFALSE;
02196    }
02197 
02198    Reset1();
02199    //HideGrabRectangles();
02200 
02201    Window_t w = GetWindowFromPoint(event->fXRoot, event->fYRoot);
02202    TGFrame *fr = 0;
02203 
02204    if (w) {
02205       fr = (TGFrame*)fClient->GetWindowById(w);
02206       if (!fr) {
02207          return kFALSE;
02208       }
02209 
02210       //fr->HandleButton(event);
02211       if (!IsEventsDisabled(fr)) {
02212          TGFrame *btnframe = GetBtnEnableParent(fr);
02213          if (btnframe) {
02214             event->fUser[0] = fr->GetId();
02215             btnframe->HandleButton(event);
02216          }
02217       }
02218 
02219       if (IsGrabDisabled(fr)) {
02220          fr = GetEditableParent(fr);
02221       }
02222 
02223       if (!fr) {
02224          return kFALSE;
02225       }
02226    } else {
02227       return kFALSE;
02228    }
02229 
02230    return RecognizeGesture(event, fr);
02231 }
02232 
02233 //______________________________________________________________________________
02234 Bool_t TGuiBldDragManager::HandleButtonRelease(Event_t *event)
02235 {
02236    // Handle button release event
02237 
02238    if (fStop) {
02239       return kFALSE;
02240    }
02241 
02242    // unmap all waiting popups
02243    if (fClient->GetWaitForEvent() == kUnmapNotify) {
02244       UnmapAllPopups();
02245    }
02246 
02247    TGWindow *w = fClient->GetWindowById(event->fWindow);
02248 
02249    if (w && !IsEventsDisabled(w)) {
02250       TGFrame *btnframe = GetBtnEnableParent((TGFrame*)w);
02251       if (btnframe) {
02252          event->fUser[0] = w->GetId();
02253          btnframe->HandleButton(event);
02254       }
02255    }
02256 
02257    fPimpl->fButtonPressed = kFALSE;
02258    gVirtualX->SetCursor(fClient->GetRoot()->GetId(), gVirtualX->CreateCursor(kPointer));
02259    EndDrag();
02260    fSelectionIsOn &= (event->fState & kKeyShiftMask);
02261 
02262    if (fLassoDrawn) {
02263       DrawLasso();
02264       return kTRUE;
02265    }
02266 
02267    if (fPimpl->fClickFrame && !fSelectionIsOn) {
02268 
02269       // make editable the clicked frame if no lasso was drawn
02270       if ((fPimpl->fClickFrame == fPimpl->fGrab) && (fSelected == fPimpl->fGrab) &&
02271            !fPimpl->fGrab->IsEditable()) {
02272          SwitchEditable(fPimpl->fClickFrame);
02273          return kTRUE;
02274 
02275       // select/grab clicked frame if there was no grab frame
02276       } else if (!fPimpl->fGrab || ((fPimpl->fClickFrame != fPimpl->fGrab) &&
02277                                     (fPimpl->fClickFrame != fSelected))) {
02278          SelectFrame(fPimpl->fClickFrame);
02279          return kTRUE;
02280       }
02281 
02282    }
02283 
02284    SelectFrame(fPimpl->fGrab);
02285 
02286    return kTRUE;
02287 }
02288 
02289 //______________________________________________________________________________
02290 Bool_t TGuiBldDragManager::HandleKey(Event_t *event)
02291 {
02292    // Handle key event
02293 
02294    if (fStop) {
02295       return kFALSE;
02296    }
02297 
02298    char   tmp[10];
02299    UInt_t keysym;
02300    Bool_t ret = kFALSE;
02301    TGFileInfo fi;
02302    static TString dir(".");
02303    static Bool_t overwr = kFALSE;
02304    TString fname;
02305 
02306    TGWindow *w = fClient->GetWindowById(GetWindowFromPoint(event->fXRoot, event->fYRoot));
02307 
02308    if (!w || !fPimpl) {
02309       return kFALSE;
02310    }
02311 
02312    if (w->GetEditDisabled() & kEditDisableKeyEnable) {
02313       return ((TGFrame*)w)->HandleKey(event);
02314    }
02315 
02316    if (event->fType != kGKeyPress) {
02317       return kFALSE;
02318    }
02319 
02320    if (IsEditDisabled(w)) {
02321       TGFrame *parent = GetEditableParent((TGFrame*)w);
02322       if (parent) {
02323          event->fWindow = parent->GetId();
02324          parent->HandleKey(event);
02325       } else {
02326          return ((TGFrame*)w)->HandleKey(event);
02327       }
02328    }
02329 
02330    fPimpl->fSpacePressedFrame = 0;
02331 
02332    if (fPimpl->fPlane) {
02333       fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
02334       fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
02335    }
02336 
02337    CloseMenus();
02338 
02339    fi.fFileTypes = gSaveMacroTypes;
02340    fi.fIniDir    = StrDup(dir);
02341    fi.fOverwrite = overwr;
02342 
02343    gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
02344 
02345    if (event->fState & kKeyControlMask) {
02346 
02347       switch ((EKeySym)keysym & ~0x20) {
02348          case kKey_Return:
02349          case kKey_Enter:
02350             HandleReturn(kTRUE);
02351             ret = kTRUE;
02352             break;
02353          case kKey_X:
02354             HandleCut();
02355             ret = kTRUE;
02356             break;
02357          case kKey_C:
02358             HandleCopy();
02359             ret = kTRUE;
02360             break;
02361          case kKey_V:
02362             if (fPimpl->fClickFrame && !fPimpl->fClickFrame->IsEditable()) {
02363                fPimpl->fClickFrame->SetEditable(kTRUE);
02364             }
02365             HandlePaste();
02366             ret = kTRUE;
02367             break;
02368          case kKey_B:
02369          {
02370             if (fPimpl->fGrab ) {
02371                BreakLayout();
02372             }
02373             ret = kTRUE;
02374             break;
02375          }
02376          case kKey_L:
02377          {
02378             if (fPimpl->fGrab && (fPimpl->fClickFrame != fClient->GetRoot())) {
02379                Compact(kFALSE);
02380             } else {
02381                Compact(kTRUE);
02382             }
02383             ret = kTRUE;
02384             break;
02385          }
02386          case kKey_R:
02387             HandleReplace();
02388             ret = kTRUE;
02389             break;
02390          case kKey_S:
02391             Save();
02392             ret = kTRUE;
02393             break;
02394          case kKey_G:
02395             HandleGrid();
02396             ret = kTRUE;
02397             break;
02398          case kKey_H:
02399             SwitchLayout();
02400             ret = kTRUE;
02401             break;
02402          case kKey_N:
02403             if (fBuilder) {
02404                fBuilder->NewProject();
02405             } else {
02406                TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
02407                main->MapRaised();
02408                main->SetEditable(kTRUE);
02409             }
02410             ret = kTRUE;
02411             break;
02412          case kKey_O:
02413             if (fBuilder) {
02414                fBuilder->NewProject();
02415             } else {
02416                TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
02417                main->MapRaised();
02418                main->SetEditable(kTRUE);
02419             }
02420             new TGFileDialog(fClient->GetDefaultRoot(), this, kFDSave, &fi);
02421 
02422             if (!fi.fFilename) return kTRUE;
02423             dir = fi.fIniDir;
02424             overwr = fi.fOverwrite;
02425             fname = gSystem->BaseName(gSystem->UnixPathName(fi.fFilename));
02426 
02427             if (fname.EndsWith(".C")) {
02428                gROOT->Macro(fname.Data());
02429             } else {
02430                Int_t retval;
02431                new TGMsgBox(fClient->GetDefaultRoot(), this, "Error...",
02432                             TString::Format("file (%s) must have extension .C", fname.Data()),
02433                             kMBIconExclamation, kMBRetry | kMBCancel, &retval);
02434                if (retval == kMBRetry) {
02435                   HandleKey(event);
02436                }
02437             }
02438             ret = kTRUE;
02439             break;
02440          default:
02441             break;
02442       }
02443    } else {
02444       switch ((EKeySym)keysym) {
02445          case kKey_Delete:
02446          case kKey_Backspace:
02447             HandleDelete(event->fState & kKeyShiftMask);
02448             ret = kTRUE;
02449             break;
02450          case kKey_Return:
02451          case kKey_Enter:
02452             //UnmapAllPopups();
02453             HandleReturn(kFALSE);
02454             ret = kTRUE;
02455             break;
02456          case kKey_Left:
02457          case kKey_Right:
02458          case kKey_Up:
02459          case kKey_Down:
02460             if (fLassoDrawn) {
02461                HandleAlignment(keysym, event->fState & kKeyShiftMask);
02462             } else if (fPimpl->fGrab) {
02463                HandleLayoutOrder((keysym == kKey_Right) || (keysym == kKey_Down));
02464             }
02465             ret = kTRUE;
02466             break;
02467          case kKey_Space:
02468             //UnmapAllPopups();
02469             if (fPimpl->fGrab) {
02470                SwitchEditable(fPimpl->fGrab);
02471 
02472                TGFrame *p = (TGFrame*)GetEditableParent(fPimpl->fGrab);
02473 
02474                if (p) {
02475                   if (p == fBuilder->GetMdiMain()->GetCurrent()) {
02476                      UngrabFrame();
02477                   } else {
02478                      SelectFrame(p);
02479                      fSource = fPimpl->fSpacePressedFrame = p;
02480                   }
02481                }
02482             }
02483             ret = kTRUE;
02484             break;
02485          default:
02486             break;
02487       }
02488    }
02489    if (fBuilder) {
02490       fBuilder->SetAction(0);
02491       //fBuilder->Update();
02492    }
02493 
02494    if (fLassoDrawn) {
02495       DrawLasso();
02496    }
02497 
02498    return ret;
02499 }
02500 
02501 //______________________________________________________________________________
02502 void TGuiBldDragManager::ReparentFrames(TGFrame *newfr, TGCompositeFrame *oldfr)
02503 {
02504    // Reparent frames
02505 
02506    if (fStop || !fClient->IsEditable() || (newfr == fClient->GetDefaultRoot())) {
02507       return;
02508    }
02509 
02510    Int_t x0, y0, xx, yy;
02511    Window_t c;
02512    static TGLayoutHints *hints = new TGLayoutHints(kLHintsNormal, 2, 2, 2, 2);
02513 
02514    if (!newfr || !newfr->GetId() || !oldfr || !oldfr->GetId()) return;
02515 
02516    gVirtualX->TranslateCoordinates(newfr->GetId(), oldfr->GetId(),
02517                                    0, 0, x0, y0, c);
02518 
02519    x0 = x0 < 0 ? 0 : x0;
02520    y0 = y0 < 0 ? 0 : y0;
02521    Int_t x = x0 + newfr->GetWidth();
02522    Int_t y = y0 + newfr->GetHeight();
02523 
02524    TGCompositeFrame *comp = 0;
02525 
02526    if (newfr->InheritsFrom(TGCompositeFrame::Class())) {
02527       comp = (TGCompositeFrame*)newfr;
02528       comp->SetLayoutBroken();
02529    }
02530 
02531    TIter next(oldfr->GetList());
02532    TGFrameElement *el;
02533 
02534    while ((el = (TGFrameElement*)next())) {
02535       TGFrame *frame = el->fFrame;
02536 
02537       if ((frame->GetX() >= x0) && (frame->GetY() >= y0) &&
02538           (frame->GetX() + (Int_t)frame->GetWidth() <= x) &&
02539           (frame->GetY() + (Int_t)frame->GetHeight() <= y)) {
02540 
02541          if (frame == fPimpl->fGrab) {
02542             UngrabFrame();
02543          }
02544 
02545          oldfr->RemoveFrame(frame);
02546 
02547          gVirtualX->TranslateCoordinates(oldfr->GetId(), newfr->GetId(),
02548                                         frame->GetX(), frame->GetY(), xx, yy, c);
02549 
02550          frame->ReparentWindow(newfr, xx, yy);
02551 
02552          if (comp) {
02553             comp->AddFrame(frame, hints); // el->fLayout);
02554          }
02555       }
02556    }
02557 }
02558 
02559 //______________________________________________________________________________
02560 TList *TGuiBldDragManager::GetFramesInside(Int_t x0, Int_t y0, Int_t x, Int_t y)
02561 {
02562    // Return the list of frames inside of some area
02563 
02564    if (fStop) {
02565       return 0;
02566    }
02567 
02568    Int_t xx, yy;
02569 
02570    if (!fClient->GetRoot()->InheritsFrom(TGCompositeFrame::Class())) {
02571       return 0;
02572    }
02573 
02574    TList *list = new TList();
02575 
02576    xx = x0; yy = y0;
02577    x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
02578    y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
02579 
02580    TIter next(((TGCompositeFrame*)fClient->GetRoot())->GetList());
02581    TGFrameElement *el;
02582 
02583    while ((el = (TGFrameElement*)next())) {
02584       if ((el->fFrame->GetX() >= x0) && (el->fFrame->GetY() >= y0) &&
02585           (el->fFrame->GetX() + (Int_t)el->fFrame->GetWidth() <= x) &&
02586           (el->fFrame->GetY() + (Int_t)el->fFrame->GetHeight() <= y)) {
02587          list->Add(el->fFrame);
02588       }
02589    }
02590    if (list->IsEmpty()) {
02591       delete list;
02592       return 0;
02593    }
02594    return list;
02595 }
02596 
02597 //______________________________________________________________________________
02598 void TGuiBldDragManager::DropCanvas(TGCanvas *canvas)
02599 {
02600    // Drop canvas container
02601 
02602    if (fStop) {
02603       return;
02604    }
02605 
02606    TGCompositeFrame *comp = (TGCompositeFrame*)canvas->GetParent();
02607    comp->SetEditable(kTRUE);
02608 
02609    TGCompositeFrame *cont = (TGCompositeFrame*)canvas->GetContainer();
02610    Int_t x = canvas->GetX();
02611    Int_t y = canvas->GetY();
02612 
02613    cont->SetEditDisabled(cont->GetEditDisabled() & ~kEditDisableGrab);
02614    cont->ReparentWindow(comp, x, y);
02615    canvas->SetContainer(0);
02616    comp->AddFrame(cont);
02617    DeleteFrame(canvas);
02618 
02619    if (fBuilder) {
02620       TString str = cont->ClassName();
02621       str += "::";
02622       str += cont->GetName();
02623       str += " dropped.";
02624       fBuilder->UpdateStatusBar(str.Data());
02625    }
02626    SelectFrame(cont);
02627 }
02628 
02629 //______________________________________________________________________________
02630 void TGuiBldDragManager::PutToCanvas(TGCompositeFrame *cont)
02631 {
02632    // Create a new TGCanvas and place container into it
02633 
02634    if (fStop || !cont) {
02635       return;
02636    }
02637 
02638    TGCompositeFrame *comp = (TGCompositeFrame*)cont->GetParent();
02639    comp->SetEditable(kTRUE);
02640 
02641    UInt_t w = cont->GetWidth()/2;
02642    UInt_t h = cont->GetHeight()/2;
02643 
02644    w = w < 100 ? 100 : w;
02645    h = h < 100 ? 100 : h;
02646 
02647    TGCanvas *canvas = new TGCanvas(comp, w, h);
02648    canvas->Move(cont->GetX(), cont->GetY());
02649    comp->RemoveFrame(cont);
02650    comp->AddFrame(canvas);
02651    cont->ReparentWindow(canvas->GetViewPort());
02652    canvas->SetContainer(cont);
02653    cont->SetCleanup(kDeepCleanup);
02654    canvas->MapSubwindows();
02655    canvas->MapWindow();
02656    SelectFrame(canvas);
02657 
02658    if (fBuilder) {
02659       fBuilder->UpdateStatusBar("Grab action performed. Presss Cntrl-Return to Drop grabbed frame.");
02660    }
02661 }
02662 
02663 //______________________________________________________________________________
02664 void TGuiBldDragManager::HandleReturn(Bool_t on)
02665 {
02666    // Handling of  return/enter key pressing
02667    //
02668    // If on is kFALSE:
02669    //    If Return or Enter key was pressed - Grab Act
02670    //    If lasso is  drawn - new composite frame is created and
02671    //                         all frames inside lasso adopted as childrens.
02672    //    If lasso is not drawn and selected frame is composite one,
02673    //                       - new TGCanvas widget is created and selcted frmae became
02674    //                         container for this canvas.
02675    //
02676    // If on is kTRUE:
02677    //    If Return or Enter key was pressed with Control Key - Drop Act,
02678    //    The opposite action to the Grab Act.
02679    //    If selected/grabbed frame is not a TGCanvas widget -
02680    //          all frames inside the grabbed/selected frame are "dropped" into
02681    //          the underlying frame and the grabbed frame is deleted.
02682    //
02683    //    If selected/grabbed frame is a TGCanvas widget -
02684    //          container frame "dropped" to editable frame
02685 
02686    if (fStop) {
02687       return;
02688    }
02689 
02690    Int_t x0, y0, x, y, xx, yy;
02691    Window_t c;
02692    TGCompositeFrame *parent = 0;
02693    TList *li = 0;
02694 
02695    if (!fClient->GetRoot()->InheritsFrom(TGCompositeFrame::Class()) ||
02696        !fClient->IsEditable()) {
02697       return;
02698    }
02699 
02700    // if grabbed frame is editable - we need to switch edit to parent
02701    if (fPimpl->fGrab && fPimpl->fGrab->IsEditable()) {
02702       ((TGFrame*)fPimpl->fGrab->GetParent())->SetEditable(kTRUE);
02703    }
02704 
02705    if (fPimpl->fGrab && !fLassoDrawn) {
02706       if (!on) {
02707          if (fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class()) &&
02708             !fPimpl->fGrab->InheritsFrom(TGCanvas::Class()) &&
02709             !fPimpl->fGrab->InheritsFrom(TGContainer::Class()) &&
02710             CanChangeLayout(fPimpl->fGrab) &&
02711             CanChangeLayout((TGWindow*)fPimpl->fGrab->GetParent())) {
02712             PutToCanvas((TGCompositeFrame*)fPimpl->fGrab);
02713             return;
02714          }
02715       } else {
02716 
02717          if ((fPimpl->fGrab->IsA() == TGCanvas::Class()) &&
02718              !((TGCanvas*)fPimpl->fGrab)->GetContainer()->InheritsFrom(TGContainer::Class()) &&
02719              CanChangeLayout((TGWindow*)fPimpl->fGrab->GetParent())) {
02720             DropCanvas((TGCanvas*)fPimpl->fGrab);
02721             return;
02722          }
02723       }
02724    }
02725 
02726    TGCompositeFrame *comp = (TGCompositeFrame*)fClient->GetRoot();
02727 
02728    if (fLassoDrawn) {
02729 
02730       gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
02731                                       fClient->GetRoot()->GetId(),
02732                                       fPimpl->fX, fPimpl->fY, x, y, c);
02733       gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
02734                                       fClient->GetRoot()->GetId(),
02735                                       fPimpl->fX0, fPimpl->fY0, x0, y0, c);
02736 
02737       xx = x0; yy = y0;
02738       x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
02739       y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
02740 
02741       li = GetFramesInside(x0, y0, x, y);
02742 
02743       if (!on && li) {
02744          parent = new TGCompositeFrame(comp, x - x0, y - y0);
02745          parent->MoveResize(x0, y0, x - x0, y - y0);
02746          ReparentFrames(parent, comp);
02747 
02748          comp->AddFrame(parent);
02749          parent->MapWindow();
02750          SetLassoDrawn(kFALSE);
02751          SelectFrame(parent);
02752 
02753          if (fBuilder) {
02754             TString str = "Grab action performed.";
02755             str += " Press Cntrl-Return to Drop grabbed frames.";
02756             str += " Presss Return for TCanvas Grab";
02757             fBuilder->UpdateStatusBar(str.Data());
02758          }
02759       }
02760    } else if (on && fPimpl->fGrab) {
02761 
02762       // check if it is forbidden
02763       if (!CanChangeLayout(fPimpl->fGrab) ||
02764           !CanChangeLayout((TGWindow*)fPimpl->fGrab->GetParent())) {
02765          if (fBuilder) {
02766             fBuilder->UpdateStatusBar("Drop action disabled");
02767          }
02768          return;
02769       }
02770 
02771       if (fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class())) {
02772          parent = (TGCompositeFrame*)fPimpl->fGrab;
02773       } else {
02774          //parent = (TGCompositeFrame*)fPimpl->fGrab->GetParent();
02775       }
02776       if (parent) {
02777          ReparentFrames(comp, parent);
02778          DeleteFrame(fPimpl->fGrab);
02779          UngrabFrame();
02780          ChangeSelected(0);   //update editors
02781 
02782          if (fBuilder) {
02783             fBuilder->UpdateStatusBar("Drop action performed");
02784          }
02785       }
02786    }
02787    delete li;
02788 }
02789 
02790 //______________________________________________________________________________
02791 void TGuiBldDragManager::HandleAlignment(Int_t to, Bool_t lineup)
02792 {
02793    // Align frames located inside lasso area.
02794 
02795    if (fStop) {
02796       return;
02797    }
02798 
02799    Int_t x0, y0, x, y, xx, yy;
02800    Window_t c;
02801    TGCompositeFrame *comp = 0;
02802 
02803    if (!fClient->GetRoot()->InheritsFrom(TGCompositeFrame::Class()) ||
02804        !fClient->IsEditable()) {
02805       return;
02806    }
02807 
02808    if (fLassoDrawn) {
02809       gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
02810                                       fClient->GetRoot()->GetId(),
02811                                       fPimpl->fX, fPimpl->fY, x, y, c);
02812       gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
02813                                       fClient->GetRoot()->GetId(),
02814                                       fPimpl->fX0, fPimpl->fY0, x0, y0, c);
02815 
02816       xx = x0; yy = y0;
02817       x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
02818       y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
02819 
02820       comp = (TGCompositeFrame*)fClient->GetRoot();
02821 
02822       ToGrid(x, y);
02823       ToGrid(x0, y0);
02824 
02825       TIter next(comp->GetList());
02826       TGFrameElement *el;
02827       TGFrame *prev = 0;
02828 
02829       while ((el = (TGFrameElement*)next())) {
02830          TGFrame *fr = el->fFrame;
02831 
02832          if ((fr->GetX() >= x0) && (fr->GetY() >= y0) &&
02833              (fr->GetX() + (Int_t)fr->GetWidth() <= x) &&
02834              (fr->GetY() + (Int_t)fr->GetHeight() <= y)) {
02835 
02836             switch ((EKeySym)to) {
02837                case kKey_Left:
02838                   fr->Move(x0, fr->GetY());
02839                   if (lineup) {
02840                      if (prev) fr->Move(fr->GetX(), prev->GetY() + prev->GetHeight());
02841                      else fr->Move(x0, y0);
02842                   }
02843                   break;
02844                case kKey_Right:
02845                   fr->Move(x - fr->GetWidth(), fr->GetY());
02846                   if (lineup) {
02847                      if (prev) fr->Move(fr->GetX(), prev->GetY() + prev->GetHeight());
02848                      else fr->Move(x - fr->GetWidth(), y0);
02849                   }
02850                   break;
02851                case kKey_Up:
02852                   fr->Move(fr->GetX(), y0);
02853                   if (lineup) {
02854                      if (prev) fr->Move(prev->GetX() + prev->GetWidth(), fr->GetY());
02855                      else fr->Move(x0, y0);
02856                   }
02857                   break;
02858                case kKey_Down:
02859                   fr->Move(fr->GetX(), y - fr->GetHeight());
02860                   if (lineup) {
02861                      if (prev) fr->Move(prev->GetX() + prev->GetWidth(), fr->GetY());
02862                      else fr->Move(x0, y - fr->GetHeight());
02863                   }
02864                   break;
02865                default:
02866                   break;
02867             }
02868             prev = fr;
02869          }
02870       }
02871    }
02872    if (fLassoDrawn) {
02873       DrawLasso();
02874    }
02875 }
02876 
02877 //______________________________________________________________________________
02878 void TGuiBldDragManager::HandleDelete(Bool_t crop)
02879 {
02880    // Handle delete or crop action
02881    //
02882    // crop is kFALSE - delete action
02883    //   - if lasso is drawn -> all frames inside lasso area are deleted
02884    //   - if frame is grabbed/selected -> the frame is deleted
02885    // crop is kTRUE - crop action
02886    //   - if lasso is drawn -> all frames outside of lasso area are deleted
02887    //   - if frame is grabbed/selected -> all frames except the grabbed frame are deleted
02888    //     In both cases the main frame is shrinked to the size of crop area.
02889 
02890    if (fStop) {
02891       return;
02892    }
02893 
02894    Int_t x0, y0, x, y, xx, yy, w, h;
02895    Window_t c;
02896 
02897    if (!fClient->GetRoot()->InheritsFrom(TGCompositeFrame::Class()) ||
02898        !fClient->IsEditable()) {
02899       return;
02900    }
02901 
02902    TGCompositeFrame *comp = 0;
02903    Bool_t fromGrab = kFALSE;
02904    TGFrame *frame = fPimpl->fGrab;
02905 
02906    if (fBuilder && crop) {
02907       comp = fBuilder->FindEditableMdiFrame(fClient->GetRoot());
02908    } else {
02909       comp = (TGCompositeFrame*)fClient->GetRoot();
02910    }
02911 
02912    if (frame && !CanChangeLayout((TGWindow*)frame->GetParent())) {
02913       frame = GetMovableParent(frame);
02914 
02915       if (!frame) {
02916          TString str = fPimpl->fGrab->ClassName();
02917          str += "::";
02918          str += fPimpl->fGrab->GetName();
02919          str += " cannot be deleted";
02920 
02921          if (fBuilder) {
02922             fBuilder->UpdateStatusBar(str.Data());
02923          }
02924          return;
02925       }
02926    }
02927 
02928    // prepare to crop grabbed frame
02929    if (frame && !fLassoDrawn && crop) {
02930       gVirtualX->TranslateCoordinates(frame->GetId(),
02931                                       fClient->GetDefaultRoot()->GetId(),
02932                                       -2, -2,
02933                                       fPimpl->fX0, fPimpl->fY0, c);
02934 
02935       fPimpl->fX = fPimpl->fX0 + frame->GetWidth()+4;
02936       fPimpl->fY = fPimpl->fY0 + frame->GetHeight()+4;
02937       fromGrab = kTRUE;
02938    }
02939 
02940    x0 = fPimpl->fX0; y0 = fPimpl->fY0;
02941    x  = fPimpl->fX;  y  = fPimpl->fY;
02942    if (comp) {
02943       gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
02944                                       comp->GetId(),
02945                                       fPimpl->fX, fPimpl->fY, x, y, c);
02946       gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
02947                                       comp->GetId(),
02948                                       fPimpl->fX0, fPimpl->fY0, x0, y0, c);
02949    }
02950 
02951    xx = x0; yy = y0;
02952    x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
02953    y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
02954    w = x - x0;
02955    h = y - y0;
02956 
02957    if (fLassoDrawn || fromGrab) {
02958       if (comp) {
02959          TIter next(comp->GetList());
02960          TGFrameElement *el;
02961 
02962          while ((el = (TGFrameElement*)next())) {
02963             TGFrame *fr = el->fFrame;
02964 
02965             if ((fr->GetX() >= x0) && (fr->GetY() >= y0) &&
02966                 (fr->GetX() + (Int_t)fr->GetWidth() <= x) &&
02967                 (fr->GetY() + (Int_t)fr->GetHeight() <= y)) {
02968                if (!crop) {
02969                   DeleteFrame(fr);
02970                } else {
02971                   fr->Move(fr->GetX() - x0, fr->GetY() - y0);
02972                }
02973             } else {
02974                if (crop) {
02975                   DeleteFrame(fr);
02976                }
02977             }
02978          }
02979          if (crop && comp) {
02980             gVirtualX->TranslateCoordinates(comp->GetId(), comp->GetParent()->GetId(),
02981                                              x0, y0, xx, yy, c);
02982 
02983             comp->MoveResize(xx, yy, w, h);
02984 
02985             if (comp->GetParent()->InheritsFrom(TGMdiDecorFrame::Class())) {
02986                TGMdiDecorFrame *decor = (TGMdiDecorFrame *)comp->GetParent();
02987 
02988                gVirtualX->TranslateCoordinates(decor->GetId(), decor->GetParent()->GetId(),
02989                                                xx, yy, xx, yy, c);
02990 
02991                Int_t b = 2 * decor->GetBorderWidth();
02992                decor->MoveResize(xx, yy, comp->GetWidth() + b,
02993                                  comp->GetHeight() + b + decor->GetTitleBar()->GetDefaultHeight());
02994             }
02995          }
02996       }
02997    } else { //  no lasso drawn -> delete selected frame
02998       if (frame)
02999          DeleteFrame(frame);
03000       UngrabFrame();
03001       ChangeSelected(0);   //update editors
03002    }
03003    SetLassoDrawn(kFALSE);
03004 
03005    if (fBuilder) {
03006       //fBuilder->Update();
03007       fBuilder->UpdateStatusBar(crop ? "Crop action performed" : "Delete action performed");
03008    }
03009 }
03010 
03011 //______________________________________________________________________________
03012 void TGuiBldDragManager::DeleteFrame(TGFrame *frame)
03013 {
03014    // Delete frame
03015 
03016    if (fStop || !frame) {
03017       return;
03018    }
03019 
03020    // remove the frame from the list tree and reset the editor...
03021    fEditor->RemoveFrame(frame);
03022 
03023    frame->UnmapWindow();
03024 
03025    TGCompositeFrame *comp = 0;
03026 
03027    if (frame->GetParent()->InheritsFrom(TGCompositeFrame::Class())) {
03028       comp = (TGCompositeFrame*)frame->GetParent();
03029    }
03030 
03031    if (comp) {
03032       comp->RemoveFrame(frame);
03033    }
03034 
03035    if (frame == fPimpl->fGrab) {
03036       UngrabFrame();
03037    }
03038 
03039    fClient->UnregisterWindow(frame);
03040 
03041    // mem.leak paid for robustness (with possibility "undelete")
03042    frame->ReparentWindow(fClient->GetDefaultRoot());
03043 }
03044 
03045 //______________________________________________________________________________
03046 void TGuiBldDragManager::HandleCut()
03047 {
03048    // Handle cut action
03049 
03050    if (fStop || !fPimpl->fGrab) {
03051       return;
03052    }
03053 
03054    //
03055    fPimpl->fGrab = GetMovableParent(fPimpl->fGrab);
03056    HandleCopy();
03057    DeleteFrame(fPimpl->fGrab);
03058    ChangeSelected(0);   //update editors
03059 }
03060 
03061 //______________________________________________________________________________
03062 void TGuiBldDragManager::HandleCopy(Bool_t brk_layout)
03063 {
03064    // Handle copy. This method is also used by SaveFrame method.
03065    // In later case  brk_layout == kFALSE
03066 
03067    if (fStop || !fPimpl->fGrab) {
03068       return;
03069    }
03070 
03071    TGMainFrame *tmp = new TGMainFrame(fClient->GetDefaultRoot(),
03072                                       fPimpl->fGrab->GetWidth(),
03073                                       fPimpl->fGrab->GetHeight());
03074 
03075    // save coordinates
03076    Int_t x0 = fPimpl->fGrab->GetX();
03077    Int_t y0 = fPimpl->fGrab->GetY();
03078 
03079    // save parent name
03080    TString name = fPimpl->fGrab->GetParent()->GetName();
03081 
03082    ((TGWindow*)fPimpl->fGrab->GetParent())->SetName(tmp->GetName());
03083 
03084    fPimpl->fGrab->SetX(0);
03085    fPimpl->fGrab->SetY(0);
03086 
03087    TGFrameElement *fe = fPimpl->fGrab->GetFrameElement();
03088 
03089    if (fe) {
03090       tmp->GetList()->Add(fe);
03091    }
03092 
03093    tmp->SetLayoutBroken(brk_layout);
03094 
03095    if (!brk_layout) { //save frame
03096       tmp->SetMWMHints(kMWMDecorAll, kMWMFuncAll, kMWMInputFullApplicationModal);
03097       tmp->SetWMSize(tmp->GetWidth(), tmp->GetHeight());
03098       tmp->SetWMSizeHints(tmp->GetDefaultWidth(), tmp->GetDefaultHeight(), 10000, 10000, 0, 0);
03099       const char *short_name = gSystem->BaseName(fPasteFileName.Data());
03100       tmp->SetWindowName(short_name);
03101       tmp->SetIconName(short_name);
03102       tmp->SetClassHints(short_name, short_name);
03103       // some problems here under win32
03104       if (gVirtualX->InheritsFrom("TGX11")) tmp->SetIconPixmap("bld_rgb.xpm");
03105    }
03106    Bool_t quite =  brk_layout || (fPasteFileName == fTmpBuildFile);
03107    tmp->SaveSource(fPasteFileName.Data(), quite ? "keep_names quiet" : "keep_names");
03108    tmp->GetList()->Remove(fe);
03109 
03110    fPimpl->fGrab->SetX(x0);
03111    fPimpl->fGrab->SetY(y0);
03112 
03113    ((TGWindow*)fPimpl->fGrab->GetParent())->SetName(name.Data());
03114 
03115    if (fBuilder) {
03116       TString str = fPimpl->fGrab->ClassName();
03117       str += "::";
03118       str += fPimpl->fGrab->GetName();
03119       str += " copied to clipboard";
03120       fBuilder->UpdateStatusBar(str.Data());
03121    }
03122 
03123    delete tmp;
03124 }
03125 
03126 //______________________________________________________________________________
03127 void TGuiBldDragManager::HandlePaste()
03128 {
03129    // Handle paste action.
03130 
03131    if (fStop) {
03132       return;
03133    }
03134 
03135    Int_t xp = 0;
03136    Int_t yp = 0;
03137 
03138    if (gSystem->AccessPathName(fPasteFileName.Data())) {
03139       return;
03140    }
03141 
03142    fPasting = kTRUE;
03143    gROOT->Macro(fPasteFileName.Data());
03144 
03145    Window_t c;
03146    TGFrame *root = (TGFrame*)fClient->GetRoot();
03147 
03148    if (!fPimpl->fReplaceOn) {
03149       gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
03150                                       root->GetId(),
03151                                       fPimpl->fX0, fPimpl->fY0, xp, yp, c);
03152       ToGrid(xp, yp);
03153 
03154       // fPasteFrame is defined in TVirtualDragManager.h
03155       // fPasteFrame is a TGMainFrame consisting "the frame to paste"
03156       // into the editable frame (aka fClient->GetRoot())
03157 
03158       if (fPasteFrame) {
03159          TGMainFrame *main = (TGMainFrame*)fPasteFrame;
03160          TGFrame *paste = ((TGFrameElement*)main->GetList()->First())->fFrame;
03161 
03162          UInt_t w = paste->GetWidth();
03163          UInt_t h = paste->GetHeight();
03164 
03165          if (xp + w > root->GetWidth()) {
03166             w = root->GetWidth() - xp -1;
03167          }
03168          if (yp + h > root->GetHeight()) {
03169             h = root->GetHeight() - yp -1;
03170          }
03171 
03172          paste->Resize(w, h);
03173          fPasteFrame->Move(xp, yp);
03174          fPimpl->fGrab = fPasteFrame;
03175          HandleReturn(1);  // drop
03176       }
03177    }
03178 
03179    fPasting = kFALSE;
03180 
03181    if (fBuilder) {
03182       fBuilder->UpdateStatusBar("Paste action performed");
03183    }
03184 }
03185 
03186 //______________________________________________________________________________
03187 void TGuiBldDragManager::DoReplace(TGFrame *frame)
03188 {
03189    // Replace frame (doesn't work yet properly)
03190 
03191    if (fStop || !frame || !fPimpl->fGrab || !fPimpl->fReplaceOn) {
03192       return;
03193    }
03194 
03195    Int_t w = fPimpl->fGrab->GetWidth();
03196    Int_t h = fPimpl->fGrab->GetHeight();
03197    Int_t x = fPimpl->fGrab->GetX();
03198    Int_t y = fPimpl->fGrab->GetY();
03199 
03200    if (fBuilder) {
03201       TString str = fPimpl->fGrab->ClassName();
03202       str += "::";
03203       str += fPimpl->fGrab->GetName();
03204       str += " replaced by ";
03205       str += frame->ClassName();
03206       str += "::";
03207       str += frame->GetName();
03208       fBuilder->UpdateStatusBar(str.Data());
03209    }
03210 
03211    TGFrameElement *fe = fPimpl->fGrab->GetFrameElement();
03212 
03213    if (fe) {
03214       fe->fFrame = 0;
03215       fPimpl->fGrab->DestroyWindow();
03216       delete fPimpl->fGrab;
03217       fPimpl->fGrab = 0;
03218 
03219       fe->fFrame = frame;
03220       frame->MoveResize(x, y, w, h);
03221       frame->MapRaised();
03222       frame->SetFrameElement(fe);
03223    }
03224 
03225    SelectFrame(frame);
03226    fPimpl->fReplaceOn = kFALSE;
03227 
03228    TGWindow *root = (TGWindow *)fClient->GetRoot();
03229    root->SetEditable(kFALSE);
03230    DoRedraw();
03231    root->SetEditable(kTRUE);
03232 }
03233 
03234 //______________________________________________________________________________
03235 void TGuiBldDragManager::HandleReplace()
03236 {
03237    // Handle replace
03238 
03239    if (fStop || !fPimpl->fGrab) {
03240       return;
03241    }
03242 
03243    fPimpl->fReplaceOn = kTRUE;
03244    TGFrame *frame = 0;
03245 
03246    if (fBuilder && fBuilder->IsExecutable())  {
03247       frame = (TGFrame *)fBuilder->ExecuteAction();
03248    } else {
03249       HandlePaste();
03250       frame = fPasteFrame;
03251    }
03252    DoReplace(frame);
03253    fPimpl->fReplaceOn = kFALSE;
03254 }
03255 
03256 //______________________________________________________________________________
03257 void TGuiBldDragManager::CloneEditable()
03258 {
03259    // Create a frame which is the same as currently editted frame
03260 
03261    if (fStop) {
03262       return;
03263    }
03264 
03265    TString tmpfile = gSystem->TempDirectory();
03266    tmpfile = gSystem->ConcatFileName(tmpfile.Data(), TString::Format("tmp%d.C",
03267                                      gRandom->Integer(100)));
03268    Save(tmpfile.Data());
03269    gROOT->Macro(tmpfile.Data());
03270    gSystem->Unlink(tmpfile.Data());
03271 
03272    if (fClient->GetRoot()->InheritsFrom(TGFrame::Class())) {
03273       TGFrame *f = (TGFrame *)fClient->GetRoot();
03274       f->Resize(f->GetWidth() + 10, f->GetHeight() + 10);
03275    }
03276 }
03277 
03278 //______________________________________________________________________________
03279 Bool_t TGuiBldDragManager::Save(const char *file)
03280 {
03281    // Save an editted frame to the file
03282 
03283    if (fStop || !fClient->GetRoot() || !fClient->IsEditable()) {
03284       return kFALSE;
03285    }
03286 
03287    TGMainFrame *main = (TGMainFrame*)fClient->GetRoot()->GetMainFrame();
03288    TGWindow *root = (TGWindow*)fClient->GetRoot();
03289    TString fname = file;
03290 
03291    root->SetEditable(kFALSE);
03292 
03293    static TImage *img = 0;
03294 
03295    if (!img) {
03296       img = TImage::Create();
03297    }
03298    img->FromWindow(main->GetId());
03299 
03300    if (!file || !strlen(file)) {
03301       static TString dir(".");
03302       static Bool_t overwr = kFALSE;
03303       TGFileInfo fi;
03304 
03305       fi.fFileTypes = gSaveMacroTypes;
03306       fi.fIniDir    = StrDup(dir);
03307       fi.fOverwrite = overwr;
03308       new TGFileDialog(fClient->GetDefaultRoot(), this, kFDSave, &fi);
03309 
03310       if (!fi.fFilename) goto out;
03311       dir = fi.fIniDir;
03312       overwr = fi.fOverwrite;
03313       fname = gSystem->BaseName(gSystem->UnixPathName(fi.fFilename));
03314    }
03315 
03316    if (fname.EndsWith(".C")) {
03317       main->SetMWMHints(kMWMDecorAll, kMWMFuncAll, kMWMInputFullApplicationModal);
03318       main->SetWMSize(main->GetWidth(), main->GetHeight());
03319       main->SetWMSizeHints(main->GetDefaultWidth(), main->GetDefaultHeight(), 10000, 10000, 0, 0);
03320       main->SetWindowName(fname.Data());
03321       main->SetIconName(fname.Data());
03322       main->SetClassHints(fname.Data(), fname.Data());
03323       // some problems here under win32
03324       if (gVirtualX->InheritsFrom("TGX11")) main->SetIconPixmap("bld_rgb.xpm");
03325       main->SaveSource(fname.Data(), file ? "keep_names quiet" : "keep_names");
03326 
03327       fBuilder->AddMacro(fname.Data(), img);
03328 
03329    } else {
03330       Int_t retval;
03331       TString msg = TString::Format("file (%s) must have extension .C", fname.Data());
03332 
03333       new TGMsgBox(fClient->GetDefaultRoot(), main, "Error...", msg.Data(),
03334                    kMBIconExclamation, kMBRetry | kMBCancel, &retval);
03335 
03336       if (retval == kMBRetry) {
03337          return Save();
03338       }
03339    }
03340 
03341 out:
03342    main->RaiseWindow();
03343    return kTRUE;
03344 }
03345 
03346 //______________________________________________________________________________
03347 Bool_t TGuiBldDragManager::SaveFrame(const char *file)
03348 {
03349    // Save composite frame as macro
03350 
03351    if (fStop || !fClient->GetRoot() || !fClient->IsEditable() ||
03352        !fPimpl->fGrab || !fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class())) {
03353       return kFALSE;
03354    }
03355 
03356    TString fname = file;
03357 
03358    TGFrame *frame = fPimpl->fGrab;
03359    SetEditable(kFALSE);
03360 
03361    static TImage *img = 0;
03362 
03363    if (!img) {
03364       img = TImage::Create();
03365    }
03366    img->FromWindow(frame->GetId());
03367 
03368    static TString dir(".");
03369    static Bool_t overwr = kFALSE;
03370 
03371    TString sav = fPasteFileName;
03372 
03373    if (!file) {
03374       TGFileInfo fi;
03375 
03376       fi.fFileTypes = gSaveMacroTypes;
03377       fi.fIniDir    = StrDup(dir);
03378       fi.fOverwrite = overwr;
03379       new TGFileDialog(fClient->GetDefaultRoot(), frame, kFDSave, &fi);
03380 
03381       if (!fi.fFilename) {
03382          goto out;
03383       }
03384 
03385       dir = fi.fIniDir;
03386       overwr = fi.fOverwrite;
03387       fname = gSystem->BaseName(gSystem->UnixPathName(fi.fFilename));
03388    }
03389 
03390    if (fname.EndsWith(".C")) {
03391       fPasteFileName = fname;
03392       fPimpl->fGrab = frame;
03393       fStop = kFALSE;
03394       TGFrameElement *fe = frame->GetFrameElement();
03395 
03396       if (!fe) { // should never happen
03397          fe = new TGFrameElement();
03398          fe->fFrame = frame;
03399          fe->fState = kIsMapped;
03400          frame->SetFrameElement(fe);
03401          TGCompositeFrame *comp = (TGCompositeFrame*)frame->GetParent();
03402          comp->GetList()->Add(fe);
03403       }
03404       delete fe->fLayout;
03405       fe->fLayout = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
03406 
03407       HandleCopy(kFALSE);
03408       fStop = kTRUE;
03409 
03410       fBuilder->AddMacro(fname.Data(), img);
03411    } else {
03412       Int_t retval;
03413       TString msg = TString::Format("file (%s) must have extension .C", fname.Data());
03414 
03415       new TGMsgBox(fClient->GetDefaultRoot(), frame, "Error...", msg.Data(),
03416                    kMBIconExclamation, kMBRetry | kMBCancel, &retval);
03417 
03418       if (retval == kMBRetry) {
03419          return SaveFrame();
03420       }
03421    }
03422 
03423 out:
03424    fPasteFileName = sav;
03425    return kTRUE;
03426 }
03427 /*
03428 //______________________________________________________________________________
03429 static Int_t canResize(TGFrame *frame, Int_t x, Int_t y, UInt_t &w, UInt_t &h)
03430 {
03431    // Not used yet. Return 0 if all child frames are inside area x,y, w,h
03432 
03433    if (frame->InheritsFrom(TGCompositeFrame::Class())) return 0;
03434 
03435    TGCompositeFrame *comp = (TGCompositeFrame*)frame;
03436 
03437    TIter next(comp->GetList());
03438    TGFrameElement *fe;
03439    Int_t d = gGuiBldDragManager->GetGridStep();
03440    Int_t ret = 0;
03441 
03442    while ((fe = (TGFrameElement*)next())) {
03443       if (x + fe->fFrame->GetX() + fe->fFrame->GetWidth() > w) {
03444          w = fe->fFrame->GetX() + x  + fe->fFrame->GetWidth();
03445          ret |= 4;
03446       }
03447       if (y + fe->fFrame->GetY() + fe->fFrame->GetHeight() > h) {
03448          h = fe->fFrame->GetY() + y + fe->fFrame->GetHeight();
03449          ret |= 8;
03450       }
03451    }
03452    return ret;
03453 }
03454 */
03455 
03456 //______________________________________________________________________________
03457 void TGuiBldDragManager::DoResize()
03458 {
03459    // handle resize
03460 
03461    if (fStop || !fClient->IsEditable()) {
03462       return;
03463    }
03464 
03465    TGFrame *fr = fPimpl->fGrab;
03466 
03467    if (!fr || IsFixedSize(fr) ||
03468         IsFixedLayout((TGWindow*)fr->GetParent())) {
03469 
03470       fr = (TGFrame*)GetResizableParent(fr);
03471 
03472       if (!fr ) {
03473          return;
03474       }
03475    }
03476 
03477    TGCompositeFrame *comp = 0;
03478 
03479    if (fr->InheritsFrom(TGCompositeFrame::Class())) {
03480       comp = (TGCompositeFrame*)fr;
03481    }
03482 
03483    Window_t c;
03484    Int_t x = fPimpl->fX;
03485    Int_t y = fPimpl->fY;
03486    UInt_t w = 0;
03487    UInt_t h = 0;
03488    UInt_t wp = ((TGFrame*)fr->GetParent())->GetWidth() - 2;
03489    UInt_t hp = ((TGFrame*)fr->GetParent())->GetHeight() - 2;
03490 
03491    gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
03492                                    fr->GetId(), x, y, x, y, c);
03493 
03494    ToGrid(x, y);
03495    HighlightCompositeFrame(fr->GetParent()->GetId());
03496 
03497    switch (fPimpl->fResizeType) {
03498       case kTopLeft:
03499          if ((((int)fr->GetWidth() > x) || (x < 0)) &&
03500              (((int)fr->GetHeight() > y) || (y < 0))) {
03501 
03502             if (fr->GetY() + y < 2) {
03503                y = 2 - fr->GetY();
03504             }
03505             if (fr->GetX() + x < 2) {
03506                x = 2 - fr->GetX();
03507             }
03508             h = fr->GetHeight() - y;
03509             w = fr->GetWidth() - x;
03510             x = fr->GetX() + x;
03511             y = fr->GetY() + y;
03512 
03513             if (!IsFixedH(fr) && !IsFixedW(fr)) {
03514                fr->MoveResize(x, y, w, h);
03515                break;
03516             }
03517             if (IsFixedH(fr)) {
03518                fr->MoveResize(x, fr->GetY(), w, fr->GetDefaultHeight());
03519                break;
03520             }
03521             if (IsFixedW(fr)) {
03522                fr->MoveResize(fr->GetX(), y, fr->GetDefaultWidth(), h);
03523                break;
03524             }
03525          }
03526          break;
03527       case kTopRight:
03528          if ((x > 0) && (((int)fr->GetHeight() > y) || (y < 0))) {
03529 
03530             if (fr->GetY() + y < 2) {
03531                y = 2 - fr->GetY();
03532             }
03533             h = fr->GetHeight() - y;
03534 
03535             if (IsFixedW(fr)) {
03536                w =  fr->GetDefaultWidth();
03537             } else {
03538                w = fr->GetX() + x > Int_t(wp) ? wp - fr->GetX() : UInt_t(x);
03539             }
03540             x = fr->GetX();
03541             y = fr->GetY() + y;
03542 
03543             if (!IsFixedH(fr)) {
03544                fr->MoveResize(x, y, w, h);
03545             } else {
03546                fr->Resize(x, fr->GetDefaultHeight());
03547             }
03548          }
03549          break;
03550       case kTopSide:
03551          if (((int)fr->GetHeight() > y) || (y < 0)) {
03552             if (IsFixedH(fr)) {
03553                break;
03554             }
03555 
03556             if (fr->GetY() + y < 2) {
03557                y = 2 - fr->GetY();
03558             }
03559             h = fr->GetHeight() - y;
03560             w = fr->GetWidth();
03561             x = fr->GetX();
03562             y = fr->GetY() + y;
03563 
03564             fr->MoveResize(x, y, w, h);
03565          }
03566          break;
03567       case kBottomLeft:
03568          if ((((int)fr->GetWidth() > x) || (x < 0)) && (y > 0)) {
03569 
03570             if (fr->GetX() + x < 2) {
03571                x = 2 - fr->GetX();
03572             }
03573             h = fr->GetY() + y > Int_t(hp) ? hp - fr->GetY() : UInt_t(y);
03574             w = fr->GetWidth() - x;
03575             x = fr->GetX() + x;
03576 
03577             if (!IsFixedH(fr) && !IsFixedW(fr)) {
03578                fr->MoveResize(x, fr->GetY(), w, h);
03579                break;
03580             }
03581             if (IsFixedH(fr)) {
03582                fr->MoveResize(x, fr->GetY(), w, fr->GetDefaultHeight());
03583                break;
03584             }
03585             if (IsFixedW(fr)) {
03586                fr->MoveResize(fr->GetX(), fr->GetY(),
03587                               fr->GetDefaultWidth(), h);
03588                break;
03589             }
03590          }
03591          break;
03592       case kBottomRight:
03593          if ((x > 0) && (y > 0)) {
03594             w = !IsFixedW(fr) ? UInt_t(x) : fr->GetDefaultWidth();
03595             h = !IsFixedH(fr) ? UInt_t(y) : fr->GetDefaultHeight();
03596 
03597             h = fr->GetY() + h > hp ? hp - fr->GetY() : h;
03598             w = fr->GetX() + w > wp ? wp - fr->GetX() : w;
03599 
03600             //canResize(comp, 0, 0, w, h);
03601             fr->Resize(w, h);
03602          }
03603          break;
03604       case kBottomSide:
03605          if (y > 0) {
03606             if (IsFixedH(fr)) {
03607                break;
03608             }
03609 
03610             w = fr->GetWidth();
03611             h = fr->GetY() + y > (Int_t)hp ? hp - fr->GetY() : UInt_t(y);
03612 
03613             //canResize(comp, 0, 0, w, h);
03614             fr->Resize(w, h);
03615          }
03616          break;
03617       case kLeftSide:
03618          if ((int)fr->GetWidth() > x ) {
03619             if (IsFixedW(fr)) {
03620                break;
03621             }
03622 
03623             if (fr->GetX() + x < 2) {
03624                x = 2 - fr->GetX();
03625             }
03626             w = fr->GetWidth() - x;
03627             h = fr->GetHeight();
03628             y = fr->GetY();
03629             x = fr->GetX() + x;
03630 
03631             //canResize(comp, x, y, w, h);
03632             fr->MoveResize(x, y, w, h);
03633          }
03634          break;
03635       case kRightSide:
03636          if (x > 0) {
03637             if (IsFixedW(fr)) {
03638                break;
03639             }
03640 
03641             h = fr->GetHeight();
03642             w = fr->GetX() + x > (Int_t)wp ? wp - fr->GetX() : UInt_t(x);
03643             //canResize(comp, 0, 0, w, h);
03644             fr->Resize(w, h);
03645          }
03646          break;
03647       default:
03648          break;
03649    }
03650    if (comp && (!comp->IsLayoutBroken() || IsFixedLayout(comp))) {
03651       layoutFrame(comp);
03652    }
03653 
03654    gVirtualX->SetCursor(fClient->GetRoot()->GetId(),
03655                         gVirtualX->CreateCursor(fPimpl->fResizeType));
03656    w = fr->GetWidth();
03657    h = fr->GetHeight();
03658 
03659    if (fBuilder) {
03660       TString str = fr->ClassName();
03661       str += "::";
03662       str += fr->GetName();
03663       str += " resized   ";
03664       str += TString::Format("(%d x %d)", w, h);
03665       fBuilder->UpdateStatusBar(str.Data());
03666    }
03667 
03668    fClient->NeedRedraw(fr, kTRUE);
03669    DoRedraw();
03670    fEditor->ChangeSelected(fr); //to update the geometry frame after drag resize
03671 }
03672 
03673 //______________________________________________________________________________
03674 void TGuiBldDragManager::DoMove()
03675 {
03676    // Handle move
03677 
03678    if (fStop || !fPimpl->fGrab || !fClient->IsEditable()) {
03679       return;
03680    }
03681 
03682    TGWindow *parent = (TGWindow*)fPimpl->fGrab->GetParent();
03683 
03684    // do not remove frame from fixed layout or non-editable parent
03685    if (IsFixedLayout(parent) || IsEditDisabled(parent)) {
03686       return;
03687    }
03688 
03689    Int_t x = fPimpl->fX - fPimpl->fXf;
03690    Int_t y = fPimpl->fY - fPimpl->fYf;
03691 
03692    static Int_t qq;
03693    static UInt_t w = 0;
03694    static UInt_t h = 0;
03695 
03696    if (w == 0) {
03697       gVirtualX->GetWindowSize(gVirtualX->GetDefaultRootWindow(), qq, qq, w, h);
03698    }
03699 
03700    //
03701    Bool_t move = (x > 0) && (y > 0) && ((x + fPimpl->fGrab->GetWidth()) < (w - 0)) &&
03702                  ((y + fPimpl->fGrab->GetHeight()) < (h - 30));
03703 
03704 
03705    // we are out of "win32 world"
03706    if (!move && !gVirtualX->InheritsFrom("TGX11")) {
03707       EndDrag();
03708       return;
03709    }
03710 
03711    fPimpl->fGrab->Move(x, y);
03712 
03713    if (fBuilder) {
03714       //fBuilder->Update();
03715       TString str = fPimpl->fGrab->ClassName();
03716       str += "::";
03717       str += fPimpl->fGrab->GetName();
03718       str += " is moved to absolute position   ";
03719       str += TString::Format("(%d , %d)", x, y);
03720       fBuilder->UpdateStatusBar(str.Data());
03721    }
03722 
03723    CheckTargetUnderGrab();
03724 }
03725 
03726 //______________________________________________________________________________
03727 TGFrame *TGuiBldDragManager::FindMdiFrame(TGFrame *in)
03728 {
03729    // Return a pointer to the parent mdi frame
03730 
03731    if (fStop || !in) {
03732       return 0;
03733    }
03734 
03735    TGFrame *p = in;
03736 
03737    while (p && (p != fClient->GetDefaultRoot()) &&
03738          !p->InheritsFrom(TGMainFrame::Class())) {
03739       if (p->InheritsFrom(TGMdiFrame::Class())) {
03740          return p;
03741       }
03742       p = (TGFrame*)p->GetParent();
03743    }
03744    return 0;
03745 }
03746 
03747 //______________________________________________________________________________
03748 void TGuiBldDragManager::RaiseMdiFrame(TGFrame *comp)
03749 {
03750    // Raise guibuilder's mdi frame.
03751 
03752    if (fStop || !comp) {
03753       return;
03754    }
03755 
03756    if (comp && comp->InheritsFrom(TGMdiFrame::Class()) && fBuilder) {
03757       TGFrame *mdi = fBuilder->FindEditableMdiFrame(comp);
03758       if (mdi) {
03759          // dragged frame is taken from some main frame
03760          //if (fPimpl->fGrab && fClient->GetRoot()->InheritsFrom(TGMainFrame::Class())) {
03761          //   fBuilder->MapRaised();
03762          //}
03763       }
03764       if (fBuilder->GetMdiMain()->GetCurrent() != comp) {
03765          fBuilder->GetMdiMain()->SetCurrent((TGMdiFrame*)comp);
03766       }
03767    }
03768 }
03769 
03770 //______________________________________________________________________________
03771 void TGuiBldDragManager::CheckTargetUnderGrab()
03772 {
03773    // Look for the drop target under grabbed/selected frame while moving
03774 
03775    if (fStop || !fPimpl->fGrab ) {
03776       return;
03777    }
03778 
03779    Int_t x = fPimpl->fGrab->GetX();
03780    Int_t y = fPimpl->fGrab->GetY();
03781    UInt_t w = fPimpl->fGrab->GetWidth();
03782    UInt_t h = fPimpl->fGrab->GetHeight();
03783 
03784    Bool_t ok = CheckTargetAtPoint(x - 1, y - 1);
03785 
03786    if (!ok) {
03787       ok = CheckTargetAtPoint(x + w + 1, y + h + 1);
03788    }
03789 
03790    if (!ok) {
03791       ok = CheckTargetAtPoint(x + w + 1, y - 1);
03792    }
03793 
03794    if (!ok) {
03795       ok = CheckTargetAtPoint(x - 1, y + h + 1);
03796    }
03797 }
03798 
03799 //______________________________________________________________________________
03800 Bool_t TGuiBldDragManager::CheckTargetAtPoint(Int_t x, Int_t y)
03801 {
03802    // Helper. Look for the drop target under grabbed/selected frame while moving.
03803 
03804    if (fStop || !fPimpl->fGrab) {
03805       return kFALSE;
03806    }
03807 
03808    UInt_t ww = fPimpl->fGrab->GetWidth();
03809    UInt_t hh = fPimpl->fGrab->GetHeight();
03810    Bool_t ret = kFALSE;
03811    Window_t c;
03812    TGWindow *win = 0;
03813 
03814    Window_t w = GetWindowFromPoint(x, y);
03815 
03816    if (w && (w != gVirtualX->GetDefaultRootWindow())) {
03817       win = fClient->GetWindowById(w);
03818       TGCompositeFrame *comp = 0;
03819 
03820       if (!win) {
03821          goto out;
03822       }
03823 
03824       if (win->InheritsFrom(TGCompositeFrame::Class())) {
03825          comp = (TGCompositeFrame *)win;
03826       } else if (win->GetParent() != fClient->GetDefaultRoot()) {
03827          comp = (TGCompositeFrame *)win->GetParent();
03828       }
03829 
03830       if (comp) {
03831          gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
03832                                          comp->GetId(), x, y, x, y, c);
03833 
03834          RaiseMdiFrame(comp);
03835 
03836          if ((comp != fPimpl->fGrab) && (x >= 0) && (y >= 0) &&
03837              (x + ww <= comp->GetWidth()) &&
03838              (y + hh <= comp->GetHeight())) {
03839 
03840             if (comp != fTarget) {
03841                comp->HandleDragEnter(fPimpl->fGrab);
03842 
03843                if (fTarget) fTarget->HandleDragLeave(fPimpl->fGrab);
03844 
03845                else Snap2Grid();
03846             } else {
03847                if (fTarget) {
03848                   fTarget->HandleDragMotion(fPimpl->fGrab);
03849                }
03850             }
03851 
03852             fTarget = comp;
03853             fTargetId = comp->GetId();
03854             ret = kTRUE;
03855             return ret;
03856 
03857          } else {
03858             if (fTarget) {
03859                fTarget->HandleDragLeave(fPimpl->fGrab);
03860             }
03861             fTarget = 0;
03862             fTargetId = 0;
03863          }
03864       }
03865    }
03866 
03867 out:
03868    if (fTarget) {
03869       fTarget->HandleDragLeave(fPimpl->fGrab);
03870    }
03871 
03872    if (!w || !win) {
03873       fTarget = 0;
03874       fTargetId = 0;
03875    }
03876    return ret;
03877 }
03878 
03879 //______________________________________________________________________________
03880 Bool_t TGuiBldDragManager::HandleMotion(Event_t *event)
03881 {
03882    // Handle motion event
03883 
03884    if (fStop) {
03885       return kFALSE;
03886    }
03887 
03888    static Long64_t was = gSystem->Now();
03889    static Int_t gy = event->fYRoot;
03890    static Int_t gx = event->fXRoot;
03891 
03892    Long64_t now = gSystem->Now();
03893 
03894    if ((now-was < 100) || !(event->fState & kButton1Mask) ||
03895        ((event->fYRoot == gy) && (event->fXRoot == gx))) {
03896       return kFALSE;
03897    }
03898 
03899    was = now;
03900    gy = event->fYRoot;
03901    gx = event->fXRoot;
03902 
03903    if (!fDragging) {
03904       if (fMoveWaiting && ((TMath::Abs(fPimpl->fX - event->fXRoot) > 10) ||
03905           (TMath::Abs(fPimpl->fY - event->fYRoot) > 10))) {
03906 
03907          return StartDrag(fSource, event->fXRoot, event->fYRoot);
03908       }
03909    } else {
03910       fPimpl->fX = event->fXRoot;
03911       fPimpl->fY = event->fYRoot;
03912 
03913       switch (fDragType) {
03914          case kDragLasso:
03915             DrawLasso();
03916             fSelectionIsOn = event->fState & kKeyShiftMask;
03917             break;
03918          case kDragMove:
03919          case kDragCopy:
03920          case kDragLink:
03921             DoMove();
03922             break;
03923          case kDragResize:
03924             DoResize();
03925             break;
03926          default:
03927             break;
03928       }
03929    }
03930    return kTRUE;
03931 }
03932 
03933 //______________________________________________________________________________
03934 void TGuiBldDragManager::PlaceFrame(TGFrame *frame, TGLayoutHints *hints)
03935 {
03936    // Put created frame at position of the last mouse click
03937 
03938    Int_t x0, y0, x, y;
03939    Window_t c;
03940 
03941    if (fStop || !frame || !fClient->IsEditable()) {
03942       return;
03943    }
03944 
03945    frame->MapSubwindows();
03946    TGFrame *root = (TGFrame*)fClient->GetRoot();
03947 
03948    gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
03949                                    root->GetId(),
03950                                    fPimpl->fX0 , fPimpl->fY0, x0, y0, c);
03951    gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
03952                                    root->GetId(),
03953                                    fPimpl->fX , fPimpl->fY, x, y, c);
03954 
03955    ToGrid(x, y);
03956    ToGrid(x0, y0);
03957 
03958    UInt_t w = TMath::Abs(x - x0);
03959    UInt_t h = TMath::Abs(y - y0);
03960    x = x > x0 ? x0 : x;
03961    y = y > y0 ? y0 : y;
03962 
03963    // do not create frame with size smaller when default size
03964    w = w < frame->GetDefaultWidth() + 2 ? frame->GetDefaultWidth() + 2 : w;
03965    h = h < frame->GetDefaultHeight() + 2 ? frame->GetDefaultHeight() + 2 : h;
03966 
03967    // do not create frame out of editable space
03968    x = x + w > root->GetWidth() ? Int_t(root->GetWidth() - w) : x;
03969    y = y + h > root->GetHeight() ? Int_t(root->GetHeight() - h) : y;
03970 
03971    frame->Move(x, y);
03972 
03973    UInt_t grid = GetGridStep();
03974 
03975    if (IsFixedW(frame) || IsFixedH(frame) || IsFixedSize(frame)) {
03976       w = IsFixedW(frame) ? frame->GetDefaultWidth() : w;
03977       h = IsFixedH(frame) ? frame->GetDefaultHeight() : h;
03978       frame->Resize(w < grid ? grid : w, h < grid ? grid : h);
03979    } else {
03980       if (frame->InheritsFrom(TGVerticalFrame::Class())) {
03981          frame->Resize(w < grid ? 15*grid : w, h < grid ?  30*grid : h);
03982       } else if (frame->InheritsFrom(TGHorizontalFrame::Class())) {
03983          frame->Resize(w < grid ? 30*grid : w, h < grid ?  15*grid : h);
03984       }
03985       else frame->Resize(w < 2*grid ? 2*grid : w, h < 2*grid ?  2*grid : h);
03986    }
03987 
03988    frame->MapRaised();
03989    frame->SetCleanup(kDeepCleanup);
03990    frame->AddInput(kButtonPressMask);
03991 
03992    if (fClient->GetRoot()->InheritsFrom(TGCompositeFrame::Class())) {
03993       TGCompositeFrame *edit = (TGCompositeFrame*)fClient->GetRoot();
03994       edit->SetCleanup(kDeepCleanup);
03995       ReparentFrames(frame, edit);
03996       frame->MapRaised();
03997       //edit->SetLayoutBroken();
03998       UInt_t g = 2;
03999       // temporary hack for status bar
04000       if (frame->InheritsFrom("TGStatusBar")) {
04001          edit->AddFrame(frame, new TGLayoutHints(kLHintsBottom | kLHintsExpandX));
04002       }
04003       else {
04004          edit->AddFrame(frame, hints ? hints : new TGLayoutHints(kLHintsNormal, g, g, g, g));
04005       }
04006 
04007       if (hints && !edit->IsLayoutBroken()) {
04008          edit->GetLayoutManager()->Layout();
04009       } else {
04010          edit->Layout();
04011       }
04012    }
04013    if (fBuilder) {
04014       TString str = frame->ClassName();
04015       str += "::";
04016       str += frame->GetName();
04017       str += " created";
04018       fBuilder->UpdateStatusBar(str.Data());
04019    }
04020 
04021    if (frame->InheritsFrom(TGCanvas::Class())) {
04022       frame = ((TGCanvas*)frame)->GetContainer();
04023    }
04024 
04025    SelectFrame(frame);
04026 
04027 }
04028 //______________________________________________________________________________
04029 void TGuiBldDragManager::DrawLasso()
04030 {
04031    // Draw lasso for allocation new object
04032 
04033    if (fStop || !fClient->IsEditable()) {
04034       return;
04035    }
04036 
04037    UngrabFrame();
04038 
04039    Int_t x0, y0, x, y;
04040    Window_t c;
04041    TGFrame *root = (TGFrame*)fClient->GetRoot();
04042 
04043    gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(), root->GetId(),
04044                                    fPimpl->fX0 , fPimpl->fY0, x0, y0, c);
04045    gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(), root->GetId(),
04046                                    fPimpl->fX , fPimpl->fY, x, y, c);
04047 
04048    UInt_t w, h;
04049    Bool_t xswap = kFALSE;
04050    Bool_t yswap = kFALSE;
04051 
04052    // check limits
04053 
04054    if ((x == x0) || ( y==y0 )) return; //lasso is not rectangle -> do not draw it
04055 
04056    if (x > x0) {
04057       x0 = x0 < 0 ? 0 : x0;
04058       w = x - x0;
04059    } else {
04060       x = x < 0 ? 0 : x;
04061       w = x0 - x;
04062       x0 = x;
04063       xswap = kTRUE;
04064    }
04065 
04066    if (y > y0) {
04067       y0 = y0 < 0 ? 0 : y0;
04068       h = y - y0;
04069    } else {
04070       y = y < 0 ? 0 : y;
04071       h = y0 - y;
04072       y0 = y;
04073       yswap = kTRUE;
04074    }
04075 
04076    w = x0 + w > root->GetWidth() ? root->GetWidth() - x0 : w;
04077    h = y0 + h > root->GetHeight() ? root->GetHeight() - y0 : h;
04078    x = x0 + w;
04079    y = y0 + h;
04080 
04081    ToGrid(x, y);
04082    ToGrid(x0, y0);
04083 
04084    // correct fPimpl->fX0 , fPimpl->fY0 , fPimpl->fX , fPimpl->fY
04085    gVirtualX->TranslateCoordinates(root->GetId(), fClient->GetDefaultRoot()->GetId(),
04086                                    xswap ? x : x0, yswap ? y : y0,
04087                                    fPimpl->fX0 , fPimpl->fY0,  c);
04088    gVirtualX->TranslateCoordinates(root->GetId(), fClient->GetDefaultRoot()->GetId(),
04089                                    xswap ? x0 : x, yswap ? y0 : y,
04090                                    fPimpl->fX , fPimpl->fY,  c);
04091    DoRedraw();
04092 
04093    gVirtualX->DrawRectangle(fClient->GetRoot()->GetId(),
04094                             GetBlackGC()(), x0, y0, w, h);
04095    gVirtualX->DrawRectangle(fClient->GetRoot()->GetId(),
04096                             GetBlackGC()(), x0+1, y0+1, w-2, h-2);
04097 
04098    gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(kCross));
04099    gVirtualX->SetCursor(fClient->GetRoot()->GetId(), gVirtualX->CreateCursor(kCross));
04100 
04101    SetLassoDrawn(kTRUE);
04102    root->RequestFocus();
04103 
04104    if (fBuilder) {
04105       TString str = "Lasso drawn. Align frames inside or presss Return key to grab frames.";
04106       fBuilder->UpdateStatusBar(str.Data());
04107    }
04108 }
04109 
04110 //______________________________________________________________________________
04111 Bool_t TGuiBldDragManager::HandleClientMessage(Event_t *event)
04112 {
04113    // Handle client message
04114 
04115    if (fStop) {
04116       return kFALSE;
04117    }
04118 
04119    if ((event->fFormat == 32) && ((Atom_t)event->fUser[0] == gWM_DELETE_WINDOW) &&
04120        (event->fHandle != gROOT_MESSAGE)) {
04121 
04122       if (fPimpl->fPlane && (fPimpl->fPlane->GetId() == event->fWindow)) {
04123          fPimpl->fPlane = 0;
04124       }
04125 
04126       TGWindow *root = (TGWindow*)fClient->GetRoot();
04127       if (!root || (root == fClient->GetDefaultRoot())) {
04128          SetEditable(kFALSE);
04129          return kTRUE;
04130       }
04131       TGMainFrame *main = (TGMainFrame*)root->GetMainFrame();
04132 
04133       if (event->fWindow == main->GetId()) {
04134          if (main != fBuilder) {
04135             if (fEditor && !fEditor->IsEmbedded()) {
04136                delete fEditor;
04137                fEditor = 0;
04138             }
04139 
04140             SetEditable(kFALSE);
04141             return kTRUE;
04142          }
04143 
04144          delete fFrameMenu;
04145          fFrameMenu =0;
04146 
04147          delete fLassoMenu;
04148          fLassoMenu = 0;
04149 
04150          delete fPimpl->fGrid;
04151          fPimpl->fGrid = 0;
04152          Reset1();
04153 
04154       } else if (fBuilder && (event->fWindow == fBuilder->GetId())) {
04155          fBuilder->CloseWindow();
04156 
04157       } else if (fEditor && (event->fWindow == fEditor->GetMainFrame()->GetId())) {
04158          TQObject::Disconnect(fEditor);
04159          fEditor = 0;
04160       }
04161 
04162       // to avoid segv. stop editting
04163       SetEditable(kFALSE);
04164    }
04165 
04166    return kFALSE;
04167 }
04168 
04169 //______________________________________________________________________________
04170 Bool_t TGuiBldDragManager::HandleDestroyNotify(Event_t *event)
04171 {
04172    // Handle destroy notify
04173 
04174    if (fPimpl->fPlane && (fPimpl->fPlane->GetId() == event->fWindow)) {
04175       fPimpl->fPlane = 0;
04176    }
04177 
04178    return kFALSE;
04179 }
04180 
04181 
04182 //______________________________________________________________________________
04183 Bool_t TGuiBldDragManager::HandleSelection(Event_t *)
04184 {
04185    // not used yet.
04186 
04187    if (fStop) {
04188       return kFALSE;
04189    }
04190 
04191    return kFALSE;
04192 }
04193 
04194 //______________________________________________________________________________
04195 Bool_t TGuiBldDragManager::HandleSelectionRequest(Event_t *)
04196 {
04197    // not used yet.
04198 
04199    if (fStop) {
04200       return kFALSE;
04201    }
04202 
04203    return kFALSE;
04204 }
04205 
04206 //______________________________________________________________________________
04207 TGFrame *TGuiBldDragManager::GetMovableParent(TGWindow *p)
04208 {
04209    // Find parent frame which can be dragged
04210 
04211    if (fStop) {
04212       return 0;
04213    }
04214 
04215    TGFrame *ret = (TGFrame*)p;
04216    TGWindow *parent = (TGWindow*)ret->GetParent();
04217 
04218    while (parent && (parent != fClient->GetDefaultRoot())) {
04219       if (!IsFixedLayout(parent) && !IsEditDisabled(parent)) {
04220          return ret;
04221       }
04222       ret = (TGFrame*)parent;
04223       parent = (TGWindow*)ret->GetParent();
04224    }
04225 
04226    return 0;
04227 }
04228 
04229 //______________________________________________________________________________
04230 TGWindow *TGuiBldDragManager::GetResizableParent(TGWindow *p)
04231 {
04232    // Find parent frame which can be resized
04233 
04234    if (fStop) {
04235       return 0;
04236    }
04237 
04238    TGWindow *parent = p;
04239 
04240    while (parent && (parent != fClient->GetDefaultRoot())) {
04241       if (!IsFixedSize(parent) &&
04242           !IsFixedLayout((TGWindow*)parent->GetParent()) &&
04243           !IsEditDisabled((TGWindow*)parent->GetParent())) {
04244          return parent;
04245       }
04246       parent = (TGWindow*)parent->GetParent();
04247    }
04248 
04249    return 0;
04250 }
04251 
04252 //______________________________________________________________________________
04253 Bool_t TGuiBldDragManager::StartDrag(TGFrame *src, Int_t x, Int_t y)
04254 {
04255    // Start dragging.
04256 
04257    if (fStop || fDragging) {
04258       return kFALSE;
04259    }
04260 
04261    TGFrame *mov = src;
04262 
04263    // special case when frame was grabbed via spacebar pressing
04264    if (fPimpl->fSpacePressedFrame) {
04265       if (fDragType == kDragNone) {
04266          fDragType = kDragMove;
04267          mov = fPimpl->fSpacePressedFrame;
04268       } else {
04269          fPimpl->fSpacePressedFrame = 0;
04270       }
04271    }
04272 
04273    TGWindow *parent = (TGWindow*)(mov ? mov->GetParent() : 0);
04274 
04275    // do not remove frame from fixed layout or non-editable parent
04276    // try to drag "draggable parent"
04277    if (parent && (IsFixedLayout(parent) || IsEditDisabled(parent))) {
04278       mov = GetMovableParent(parent);
04279       if (!mov) {
04280          return kFALSE;
04281       }
04282    }
04283 
04284    SetEditable(kTRUE);  // grab server
04285 
04286    fPimpl->fX = x;
04287    fPimpl->fY = y;
04288    fSelectionIsOn = kFALSE;
04289 
04290    fPimpl->fRepeatTimer->Reset();
04291    gSystem->AddTimer(fPimpl->fRepeatTimer);
04292 
04293    fMoveWaiting = kFALSE;
04294    fDragging = kTRUE;
04295    if (src) gVirtualX->SetCursor(src->GetId(), gVirtualX->CreateCursor(kMove));
04296 
04297    switch (fDragType) {
04298       case kDragCopy:
04299          HandleCopy();
04300          HandlePaste();
04301          GrabFrame(fPimpl->fGrab);
04302          break;
04303       case kDragMove:
04304          fPimpl->fGrab = mov;
04305          GrabFrame(fPimpl->fGrab);
04306          break;
04307       default:
04308          //fPimpl->fGrab = 0;
04309          break;
04310    }
04311 
04312    return kTRUE;
04313 }
04314 
04315 //______________________________________________________________________________
04316 Bool_t TGuiBldDragManager::EndDrag()
04317 {
04318    // End dragging.
04319 
04320    TGFrame *frame = 0;
04321    Bool_t ret = kFALSE;
04322 
04323    if (fStop) {
04324       return kFALSE;
04325    }
04326 
04327    fMoveWaiting = kFALSE;  // for sanity check
04328 
04329    if (fPimpl->fGrab && (fDragType >= kDragMove) && (fDragType <= kDragLink)) {
04330 
04331       ret = Drop();
04332 
04333    } else if (fBuilder && fBuilder->IsExecutable() &&
04334               (fDragType == kDragLasso) && !fSelectionIsOn) {
04335 
04336       frame = (TGFrame*)fBuilder->ExecuteAction();
04337       PlaceFrame(frame, fBuilder->GetAction()->fHints);
04338       SetLassoDrawn(kFALSE);
04339       ret = kTRUE;
04340       //return ret;
04341    } else if ((fDragType == kDragLasso) && fSelectionIsOn) {
04342 
04343       HandleReturn(kFALSE);
04344       ret = kTRUE;
04345    }
04346 
04347    if (!fLassoDrawn) {
04348       DoRedraw();
04349    }
04350 
04351    Reset1();
04352    fPimpl->fSpacePressedFrame = 0;
04353 
04354    if (fBuilder) {
04355       fBuilder->SetAction(0);
04356    }
04357 
04358    return ret;
04359 }
04360 
04361 //______________________________________________________________________________
04362 Bool_t TGuiBldDragManager::Cancel(Bool_t /*delSrc*/)
04363 {
04364    // Do cancel action.
04365 
04366    if (fStop) {
04367       return kFALSE;
04368    }
04369 
04370    fTarget = 0;
04371    EndDrag();
04372    return kTRUE;
04373 }
04374 
04375 //______________________________________________________________________________
04376 Bool_t TGuiBldDragManager::Drop()
04377 {
04378    // Drop grabbed frame
04379 
04380    if (fStop || !fDragging || !fPimpl->fGrab ||
04381        !((fDragType >= kDragMove) && (fDragType <= kDragLink))) {
04382       return kFALSE;
04383    }
04384 
04385    fDropStatus = kFALSE;
04386    TGFrame *frame = 0;
04387    TGFrame *parent = 0;
04388    Int_t x, y;
04389    Window_t c;
04390 
04391    switch (fDragType) {
04392       case kDragCopy:
04393       case kDragMove:
04394          frame = (TGFrame*)fPimpl->fGrab;
04395          break;
04396       default:
04397          break;
04398    }
04399 
04400    TGWindow *w = fClient->GetWindowById(fTargetId);
04401 
04402    if (fTarget && fPimpl->fGrab && (w == fTarget) &&  w &&
04403        (w != fClient->GetDefaultRoot())) {
04404       parent = fTarget;
04405 
04406       gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
04407                                       fTarget->GetId(),
04408                                       fPimpl->fGrab->GetX(),
04409                                       fPimpl->fGrab->GetY(), x, y, c);
04410       fTarget->HandleDragLeave(fPimpl->fGrab);
04411    } else {
04412       parent = (TGFrame*)fPimpl->fGrabParent;
04413       x = fPimpl->fGrabX;
04414       y = fPimpl->fGrabY;
04415    }
04416 
04417    //reject move if layout is on
04418    if (parent && !parent->IsLayoutBroken() && (parent == fPimpl->fGrabParent) ) {
04419       fDropStatus = 0;
04420    } else if (parent && frame && (parent != fClient->GetDefaultRoot()) ) {
04421       ToGrid(x, y);
04422       fDropStatus = parent->HandleDragDrop(frame, x, y, fPimpl->fGrabLayout);
04423 
04424       // drop was rejected
04425       if (!fDropStatus) {
04426          if (fDragType == kDragMove) {  // return dragged frame to initial position
04427             parent = (TGFrame*)fPimpl->fGrabParent;
04428             x = fPimpl->fGrabX;
04429             y = fPimpl->fGrabY;
04430             frame = fPimpl->fGrab;
04431 
04432             if (parent && frame && (parent != fClient->GetDefaultRoot())) {
04433                fDropStatus = parent->HandleDragDrop(frame, x, y, fPimpl->fGrabLayout);
04434             }
04435          } else { // (fDragType == kDragCopy) - delete it
04436             DeleteFrame(frame);
04437          }
04438       }
04439    }
04440 
04441    if (fDropStatus) {
04442       //do not break layout of the new parent if layout there is enabled
04443       if (parent && !parent->IsLayoutBroken()) {
04444          parent->Layout();
04445       }
04446 
04447       if (fBuilder) {
04448          TString str = frame->ClassName();
04449          str += "::";
04450          str += frame->GetName();
04451          str += " dropped into ";
04452          str += parent->ClassName();
04453          str += "::";
04454          str += parent->GetName();
04455          str += " at position  ";
04456          str += TString::Format("(%d , %d)", x, y);
04457          fBuilder->UpdateStatusBar(str.Data());
04458       }
04459       fTarget = 0;
04460       fTargetId = 0;
04461 
04462       if (parent && (parent == fPimpl->fGrabParent) && fPimpl->fGrabListPosition &&
04463           frame && parent->InheritsFrom(TGCompositeFrame::Class())) {
04464 
04465          TList *li = ((TGCompositeFrame*)parent)->GetList();
04466          li->Remove(frame->GetFrameElement());
04467          li->AddAfter(fPimpl->fGrabListPosition, frame->GetFrameElement());
04468       }
04469    } else { // grab frame cannot be dropped
04470 //      if (fDragType == kDragCopy) { // dosn't work (point is not reached ???)
04471 //         HandleDelete(kFALSE);
04472 //      }
04473 
04474       if (fPimpl->fGrab && fPimpl->fGrabParent) {
04475          fPimpl->fGrab->ReparentWindow(fPimpl->fGrabParent, fPimpl->fGrabX, fPimpl->fGrabY);
04476          ((TGCompositeFrame*)fPimpl->fGrabParent)->AddFrame(fPimpl->fGrab);
04477       }
04478    }
04479 
04480    fPimpl->fGrabParent = 0;
04481    fPimpl->fGrabX = 0;
04482    fPimpl->fGrabY = 0;
04483    fPimpl->fGrabListPosition = 0;
04484 
04485    return fDropStatus;
04486 }
04487 
04488 //______________________________________________________________________________
04489 Bool_t TGuiBldDragManager::IsMoveWaiting() const
04490 {
04491    // Waits for either the mouse move from the given initial ButtonPress location
04492    // or for the mouse button to be released. If mouse moves away from the initial
04493    // ButtonPress location before the mouse button is released "IsMoveWaiting"
04494    // returns kTRUE. If the mouse button released before the mose moved from the
04495    // initial ButtonPress location, "IsMoveWaiting" returns kFALSE.
04496 
04497    return fMoveWaiting;
04498 }
04499 
04500 //______________________________________________________________________________
04501 void TGuiBldDragManager::Compact(Bool_t global)
04502 {
04503    // Layout and Resize frame.
04504    // If global is kFALSE - compact selected frame
04505    // If global is kFALSE - compact main frame of selected frame
04506 
04507    TGCompositeFrame *comp = 0;
04508    TGFrameElement *fe;
04509 
04510    if (fStop || !fClient || !fClient->IsEditable() || !fPimpl->fGrab) {
04511       return;
04512    }
04513 
04514    TGWindow *parent = (TGWindow*)fPimpl->fGrab->GetParent();
04515 
04516    if (global) {
04517       if (!fBuilder) {
04518          comp = (TGCompositeFrame*)fClient->GetRoot()->GetMainFrame();
04519       } else {
04520          comp = fBuilder->FindEditableMdiFrame(fClient->GetRoot());
04521          if (!comp) {
04522             comp = (TGCompositeFrame*)fClient->GetRoot()->GetMainFrame();
04523          }
04524       }
04525    } else {
04526       if (fPimpl->fGrab &&
04527           fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class())) {
04528          comp = (TGCompositeFrame*)fPimpl->fGrab;
04529       } else {
04530          comp = (TGCompositeFrame*)parent;
04531       }
04532    }
04533 
04534    if (!comp || IsFixedLayout(comp)  || IsFixedLayout(parent) ||
04535        IsFixedSize(comp) || IsFixedH(comp) || IsFixedW(comp)) return;
04536 
04537    comp->SetLayoutBroken(kFALSE);
04538 
04539    TIter next(comp->GetList());
04540 
04541    TGFrame *root = (TGFrame *)fClient->GetRoot();
04542    root->SetEditable(kFALSE);
04543 
04544    TGDimension d;
04545 
04546    if (global) {
04547       while ((fe = (TGFrameElement*)next())) {
04548          if (IsFixedLayout(fe->fFrame) || IsFixedSize(fe->fFrame) ||
04549              IsFixedH(fe->fFrame) || IsFixedW(fe->fFrame)) continue;
04550 
04551          fe->fFrame->SetLayoutBroken(kFALSE);
04552          d = fe->fFrame->GetDefaultSize();
04553 
04554          // avoid "to point" resizing
04555          if ((d.fWidth > 10) && (d.fHeight > 10)) {
04556             fe->fFrame->Resize();
04557          } else if (d.fWidth > 10) {
04558             fe->fFrame->Resize(d.fWidth, 10);
04559          } else if (d.fHeight > 10) {
04560             fe->fFrame->Resize(10, d.fHeight);
04561          } else {
04562             fe->fFrame->Resize(10, 10);
04563          }
04564          fClient->NeedRedraw(fe->fFrame);
04565       }
04566       if (!IsFixedLayout(root)) {
04567          root->SetLayoutBroken(kFALSE);
04568       }
04569       fPimpl->fCompacted = kTRUE;
04570    }
04571 
04572    if (!IsFixedLayout(comp)) {
04573       comp->SetLayoutBroken(kFALSE);
04574       d = comp->GetDefaultSize();
04575 
04576       // avoid "to point" resizing
04577       if ((d.fWidth > 10) && (d.fHeight > 10)) {
04578          comp->Resize();
04579       } else if (d.fWidth > 10) {
04580          comp->Resize(d.fWidth, 10);
04581       } else if (d.fHeight > 10) {
04582          comp->Resize(10, d.fHeight);
04583       } else {
04584          comp->Resize(10, 10);
04585       }
04586       layoutFrame(comp);
04587    }
04588 
04589    if (comp->GetParent()->InheritsFrom(TGMdiDecorFrame::Class())) {
04590       TGMdiDecorFrame *decor = (TGMdiDecorFrame *)comp->GetParent();
04591       Int_t b = 2 * decor->GetBorderWidth();
04592       decor->MoveResize(decor->GetX(), decor->GetY(), comp->GetDefaultWidth() + b,
04593                         comp->GetDefaultHeight() + b + decor->GetTitleBar()->GetDefaultHeight());
04594    }
04595 
04596    root->SetEditable(kTRUE);
04597 
04598    fClient->NeedRedraw(comp);
04599    SelectFrame(comp);
04600    DoRedraw();
04601 }
04602 
04603 //______________________________________________________________________________
04604 void TGuiBldDragManager::SetEditable(Bool_t on)
04605 {
04606    // Grab server.
04607 
04608    static Bool_t gon = kFALSE;
04609    static const TGWindow *gw = 0;
04610 
04611    if ((gon == on) && (fClient->GetRoot() == gw)) {
04612       return;
04613    }
04614 
04615    gon = on;  gw = fClient->GetRoot();
04616 
04617    if (on) {
04618       fStop = kFALSE;
04619 
04620       if (fPimpl->fRepeatTimer) {
04621          fPimpl->fRepeatTimer->Reset();
04622       } else {
04623          fPimpl->fRepeatTimer = new TGuiBldDragManagerRepeatTimer(this, 100);
04624       }
04625       gSystem->AddTimer(fPimpl->fRepeatTimer);
04626       ((TGFrame*)fClient->GetRoot())->AddInput(kKeyPressMask | kButtonPressMask);
04627 
04628       Snap2Grid();
04629    } else {
04630       HideGrabRectangles();
04631 
04632       if (fPimpl->fRepeatTimer) {
04633          fPimpl->fRepeatTimer->Remove();
04634       }
04635 
04636       fSelected = fPimpl->fGrab = 0;
04637 
04638       delete fPimpl->fGrid;
04639       fPimpl->fGrid = 0;
04640 
04641       fPimpl->ResetParams();
04642 
04643       TGWindow *root = (TGWindow*)fClient->GetRoot();
04644       if (root) {
04645          fClient->SetRoot(0);
04646       }
04647 
04648       if (!gSystem->AccessPathName(fPasteFileName.Data())) {
04649          gSystem->Unlink(fPasteFileName.Data());
04650       }
04651 
04652       if (!gSystem->AccessPathName(fTmpBuildFile.Data())) {
04653          gSystem->Unlink(fTmpBuildFile.Data());
04654       }
04655 
04656       if (fBuilder) {
04657          fBuilder->Update();
04658       }
04659       //CloseMenus();
04660 
04661       fStop = kTRUE;
04662    }
04663 
04664    if (on && fClient->IsEditable()) {
04665       gVirtualX->SetCursor(fClient->GetRoot()->GetId(),
04666                            gVirtualX->CreateCursor(kPointer));
04667    }
04668 }
04669 
04670 //______________________________________________________________________________
04671 void TGuiBldDragManager::ToGrid(Int_t &x, Int_t &y)
04672 {
04673    // Return grid coordinates which are close to given
04674 
04675    UInt_t step = GetGridStep();
04676    x = x - x%step;
04677    y = y - y%step;
04678 }
04679 
04680 //______________________________________________________________________________
04681 void TGuiBldDragManager::HandleAction(Int_t act)
04682 {
04683    // Main handler of actions
04684 
04685    fPimpl->fLastPopupAction = act;
04686 
04687    switch ((EActionType)act) {
04688       case kPropertyAct:
04689          CreatePropertyEditor();
04690          break;
04691       case kEditableAct:
04692          if (fPimpl->fSaveGrab) fPimpl->fSaveGrab->SetEditable(kTRUE);
04693          if (fBuilder) {
04694             fBuilder->HandleMenu(kGUIBLD_FILE_START);
04695          }
04696          break;
04697       case kCutAct:
04698          HandleCut();
04699          break;
04700       case kCopyAct:
04701          HandleCopy();
04702          break;
04703       case kPasteAct:
04704          HandlePaste();
04705          break;
04706       case kCropAct:
04707          HandleDelete(kTRUE);
04708          break;
04709       case kCompactAct:
04710          Compact(kFALSE);
04711          break;
04712       case kCompactGlobalAct:
04713          Compact(kTRUE);
04714          break;
04715       case kDropAct:
04716          HandleReturn(kTRUE);
04717          break;
04718       case kLayUpAct:
04719          HandleLayoutOrder(kFALSE);
04720          break;
04721       case kLayDownAct:
04722          HandleLayoutOrder(kTRUE);
04723          break;
04724       case kCloneAct:
04725          CloneEditable();
04726          break;
04727       case kGrabAct:
04728          HandleReturn(kFALSE);
04729          break;
04730       case kDeleteAct:
04731          HandleDelete(kFALSE);
04732          break;
04733       case kLeftAct:
04734          HandleAlignment(kKey_Left);
04735          break;
04736       case kRightAct:
04737          HandleAlignment(kKey_Right);
04738          break;
04739       case kUpAct:
04740          HandleAlignment(kKey_Up);
04741          break;
04742       case kDownAct:
04743          HandleAlignment(kKey_Down);
04744          break;
04745       case kEndEditAct:
04746          if (fBuilder) {
04747             fBuilder->HandleMenu(kGUIBLD_FILE_STOP);
04748          }
04749          SetEditable(kFALSE);
04750          break;
04751       case kReplaceAct:
04752          HandleReplace();
04753          break;
04754       case kGridAct:
04755          HandleGrid();
04756          break;
04757       case kBreakLayoutAct:
04758          BreakLayout();
04759          break;
04760       case kSwitchLayoutAct:
04761       case kLayoutVAct:
04762       case kLayoutHAct:
04763          SwitchLayout();
04764          break;
04765       case kNewAct:
04766          if (fBuilder) {
04767             fBuilder->NewProject();
04768          } else {
04769             TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
04770             main->MapRaised();
04771             main->SetEditable(kTRUE);
04772          }
04773          break;
04774       case kOpenAct:
04775          if (fBuilder) {
04776             fBuilder->OpenProject();
04777          } else {
04778             TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
04779             main->MapRaised();
04780             main->SetEditable(kTRUE);
04781          }
04782          break;
04783       case kSaveAct:
04784          if (fBuilder) {
04785             if (fBuilder->FindEditableMdiFrame(fClient->GetRoot()) ||
04786                 (!fClient->IsEditable() && fBuilder->GetMdiMain()->GetCurrent())) {
04787                fBuilder->SaveProject();
04788             } else {
04789                Save();
04790             }
04791          } else {
04792             Save();
04793          }
04794          break;
04795       case kSaveFrameAct:
04796          SaveFrame();
04797          break;
04798       default:
04799          break;
04800    }
04801 
04802    fPimpl->fPlacePopup = kFALSE;
04803 
04804    if (fBuilder) {
04805       fBuilder->SetAction(0);
04806       //fBuilder->Update();
04807    }
04808 
04809    if (fPimpl->fSaveGrab) {
04810       fClient->NeedRedraw(fPimpl->fSaveGrab, kTRUE);
04811    }
04812 
04813    DoRedraw();
04814 }
04815 
04816 //______________________________________________________________________________
04817 Bool_t TGuiBldDragManager::CanChangeLayout(TGWindow *w) const
04818 {
04819    //  kTRUE - if it's possible to switch disable/enable layout
04820 
04821    return (!(w->GetEditDisabled() & kEditDisable) &&
04822            !IsFixedLayout(w) && w->InheritsFrom(TGCompositeFrame::Class()));
04823 }
04824 
04825 //______________________________________________________________________________
04826 Bool_t TGuiBldDragManager::CanChangeLayoutOrder(TGWindow *w) const
04827 {
04828    // kTRUE - if it's possible to change layout order in the parent's layout of window w
04829 
04830    return (w->GetParent()->InheritsFrom(TGCompositeFrame::Class()) &&
04831            !((TGCompositeFrame*)w->GetParent())->IsLayoutBroken() &&
04832            !IsFixedLayout((TGWindow*)w->GetParent()));
04833 }
04834 
04835 //______________________________________________________________________________
04836 Bool_t TGuiBldDragManager::CanCompact(TGWindow *w) const
04837 {
04838    // kTRUE is frame could be compacted/"layouted"
04839 
04840    return CanChangeLayout(w);
04841 /*
04842    return (!IsFixedLayout(w) &&
04843            w->InheritsFrom(TGCompositeFrame::Class()) &&
04844            ((TGCompositeFrame*)w)->IsLayoutBroken() &&
04845            !IsEditDisabled((TGWindow*)w->GetParent()) &&
04846            !IsFixedLayout((TGWindow*)w->GetParent()));
04847 */
04848 }
04849 
04850 //______________________________________________________________________________
04851 void TGuiBldDragManager::CreatePropertyEditor()
04852 {
04853    // Create widget property editor (it could be located outside of guibuilder)
04854 
04855 //   if (!fPimpl->fClickFrame) return;
04856 
04857    TGWindow *root = (TGWindow*)fClient->GetRoot();
04858    root->SetEditable(kFALSE);
04859 
04860    fBuilder = (TRootGuiBuilder*)TRootGuiBuilder::Instance();
04861 
04862    fBuilder->Move(fPimpl->fX0, fPimpl->fY0);
04863    fBuilder->SetWMPosition(fPimpl->fX0, fPimpl->fY0);
04864    SetPropertyEditor(fBuilder->GetEditor());
04865 
04866    root->SetEditable(kTRUE);
04867 }
04868 
04869 //______________________________________________________________________________
04870 void TGuiBldDragManager::SetPropertyEditor(TGuiBldEditor *e)
04871 {
04872    // Helper method
04873 
04874    fEditor = e;
04875 
04876    if (!fEditor) {
04877       return;
04878    }
04879 
04880    ChangeSelected(fPimpl->fClickFrame);
04881    fEditor->Connect("UpdateSelected(TGFrame*)", "TGuiBldDragManager", this,
04882                     "HandleUpdateSelected(TGFrame*)");
04883 }
04884 
04885 //______________________________________________________________________________
04886 void TGuiBldDragManager::HandleLayoutOrder(Bool_t forward)
04887 {
04888    // Change layout order
04889 
04890    if (fStop || !fPimpl->fGrab || !fPimpl->fGrab->GetFrameElement() ||
04891        !CanChangeLayoutOrder(fPimpl->fGrab)) {
04892       return;
04893    }
04894 
04895    TGCompositeFrame *comp = (TGCompositeFrame*)fPimpl->fGrab->GetParent();
04896    TList *li = comp->GetList();
04897    TGFrameElement *fe = fPimpl->fGrab->GetFrameElement();
04898 
04899    if (!fe) { // sanity check
04900       return;
04901    }
04902 
04903    TGFrame *frame;
04904    TGFrameElement *el;
04905 
04906    if (forward) {
04907       el = (TGFrameElement *)li->After(fe);
04908       if (!el) return;
04909       frame = el->fFrame;
04910 
04911       el->fFrame = fPimpl->fGrab;
04912       fPimpl->fGrab->SetFrameElement(el);
04913       fe->fFrame = frame;
04914       frame->SetFrameElement(fe);
04915    } else {
04916       el = (TGFrameElement *)li->Before(fe);
04917 
04918       if (!el) {
04919          return;
04920       }
04921       frame = el->fFrame;
04922 
04923       el->fFrame = fPimpl->fGrab;
04924       fPimpl->fGrab->SetFrameElement(el);
04925       fe->fFrame = frame;
04926       frame->SetFrameElement(fe);
04927    }
04928 
04929    Bool_t sav = comp->IsLayoutBroken();
04930    comp->SetLayoutBroken(kFALSE);
04931    TGWindow *root = (TGWindow *)fClient->GetRoot();
04932    root->SetEditable(kFALSE);
04933    comp->Layout();
04934    DoRedraw();
04935    root->SetEditable(kTRUE);
04936 
04937    if (sav) {
04938       comp->SetLayoutBroken(kTRUE);
04939    }
04940    SelectFrame(el->fFrame);
04941 }
04942 
04943 //______________________________________________________________________________
04944 void TGuiBldDragManager::HandleGrid()
04945 {
04946    // Switch on/of grid drawn.
04947 
04948    if (fStop) {
04949       return;
04950    }
04951 
04952    TGWindow *root = (TGWindow*)fClient->GetRoot();
04953 
04954    if (!root || (root == fClient->GetDefaultRoot())) {
04955       return;
04956    }
04957 
04958    if (fPimpl->fGrid->fgStep > 1) {
04959       fPimpl->fGrid->SetStep(1);
04960       if (fBuilder) {
04961          fBuilder->UpdateStatusBar("Grid switched OFF");
04962       }
04963    } else {
04964       fPimpl->fGrid->SetStep(gGridStep);
04965 
04966       if (fBuilder) {
04967          fBuilder->UpdateStatusBar("Grid switched ON");
04968       }
04969 
04970       if (root->InheritsFrom(TGCompositeFrame::Class())) {
04971          TGCompositeFrame *comp = (TGCompositeFrame*)root;
04972          TIter next(comp->GetList());
04973          TGFrameElement *fe;
04974          Int_t x, y, w, h;
04975 
04976          while ((fe = (TGFrameElement*)next())) {
04977             x = fe->fFrame->GetX();
04978             y = fe->fFrame->GetY();
04979             w = fe->fFrame->GetWidth();
04980             h = fe->fFrame->GetHeight();
04981             ToGrid(x, y);
04982             ToGrid(w, h);
04983             fe->fFrame->MoveResize(x, y, w, h);
04984          }
04985       }
04986    }
04987 
04988    Snap2Grid();
04989    DrawGrabRectangles();
04990 }
04991 
04992 //______________________________________________________________________________
04993 TGCompositeFrame *TGuiBldDragManager::FindLayoutFrame(TGFrame *f)
04994 {
04995    // Helper to find a frame which can be layouted
04996 
04997    if (fStop || !f) {
04998       return 0;
04999    }
05000 
05001    const TGWindow *parent = f->GetParent();
05002    TGCompositeFrame *ret = 0;
05003 
05004    while (parent && (parent != fClient->GetDefaultRoot())) {
05005       ret = (TGCompositeFrame*)parent;
05006       if (parent->InheritsFrom(TGMdiFrame::Class())) return ret;
05007       parent = parent->GetParent();
05008    }
05009    return ret;
05010 }
05011 
05012 //______________________________________________________________________________
05013 void TGuiBldDragManager::HandleUpdateSelected(TGFrame *f)
05014 {
05015    // When selected frame was changed by guibuilder editor -> update its appearence
05016 
05017    if (fStop || !f) {
05018       return;
05019    }
05020 
05021    TGCompositeFrame *parent = 0;
05022    if (f->GetParent() &&
05023        f->GetParent()->InheritsFrom(TGCompositeFrame::Class())) {
05024       parent = (TGCompositeFrame*)f->GetParent();
05025    }
05026 
05027    if (!parent || !CanChangeLayout(parent)) {
05028       return;
05029    }
05030 
05031    Bool_t sav = parent->IsLayoutBroken();
05032    parent->SetLayoutBroken(kFALSE);
05033 
05034    if ((parent->GetWidth() < parent->GetDefaultWidth()) ||
05035         (parent->GetHeight() < parent->GetDefaultHeight())) {
05036       parent->Resize(parent->GetDefaultSize());
05037    } else {
05038       parent->Layout();
05039       if (f->InheritsFrom(TGCompositeFrame::Class())) {
05040          layoutFrame(f);
05041       }
05042    }
05043    fClient->NeedRedraw(parent, kTRUE);
05044    fClient->NeedRedraw(f);
05045 
05046    if (sav) parent->SetLayoutBroken(kTRUE);
05047 
05048    SelectFrame(f);
05049 }
05050 
05051 //______________________________________________________________________________
05052 void TGuiBldDragManager::HideGrabRectangles()
05053 {
05054    // Hide/Unmap grab rectangles.
05055 
05056    static Bool_t first = kFALSE;
05057 
05058    if (fPimpl->fGrabRectHidden) {
05059       return;
05060    }
05061    // skip very first event
05062    if (!first) {
05063       first = kTRUE;
05064       return;
05065    }
05066    int i = 0;
05067    for (i = 0; i < 8; i++) fPimpl->fGrabRect[i]->UnmapWindow();
05068    for (i = 0; i < 4; i++) fPimpl->fAroundFrame[i]->UnmapWindow();
05069    fPimpl->fGrabRectHidden = kTRUE;
05070 }
05071 
05072 //______________________________________________________________________________
05073 void TGuiBldDragManager::DeletePropertyEditor()
05074 {
05075    // Delete widget property editor.
05076 
05077    if (fStop || !fEditor) {
05078       return;
05079    }
05080 
05081    TQObject::Disconnect(fEditor);
05082 
05083    delete fEditor;
05084    fEditor = 0;
05085 }
05086 
05087 //______________________________________________________________________________
05088 Int_t TGuiBldDragManager::GetStrartDragX() const
05089 {
05090    // Return the X coordinate where drag started
05091 
05092    return fPimpl->fX0;
05093 }
05094 
05095 //______________________________________________________________________________
05096 Int_t TGuiBldDragManager::GetStrartDragY() const
05097 {
05098    // Return the Y coordinate where drag started
05099 
05100    return fPimpl->fY0;
05101 }
05102 
05103 //______________________________________________________________________________
05104 Int_t TGuiBldDragManager::GetEndDragX() const
05105 {
05106    // Return the current X coordinate of the dragged frame
05107 
05108    return fPimpl->fY;
05109 }
05110 
05111 //______________________________________________________________________________
05112 Int_t TGuiBldDragManager::GetEndDragY() const
05113 {
05114    // Returns the current Y coordinate of the dragged frame
05115 
05116    return fPimpl->fY;
05117 }
05118 
05119 //______________________________________________________________________________
05120 void TGuiBldDragManager::BreakLayout()
05121 {
05122    // Disable/Enable layout for selected/grabbed composite frame.
05123 
05124    if (fStop) {
05125       return;
05126    }
05127 
05128    TGFrame *frame = fSelected;
05129 
05130    if (!frame) {
05131       return;
05132    }
05133 
05134    TString str = frame->ClassName();
05135    str += "::";
05136    str += frame->GetName();
05137 
05138    if (IsFixedLayout(frame)) {
05139       if (fBuilder) {
05140          str += " layout cannot be broken";
05141          fBuilder->UpdateStatusBar(str.Data());
05142       }
05143       return;
05144    }
05145 
05146    frame->SetLayoutBroken(!frame->IsLayoutBroken());
05147    DrawGrabRectangles();
05148 
05149    if (fBuilder) {
05150       str += (frame->IsLayoutBroken() ? " Disable Layout" : " Enable Layout");
05151       fBuilder->UpdateStatusBar(str.Data());
05152    }
05153    if (fPimpl->fGrab && (fPimpl->fGrab->IsA() == TGCanvas::Class())) {
05154       fPimpl->fGrab->Layout();
05155    }
05156 }
05157 
05158 //______________________________________________________________________________
05159 void TGuiBldDragManager::SwitchLayout()
05160 {
05161    // Switch Horizontal/Vertical layout of selected/grabbed composite frame
05162 
05163    if (fStop || !fPimpl->fGrab) {
05164       return;
05165    }
05166 
05167    TGCompositeFrame *comp = (TGCompositeFrame*)fSelected;
05168 
05169    comp->SetLayoutBroken(kFALSE);
05170 
05171    UInt_t opt = comp->GetOptions();
05172    TGLayoutManager *m = comp->GetLayoutManager();
05173 
05174    if (!m) {
05175       return;
05176    }
05177 
05178    if (m->InheritsFrom(TGHorizontalLayout::Class())) {
05179       opt &= ~kHorizontalFrame;
05180       opt |= kVerticalFrame;
05181 
05182       if (fBuilder) {
05183          TString str = comp->ClassName();
05184          str += "::";
05185          str += comp->GetName();
05186          str += " Vertical Layout ON";
05187          fBuilder->UpdateStatusBar(str.Data());
05188       }
05189    } else if (m->InheritsFrom(TGVerticalLayout::Class())) {
05190       opt &= ~kVerticalFrame;
05191       opt |= kHorizontalFrame;
05192 
05193       if (fBuilder) {
05194          TString str = comp->ClassName();
05195          str += "::";
05196          str += comp->GetName();
05197          str += " Horizontal Layout ON";
05198          fBuilder->UpdateStatusBar(str.Data());
05199       }
05200    }
05201 
05202    comp->ChangeOptions(opt);
05203    if (!IsFixedSize(comp)) {
05204       comp->Resize();
05205    }
05206 
05207    if (fPimpl->fGrab && (fPimpl->fGrab->IsA() == TGCanvas::Class())) {
05208       fPimpl->fGrab->Layout();
05209    }
05210 
05211    fClient->NeedRedraw(comp);
05212    SelectFrame(comp);
05213 }
05214 
05215 //______________________________________________________________________________
05216 TGFrame *TGuiBldDragManager::GetSelected() const
05217 {
05218    // Return the current grabbed/selected frame.
05219 
05220    return fSelected;
05221 }
05222 
05223 //______________________________________________________________________________
05224 void TGuiBldDragManager::CloseMenus()
05225 {
05226    // Helper to close all menus
05227 
05228    void *ud;
05229 
05230    if (fFrameMenu) {
05231       fFrameMenu->EndMenu(ud);
05232    }
05233    if (fLassoMenu) {
05234       fLassoMenu->EndMenu(ud);
05235    }
05236    //UnmapAllPopups();
05237 }
05238 
05239 //______________________________________________________________________________
05240 TGFrame *TGuiBldDragManager::GetEditableParent(TGFrame *fr)
05241 {
05242    // Return the parent frame which can be editted.
05243 
05244    if (!fr || (fr == fClient->GetDefaultRoot())) {
05245       return 0;
05246    }
05247 
05248    TGWindow *parent = (TGWindow*)fr->GetParent();
05249 
05250    while (parent && (parent != fClient->GetDefaultRoot())) {
05251       if (!IsEditDisabled(parent) && !IsGrabDisabled(parent)) {
05252          return (TGFrame*)parent;
05253       }
05254       parent = (TGWindow*)parent->GetParent();
05255    }
05256    return 0;
05257 }
05258 
05259 //______________________________________________________________________________
05260 static TString FindMenuIconName(TString &in)
05261 {
05262    // Return a name of icon
05263 
05264    Int_t p1 = in.Index("*icon=", 1);
05265    if (p1 == kNPOS) return "";
05266    p1 += 6;
05267    Int_t p2 = in.Index("*", p1);
05268 
05269    if (p2 == kNPOS) return "";
05270 
05271    return in(p1, p2-p1);
05272 }
05273 
05274 //______________________________________________________________________________
05275 static Bool_t containBaseClass(const char *somestring, TClass *cl)
05276 {
05277    // Helper
05278 
05279    TString str = somestring;
05280 
05281    if (str.Contains(cl->GetName())) {
05282       return kTRUE;
05283    }
05284 
05285    TIter nextBaseClass(cl->GetListOfBases());
05286    TBaseClass *bc;
05287 
05288    while ((bc = (TBaseClass*)nextBaseClass())) {
05289       if (!bc->GetClassPointer()) {
05290          continue;
05291       }
05292       if (containBaseClass(somestring, bc->GetClassPointer())) {
05293          return kTRUE;
05294       }
05295    }
05296 
05297    return kFALSE;
05298 }
05299 
05300 //______________________________________________________________________________
05301 void TGuiBldDragManager::AddDialogMethods(TGPopupMenu *menu, TObject *object)
05302 {
05303    // Add DIALOG entries to the selected frame popup menu
05304 
05305    if (!menu || !object) {
05306       return;
05307    }
05308 
05309    TMethod *method;
05310    TIter next(fListOfDialogs);
05311    TString str;
05312    TString pname;
05313    const TGPicture *pic;
05314    TClass *cl = object->IsA();
05315    TString ename;
05316 
05317    while ((method = (TMethod*) next())) {
05318       ename = method->GetName();
05319       ename += "...";
05320       if (menu->GetEntry(ename.Data())) {
05321          continue;
05322       }
05323       if (!containBaseClass(method->GetSignature(), cl)) {
05324          continue;
05325       }
05326 
05327       str = method->GetCommentString();
05328       pname = FindMenuIconName(str);
05329       pic = fClient->GetPicture(pname.Data());
05330       menu->AddEntry(ename.Data(), kMethodMenuAct, method, pic);
05331    }
05332    menu->AddSeparator();
05333 }
05334 
05335 //______________________________________________________________________________
05336 void TGuiBldDragManager::AddClassMenuMethods(TGPopupMenu *menu, TObject *object)
05337 {
05338    // Add entries with class //*MENU* methods
05339 
05340    if (!menu || !object) {
05341       return;
05342    }
05343 
05344    TList *menuItemList;
05345    TClassMenuItem *menuItem;
05346    TString str;
05347    TString pname;
05348    const TGPicture *pic;
05349    TMethod  *method;
05350    TClass   *classPtr = 0;
05351    TList    *methodList;
05352    EMenuItemKind menuKind;
05353    TDataMember *m;
05354 
05355    AddDialogMethods(menu, object);
05356 
05357    menuItemList = object->IsA()->GetMenuList();
05358    TIter nextItem(menuItemList);
05359 
05360    fPimpl->fMenuObject = (TGFrame*)object;
05361    nextItem.Reset();
05362 
05363    while ((menuItem = (TClassMenuItem*) nextItem())) {
05364       switch (menuItem->GetType()) {
05365          case TClassMenuItem::kPopupStandardList:
05366             {
05367                // Standard list of class methods. Rebuild from scratch.
05368                // Get linked list of objects menu items (i.e. member functions
05369                // with the token *MENU in their comment fields.
05370                methodList = new TList;
05371                object->IsA()->GetMenuItems(methodList);
05372 
05373                TIter next(methodList);
05374 
05375                while ((method = (TMethod*) next())) {
05376                   if (classPtr != method->GetClass()) {
05377 //                     menu->AddSeparator();
05378                      classPtr = method->GetClass();
05379                   }
05380 
05381                   menuKind = method->IsMenuItem();
05382 
05383                   switch (menuKind) {
05384                      case kMenuDialog:
05385                      {
05386                         str = method->GetCommentString();
05387                         pname = FindMenuIconName(str);
05388                         pic = fClient->GetPicture(pname.Data());
05389                         menu->AddEntry(method->GetName(), kMethodMenuAct, method, pic);
05390                         break;
05391                      }
05392 
05393                      case kMenuSubMenu:
05394                         if ((m = method->FindDataMember())) {
05395                            if (m->GetterMethod()) {
05396                               TGPopupMenu *r = TRootGuiBuilder::CreatePopup();
05397                               menu->AddPopup(method->GetName(), r);
05398                               fPimpl->fFrameMenuTrash->Add(r);
05399                               TIter nxt(m->GetOptions());
05400                               TOptionListItem *it;
05401 
05402                               while ((it = (TOptionListItem*) nxt())) {
05403                                  char  *name  = it->fOptName;
05404                                  Long_t val   = it->fValue;
05405 
05406                                  TToggle *t = new TToggle;
05407                                  t->SetToggledObject(object, method);
05408                                  t->SetOnValue(val);
05409                                  fPimpl->fFrameMenuTrash->Add(t);
05410 
05411                                  //r->AddSeparator();
05412                                  r->AddEntry(name, kToggleMenuAct, t);
05413                                  if (t->GetState()) r->CheckEntryByData(t);
05414                               }
05415                            } else {
05416                               menu->AddEntry(method->GetName(), kMethodMenuAct, method);
05417                            }
05418                         }
05419                         break;
05420 
05421                      case kMenuToggle:
05422                         {
05423                            TToggle *t = new TToggle;
05424                            t->SetToggledObject(object, method);
05425                            t->SetOnValue(1);
05426                            fPimpl->fFrameMenuTrash->Add(t);
05427                            menu->AddEntry(method->GetName(), kToggleMenuAct, t);
05428                            if (t->GetState()) menu->CheckEntryByData(t);
05429                         }
05430                         break;
05431 
05432                      default:
05433                         break;
05434                   }
05435                }
05436                delete methodList;
05437             }
05438             break;
05439          case TClassMenuItem::kPopupUserFunction:
05440             {
05441                if (menuItem->IsToggle()) {
05442                   TMethod* method2 =
05443                         object->IsA()->GetMethodWithPrototype(menuItem->GetFunctionName(),
05444                                                               menuItem->GetArgs());
05445                   TToggle *t = new TToggle;
05446                   t->SetToggledObject(object, method2);
05447                   t->SetOnValue(1);
05448                   fPimpl->fFrameMenuTrash->Add(t);
05449 
05450                   menu->AddEntry(method2->GetName(), kToggleMenuAct, t);
05451                   if (t->GetState()) menu->CheckEntryByData(t);
05452                } else {
05453                   const char* menuItemTitle = menuItem->GetTitle();
05454                   if (strlen(menuItemTitle)==0) menuItemTitle = menuItem->GetFunctionName();
05455                   menu->AddEntry(menuItemTitle, kMethodMenuAct, menuItem);
05456                }
05457             }
05458 
05459             break;
05460          default:
05461             break;
05462       }
05463    }
05464 }
05465 
05466 //______________________________________________________________________________
05467 void TGuiBldDragManager::DoClassMenu(Int_t id)
05468 {
05469    // Process a method choosen via frame context menu
05470 
05471    if (!fFrameMenu || ((id != kMethodMenuAct) && (id != kToggleMenuAct))) {
05472       return;
05473    }
05474 
05475    TGMenuEntry *me = 0;
05476 
05477    if (id == kMethodMenuAct) {
05478       delete gMenuDialog;
05479       me = fFrameMenu->GetCurrent();
05480 
05481       if (!me || !fPimpl->fMenuObject) {
05482          return;
05483       }
05484       TMethod *method = (TMethod*)me->GetUserData();
05485       TString str = method->GetCommentString();
05486 
05487       if (str.Contains("*DIALOG")) {
05488          TString str2;
05489          str2.Form("((TGuiBldDragManager*)0x%lx)->%s((%s*)0x%lx)", (ULong_t)this, method->GetName(),
05490                   fPimpl->fMenuObject->ClassName(), (ULong_t)fPimpl->fMenuObject);
05491          gCint->Calc((char *)str2.Data());
05492          //delete fFrameMenu;  // suicide (BB)?
05493          //fFrameMenu = 0;
05494          return;
05495       }
05496       gMenuDialog = new TGuiBldMenuDialog(fPimpl->fMenuObject, fPimpl->fMenuObject, method);
05497       gMenuDialog->Popup();
05498 
05499    } else if (id == kToggleMenuAct) {
05500       me = fFrameMenu->GetCurrent();
05501       if (!me) {
05502          return;
05503       }
05504       TGPopupMenu *menu = me->GetPopup();
05505       TToggle *toggle = 0;
05506 
05507       if (menu) {    //process submenu
05508          toggle = (TToggle*)menu->GetCurrent()->GetUserData();
05509       } else {    //process check entry
05510          toggle = (TToggle*)fFrameMenu->GetCurrent()->GetUserData();
05511       }
05512       if (toggle) {
05513          toggle->Toggle();
05514       }
05515    }
05516 }
05517 
05518 //______________________________________________________________________________
05519 void TGuiBldDragManager::DeleteMenuDialog()
05520 {
05521    // Delete dialog and trash
05522 
05523    fPimpl->fFrameMenuTrash->Delete();
05524    gMenuDialog->DeleteWindow();
05525    gMenuDialog = 0;
05526    fPimpl->fMenuObject = 0;
05527 }
05528 
05529 //______________________________________________________________________________
05530 void TGuiBldDragManager::DoDialogOK()
05531 {
05532    // Process dialog OK button pressed
05533 
05534    gMenuDialog->ApplyMethod();
05535    DoRedraw();
05536    DeleteMenuDialog();
05537    gMenuDialog = 0;
05538 }
05539 
05540 //______________________________________________________________________________
05541 void TGuiBldDragManager::DoDialogApply()
05542 {
05543    // Process dialog Apply button pressed
05544 
05545    gMenuDialog->ApplyMethod();
05546 }
05547 
05548 //______________________________________________________________________________
05549 void TGuiBldDragManager::DoDialogCancel()
05550 {
05551    // Process dialog Cancel button pressed
05552 
05553    DeleteMenuDialog();
05554    gMenuDialog = 0;
05555 }
05556 
05557 //______________________________________________________________________________
05558 void TGuiBldDragManager::Menu4Frame(TGFrame *frame, Int_t x, Int_t y)
05559 {
05560    // Create and  place context menu for selected frame
05561 
05562    if (fStop) {
05563       return;
05564    }
05565 
05566    fPimpl->fSaveGrab = fPimpl->fGrab;
05567    fPimpl->fX0 = x;
05568    fPimpl->fY0 = y;
05569    fPimpl->fClickFrame = frame;
05570 
05571    Bool_t composite = frame->InheritsFrom(TGCompositeFrame::Class());
05572    Bool_t compar = frame->GetParent()->InheritsFrom(TGCompositeFrame::Class());
05573 
05574    TGCompositeFrame *cfr = 0;
05575    TGCompositeFrame *cfrp = 0;
05576    TGLayoutManager *lm = 0;
05577 
05578    if (composite)  {
05579       cfr = (TGCompositeFrame *)frame;
05580       lm = cfr->GetLayoutManager();
05581    }
05582    if (compar)  {
05583       cfrp = (TGCompositeFrame *)frame->GetParent();
05584    }
05585 
05586    delete fFrameMenu;
05587 
05588    fFrameMenu = TRootGuiBuilder::CreatePopup();
05589    fFrameMenu->Connect("Activated(Int_t)", "TGuiBldDragManager", this, "DoClassMenu(Int_t)");
05590 
05591    TString title = frame->ClassName();
05592    title += "::";
05593    title += frame->GetName();
05594    fFrameMenu->AddLabel(title.Data());
05595    fFrameMenu->AddSeparator();
05596 
05597    // special case - menu for editable Mdi frame
05598    if (fBuilder && (frame == fBuilder->GetMdiMain()->GetCurrent())) {
05599       if (!gSystem->AccessPathName(fPasteFileName.Data())) {
05600          fFrameMenu->AddEntry("Paste\tCtrl+V", kPasteAct,
05601                                0, fClient->GetPicture("bld_paste.png"));
05602       }
05603       fFrameMenu->AddEntry("Compact\tCtrl+L", kCompactAct,
05604                                0, fClient->GetPicture("bld_compact.png"));
05605       fFrameMenu->AddEntry("Grid On/Off\tCtrl+G", kGridAct,
05606                               0, fClient->GetPicture("bld_grid.png"));
05607       fFrameMenu->AddEntry("Save As ...\tCtrl+S", kSaveAct,
05608                               0, fClient->GetPicture("bld_save.png"));
05609       fFrameMenu->AddEntry("End Edit\tCtrl+DblClick", kEndEditAct,
05610                               0, fClient->GetPicture("bld_stop.png"));
05611       goto out;
05612    }
05613 
05614    AddClassMenuMethods(fFrameMenu, frame);
05615 
05616    if (!fBuilder) {
05617       fFrameMenu->AddEntry("Gui Builder", kPropertyAct);
05618       fFrameMenu->AddSeparator();
05619    }
05620 /*
05621    if (!frame->IsEditable() && !InEditable(frame->GetId())) {
05622       fPimpl->fSaveGrab = frame;
05623       goto out;
05624    }
05625 */
05626    if (!IsEditDisabled(cfrp)) {
05627       fFrameMenu->AddSeparator();
05628 
05629       if (composite && !IsFixedLayout(frame) && cfr->GetList()->GetEntries()) {
05630          fFrameMenu->AddEntry("Drop\tCtrl+Return", kDropAct);
05631       }
05632 
05633       if (!IsFixedLayout(cfrp)) {
05634          fFrameMenu->AddEntry("Cut\tCtrl+X", kCutAct,
05635                                0, fClient->GetPicture("bld_cut.png"));
05636       }
05637       //
05638       fFrameMenu->AddEntry("Copy\tCtrl+C", kCopyAct,
05639                             0, fClient->GetPicture("bld_copy.png"));
05640 
05641       if (frame->IsEditable() && !IsFixedLayout(frame) &&
05642           !gSystem->AccessPathName(fPasteFileName.Data())) {
05643          fFrameMenu->AddEntry("Paste\tCtrl+V", kPasteAct,
05644                                0, fClient->GetPicture("bld_paste.png"));
05645       }
05646 
05647       if (!IsFixedLayout(cfrp)) {
05648          fFrameMenu->AddEntry("Delete\tDel", kDeleteAct,
05649                               0, fClient->GetPicture("bld_delete.png"));
05650       }
05651 
05652       if (!IsFixedLayout(cfrp)) {
05653          fFrameMenu->AddEntry("Crop\tShift+Del", kCropAct,
05654                                0, fClient->GetPicture("bld_crop.png"));
05655       }
05656 
05657 //      if (!IsFixedLayout(cfrp) && !gSystem->AccessPathName(fPasteFileName.Data())) {
05658 //         fFrameMenu->AddEntry("Replace\tCtrl+R", kReplaceAct,
05659 //                               0, fClient->GetPicture("bld_paste_into.png"));
05660 //      }
05661 
05662       fFrameMenu->AddSeparator();
05663    } else {
05664       if (!gSystem->AccessPathName(fPasteFileName.Data()) && !IsFixedLayout(frame)) {
05665          fFrameMenu->AddEntry("Paste\tCtrl+V", kPasteAct,
05666                                0, fClient->GetPicture("bld_paste.png"));
05667       }
05668       if (frame->GetMainFrame() == frame) {
05669          fFrameMenu->AddEntry("Clone\tCtrl+A", kCloneAct);
05670       }
05671       fFrameMenu->AddSeparator();
05672    }
05673 
05674    if (CanChangeLayout(frame)) {
05675       const char *label = (frame->IsLayoutBroken() ? "Allow Layout\tCtrl+B" :
05676                                                      "Break Layout\tCtrl+B");
05677       fFrameMenu->AddEntry(label, kBreakLayoutAct,
05678                             0, fClient->GetPicture("bld_break.png"));
05679    }
05680 
05681    if (composite && !cfr->GetList()->IsEmpty()) {
05682       if (CanCompact(frame)) {
05683          if (!frame->IsEditable()) {
05684             fFrameMenu->AddEntry("Compact\tCtrl+L", kCompactAct,
05685                                   0, fClient->GetPicture("bld_compact.png"));
05686          } else {
05687             fFrameMenu->AddEntry("Compact\tCtrl+L", kCompactGlobalAct,
05688                                   0, fClient->GetPicture("bld_compact.png"));
05689          }
05690       }
05691 
05692       if (lm && ((lm->IsA() == TGVerticalLayout::Class()) ||
05693            (lm->IsA() == TGHorizontalLayout::Class())) && !IsFixedLayout(frame)) {
05694 
05695          if (lm->IsA() == TGVerticalLayout::Class()) {
05696             fFrameMenu->AddEntry("Horizontal\tCtrl+H", kSwitchLayoutAct,
05697                                  0, fClient->GetPicture("bld_hbox.png"));
05698          } else if (lm->IsA() == TGHorizontalLayout::Class()) {
05699             fFrameMenu->AddEntry("Vertical\tCtrl+H", kSwitchLayoutAct,
05700                                  0, fClient->GetPicture("bld_vbox.png"));
05701          }
05702       }
05703    }
05704 
05705    if (compar && (cfrp->GetList()->GetSize() > 1) && CanChangeLayoutOrder(frame)) {
05706       if (cfrp->GetList()->First() != frame->GetFrameElement()) {
05707          fFrameMenu->AddEntry("Lay Up\tUp/Left", kLayUpAct);
05708       }
05709       if (cfrp->GetList()->Last() != frame->GetFrameElement()) {
05710          fFrameMenu->AddEntry("Lay Down\tDown/Right", kLayDownAct);
05711       }
05712       fFrameMenu->AddSeparator();
05713    }
05714 
05715    if (frame->IsEditable()) {
05716       fFrameMenu->AddEntry("Grid On/Off\tCtrl+G", kGridAct,
05717                             0, fClient->GetPicture("bld_grid.png"));
05718    }
05719    if (composite && !cfr->GetList()->IsEmpty()) {
05720       fPimpl->fSaveGrab = frame;
05721       fFrameMenu->AddEntry("Save As ...       ", kSaveFrameAct,
05722                             0, fClient->GetPicture("bld_save.png"));
05723    }
05724 
05725 out:
05726    fFrameMenu->Connect("Activated(Int_t)", "TGuiBldDragManager", this, "HandleAction(Int_t)");
05727 
05728    fPimpl->fLastPopupAction = kNoneAct;
05729    fPimpl->fPlacePopup = kTRUE;
05730 
05731    fFrameMenu->PlaceMenu(x, y, kFALSE, kTRUE);
05732 }
05733 
05734 //______________________________________________________________________________
05735 void TGuiBldDragManager::Menu4Lasso(Int_t x, Int_t y)
05736 {
05737    // Create context menu for lasso actions.
05738 
05739    if (fStop || !fLassoDrawn) {
05740       return;
05741    }
05742 
05743    DrawLasso();
05744 
05745    delete fLassoMenu;
05746 
05747    fLassoMenu = TRootGuiBuilder::CreatePopup();
05748    fLassoMenu->AddLabel("Edit actions");
05749    fLassoMenu->AddSeparator();
05750    fLassoMenu->AddEntry("Grab\tReturn", kGrabAct);
05751    fLassoMenu->AddSeparator();
05752    fLassoMenu->AddEntry("Delete\tDelete", kDeleteAct,
05753                         0, fClient->GetPicture("bld_delete.png"));
05754    fLassoMenu->AddEntry("Crop\tShift+Delete", kCropAct,
05755                         0, fClient->GetPicture("bld_crop.png"));
05756    fLassoMenu->AddSeparator();
05757    fLassoMenu->AddEntry("Align Left\tLeft Key", kLeftAct,
05758                         0, fClient->GetPicture("bld_AlignLeft.png"));
05759    fLassoMenu->AddEntry("Align Right\tRight Key", kRightAct,
05760                         0, fClient->GetPicture("bld_AlignRight.png"));
05761    fLassoMenu->AddEntry("Align Up\tUp Key", kUpAct,
05762                         0, fClient->GetPicture("bld_AlignTop.png"));
05763    fLassoMenu->AddEntry("Align Down\tDown Key", kDownAct,
05764                         0, fClient->GetPicture("bld_AlignBtm.png"));
05765 
05766    fLassoMenu->Connect("Activated(Int_t)", "TGuiBldDragManager", this, "HandleAction(Int_t)");
05767 
05768    fPimpl->fLastPopupAction = kNoneAct;
05769    fPimpl->fPlacePopup = kTRUE;
05770    fLassoMenu->PlaceMenu(x, y, kFALSE, kTRUE);
05771 }
05772 
05773 //______________________________________________________________________________
05774 Bool_t TGuiBldDragManager::IsPasteFrameExist()
05775 {
05776    // Return kTRUE if paste frame exist.
05777 
05778    return !gSystem->AccessPathName(fPasteFileName.Data());
05779 }
05780 
05781 //______________________________________________________________________________
05782 TGColorDialog *TGuiBldDragManager::GetGlobalColorDialog(Bool_t create)
05783 {
05784    // Return pointer to global color dialog. If dialog is not yet created
05785    // and input parameter is kTRUE - the dialog will be created.
05786 
05787    static Int_t retc;
05788    static Pixel_t color;
05789 
05790    if (!fgGlobalColorDialog && create) {
05791       fgGlobalColorDialog = new TGColorDialog(gClient->GetDefaultRoot(), 0,
05792                                               &retc, &color, kFALSE);
05793       int i = 0;
05794       for (i = 0; i < 10; i++) {
05795          fgGlobalColorDialog->GetCustomPalette()->SetColor(i, TColor::Number2Pixel(i));
05796       }
05797       for (i = 0; i < 10; i++) {
05798          fgGlobalColorDialog->GetCustomPalette()->SetColor(10+i, TColor::Number2Pixel(180+i));
05799       }
05800    }
05801    return fgGlobalColorDialog;
05802 }
05803 
05804 //______________________________________________________________________________
05805 TGFontDialog *TGuiBldDragManager::GetGlobalFontDialog()
05806 {
05807    // Create global font dialog.
05808 
05809    static TGFontDialog::FontProp_t prop;
05810 
05811    if (!fgGlobalFontDialog) {
05812      fgGlobalFontDialog = new TGFontDialog(gClient->GetDefaultRoot(), 0, &prop, "", 0, kFALSE);
05813    }
05814    return fgGlobalFontDialog;
05815 }
05816 
05817 //______________________________________________________________________________
05818 void TGuiBldDragManager::MapGlobalDialog(TGMainFrame *dialog, TGFrame *fr)
05819 {
05820    // Map dialog and place it relative to selected frame.
05821 
05822    Int_t x = 0, y = 0;
05823    Window_t wdummy;
05824    UInt_t dw = gClient->GetDisplayWidth() - 20;
05825    UInt_t dh = gClient->GetDisplayHeight() - 50;
05826 
05827    TGFrame *parent = (TGFrame*)fr->GetParent();
05828    gVirtualX->TranslateCoordinates(parent->GetId(), gClient->GetDefaultRoot()->GetId(),
05829                                    fr->GetX() + fr->GetWidth(),
05830                                    fr->GetY() + fr->GetHeight(), x, y, wdummy);
05831 
05832    if (x + dialog->GetWidth() > dw) {
05833       x = dw - dialog->GetWidth();
05834    }
05835 
05836    if (y + dialog->GetHeight() > dh) {
05837       y = dh - dialog->GetHeight();
05838    }
05839 
05840    dialog->Move(x, y);
05841    dialog->SetWMPosition(x, y);
05842    dialog->MapRaised();
05843 }
05844 
05845 //______________________________________________________________________________
05846 void TGuiBldDragManager::ChangeBackgroundColor(TGFrame *fr)
05847 {
05848    // Change background color via context menu.
05849 
05850    TGColorDialog *cd = GetGlobalColorDialog();
05851    cd->SetCurrentColor(fr->GetBackground());
05852    cd->Connect("ColorSelected(Pixel_t)", "TGFrame", fr, "ChangeBackground(Pixel_t)");
05853    MapGlobalDialog(cd, fr);
05854    fClient->WaitForUnmap(cd);
05855    TQObject::Disconnect(cd);
05856 }
05857 
05858 //______________________________________________________________________________
05859 void TGuiBldDragManager::ChangeBackgroundColor(TGCompositeFrame *fr)
05860 {
05861    // Change background color via context menu for this frame and all subframes.
05862    // This method is activated via context menu during guibuilding.
05863 
05864    TGColorDialog *cd = GetGlobalColorDialog();
05865    cd->SetCurrentColor(fr->GetBackground());
05866    cd->Connect("ColorSelected(Pixel_t)", "TGCompositeFrame", fr,
05867                "ChangeSubframesBackground(Pixel_t)");
05868    MapGlobalDialog(cd, fr);
05869    fClient->WaitForUnmap(cd);
05870    TQObject::Disconnect(cd);
05871 }
05872 
05873 //______________________________________________________________________________
05874 void TGuiBldDragManager::ChangeTextColor(TGGroupFrame *fr)
05875 {
05876    // Change text color via color selection dialog. This method is activated
05877    // via context menu during guibuilding.
05878 
05879    TGGC *gc = fClient->GetResourcePool()->GetGCPool()->FindGC(fr->GetNormGC());
05880 
05881    if (!gc) {
05882       return;
05883    }
05884    ULong_t color = gc->GetForeground();
05885 
05886    TGColorDialog *cd = GetGlobalColorDialog();
05887    cd->SetCurrentColor(color);
05888    cd->Connect("ColorSelected(Pixel_t)", "TGGroupFrame", fr, "SetTextColor(Pixel_t)");
05889    MapGlobalDialog(cd, fr);
05890    fClient->WaitForUnmap(cd);
05891    TQObject::Disconnect(cd);
05892 }
05893 
05894 //______________________________________________________________________________
05895 void TGuiBldDragManager::ChangeTextFont(TGGroupFrame *fr)
05896 {
05897    // Change text font via font selection dialog. This method is activated
05898    // via context menu during guibuilding.
05899 
05900    TGFontDialog *fd = GetGlobalFontDialog();
05901 
05902    TGGC *gc = fClient->GetResourcePool()->GetGCPool()->FindGC(fr->GetNormGC());
05903 
05904    if (!gc) {
05905       return;
05906    }
05907 
05908    TGFont *font = fClient->GetResourcePool()->GetFontPool()->FindFont(fr->GetFontStruct());
05909 
05910    if (!font) {
05911       return;
05912    }
05913    fd->SetColor(gc->GetForeground());
05914    fd->SetFont(font);
05915    fd->EnableAlign(kFALSE);
05916    fd->Connect("FontSelected(char*)", "TGGroupFrame", fr, "SetTextFont(char*)");
05917    fd->Connect("ColorSelected(Pixel_t)", "TGGroupFrame", fr, "SetTextColor(Pixel_t)");
05918 
05919    MapGlobalDialog(fd, fr);
05920    fClient->WaitForUnmap(fd);
05921    TQObject::Disconnect(fd);
05922 }
05923 
05924 //______________________________________________________________________________
05925 void TGuiBldDragManager::ChangeProperties(TGTextButton *fr)
05926 {
05927    // Edit properties via font selection dialog. This method is activated
05928    // via context menu during guibuilding.
05929 
05930    TGFontDialog *fd = GetGlobalFontDialog();
05931 
05932    TGGC *gc = fClient->GetResourcePool()->GetGCPool()->FindGC(fr->GetNormGC());
05933    if (!gc) {
05934       return;
05935    }
05936 
05937    TGFont *font = fClient->GetResourcePool()->GetFontPool()->FindFont(fr->GetFontStruct());
05938 
05939    if (!font) {
05940       return;
05941    }
05942    fd->SetColor(gc->GetForeground());
05943    fd->SetFont(font);
05944    fd->SetAlign(fr->GetTextJustify());
05945 
05946    fd->Connect("FontSelected(char*)", "TGTextButton", fr, "SetFont(char*)");
05947    fd->Connect("ColorSelected(Pixel_t)", "TGTextButton", fr, "SetTextColor(Pixel_t)");
05948    fd->Connect("AlignSelected(Int_t)", "TGTextButton", fr, "SetTextJustify(Int_t)");
05949 
05950    MapGlobalDialog(fd, fr);
05951    fClient->WaitForUnmap(fd);
05952    TQObject::Disconnect(fd);
05953 }
05954 
05955 //______________________________________________________________________________
05956 void TGuiBldDragManager::ChangeTextColor(TGTextButton *fr)
05957 {
05958    // Change text color via color selection dialog. This method is activated
05959    // via context menu during guibuilding.
05960 
05961    TGGC *gc = gClient->GetResourcePool()->GetGCPool()->FindGC(fr->GetNormGC());
05962 
05963    if (!gc) {
05964       return;
05965    }
05966    ULong_t color = gc->GetForeground();
05967 
05968    TGColorDialog *cd = GetGlobalColorDialog();
05969    cd->SetCurrentColor(color);
05970    cd->Connect("ColorSelected(Pixel_t)", "TGTextButton", fr, "SetTextColor(Pixel_t)");
05971 
05972    MapGlobalDialog(cd, fr);
05973    fClient->WaitForUnmap(cd);
05974    TQObject::Disconnect(cd);
05975 }
05976 
05977 //______________________________________________________________________________
05978 void TGuiBldDragManager::ChangePicture(TGPictureButton *fr)
05979 {
05980    // Invoke file dialog to assign a new picture.
05981    // This method is activated via context menu during guibuilding.
05982 
05983    static TGFileInfo fi;
05984    static TString dir(".");
05985    static Bool_t overwr = kFALSE;
05986    TString fname;
05987 
05988    fi.fFileTypes = gImageTypes;
05989    fi.fIniDir    = StrDup(dir);
05990    fi.fOverwrite = overwr;
05991 
05992    TGWindow *root = (TGWindow*)fClient->GetRoot();
05993    SetEditable(kFALSE);
05994 
05995    new TGFileDialog(fClient->GetDefaultRoot(), fr, kFDOpen, &fi);
05996 
05997    if (!fi.fFilename) {
05998       root->SetEditable(kTRUE);
05999       SetEditable(kTRUE);
06000       return;
06001    }
06002 
06003    dir    = fi.fIniDir;
06004    overwr = fi.fOverwrite;
06005    fname  = fi.fFilename;
06006 
06007    const TGPicture *pic = fClient->GetPicture(fname.Data());
06008 
06009    if (!pic) {
06010       Int_t retval;
06011       new TGMsgBox(fClient->GetDefaultRoot(), fr, "Error...",
06012                    TString::Format("Cannot read image file (%s)", fname.Data()),
06013                    kMBIconExclamation, kMBRetry | kMBCancel, &retval);
06014 
06015       if (retval == kMBRetry) {
06016          ChangePicture(fr);
06017       }
06018    } else {
06019       const TGPicture *tmp = fr->GetPicture();
06020       if (tmp) fClient->FreePicture(tmp);
06021 
06022       fr->SetPicture(pic);
06023 
06024       // not clear how to do at this point
06025       tmp = fr->GetDisabledPicture();
06026       if (tmp) fClient->FreePicture(tmp);
06027    }
06028    root->SetEditable(kTRUE);
06029    SetEditable(kTRUE);
06030 }
06031 
06032 //______________________________________________________________________________
06033 void TGuiBldDragManager::ChangeBackgroundColor(TGCanvas *fr)
06034 {
06035    // Change background color via context menu
06036 
06037    TGColorDialog *cd = GetGlobalColorDialog();
06038    cd->SetCurrentColor(fr->GetBackground());
06039    cd->Connect("ColorSelected(Pixel_t)", "TGFrame", fr, "ChangeBackground(Pixel_t)");
06040    cd->Connect("ColorSelected(Pixel_t)", "TGScrollBar", fr->GetHScrollbar(), "ChangeBackground(Pixel_t)");
06041    cd->Connect("ColorSelected(Pixel_t)", "TGScrollBar", fr->GetVScrollbar(), "ChangeBackground(Pixel_t)");
06042 
06043    MapGlobalDialog(cd, fr);
06044    fClient->WaitForUnmap(cd);
06045    TQObject::Disconnect(cd);
06046 }
06047 
06048 //______________________________________________________________________________
06049 void TGuiBldDragManager::ChangeBackgroundColor(TGComboBox *fr)
06050 {
06051    // Change background color for list box entries. This method is invoked
06052    // via context menu during guibuilding.
06053 
06054    Pixel_t color = TGFrame::GetWhitePixel();
06055 
06056    TGColorDialog *cd = GetGlobalColorDialog();
06057    cd->SetCurrentColor(color);
06058 
06059    cd->Connect("ColorSelected(Pixel_t)", "TGListBox", fr->GetListBox(),
06060                "ChangeBackground(Pixel_t)");
06061 
06062    TGLBEntry *se = fr->GetSelectedEntry();
06063 
06064    if (se) {
06065       cd->Connect("ColorSelected(Pixel_t)", "TGLBEntry", se,
06066                   "SetBackgroundColor(Pixel_t)");
06067    }
06068 
06069    TGTextEntry *te = fr->GetTextEntry();
06070 
06071    if (te) {
06072       cd->Connect("ColorSelected(Pixel_t)", "TGTextEntry", te,
06073                   "SetBackgroundColor(Pixel_t)");
06074    }
06075 
06076    MapGlobalDialog(cd, fr);
06077    fClient->WaitForUnmap(cd);
06078    TQObject::Disconnect(cd);
06079 
06080    if (se) {
06081       fClient->NeedRedraw(se, kTRUE); // force redraw
06082    }
06083 
06084    if (te) {
06085       fClient->NeedRedraw(te, kTRUE);
06086    }
06087 }
06088 
06089 //______________________________________________________________________________
06090 void TGuiBldDragManager::ChangeProperties(TGLabel *fr)
06091 {
06092    // Edit properties via font selection dialog. This method is activated
06093    // via context menu during guibuilding.
06094 
06095    TGFontDialog *fd = GetGlobalFontDialog();
06096 
06097    TGGC *gc = fClient->GetResourcePool()->GetGCPool()->FindGC(fr->GetNormGC());
06098 
06099    if (!gc) {
06100       return;
06101    }
06102 
06103    TGFont *font = fClient->GetResourcePool()->GetFontPool()->FindFont(fr->GetFontStruct());
06104 
06105    if (!font) {
06106       return;
06107    }
06108 
06109    fd->SetColor(gc->GetForeground());
06110    fd->SetFont(font);
06111    fd->SetAlign(fr->GetTextJustify());
06112 
06113    fd->Connect("FontSelected(char*)", "TGLabel", fr, "SetTextFont(char*)");
06114    fd->Connect("ColorSelected(Pixel_t)", "TGLabel", fr, "SetTextColor(Pixel_t)");
06115    fd->Connect("AlignSelected(Int_t)", "TGLabel", fr, "SetTextJustify(Int_t)");
06116 
06117    MapGlobalDialog(fd, fr);
06118    fClient->WaitForUnmap(fd);
06119    TQObject::Disconnect(fd);
06120 }
06121 
06122 //______________________________________________________________________________
06123 void TGuiBldDragManager::ChangeTextColor(TGLabel *fr)
06124 {
06125    // Change text color via color selection dialog. This method is activated
06126    // via context menu during guibuilding.
06127 
06128    TGGC *gc = gClient->GetResourcePool()->GetGCPool()->FindGC(fr->GetNormGC());
06129 
06130    if (!gc) {
06131       return;
06132    }
06133 
06134    ULong_t color = gc->GetForeground();
06135 
06136    TGColorDialog *cd = GetGlobalColorDialog();
06137    cd->SetCurrentColor(color);
06138    cd->Connect("ColorSelected(Pixel_t)", "TGLabel", fr, "SetTextColor(Pixel_t)");
06139 
06140    MapGlobalDialog(cd, fr);
06141    fClient->WaitForUnmap(cd);
06142    TQObject::Disconnect(cd);
06143 }
06144 
06145 //______________________________________________________________________________
06146 void TGuiBldDragManager::ChangeBackgroundColor(TGListBox *fr)
06147 {
06148    // Set background color for list box entries. This method is invoked
06149    // via context menu during  guibuilding.
06150 
06151    Pixel_t color = TGFrame::GetWhitePixel();
06152 
06153    TGColorDialog *cd = GetGlobalColorDialog();
06154    cd->SetCurrentColor(color);
06155    cd->Connect("ColorSelected(Pixel_t)", "TGListBox", fr, "ChangeBackground(Pixel_t)");
06156 
06157    MapGlobalDialog(cd, fr);
06158    fClient->WaitForUnmap(cd);
06159    TQObject::Disconnect(cd);
06160 }
06161 
06162 //______________________________________________________________________________
06163 void TGuiBldDragManager::ChangeBarColor(TGProgressBar *fr)
06164 {
06165    // Set progress bar color via TGColorDialog.
06166    // This method is activated via context menu during guibuilding.
06167 
06168    ULong_t color = fr->GetBarColor();
06169 
06170    TGColorDialog *cd = GetGlobalColorDialog();
06171 
06172    cd->SetCurrentColor(color);
06173    cd->Connect("ColorSelected(Pixel_t)", "TGProgressBar", fr,  "SetBarColor(Pixel_t)");
06174 
06175    MapGlobalDialog(cd, fr);
06176    fClient->WaitForUnmap(cd);
06177    TQObject::Disconnect(cd);
06178 }
06179 
06180 //______________________________________________________________________________
06181 void TGuiBldDragManager::ChangeTextColor(TGProgressBar *fr)
06182 {
06183    // Change text color which displays position.
06184 
06185    TGGC *gc = gClient->GetResourcePool()->GetGCPool()->FindGC(fr->GetNormGC());
06186 
06187    if (!gc) {
06188       return;
06189    }
06190 
06191    Pixel_t pixel = gc->GetForeground();
06192    TGColorDialog *cd = GetGlobalColorDialog();
06193 
06194    cd->SetCurrentColor(pixel);
06195    cd->Connect("ColorSelected(Pixel_t)", "TGProgressBar", fr,
06196                "SetForegroundColor(Pixel_t)");
06197 
06198    MapGlobalDialog(cd, fr);
06199    fClient->WaitForUnmap(cd);
06200    TQObject::Disconnect(cd);
06201 }
06202 
06203 //______________________________________________________________________________
06204 void TGuiBldDragManager::ChangeTextColor(TGTextEntry *fr)
06205 {
06206    // Set text color. This method is invoked
06207    // via context menu during  guibuilding.
06208 
06209    Pixel_t color = fr->GetTextColor();
06210 
06211    TGColorDialog *cd = GetGlobalColorDialog();
06212    cd->SetCurrentColor(color);
06213    cd->Connect("ColorSelected(Pixel_t)", "TGTextEntry", fr, "SetTextColor(Pixel_t)");
06214 
06215    MapGlobalDialog(cd, fr);
06216    fClient->WaitForUnmap(cd);
06217    TQObject::Disconnect(cd);
06218 }
06219 
06220 //______________________________________________________________________________
06221 void TGuiBldDragManager::ChangeTextFont(TGTextEntry *fr)
06222 {
06223    // Change text font via font selection dialog. This method is activated
06224    // via context menu during guibuilding.
06225 
06226    TGFontDialog *fd = GetGlobalFontDialog();
06227 
06228    fd->SetColor(fr->GetTextColor());
06229    FontStruct_t fs = fr->GetFontStruct();
06230    TGFont *font = fClient->GetResourcePool()->GetFontPool()->FindFont(fs);
06231 
06232    if (font) {
06233       fd->SetFont(font);
06234    }
06235 
06236    fd->EnableAlign(kFALSE);
06237    fd->Connect("FontSelected(char*)", "TGTextEntry", fr, "SetFont(char*)");
06238    fd->Connect("ColorSelected(Pixel_t)", "TGTextEntry", fr, "SetTextColor(Pixel_t)");
06239 
06240    MapGlobalDialog(fd, fr);
06241    fClient->WaitForUnmap(fd);
06242    TQObject::Disconnect(fd);
06243 
06244    int tw, max_ascent, max_descent;
06245    tw = gVirtualX->TextWidth(fs, fr->GetText(), fr->GetBuffer()->GetTextLength());
06246 
06247    if (tw < 1) {
06248       TString dummy('w', fr->GetBuffer()->GetBufferLength());
06249       tw = gVirtualX->TextWidth(fs, dummy.Data(), dummy.Length());
06250    }
06251 
06252    gVirtualX->GetFontProperties(fs, max_ascent, max_descent);
06253    fr->Resize(tw + 8, max_ascent + max_descent + 7);
06254 }
06255 
06256 //______________________________________________________________________________
06257 void TGuiBldDragManager::ChangeImage(TGIcon *fr)
06258 {
06259    // Invoke file dialog to assign a new image.
06260    // This method is activated via context menu during guibuilding.
06261 
06262    static TGFileInfo fi;
06263    static TString dir(".");
06264    static Bool_t overwr = kFALSE;
06265    TString fname;
06266 
06267    fi.fFileTypes = gImageTypes;
06268    fi.fIniDir    = StrDup(dir);
06269    fi.fOverwrite = overwr;
06270 
06271    TGWindow *root = (TGWindow*)fClient->GetRoot();
06272    SetEditable(kFALSE);
06273 
06274    new TGFileDialog(fClient->GetDefaultRoot(), fr, kFDOpen, &fi);
06275 
06276    if (!fi.fFilename) {
06277       root->SetEditable(kTRUE);
06278       gDragManager->SetEditable(kTRUE);
06279       return;
06280    }
06281 
06282    dir    = fi.fIniDir;
06283    overwr = fi.fOverwrite;
06284    fname  = fi.fFilename;
06285 
06286    TImage *img = TImage::Open(fname.Data());
06287 
06288    if (!img) {
06289       Int_t retval;
06290       new TGMsgBox(fClient->GetDefaultRoot(), fr, "Error...",
06291                    TString::Format("Cannot read image file (%s)", fname.Data()),
06292                    kMBIconExclamation, kMBRetry | kMBCancel, &retval);
06293 
06294       if (retval == kMBRetry) {
06295          ChangeImage(fr);
06296       }
06297    } else {
06298       fr->SetImage(img);
06299       fr->SetImagePath(gSystem->DirName(fname.Data()));
06300    }
06301 
06302    root->SetEditable(kTRUE);
06303    SetEditable(kTRUE);
06304 }
06305 
06306 //______________________________________________________________________________
06307 void TGuiBldDragManager::SetLassoDrawn(Bool_t on)
06308 {
06309    // Set lasso drawn flag
06310 
06311    if (fLassoDrawn == on) {
06312       return;
06313    }
06314 
06315    fLassoDrawn = on;
06316 
06317    if (fBuilder) {
06318       if (on) {
06319          fBuilder->EnableEditButtons(kFALSE);
06320       }
06321 
06322       fBuilder->EnableLassoButtons(on);
06323    }
06324 }

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