| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091 | //---------------------------------------------------------------------#include <FormsPCH.h>#pragma hdrstop#include <RemoteFiles.h>#include "LocationProfiles.h"#include "Custom.h"//---------------------------------------------------------------------#pragma link "HistoryComboBox"#pragma link "PngImageList"#pragma resource "*.dfm"//---------------------------------------------------------------------bool __fastcall LocationProfilesDialog(TOpenDirectoryMode Mode,  TOperationSide Side, UnicodeString & LocalDirectory, UnicodeString & RemoteDirectory,  TStrings * LocalDirectories, TStrings * RemoteDirectories, TTerminal * Terminal){  bool Result;  TLocationProfilesDialog * Dialog = new TLocationProfilesDialog(Application);  try  {    Dialog->LocalDirectory = LocalDirectory;    Dialog->RemoteDirectory = RemoteDirectory;    Dialog->OperationSide = Side;    Dialog->Terminal = Terminal;    Dialog->RemoteDirectories = RemoteDirectories;    Dialog->LocalDirectories = LocalDirectories;    Dialog->Mode = Mode;    Result = Dialog->Execute();    if (Result)    {      LocalDirectory = Dialog->LocalDirectory;      RemoteDirectory = Dialog->RemoteDirectory;    }  }  __finally  {    delete Dialog;  }  return Result;}//---------------------------------------------------------------------------//---------------------------------------------------------------------------void __fastcall BookmarkNameValidateName(const UnicodeString Name){  if (Name.IsEmpty() || IsNumber(Name))  {    throw Exception(FMTLOAD(BOOKMARK_INVALID_NAME, (Name)));  }}//---------------------------------------------------------------------------void __fastcall BookmarkFolderValidateName(const UnicodeString Name,  bool AllowEmpty){  if ((!AllowEmpty && Name.IsEmpty()) || Name.Pos(L"\\"))  {    throw Exception(FMTLOAD(BOOKMARK_FOLDER_INVALID_NAME, (Name)));  }}//---------------------------------------------------------------------------//---------------------------------------------------------------------------class TBookmarkNameDialog : public TCustomDialog{public:  __fastcall TBookmarkNameDialog(TStrings * PeerBookmarks, bool AllowShared);  bool __fastcall Execute(UnicodeString & Name, bool & Shared);protected:  virtual void __fastcall DoValidate();private:  TComboBox * NameCombo;  TCheckBox * SharedCheck;};//---------------------------------------------------------------------__fastcall TBookmarkNameDialog::TBookmarkNameDialog(TStrings * PeerBookmarks,    bool AllowShared) :  TCustomDialog(HELP_LOCATION_PROFILE_ADD){  Caption = LoadStr(ADD_BOOKMARK_CAPTION);  NameCombo = new TUIStateAwareComboBox(this);  NameCombo->AutoComplete = false;  NameCombo->DropDownCount = Max(NameCombo->DropDownCount, 16);  AddComboBox(NameCombo, CreateLabel(LoadStr(ADD_BOOKMARK_PROMPT)));  NameCombo->Items = PeerBookmarks;  if (AllowShared)  {    SharedCheck = new TCheckBox(this);    SharedCheck->Caption = LoadStr(ADD_BOOKMARK_SHARED);    AddButtonControl(SharedCheck);  }  else  {    SharedCheck = NULL;  }}//---------------------------------------------------------------------void __fastcall TBookmarkNameDialog::DoValidate(){  if (NameCombo->Text.IsEmpty() || IsNumber(NameCombo->Text))  {    throw Exception(FMTLOAD(BOOKMARK_INVALID_NAME, (NameCombo->Text)));  }  TCustomDialog::DoValidate();}//---------------------------------------------------------------------bool __fastcall TBookmarkNameDialog::Execute(UnicodeString & Name, bool & Shared){  NameCombo->Text = Name;  if (SharedCheck != NULL)  {    SharedCheck->Checked = Shared;  }  bool Result = TCustomDialog::Execute();  if (Result)  {    Name = NameCombo->Text;    if (SharedCheck != NULL)    {      Shared = SharedCheck->Checked;    }  }  return Result;}//---------------------------------------------------------------------------//---------------------------------------------------------------------------class TBookmarkFolderDialog : public TCustomDialog{public:  __fastcall TBookmarkFolderDialog(TStrings * Folders);  bool __fastcall Execute(UnicodeString & Name);protected:  virtual void __fastcall DoValidate();private:  TComboBox * NameCombo;};//---------------------------------------------------------------------__fastcall TBookmarkFolderDialog::TBookmarkFolderDialog(TStrings * Folders) :  TCustomDialog(HELP_LOCATION_PROFILE_MOVE){  Caption = LoadStr(MOVE_BOOKMARK_CAPTION);  NameCombo = new TUIStateAwareComboBox(this);  NameCombo->AutoComplete = false;  AddComboBox(NameCombo, CreateLabel(LoadStr(MOVE_BOOKMARK_PROMPT)));  NameCombo->Items = Folders;}//---------------------------------------------------------------------void __fastcall TBookmarkFolderDialog::DoValidate(){  BookmarkFolderValidateName(NameCombo->Text, true);  TCustomDialog::DoValidate();}//---------------------------------------------------------------------bool __fastcall TBookmarkFolderDialog::Execute(UnicodeString & Name){  NameCombo->Text = Name;  bool Result = TCustomDialog::Execute();  if (Result)  {    Name = NameCombo->Text;  }  return Result;}//---------------------------------------------------------------------//---------------------------------------------------------------------__fastcall TLocationProfilesDialog::TLocationProfilesDialog(TComponent * AOwner):  TForm(AOwner){  FOperationSide = osLocal;  FBookmarkDragSource = NULL;  FTerminal = NULL;  FSessionBookmarkList = new TBookmarkList();  FSharedBookmarkList = new TBookmarkList();  FChanging = false;  FSessionFolders = CreateSortedStringList();  FSharedFolders = CreateSortedStringList();  FSessionScrollOnDragOver = new TTreeViewScrollOnDragOver(SessionProfilesView, true);  FSharedScrollOnDragOver = new TTreeViewScrollOnDragOver(SharedProfilesView, true);  UseSystemSettings(this);  SelectScaledImageList(BookmarkImageList);  SessionProfilesView->Images = TreeViewImageList(BookmarkImageList);  LoadDialogImage(Image, L"Open folder");}//---------------------------------------------------------------------__fastcall TLocationProfilesDialog::~TLocationProfilesDialog(){  SAFE_DESTROY(FSharedScrollOnDragOver);  SAFE_DESTROY(FSessionScrollOnDragOver);  SAFE_DESTROY(FSharedBookmarkList);  SAFE_DESTROY(FSessionBookmarkList);  SAFE_DESTROY(FSharedFolders);  SAFE_DESTROY(FSessionFolders);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::SetLocalDirectory(UnicodeString value){  if (LocalDirectory != value)  {    LocalDirectoryEdit->Text = value;    FindProfile();    UpdateControls();  }}//---------------------------------------------------------------------------UnicodeString __fastcall TLocationProfilesDialog::GetLocalDirectory(){  return ExcludeTrailingBackslash(LocalDirectoryEdit->Text);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::SetRemoteDirectory(UnicodeString value){  if (RemoteDirectory != value)  {    RemoteDirectoryEdit->Text = value;    FindProfile();    UpdateControls();  }}//---------------------------------------------------------------------------UnicodeString __fastcall TLocationProfilesDialog::GetRemoteDirectory(){  return UnixExcludeTrailingBackslash(RemoteDirectoryEdit->Text);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::SetRemoteDirectories(TStrings * value){  RemoteDirectoryEdit->Items = value;}//---------------------------------------------------------------------------TStrings * __fastcall TLocationProfilesDialog::GetRemoteDirectories(){  return RemoteDirectoryEdit->Items;}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::SetLocalDirectories(TStrings * value){  LocalDirectoryEdit->Items = value;}//---------------------------------------------------------------------------TStrings * __fastcall TLocationProfilesDialog::GetLocalDirectories(){  return LocalDirectoryEdit->Items;}//---------------------------------------------------------------------------bool __fastcall TLocationProfilesDialog::ProfileMatch(TTreeNode * Node){  bool Result = false;  if (Node->Data)  {    TBookmark * Bookmark = (TBookmark *)Node->Data;    Result =      (Bookmark->Local == LocalDirectory) &&      (Bookmark->Remote == RemoteDirectory);  }  return Result;}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::FindProfile(TTreeView * ProfilesView){  if ((ProfilesView->Selected == NULL) ||      !ProfileMatch(ProfilesView->Selected))  {    TTreeNode * Match = NULL;    for (int Index = 0; Index < ProfilesView->Items->Count; Index++)    {      TTreeNode * Node = ProfilesView->Items->Item[Index];      if (ProfileMatch(Node))      {        Match = Node;        break;      }    }    if (Match)    {      ProfilesView->Selected = Match;      Match->MakeVisible();    }    else    {      ProfilesView->Selected = NULL;    }  }}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::FindProfile(){  FindProfile(SessionProfilesView);  FindProfile(SharedProfilesView);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ControlChange(TObject * /*Sender*/){  UpdateControls();}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::UpdateProfilesControls(  TTreeView * ProfilesView,  TButton * AddBookmarkButton, TButton * RemoveBookmarkButton,  TButton * RenameBookmarkButton,  TButton * BookmarkMoveToButton,  TButton * ShortCutBookmarkButton,  TButton * UpBookmarkButton, TButton * DownBookmarkButton){  EnableControl(AddBookmarkButton,    !LocalDirectory.IsEmpty() || !RemoteDirectory.IsEmpty());  EnableControl(RemoveBookmarkButton, ProfilesView->Selected);  EnableControl(RenameBookmarkButton, ProfilesView->Selected);  EnableControl(BookmarkMoveToButton, ProfilesView->Selected && ProfilesView->Selected->Data);  if (ShortCutBookmarkButton != NULL)  {    EnableControl(ShortCutBookmarkButton, ProfilesView->Selected && ProfilesView->Selected->Data);  }  EnableControl(UpBookmarkButton, ProfilesView->Selected &&    ProfilesView->Selected->Data && ProfilesView->Selected->getPrevSibling() &&    ProfilesView->Selected->getPrevSibling()->Data);  EnableControl(DownBookmarkButton, ProfilesView->Selected &&    ProfilesView->Selected->Data && ProfilesView->Selected->getNextSibling() &&    ProfilesView->Selected->getNextSibling()->Data);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::UpdateControls(){  EnableControl(OKBtn, !LocalDirectory.IsEmpty() || !RemoteDirectory.IsEmpty());  UpdateProfilesControls(SessionProfilesView,    AddSessionBookmarkButton, RemoveSessionBookmarkButton,    RenameSessionBookmarkButton,  SessionBookmarkMoveToButton, NULL,    UpSessionBookmarkButton, DownSessionBookmarkButton);  UpdateProfilesControls(SharedProfilesView,    AddSharedBookmarkButton, RemoveSharedBookmarkButton,    RenameSharedBookmarkButton, SharedBookmarkMoveToButton,    ShortCutSharedBookmarkButton,    UpSharedBookmarkButton, DownSharedBookmarkButton);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::LoadBookmarks(  TTreeView * ProfilesView, TStringList * Folders, TBookmarkList * BookmarkList,  TBookmarkList * Source){  if (Source != NULL)  {    BookmarkList->Assign(Source);  }  else  {    BookmarkList->Clear();  }  Configuration->Usage->SetMax(L"MaxBookmarks", BookmarkList->Count);  DebugAssert(BookmarkList != NULL);  Folders->Clear();  for (int Index = 0; Index < BookmarkList->Count; Index++)  {    TBookmark * Bookmark = BookmarkList->Bookmarks[Index];    if (!Bookmark->Node.IsEmpty())    {      Folders->Add(Bookmark->Node);    }  }  // WORKAROUND  // TTreeNodes::Clear is noop, when tree does not have a handle yet.  // (what happens here for a tree view on an inactive page)  ProfilesView->HandleNeeded();  ProfilesView->Items->Clear();  for (int Index = 0; Index < Folders->Count; Index++)  {    Folders->Objects[Index] = ProfilesView->Items->Add(NULL, Folders->Strings[Index]);  }  for (int Index = 0; Index < BookmarkList->Count; Index++)  {    TBookmark * Bookmark = BookmarkList->Bookmarks[Index];    TTreeNode * Parent = NULL;    if (!Bookmark->Node.IsEmpty())    {      DebugAssert(Folders->IndexOf(Bookmark->Node) >= 0);      Parent = dynamic_cast<TTreeNode *>(Folders->Objects[Folders->IndexOf(Bookmark->Node)]);    }    ProfilesView->Items->AddChildObject(Parent, BookmarkText(Bookmark), Bookmark);    if ((Parent != NULL) && (Parent->Count == 1))    {      // only now, when folder node has its first child, we can eventually expand it      Parent->Expanded = BookmarkList->NodeOpened[Parent->Text];    }  }}//---------------------------------------------------------------------------bool __fastcall TLocationProfilesDialog::Execute(){  bool Result;  PageControl->ActivePage = GetProfilesSheet();  FBookmarkSelected = false;  Result = (ShowModal() == DefaultResult(this));  if (Terminal)  {    WinConfiguration->Bookmarks[FSessionKey] = FSessionBookmarkList;    WinConfiguration->SharedBookmarks = FSharedBookmarkList;    WinConfiguration->UseSharedBookmarks = (PageControl->ActivePage == SharedProfilesSheet);  }  if (Result)  {    if (FBookmarkSelected)    {      Configuration->Usage->Inc(L"OpenedBookmark");    }    else    {      Configuration->Usage->Inc(L"OpenedPath");    }  }  return Result;}//---------------------------------------------------------------------------TTabSheet * TLocationProfilesDialog::GetProfilesSheet(){  return WinConfiguration->UseSharedBookmarks ? SharedProfilesSheet : SessionProfilesSheet;}//---------------------------------------------------------------------------template<class T>T * GetProfilesObject(TObject * Sender, T * SessionObject, T * SharedObject){  TControl * Control = dynamic_cast<TControl *>(Sender);  DebugAssert(Control != NULL);  switch (abs(Control->Tag))  {    case 1: return SessionObject;    case 2: return SharedObject;    default: DebugFail(); return NULL;  }}//---------------------------------------------------------------------------TBookmarkList * TLocationProfilesDialog::GetBookmarkList(TObject * Sender){  return GetProfilesObject(Sender, FSessionBookmarkList, FSharedBookmarkList);}//---------------------------------------------------------------------------TStringList * TLocationProfilesDialog::GetFolders(TObject * Sender){  #ifdef _DEBUG  DebugAssert(FSessionProfilesViewHandle == SessionProfilesView->Handle);  DebugAssert(FSharedProfilesViewHandle == SharedProfilesView->Handle);  #endif  return GetProfilesObject(Sender, FSessionFolders, FSharedFolders);}//---------------------------------------------------------------------------TTreeView * TLocationProfilesDialog::GetProfilesView(TObject * Sender){  return GetProfilesObject(Sender, SessionProfilesView, SharedProfilesView);}//---------------------------------------------------------------------------TTreeViewScrollOnDragOver * TLocationProfilesDialog::GetScrollOnDragOver(TObject * Sender){  return GetProfilesObject(Sender, FSessionScrollOnDragOver, FSharedScrollOnDragOver);}//---------------------------------------------------------------------------bool __fastcall TLocationProfilesDialog::AddAsBookmark(TObject * Sender, bool Initial){  TBookmarkList * BookmarkList = GetBookmarkList(Sender);  TTreeView * ProfilesView = GetProfilesView(Sender);  DebugAssert(!LocalDirectory.IsEmpty() || !RemoteDirectory.IsEmpty());  bool Result;  UnicodeString BookmarkName;  if ((OperationSide == osLocal && !LocalDirectory.IsEmpty()) ||      RemoteDirectory.IsEmpty())  {    BookmarkName = LocalDirectory;  }  else  {    BookmarkName = RemoteDirectory;  }  TTreeNode * Selected = ProfilesView->Selected;  TBookmark * SelectedBookmark = NULL;  UnicodeString SelectedNode;  if (Selected != NULL)  {    DebugAssert(!Initial);    SelectedBookmark = (TBookmark *)Selected->Data;    if (SelectedBookmark != NULL)    {      SelectedNode = SelectedBookmark->Node;    }    else    {      SelectedNode = Selected->Text;    }  }  TStrings * PeerBookmarks = new TStringList();  try  {    for (int Index = 0; Index < BookmarkList->Count; Index++)    {      TBookmark * Bookmark = BookmarkList->Bookmarks[Index];      if (Bookmark->Node == SelectedNode)      {        PeerBookmarks->Add(Bookmark->Name);      }    }    TBookmarkNameDialog * Dialog = new TBookmarkNameDialog(PeerBookmarks, Initial);    try    {      bool Shared = WinConfiguration->UseSharedBookmarks;      Result = Dialog->Execute(BookmarkName, Shared);      if (Result)      {        if (Initial)        {          WinConfiguration->UseSharedBookmarks = Shared;          PageControl->ActivePage = GetProfilesSheet();          BookmarkList = GetBookmarkList(PageControl->ActivePage);          ProfilesView = GetProfilesView(PageControl->ActivePage);        }        TBookmark * Bookmark = BookmarkList->FindByName(SelectedNode, BookmarkName);        if (Bookmark != NULL)        {          Bookmark->Local = LocalDirectory;          Bookmark->Remote = RemoteDirectory;          for (int Index = 0; Index < ProfilesView->Items->Count; Index++)          {            TTreeNode * Node = ProfilesView->Items->Item[Index];            if (Node->Data == Bookmark)            {              Selected = Node;              break;            }          }        }        else        {          Bookmark = new TBookmark();          Bookmark->Name = BookmarkName;          Bookmark->Local = LocalDirectory;          Bookmark->Remote = RemoteDirectory;          if (SelectedBookmark != NULL)          {            Bookmark->Node = SelectedBookmark->Node;            BookmarkList->InsertBefore(SelectedBookmark, Bookmark);            Selected = ProfilesView->Items->InsertObject(Selected, BookmarkText(Bookmark), Bookmark);          }          else if ((Selected != NULL) && (SelectedBookmark == NULL))          {            // must be a folder            DebugAssert(!Selected->Parent); // more than one level of folders is not supported            Bookmark->Node = Selected->Text;            BookmarkList->Add(Bookmark);            Selected = ProfilesView->Items->AddChildObject(Selected, BookmarkText(Bookmark), Bookmark);          }          else          {            BookmarkList->Add(Bookmark);            Selected = ProfilesView->Items->AddObject(NULL, BookmarkText(Bookmark), Bookmark);          }        }        ProfilesView->Selected = Selected;      }    }    __finally    {      delete Dialog;    }  }  __finally  {    delete PeerBookmarks;  }  UpdateControls();  return Result;}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::AddBookmarkButtonClick(TObject * Sender){  AddAsBookmark(Sender, false);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::RemoveBookmark(TObject * Sender){  TBookmarkList * BookmarkList = GetBookmarkList(Sender);  TTreeView * ProfilesView = GetProfilesView(Sender);  TStringList * Folders = GetFolders(Sender);  DebugAssert(ProfilesView->Selected);  TTreeNode * Node = ProfilesView->Selected;  if (Node->Data)  {    BookmarkList->Delete((TBookmark *)Node->Data);    TTreeNode * ParentNode = Node->Parent;    Node->Delete();    if (ParentNode && !ParentNode->Count)    {      DebugAssert(Folders->IndexOfObject(ParentNode) >= 0);      Folders->Delete(Folders->IndexOfObject(ParentNode));      ParentNode->Delete();    }  }  else  {    UnicodeString Message = MainInstructions(LoadStr(DELETE_BOOKMARK_FOLDER));    if (MessageDialog(Message, qtConfirmation,          qaYes | qaNo, HELP_LOCATION_PROFILE_DELETE) == qaYes)    {      DebugAssert(Node->Count);      for (int i = 0; i < Node->Count; i++)      {        BookmarkList->Delete((TBookmark *)Node->Item[i]->Data);      }      DebugAssert(Folders->IndexOfObject(Node) >= 0);      Folders->Delete(Folders->IndexOfObject(Node));      Node->Delete();    }  }  UpdateControls();}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::RemoveBookmarkButtonClick(TObject * Sender){  RemoveBookmark(Sender);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::BookmarkMove(TObject * Sender,  TTreeNode * Source, TTreeNode * Dest){  TBookmarkList * BookmarkList = GetBookmarkList(Sender);  TTreeView * ProfilesView = GetProfilesView(Sender);  TStringList * Folders = GetFolders(Sender);  DebugAssert(Source && Source->Data);  TBookmark * Bookmark = (TBookmark *)Source->Data;  TTreeNode * PrevFolderNode = Source->Parent;  if (!Dest || !Dest->Data)  {    Bookmark->Node = Dest ? Dest->Text : UnicodeString();    BookmarkList->MoveTo(BookmarkList->Bookmarks[BookmarkList->Count - 1],      Bookmark, false);    ProfilesView->Selected->MoveTo(Dest, naAddChild);  }  else  {    TBookmark * DestBookmark = (TBookmark *)Dest->Data;    Bookmark->Node = DestBookmark->Node;    BookmarkList->MoveTo(DestBookmark, Bookmark,      Source->AbsoluteIndex > Dest->AbsoluteIndex);    if (Source->AbsoluteIndex > Dest->AbsoluteIndex)    {      Source->MoveTo(Dest, naInsert);    }    else if (Dest->getNextSibling() != NULL)    {      Source->MoveTo(Dest->getNextSibling(), naInsert);    }    else    {      Source->MoveTo(Dest, naAdd);    }  }  if (PrevFolderNode && !PrevFolderNode->Count)  {    DebugAssert(Folders->IndexOfObject(PrevFolderNode) >= 0);    Folders->Delete(Folders->IndexOfObject(PrevFolderNode));    PrevFolderNode->Delete();  }  Source->MakeVisible();  UpdateControls();}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::BookmarkButtonClick(TObject * Sender){  TControl * Control = dynamic_cast<TControl *>(Sender);  TTreeNode * Node = GetProfilesView(Sender)->Selected;  DebugAssert(Node);  DebugAssert(Node->Data);  TTreeNode * TargetNode;  if (Control->Tag < 0)  {    TargetNode = Node->getPrevSibling();    DebugAssert(TargetNode);  }  else  {    TargetNode = Node->getNextSibling();  }  BookmarkMove(Sender, Node, TargetNode ? TargetNode : Node->Parent);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewStartDrag(  TObject * Sender, TDragObject *& /*DragObject*/){  TTreeView * ProfilesView = GetProfilesView(Sender);  if (!ProfilesView->Selected->Data)  {    Abort();  }  FBookmarkDragSource = ProfilesView->Selected;  GetScrollOnDragOver(Sender)->StartDrag();}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewDragOver(  TObject * Sender, TObject * Source, int X, int Y,  TDragState /*State*/, bool & Accept){  TTreeView * ProfilesView = GetProfilesView(Sender);  if (Source == ProfilesView)  {    Accept = (ProfilesView->DropTarget != NULL) &&      (FBookmarkDragSource != ProfilesView->DropTarget);    GetScrollOnDragOver(Sender)->DragOver(TPoint(X, Y));  }}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewDragDrop(  TObject * Sender, TObject * Source, int /*X*/, int /*Y*/){  TTreeView * ProfilesView = GetProfilesView(Sender);  if ((Source == ProfilesView) && (ProfilesView->DropTarget != NULL) &&      (FBookmarkDragSource != ProfilesView->DropTarget))  {    DebugAssert(FBookmarkDragSource);    TTreeNode * Target = ProfilesView->DropTarget;    BookmarkMove(Sender, FBookmarkDragSource, Target);    FBookmarkDragSource = NULL;  }}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewDblClick(TObject * Sender){  TTreeView * ProfilesView = GetProfilesView(Sender);  TPoint P = ProfilesView->ScreenToClient(Mouse->CursorPos);  TTreeNode * Node = ProfilesView->GetNodeAt(P.x, P.y);  if (OKBtn->Enabled && Node && Node->Data && Node->Selected)  {    ModalResult = DefaultResult(this);  }}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::FormShow(TObject * /*Sender*/){  if (DebugAlwaysTrue(Terminal != NULL))  {    // cache session key, in case terminal is closed while the window is open    FSessionKey = Terminal->SessionData->SessionKey;    // WORKAROUND    // Has to load this only now (not in Execute before ShowModal),    // when the trees are finally (re)created,    // otherwise the references in *Folders would be invalid already    LoadBookmarks(SessionProfilesView, FSessionFolders, FSessionBookmarkList, WinConfiguration->Bookmarks[FSessionKey]);    LoadBookmarks(SharedProfilesView, FSharedFolders, FSharedBookmarkList, WinConfiguration->SharedBookmarks);    #ifdef _DEBUG    FSessionProfilesViewHandle = SessionProfilesView->Handle;    FSharedProfilesViewHandle = SharedProfilesView->Handle;    #endif  }  if (Mode == odAddBookmark)  {    AddAsBookmark(GetProfilesSheet(), true);  }  InstallPathWordBreakProc(LocalDirectoryEdit);  InstallPathWordBreakProc(RemoteDirectoryEdit);  FindProfile();  if (OperationSide == osLocal)  {    ActiveControl = LocalDirectoryEdit;  }  else  {    ActiveControl = RemoteDirectoryEdit;  }  UpdateControls();}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewKeyDown(TObject * Sender,  WORD & Key, TShiftState /*Shift*/){  TTreeView * ProfilesView = GetProfilesView(Sender);  if (!ProfilesView->IsEditing())  {    if ((ProfilesView->Selected != NULL) && (Key == VK_DELETE))    {      RemoveBookmark(Sender);      Key = 0;    }    else if ((ProfilesView->Selected != NULL) && (Key == VK_F2))    {      RenameBookmark(Sender);      Key = 0;    }  }}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::DirectoryEditChange(TObject * /*Sender*/){  if (!FChanging)  {    FindProfile();    UpdateControls();    FBookmarkSelected = false;  }}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewChange(  TObject * /*Sender*/, TTreeNode * Node){  if (Node && Node->Data)  {    DebugAssert(!FChanging);    FChanging = true;    try    {      LocalDirectoryEdit->Text = ((TBookmark *)Node->Data)->Local;      RemoteDirectoryEdit->Text = ((TBookmark *)Node->Data)->Remote;    }    __finally    {      FChanging = false;    }    // try to locate the same profile in the other set    FindProfile();    FBookmarkSelected = true;  }  UpdateControls();}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::BookmarkMoveToButtonClick(TObject * Sender){  TTreeView * ProfilesView = GetProfilesView(Sender);  TStringList * Folders = GetFolders(Sender);  DebugAssert(ProfilesView->Selected->Data);  TBookmark * Bookmark = (TBookmark *)ProfilesView->Selected->Data;  TBookmarkFolderDialog * Dialog = new TBookmarkFolderDialog(Folders);  try  {    UnicodeString NodeName = Bookmark->Node;    if (Dialog->Execute(NodeName) &&        (NodeName != Bookmark->Node))    {      TTreeNode * FolderNode;      int I = Folders->IndexOf(NodeName);      if (NodeName.IsEmpty())      {        FolderNode = NULL;      }      else if (I >= 0)      {        FolderNode = dynamic_cast<TTreeNode *>(Folders->Objects[I]);        DebugAssert(FolderNode);      }      else      {        I = Folders->Add(NodeName);        TTreeNode * NextNode;        // duplicated in RenameButtonClick()        if (I < Folders->Count-1)        {          NextNode = dynamic_cast<TTreeNode *>(Folders->Objects[I+1]);          DebugAssert(NextNode);        }        else if (Folders->Count > 1)        {          NextNode = (dynamic_cast<TTreeNode *>(Folders->Objects[I-1]))->getNextSibling();        }        else        {          DebugAssert(ProfilesView->Items->Count);          NextNode = ProfilesView->Items->Item[0];        }        FolderNode = ProfilesView->Items->Insert(NextNode, NodeName);        DebugAssert(FolderNode);        Folders->Objects[I] = FolderNode;      }      BookmarkMove(Sender, ProfilesView->Selected, FolderNode);    }  }  __finally  {    delete Dialog;  }}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::RenameBookmark(TObject * Sender){  TTreeView * ProfilesView = GetProfilesView(Sender);  DebugAssert(ProfilesView->Selected != NULL);  if (ProfilesView->Selected != NULL)  {    ProfilesView->SetFocus();    ProfilesView->Selected->EditText();  }}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::RenameBookmarkButtonClick(TObject * Sender){  RenameBookmark(Sender);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewGetImageIndex(      TObject * /*Sender*/, TTreeNode * Node){  Node->ImageIndex = Node->Data ? 0 : (Node->Expanded ? 1 : 2);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewGetSelectedIndex(      TObject * /*Sender*/, TTreeNode * Node){  Node->SelectedIndex = Node->Data ? 0 : (Node->Expanded ? 1 : 2);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::LocalDirectoryBrowseButtonClick(  TObject * /*Sender*/){  SelectDirectoryForEdit(LocalDirectoryEdit);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::SwitchButtonClick(TObject * /*Sender*/){  WinConfiguration->UseLocationProfiles = false;}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::HelpButtonClick(TObject * /*Sender*/){  FormHelp(this);}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewCollapsed(  TObject * Sender, TTreeNode * Node){  DebugAssert(Node != NULL);  DebugAssert(Node->Data == NULL);  GetBookmarkList(Sender)->NodeOpened[Node->Text] = false;}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewExpanded(  TObject * Sender, TTreeNode * Node){  DebugAssert(Node != NULL);  DebugAssert(Node->Data == NULL);  GetBookmarkList(Sender)->NodeOpened[Node->Text] = true;}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewEdited(  TObject * Sender, TTreeNode * Node, UnicodeString & S){  TTreeView * ProfilesView = GetProfilesView(Sender);  TStringList * Folders = GetFolders(Sender);  if (Node->Data != NULL)  {    BookmarkNameValidateName(S);    // raises exception in case of duplicate name??    ((TBookmark *)Node->Data)->Name = S;  }  else  {    BookmarkFolderValidateName(S, false);    if (S.IsEmpty())    {      throw Exception(FMTLOAD(BOOKMARK_FOLDER_INVALID_NAME, (S)));    }    if ((Folders->IndexOf(S) >= 0) && AnsiCompareText(S, Node->Text))    {      throw Exception(FMTLOAD(DUPLICATE_BOOKMARK_FOLDER, (S)));    }    DebugAssert(Node->Count);    Folders->Delete(Folders->IndexOf(Node->Text));    int I = Folders->AddObject(S, Node);    TTreeNode * NextNode;    // duplicated in MoveToButtonClick()    if (I < Folders->Count-1)    {      NextNode = dynamic_cast<TTreeNode *>(Folders->Objects[I+1]);      DebugAssert(NextNode);    }    else if (Folders->Count > 1)    {      NextNode = (dynamic_cast<TTreeNode *>(Folders->Objects[I-1]))->getNextSibling();    }    else    {      DebugAssert(ProfilesView->Items->Count);      NextNode = ProfilesView->Items->Item[0];    }    if (NextNode != Node)    {      Node->MoveTo(NextNode, NextNode ? naInsert : naAddChild);    }    for (int i = 0; i < Node->Count; i++)    {      ((TBookmark *)Node->Item[i]->Data)->Node = S;    }    Node->MakeVisible();  }}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewEditing(  TObject * /*Sender*/, TTreeNode * /*Node*/, bool & /*AllowEdit*/){  OKBtn->Default = false;  CancelBtn->Cancel = false;}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::UpdateActions(){  TForm::UpdateActions();  if ((!OKBtn->Default || !CancelBtn->Cancel) &&      !GetProfilesView(PageControl->ActivePage)->IsEditing())  {    OKBtn->Default = true;    CancelBtn->Cancel = true;  }}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ProfilesViewEndDrag(  TObject * Sender, TObject * /*Target*/, int /*X*/, int /*Y*/){  GetScrollOnDragOver(Sender)->EndDrag();}//---------------------------------------------------------------------------void __fastcall TLocationProfilesDialog::ShortCutBookmarkButtonClick(  TObject * Sender){  TBookmarkList * BookmarkList = GetBookmarkList(Sender);  TTreeView * ProfilesView = GetProfilesView(Sender);  DebugAssert(ProfilesView->Selected != NULL);  TTreeNode * Node = ProfilesView->Selected;  DebugAssert(Node->Data != NULL);  TBookmark * Bookmark = static_cast<TBookmark *>(Node->Data);  TShortCuts ShortCuts;  WinConfiguration->CustomCommandShortCuts(ShortCuts);  BookmarkList->ShortCuts(ShortCuts);  TShortCut ShortCut = Bookmark->ShortCut;  if (DoShortCutDialog(ShortCut, ShortCuts, HelpKeyword))  {    Bookmark->ShortCut = ShortCut;    Node->Text = BookmarkText(Bookmark);    UpdateControls();  }}//---------------------------------------------------------------------------UnicodeString __fastcall TLocationProfilesDialog::BookmarkText(TBookmark * Bookmark){  UnicodeString Result = Bookmark->Name;  if (!Result.IsEmpty() && (Bookmark->ShortCut != 0))  {    Result = FORMAT(L"%s (%s)", (Result, ShortCutToText(Bookmark->ShortCut)));  }  return Result;}//---------------------------------------------------------------------------
 |