#include "TTVLVContainer.h"
#include "TTreeViewer.h"
#include "TGPicture.h"
#include "TGLabel.h"
#include "TGButton.h"
#include "TGTextEntry.h"
#include "TGToolTip.h"
#include "TList.h"
ClassImp(TGItemContext)
TGItemContext::TGItemContext()
{
   
   fItem = 0;
}
void TGItemContext::Draw(Option_t *)
{
   
   fItem->GetContainer()->GetViewer()->ProcessMessage(MK_MSG(kC_CONTAINER, kCT_ITEMDBLCLICK), kButton1, 0);
}
void TGItemContext::EditExpression()
{
   
   fItem->GetContainer()->GetViewer()->EditExpression();
}
void TGItemContext::Empty()
{
   
   fItem->Empty();
}
void TGItemContext::RemoveItem()
{
   
   fItem->GetContainer()->GetViewer()->RemoveItem();
}
void TGItemContext::Scan()
{
   
   fItem->GetContainer()->GetViewer()->SetScanMode();
   fItem->GetContainer()->GetViewer()->ProcessMessage(MK_MSG(kC_CONTAINER, kCT_ITEMDBLCLICK), kButton1, 0);
}
void TGItemContext::SetExpression(const char *name, const char *alias, Bool_t cut)
{
   
   fItem->SetExpression(name, alias, cut);
}
ClassImp(TTVLVEntry)
TTVLVEntry::TTVLVEntry(const TGWindow *p,
                             const TGPicture *bigpic, const TGPicture *smallpic,
                             TGString *name, TGString **subnames,
                             EListViewMode ViewMode)
              :TGLVEntry(p, bigpic, smallpic, name, subnames, ViewMode)
{
   
   
   fTrueName.InitialCapacity(1000);
   fContainer = (TTVLVContainer *) p;
   fTip = 0;
   fIsCut = kFALSE;
   fTrueName = name->GetString();
   fContext = new TGItemContext();
   fContext->Associate(this);
   AddInput(kEnterWindowMask | kLeaveWindowMask);
}
TTVLVEntry::~TTVLVEntry()
{
   
   if (fTip) delete fTip;
   delete fContext;
}
const char *TTVLVEntry::ConvertAliases()
{
   
   TList *list = GetContainer()->GetViewer()->ExpressionList();
   fConvName = fTrueName;
   TString start(fConvName);
   TIter next(list);
   TTVLVEntry* item;
   while (!FullConverted()) {
      next.Reset();
      start = fConvName;
      while ((item=(TTVLVEntry*)next())) {
         if (item != this)
            fConvName.ReplaceAll(item->GetAlias(), item->GetTrueName());
      }
      if (fConvName == start) {
         Warning(item->GetAlias(), "Cannot convert aliases for this expression.");
         return(fConvName.Data());
      }
   }
   return(fConvName.Data());
}
Bool_t TTVLVEntry::FullConverted()
{
   
   TList *list = GetContainer()->GetViewer()->ExpressionList();
   TIter next(list);
   TTVLVEntry* item;
   while ((item=(TTVLVEntry*)next())) {
      if (item != this) {
         if (fConvName.Contains(item->GetAlias())) return kFALSE;
      }
   }
   return kTRUE;
}
void TTVLVEntry::CopyItem(TTVLVEntry *dest)
{
   
   if (!dest) return;
   dest->SetExpression(fTrueName.Data(), fAlias.Data(), fIsCut);
   TString alias = dest->GetAlias();
   if (!alias.BeginsWith("~") && !alias.Contains("empty")) dest->PrependTilde();
}
Bool_t TTVLVEntry::HandleCrossing(Event_t *event)
{
   
   if (fTip) {
      if (event->fType == kEnterNotify)
         fTip->Reset();
      else
         fTip->Hide();
   }
   return kTRUE;
}
Bool_t TTVLVEntry::HasAlias()
{
   
   if (fAlias.Length()) return kTRUE;
   return kFALSE;
}
void TTVLVEntry::PrependTilde()
{
   
   fAlias = "~" + fAlias;
   SetItemName(fAlias.Data());
}
void TTVLVEntry::SetItemName(const char* name)
{
   
   if (fItemName) delete fItemName;
   fItemName = new TGString(name);
   Int_t max_ascent, max_descent;
   fTWidth = gVirtualX->TextWidth(fFontStruct, fItemName->GetString(), fItemName->GetLength());
   gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
   fTHeight = max_ascent + max_descent;
   gVirtualX->ClearWindow(fId);
   Resize(GetDefaultSize());
   fClient->NeedRedraw(this);
}
void TTVLVEntry::SetCutType(Bool_t type)
{
   
   if (fIsCut && type) return;
   if (!fIsCut && !type) return;
   if (type) {
      SetSmallPic(fClient->GetPicture("selection_t.xpm"));
      SetToolTipText("Selection expression. Drag to scissors to activate");
   } else
      SetSmallPic(fClient->GetPicture("expression_t.xpm"));
   fIsCut = type;
}
void TTVLVEntry::SetExpression(const char* name, const char* alias, Bool_t cutType)
{
   
   SetItemName(alias);
   SetAlias(alias);
   SetTrueName(name);
   ULong_t *itemType = (ULong_t *) GetUserData();
   if (*itemType & TTreeViewer::kLTPackType) {
      if (strlen(name))
         SetSmallPic(fClient->GetPicture("pack_t.xpm"));
      else
         SetSmallPic(fClient->GetPicture("pack-empty_t.xpm"));
   }
   if ((*itemType & TTreeViewer::kLTDragType) && strlen(name) && !fIsCut)
      SetToolTipText("Double-click to draw. Drag and drop. Use Edit/Expression or context menu to edit.");
   if (*itemType & TTreeViewer::kLTDragType) SetCutType(cutType);
}
void TTVLVEntry::Empty()
{
   
   SetExpression("","-empty-");
   ULong_t *itemType = (ULong_t *) GetUserData();
   if (itemType && (*itemType & TTreeViewer::kLTDragType))
      SetToolTipText("User-defined expression/cut. Double-click to edit");
}
void TTVLVEntry::SetToolTipText(const char *text, Long_t delayms)
{
   
   
   if (fTip) {
      delete fTip;
      fTip = 0;
   }
   if (text && strlen(text))
      fTip = new TGToolTip(fClient->GetRoot(), this, text, delayms);
}
void TTVLVEntry::SetSmallPic(const TGPicture *spic)
{
   
   const TGPicture *cspic = fSmallPic;
   fSmallPic = spic;
   fCurrent = fSmallPic;
   if (fSelPic) delete fSelPic;
   fSelPic = 0;
   if (fActive) {
      fSelPic = new TGSelectedPicture(fClient, fCurrent);
   }
   DoRedraw();
   fClient->FreePicture(cspic);
}
ClassImp(TTVLVContainer)
TTVLVContainer::TTVLVContainer(const TGWindow *p, UInt_t w, UInt_t h, UInt_t options)
          :TGLVContainer(p, w, h,options | kSunkenFrame)
{
   
   fListView = 0;
   fViewer = 0;
   fExpressionList = new TList;
   fCursor = gVirtualX->CreateCursor(kMove);
   fDefaultCursor = gVirtualX->CreateCursor(kPointer);
   fMapSubwindows = kTRUE;
}
TTVLVContainer::~TTVLVContainer()
{
   
   delete fExpressionList;
}
const char* TTVLVContainer::Cut()
{
   
   TGFrameElement *el = (TGFrameElement *) fList->At(3);
   if (el) {
      TTVLVEntry *f = (TTVLVEntry *) el->fFrame;
      if (f) return f->ConvertAliases();
      return 0;
   }
   return 0;
}
TTVLVEntry * TTVLVContainer::ExpressionItem(Int_t index)
{
   
   TGFrameElement *el = (TGFrameElement *) fList->At(index);
   if (el) {
      TTVLVEntry *item = (TTVLVEntry *) el->fFrame;
      return item;
   }
   return 0;
}
TList* TTVLVContainer::ExpressionList()
{
   
   fExpressionList->Clear();
   TIter next(fList);
   TGFrameElement *el;
   while ((el = (TGFrameElement*)next())) {
      TTVLVEntry *item = (TTVLVEntry *)el->fFrame;
      if (item) {
         ULong_t *itemType = (ULong_t *) item->GetUserData();
         if ((*itemType & TTreeViewer::kLTExpressionType) &&
            (*itemType & TTreeViewer::kLTDragType)) fExpressionList->Add(item);
      }
   }
   return fExpressionList;
}
const char* TTVLVContainer::Ex()
{
   
   TGFrameElement *el = (TGFrameElement *) fList->At(0);
   if (el) {
      TTVLVEntry *f = (TTVLVEntry *) el->fFrame;
      if (f) return f->ConvertAliases();
      return 0;
   }
   return 0;
}
const char* TTVLVContainer::Ey()
{
   
   TGFrameElement *el = (TGFrameElement *) fList->At(1);
   if (el) {
      TTVLVEntry *f = (TTVLVEntry *) el->fFrame;
      if (f) return f->ConvertAliases();
      return 0;
   }
   return 0;
}
const char* TTVLVContainer::Ez()
{
   
   TGFrameElement *el = (TGFrameElement *) fList->At(2);
   if (el) {
      TTVLVEntry *f = (TTVLVEntry *) el->fFrame;
      if (f) return f->ConvertAliases();
      return 0;
   }
   return 0;
}
const char* TTVLVContainer::ScanList()
{
   
   TGFrameElement *el = (TGFrameElement *) fList->At(4);
   if (el) {
      TTVLVEntry *f = (TTVLVEntry *) el->fFrame;
      if (f) return f->GetTrueName();
      return 0;
   }
   return 0;
}
Bool_t TTVLVContainer::HandleButton(Event_t *event)
{
   
   int total, selected;
   if (event->fType == kButtonPress) {
      fXp = event->fX;
      fYp = event->fY;
      if (fLastActive) {
         fLastActive->Activate(kFALSE);
         fLastActive = 0;
      }
      total = selected = 0;
      TGFrameElement *el;
      TIter next(fList);
      while ((el = (TGFrameElement *) next())) {
         TTVLVEntry *f = (TTVLVEntry *) el->fFrame;
         ++total;
         if (f->GetId() == (Window_t)event->fUser[0]) {  
            f->Activate(kTRUE);
            if (f->GetTip()) (f->GetTip())->Hide();
            fX0 = f->GetX();
            fY0 = f->GetY();
            ++selected;
            fLastActive = f;
         } else {
            f->Activate(kFALSE);
         }
      }
      if (fTotal != total || fSelected != selected) {
         fTotal = total;
         fSelected = selected;
         SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
                     fTotal, fSelected);
      }
      if (selected == 1 && event->fCode == 1) {
         ULong_t *itemType = (ULong_t *) fLastActive->GetUserData();
         if (*itemType & TTreeViewer::kLTDragType) {
            fDragging = kTRUE;
            gVirtualX->SetCursor(fId,fCursor);
            fXp = event->fX;
            fYp = event->fY;
         }
      }
   }
   if (event->fType == kButtonRelease) {
      if (fDragging) {
         fDragging = kFALSE;
         gVirtualX->SetCursor(fId,fDefaultCursor);
         fLastActive->Move(fX0,fY0);
         TGFrameElement *el;
         TIter next(fList);
         while ((el = (TGFrameElement *) next())) {
            TTVLVEntry *f = (TTVLVEntry *) el->fFrame;
            if ((f == fLastActive) || !f->IsActive()) continue;
            ULong_t *itemType = (ULong_t *) f->GetUserData();
            fLastActive->Activate(kFALSE);
            if (!(*itemType & TTreeViewer::kLTPackType)) {
               
               ((TTVLVEntry *) fLastActive)->CopyItem(f);
               if (*itemType & TTreeViewer::kLTDragType)
                  f->SetToolTipText("Double-click to draw. Drag and drop. Use Edit/Expression or context menu to edit.");
            } else {
               if (strlen(((TTVLVEntry *) fLastActive)->GetTrueName())) {
                  
                  if (!strlen(f->GetTrueName())) {
                     f->SetTrueName(((TTVLVEntry *)fLastActive)->GetTrueName());
                     f->SetSmallPic(fClient->GetPicture("pack_t.xpm"));
                  } else {
                     TString name(2000);
                     TString dragged = ((TTVLVEntry *)fLastActive)->ConvertAliases();
                     name  = f->GetTrueName();
                     if ((name.Length()+dragged.Length()) < 228) {
                        name += ":";
                        name += dragged;
                        f->SetTrueName(name.Data());
                     } else {
                        Warning("HandleButton",
                                "Name too long. Can not add any more items to scan box.");
                     }
                  }
               }
            }
            fLastActive = f;
            if (fViewer) {
               char msg[2000];
               msg[0] = 0;
               sprintf(msg, "Content : %s", f->GetTrueName());
               fViewer->Message(msg);
            }
         }
         if ((TMath::Abs(event->fX - fXp) < 2) && (TMath::Abs(event->fY - fYp) < 2)) {
            SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMCLICK),
                        event->fCode, (event->fYRoot << 16) | event->fXRoot);
         }
      } else {
         SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMCLICK),
                     event->fCode, (event->fYRoot << 16) | event->fXRoot);
      }
   }
   return kTRUE;
}
Bool_t TTVLVContainer::HandleMotion(Event_t *event)
{
   
   Int_t xf0, xff, yf0, yff;
   Int_t xpos = event->fX - (fXp-fX0);
   Int_t ypos = event->fY - (fYp-fY0);
   if (fDragging) {
      TGFrameElement *el;
      ULong_t *itemType;
      TIter next(fList);
      while ((el = (TGFrameElement *) next())) {
         TTVLVEntry *f = (TTVLVEntry *) el->fFrame;
         if (f == fLastActive) {
            if (f->GetTip()) (f->GetTip())->Hide();
            continue;
         }
         xf0 = f->GetX();
         yf0 = f->GetY();
         xff = f->GetX() + f->GetWidth();
         yff = f->GetY() + f->GetHeight();
         itemType = (ULong_t *) f->GetUserData();
         if (*itemType & TTreeViewer::kLTExpressionType) {
            if (xpos>xf0 && xpos<xff && ypos>yf0 && ypos<yff) {
               f->Activate(kTRUE);
            } else {
               f->Activate(kFALSE);
            }
         }
      }
      if ((fXp - event->fX) > 10) {
         fListView->SetHsbPosition(0);
         fListView->SetVsbPosition(0);
      }
      fLastActive->Move(xpos, ypos);
      gVirtualX->RaiseWindow(fLastActive->GetId());
      SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER,(EWidgetMessageTypes)4),event->fX, event->fY);
   }
   return kTRUE;
}
void TTVLVContainer::EmptyAll()
{
   
   TGFrameElement *el;
   TIter next(fList);
   while ((el = (TGFrameElement *) next())) {
      TTVLVEntry *f = (TTVLVEntry *) el->fFrame;
      UInt_t *userData = (UInt_t *) f->GetUserData();
      if (*userData & TTreeViewer::kLTExpressionType) {
         if (*userData & TTreeViewer::kLTPackType) {
            f->SetSmallPic(fClient->GetPicture("pack-empty_t.xpm"));
            f->SetTrueName("");
         } else {
            f->Empty();
         }
      }
   }
}
void TTVLVContainer::RemoveNonStatic()
{
   
   TGFrameElement *el;
   TIter next(fList);
   while ((el = (TGFrameElement *) next())) {
      TTVLVEntry *f = (TTVLVEntry *) el->fFrame;
      UInt_t *userData = (UInt_t *) f->GetUserData();
      if (!((*userData) & TTreeViewer::kLTExpressionType)) {
         RemoveItem(f);
      }
   }
}
void TTVLVContainer::SelectItem(const char* name)
{
   
   if (fLastActive) {
      fLastActive->Activate(kFALSE);
      fLastActive = 0;
   }
   TGFrameElement *el;
   fSelected = 0;
   TIter next(fList);
   while ((el = (TGFrameElement *) next())) {
      TTVLVEntry *f = (TTVLVEntry *) el->fFrame;
      if (!strcmp(f->GetItemName()->GetString(),name)) {
         f->Activate(kTRUE);
         fLastActive = (TGLVEntry *) f;
         fSelected++;
      } else {
         f->Activate(kFALSE);
      }
   }
}
ClassImp(TGSelectBox)
enum ETransientFrameCommands {
   kTFDone,
   kTFCancel
};
TGSelectBox* TGSelectBox::fgInstance = 0;
TGSelectBox::TGSelectBox(const TGWindow *p, const TGWindow *main,
                         UInt_t w, UInt_t h)
            :TGTransientFrame(p, main, w, h)
{
   
   if (!fgInstance) {
      fgInstance = this;
      fViewer = (TTreeViewer *)fMain;
      if (!fViewer) Error("TGSelectBox", "Must be started from viewer");
      fEntry = 0;
      fLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterY | kLHintsExpandX, 0, 0, 0, 2);
      fBLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 2, 2, 2);
      fBLayout1= new TGLayoutHints(kLHintsTop | kLHintsRight, 2, 0, 2, 2);
      fLabel = new TGLabel(this, "");
      AddFrame(fLabel,fLayout);
      fTe = new TGTextEntry(this, new TGTextBuffer(2000));
      fTe->SetToolTipText("Type an expression using C++ syntax. Click other expression/leaves to paste them here.");
      AddFrame(fTe, fLayout);
      fLabelAlias = new TGLabel(this, "Alias");
      AddFrame(fLabelAlias,fLayout);
      fTeAlias = new TGTextEntry(this, new TGTextBuffer(100));
      fTeAlias->SetToolTipText("Define an alias for this expression. Do NOT use leading strings of other aliases.");
      AddFrame(fTeAlias, fLayout);
      fBf = new TGHorizontalFrame(this, 10, 10);
      fCANCEL = new TGTextButton(fBf, "&Cancel", kTFCancel);
      fCANCEL->Associate(this);
      fBf->AddFrame(fCANCEL, fBLayout);
      fDONE = new TGTextButton(fBf, "&Done", kTFDone);
      fDONE->Associate(this);
      fBf->AddFrame(fDONE, fBLayout1);
      AddFrame(fBf, fLayout);
      MapSubwindows();
      Resize(GetDefaultSize());
      Window_t wdum;
      Int_t ax, ay;
      gVirtualX->TranslateCoordinates(main->GetId(), GetParent()->GetId(), 25,
                        (Int_t)(((TGFrame *) main)->GetHeight() - fHeight) >> 1,
                        ax, ay, wdum);
      MoveResize(ax, ay, w, GetDefaultHeight());
      MapWindow();
   }
}
TGSelectBox::~TGSelectBox()
{
   
   fgInstance = 0;
   delete fLabel;
   delete fTe;
   delete fLabelAlias;
   delete fTeAlias;
   delete fDONE;
   delete fCANCEL;
   delete fBf;
   delete fLayout;
   delete fBLayout;
   delete fBLayout1;
}
void TGSelectBox::CloseWindow()
{
   
   gVirtualX->UnmapWindow(GetId());
   delete this;
}
TGSelectBox * TGSelectBox::GetInstance()
{
   
   return fgInstance;
}
void TGSelectBox::GrabPointer()
{
   
   Event_t event;
   event.fType = kButtonPress;
   event.fCode = kButton1;
   Int_t position = fTe->GetCursorPosition();
   fTe->HandleButton(&event);
   fTe->SetCursorPosition(position);
}
void TGSelectBox::SetLabel(const char* title)
{
   
   fLabel->SetText(new TGString(title));
}
void TGSelectBox::SaveText()
{
   
   if (fEntry) {
      Bool_t cutType;
      TString name(fTe->GetText());
      if (name.Length())
         fEntry->SetToolTipText("Double-click to draw. Drag and drop. Use Edit/Expression or context menu to edit.");
      else
         fEntry->SetToolTipText("User-defined expression/cut. Double-click to edit");
      
      cutType = name.Contains("<") || name.Contains(">") || name.Contains("=") ||
                name.Contains("!") || name.Contains("&") || name.Contains("|");
      TString alias(fTeAlias->GetText());
      if (!alias.BeginsWith("~") && !alias.Contains("empty")) fTeAlias->InsertText("~", 0);
      fEntry->SetExpression(fTe->GetText(), fTeAlias->GetText(), cutType);
      if (fOldAlias.Contains("empty")) {
         fOldAlias = fTeAlias->GetText();
         return;
      }
      TList *list = fViewer->ExpressionList();
      TIter next(list);
      TTVLVEntry* item;
      while ((item=(TTVLVEntry*)next())) {
         if (item != fEntry) {
            TString name = item->GetTrueName();
            name.ReplaceAll(fOldAlias.Data(), fTeAlias->GetText());
            item->SetTrueName(name.Data());
         }
      }
   }
}
void TGSelectBox::SetEntry(TTVLVEntry *entry)
{
   
   fEntry = entry;
   fTe->SetText(entry->GetTrueName());
   fTeAlias->SetText(entry->GetAlias());
   fOldAlias = entry->GetAlias();
}
void TGSelectBox::InsertText(const char* text)
{
   
   Int_t start = fTe->GetCursorPosition();
   fTe->InsertText(text, fTe->GetCursorPosition());
   fTe->SetCursorPosition(start+strlen(text));
}
Bool_t TGSelectBox::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
{
   
   switch (GET_MSG(msg)) {
      case kC_TEXTENTRY:
         switch (GET_SUBMSG(msg)) {
            case kTE_ENTER:
               if (ValidateAlias()) SaveText();
               break;
            default:
               break;
         }
         break;
      case kC_COMMAND:
         switch (GET_SUBMSG(msg)) {
            case kCM_BUTTON:
               switch (parm1) {
                  case kTFDone:
                     if (!ValidateAlias()) break;
                     SaveText();
                     CloseWindow();
                     break;
                  case kTFCancel:
                     CloseWindow();
                     break;
                  default:
                     break;
               }
               break;
            default:
               break;
         }
         break;
      default:
         if (parm2) break;       
         break;
   }
   return kTRUE;
}
Bool_t TGSelectBox::ValidateAlias()
{
   
   if (!strcmp(fTeAlias->GetText(), "-empty-") || !strlen(fTeAlias->GetText())) {
      fViewer->Warning("ValidateAlias", "You should define the alias first.");
      return kFALSE;
   }
   TList *list = fViewer->ExpressionList();
   TIter next(list);
   TTVLVEntry* item;
   while ((item=(TTVLVEntry*)next())) {
      if (item != fEntry) {
         TString itemalias(item->GetAlias());
         if (itemalias.Contains(fTeAlias->GetText())) {
            fViewer->Warning("ValidAlias", "Alias can not be the leading string of other alias.");
            return kFALSE;
         }
      }
   }
   return kTRUE;
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.