// @(#)root/treeviewer:$Id$ //Author : Andrei Gheata 16/08/00 /************************************************************************* * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #include "TTVLVContainer.h" #include "TTreeViewer.h" #include "TGPicture.h" #include "TGLabel.h" #include "TGButton.h" #include "TGTextEntry.h" #include "TGToolTip.h" #include "TList.h" #include "TVirtualX.h" ClassImp(TGItemContext); /** \class TGItemContext empty object used as context menu support for TGLVTreeEntries. */ //////////////////////////////////////////////////////////////////////////////// /// Constructor TGItemContext::TGItemContext() { fItem = 0; } //////////////////////////////////////////////////////////////////////////////// /// Draw item void TGItemContext::Draw(Option_t *) { fItem->GetContainer()->GetViewer()->ProcessMessage(MK_MSG(kC_CONTAINER, kCT_ITEMDBLCLICK), kButton1, 0); } //////////////////////////////////////////////////////////////////////////////// /// Edit expression void TGItemContext::EditExpression() { fItem->GetContainer()->GetViewer()->EditExpression(); } //////////////////////////////////////////////////////////////////////////////// /// Empty item void TGItemContext::Empty() { fItem->Empty(); } //////////////////////////////////////////////////////////////////////////////// /// Remove item void TGItemContext::RemoveItem() { fItem->GetContainer()->GetViewer()->RemoveItem(); } //////////////////////////////////////////////////////////////////////////////// /// Scan item void TGItemContext::Scan() { fItem->GetContainer()->GetViewer()->SetScanMode(); fItem->GetContainer()->GetViewer()->ProcessMessage(MK_MSG(kC_CONTAINER, kCT_ITEMDBLCLICK), kButton1, 0); } //////////////////////////////////////////////////////////////////////////////// /// Set item expression void TGItemContext::SetExpression(const char *name, const char *alias, Bool_t cut) { fItem->SetExpression(name, alias, cut); } ClassImp(TTVLVEntry); /** \class TTVLVEntry This class represent entries that goes into the TreeViewer listview container. It subclasses TGLVEntry and adds 2 data members: the item true name and the alias. */ //////////////////////////////////////////////////////////////////////////////// /// TTVLVEntry constructor. TTVLVEntry::TTVLVEntry(const TGWindow *p, const TGPicture *bigpic, const TGPicture *smallpic, TGString *name, TGString **subnames, EListViewMode ViewMode) :TGLVEntry(p, bigpic, smallpic, name, subnames, ViewMode) { // both alias and true name are initialized to name fContainer = (TTVLVContainer *) p; fTip = 0; fIsCut = kFALSE; fTrueName = name->GetString(); fContext = new TGItemContext(); fContext->Associate(this); AddInput(kEnterWindowMask | kLeaveWindowMask); } //////////////////////////////////////////////////////////////////////////////// /// TTVLVEntry destructor TTVLVEntry::~TTVLVEntry() { if (fTip) delete fTip; delete fContext; } //////////////////////////////////////////////////////////////////////////////// /// Convert all aliases into true names 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) { //the following line is deadcode reported by coverity because item=0 //if (item) Warning(item->GetAlias(), "Cannot convert aliases for this expression."); return(fConvName.Data()); } } return(fConvName.Data()); } //////////////////////////////////////////////////////////////////////////////// /// Return true if converted name is alias free 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; } //////////////////////////////////////////////////////////////////////////////// /// Copy this item's name and alias to an other. 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(); } //////////////////////////////////////////////////////////////////////////////// /// Handle mouse crossing event. Bool_t TTVLVEntry::HandleCrossing(Event_t *event) { if (fTip) { if (event->fType == kEnterNotify) fTip->Reset(); else fTip->Hide(); } return kTRUE; } //////////////////////////////////////////////////////////////////////////////// /// Check if alias name is not empty. Bool_t TTVLVEntry::HasAlias() { if (fAlias.Length()) return kTRUE; return kFALSE; } //////////////////////////////////////////////////////////////////////////////// /// Prepend a ~ to item alias void TTVLVEntry::PrependTilde() { fAlias = "~" + fAlias; SetItemName(fAlias.Data()); } //////////////////////////////////////////////////////////////////////////////// /// Redraw this entry with new name 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); } //////////////////////////////////////////////////////////////////////////////// /// Set cut type 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; } //////////////////////////////////////////////////////////////////////////////// /// Set the true name, alias and type of the expression, then refresh it 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); } //////////////////////////////////////////////////////////////////////////////// /// Clear all names and alias 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"); } //////////////////////////////////////////////////////////////////////////////// /// Set tool tip text associated with this item. The delay is in /// milliseconds (minimum 250). To remove tool tip call method with text = 0 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); } //////////////////////////////////////////////////////////////////////////////// /// Set small picture 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); /** \class TTVLVContainer This class represent the list view container for the. TreeView class. It is a TGLVContainer with item dragging capabilities for the TTVLVEntry objects inside. */ //////////////////////////////////////////////////////////////////////////////// /// TGLVContainer constructor 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; } //////////////////////////////////////////////////////////////////////////////// /// TGLVContainer destructor TTVLVContainer::~TTVLVContainer() { delete fExpressionList; } //////////////////////////////////////////////////////////////////////////////// /// Return the cut entry 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; } //////////////////////////////////////////////////////////////////////////////// /// Return the expression item at specific position TTVLVEntry * TTVLVContainer::ExpressionItem(Int_t index) { TGFrameElement *el = (TGFrameElement *) fList->At(index); if (el) { TTVLVEntry *item = (TTVLVEntry *) el->fFrame; return item; } return 0; } //////////////////////////////////////////////////////////////////////////////// /// Return the list of user-defined expressions 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; } //////////////////////////////////////////////////////////////////////////////// /// Return the expression on X 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; } //////////////////////////////////////////////////////////////////////////////// /// Return the expression on Y 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; } //////////////////////////////////////////////////////////////////////////////// /// Return the expression on Z 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; } //////////////////////////////////////////////////////////////////////////////// /// Return the cut entry 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; } //////////////////////////////////////////////////////////////////////////////// /// Handle mouse button event in container. 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]) { // fUser[0] = subwindow 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)) { // dragging items to expressions ((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())) { // dragging to scan box 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; snprintf(msg,2000, "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; } //////////////////////////////////////////////////////////////////////////////// /// Handle mouse motion events. 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 && xposyf0 && yposActivate(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; } //////////////////////////////////////////////////////////////////////////////// /// Clear all names and aliases for expression type items 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(); } } } } //////////////////////////////////////////////////////////////////////////////// /// Remove all non-static items from the list view, except expressions 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); } } fLastActive = 0; } //////////////////////////////////////////////////////////////////////////////// /// Select an item 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); /** \class TGSelectBox This class represent a specialized expression editor for TTVLVEntry 'true name' and 'alias' data members. It is a singleton in order to be able to use it for several expressions. */ enum ETransientFrameCommands { kTFDone, kTFCancel }; TGSelectBox* TGSelectBox::fgInstance = 0; //////////////////////////////////////////////////////////////////////////////// /// TGSelectBox constructor 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()); // SetBackgroundColor(color); 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 destructor TGSelectBox::~TGSelectBox() { fgInstance = 0; delete fLabel; delete fTe; delete fLabelAlias; delete fTeAlias; delete fDONE; delete fCANCEL; delete fBf; delete fLayout; delete fBLayout; delete fBLayout1; } //////////////////////////////////////////////////////////////////////////////// /// Close the select box void TGSelectBox::CloseWindow() { gVirtualX->UnmapWindow(GetId()); delete this; } //////////////////////////////////////////////////////////////////////////////// /// Return the pointer to the instantiated singleton TGSelectBox * TGSelectBox::GetInstance() { return fgInstance; } //////////////////////////////////////////////////////////////////////////////// /// Just focus the cursor inside void TGSelectBox::GrabPointer() { Event_t event; event.fType = kButtonPress; event.fCode = kButton1; event.fX = event.fY = 1; Int_t position = fTe->GetCursorPosition(); fTe->HandleButton(&event); fTe->SetCursorPosition(position); } //////////////////////////////////////////////////////////////////////////////// /// Set label of selection box void TGSelectBox::SetLabel(const char* title) { fLabel->SetText(new TGString(title)); } //////////////////////////////////////////////////////////////////////////////// /// Save the edited entry true name and alias 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"); // Set type of item to "cut" if containing boolean operators 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) { name = item->GetTrueName(); name.ReplaceAll(fOldAlias.Data(), fTeAlias->GetText()); item->SetTrueName(name.Data()); } } } } //////////////////////////////////////////////////////////////////////////////// /// Connect one entry void TGSelectBox::SetEntry(TTVLVEntry *entry) { fEntry = entry; fTe->SetText(entry->GetTrueName()); fTeAlias->SetText(entry->GetAlias()); fOldAlias = entry->GetAlias(); } //////////////////////////////////////////////////////////////////////////////// /// Insert text in text entry void TGSelectBox::InsertText(const char* text) { Int_t start = fTe->GetCursorPosition(); fTe->InsertText(text, fTe->GetCursorPosition()); fTe->SetCursorPosition(start+strlen(text)); } //////////////////////////////////////////////////////////////////////////////// /// Message interpreter 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; // just to avoid warning on CC compiler break; } return kTRUE; } //////////////////////////////////////////////////////////////////////////////// /// Return true if edited alias is not a leading string of other expression aliases 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; }