//--------------------------------------------------------------------------- #include #pragma hdrstop #include "Common.h" #include "NamedObjs.h" //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- int __fastcall NamedObjectSortProc(void * Item1, void * Item2) { return static_cast(Item1)->Compare(static_cast(Item2)); } //--- TNamedObject ---------------------------------------------------------- __fastcall TNamedObject::TNamedObject(UnicodeString AName) { Name = AName; } //--------------------------------------------------------------------------- void __fastcall TNamedObject::SetName(UnicodeString value) { FHidden = (value.SubString(1, TNamedObjectList::HiddenPrefix.Length()) == TNamedObjectList::HiddenPrefix); FName = value; } //--------------------------------------------------------------------------- int __fastcall TNamedObject::Compare(TNamedObject * Other) { int Result; if (Hidden && !Other->Hidden) { Result = -1; } else if (!Hidden && Other->Hidden) { Result = 1; } else { Result = CompareLogicalText(Name, Other->Name, true); } return Result; } //--------------------------------------------------------------------------- bool __fastcall TNamedObject::IsSameName(const UnicodeString & AName) { return (Name.CompareIC(AName) == 0); } //--------------------------------------------------------------------------- void __fastcall TNamedObject::MakeUniqueIn(TNamedObjectList * List) { // This object can't be item of list, it would create infinite loop if (List && (List->IndexOf(this) == -1)) while (List->FindByName(Name)) { Integer N = 0, P = 0; // shut up // If name already contains number parenthesis remove it (and remember it) if ((Name[Name.Length()] == L')') && ((P = Name.LastDelimiter(L'(')) > 0)) try { N = StrToInt(Name.SubString(P + 1, Name.Length() - P - 1)); Name.Delete(P, Name.Length() - P + 1); Name = Name.TrimRight(); } catch (Exception &) { N = 0; } Name += L" (" + IntToStr(N+1) + L")"; } } //--- TNamedObjectList ------------------------------------------------------ const UnicodeString TNamedObjectList::HiddenPrefix = L"_!_"; //--------------------------------------------------------------------------- __fastcall TNamedObjectList::TNamedObjectList(): TObjectList() { AutoSort = True; FHiddenCount = 0; FControlledAdd = false; } //--------------------------------------------------------------------------- TNamedObject * __fastcall TNamedObjectList::AtObject(Integer Index) { return (TNamedObject *)Items[Index+FHiddenCount]; } //--------------------------------------------------------------------------- void __fastcall TNamedObjectList::Recount() { int i = 0; while ((i < TObjectList::Count) && ((TNamedObject *)Items[i])->Hidden) i++; FHiddenCount = i; } //--------------------------------------------------------------------------- void __fastcall TNamedObjectList::AlphaSort() { Sort(NamedObjectSortProc); Recount(); } //--------------------------------------------------------------------------- int __fastcall TNamedObjectList::Add(TObject * AObject) { int Result; TAutoFlag ControlledAddFlag(FControlledAdd); TNamedObject * NamedObject = static_cast(AObject); // If temporarily not auto-sorting (when loading session list), // keep the hidden objects in front, so that HiddenCount is correct if (!AutoSort && NamedObject->Hidden) { Result = 0; Insert(Result, AObject); FHiddenCount++; } else { Result = TObjectList::Add(AObject); } return Result; } //--------------------------------------------------------------------------- void __fastcall TNamedObjectList::Notify(void *Ptr, TListNotification Action) { if (Action == lnDeleted) { TNamedObject * NamedObject = static_cast(Ptr); if (NamedObject->Hidden && (FHiddenCount >= 0)) { FHiddenCount--; } } TObjectList::Notify(Ptr, Action); if (Action == lnAdded) { if (!FControlledAdd) { FHiddenCount = -1; } if (AutoSort) { AlphaSort(); } } } //--------------------------------------------------------------------------- TNamedObject * __fastcall TNamedObjectList::FindByName(const UnicodeString & Name) { // This should/can be optimized when list is sorted for (Integer Index = 0; Index < CountIncludingHidden; Index++) { // Not using AtObject as we iterate even hidden objects here TNamedObject * NamedObject = static_cast(Items[Index]); if (NamedObject->IsSameName(Name)) { return NamedObject; } } return NULL; } //--------------------------------------------------------------------------- int __fastcall TNamedObjectList::GetCount() { DebugAssert(FHiddenCount >= 0); return TObjectList::Count - FHiddenCount; } //--------------------------------------------------------------------------- int __fastcall TNamedObjectList::GetCountIncludingHidden() { DebugAssert(FHiddenCount >= 0); return TObjectList::Count; }