LocationProfiles.cpp 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. //---------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <CoreMain.h>
  5. #include <Configuration.h>
  6. #include <RemoteFiles.h>
  7. #include <VCLCommon.h>
  8. #include <TextsWin.h>
  9. #include <HelpWin.h>
  10. #include <Common.h>
  11. #include "LocationProfiles.h"
  12. #include "WinConfiguration.h"
  13. #include "Custom.h"
  14. //---------------------------------------------------------------------
  15. #pragma link "IEComboBox"
  16. #ifndef NO_RESOURCES
  17. #pragma resource "*.dfm"
  18. #endif
  19. //---------------------------------------------------------------------
  20. bool __fastcall LocationProfilesDialog(TOpenDirectoryMode Mode,
  21. TOperationSide Side, UnicodeString & LocalDirectory, UnicodeString & RemoteDirectory,
  22. TStrings * LocalDirectories, TStrings * RemoteDirectories, TTerminal * Terminal)
  23. {
  24. bool Result;
  25. TLocationProfilesDialog * Dialog = new TLocationProfilesDialog(Application);
  26. try
  27. {
  28. Dialog->LocalDirectory = LocalDirectory;
  29. Dialog->RemoteDirectory = RemoteDirectory;
  30. Dialog->OperationSide = Side;
  31. Dialog->Terminal = Terminal;
  32. Dialog->RemoteDirectories = RemoteDirectories;
  33. Dialog->LocalDirectories = LocalDirectories;
  34. Dialog->Mode = Mode;
  35. Result = Dialog->Execute();
  36. if (Result)
  37. {
  38. LocalDirectory = Dialog->LocalDirectory;
  39. RemoteDirectory = Dialog->RemoteDirectory;
  40. }
  41. }
  42. __finally
  43. {
  44. delete Dialog;
  45. }
  46. return Result;
  47. }
  48. //---------------------------------------------------------------------------
  49. //---------------------------------------------------------------------------
  50. void __fastcall BookmarkNameValidateName(const UnicodeString Name)
  51. {
  52. if (Name.IsEmpty() || IsNumber(Name))
  53. {
  54. throw Exception(FMTLOAD(BOOKMARK_INVALID_NAME, (Name)));
  55. }
  56. }
  57. //---------------------------------------------------------------------------
  58. void __fastcall BookmarkFolderValidateName(const UnicodeString Name,
  59. bool AllowEmpty)
  60. {
  61. if ((!AllowEmpty && Name.IsEmpty()) || Name.Pos(L"\\"))
  62. {
  63. throw Exception(FMTLOAD(BOOKMARK_FOLDER_INVALID_NAME, (Name)));
  64. }
  65. }
  66. //---------------------------------------------------------------------------
  67. //---------------------------------------------------------------------------
  68. class TBookmarkNameDialog : public TCustomDialog
  69. {
  70. public:
  71. __fastcall TBookmarkNameDialog(TStrings * PeerBookmarks, bool AllowShared);
  72. bool __fastcall Execute(UnicodeString & Name, bool & Shared);
  73. protected:
  74. virtual void __fastcall DoValidate();
  75. private:
  76. TComboBox * NameCombo;
  77. TCheckBox * SharedCheck;
  78. };
  79. //---------------------------------------------------------------------
  80. __fastcall TBookmarkNameDialog::TBookmarkNameDialog(TStrings * PeerBookmarks,
  81. bool AllowShared) :
  82. TCustomDialog(HELP_LOCATION_PROFILE_ADD)
  83. {
  84. Caption = LoadStr(ADD_BOOKMARK_CAPTION);
  85. NameCombo = new TComboBox(this);
  86. NameCombo->AutoComplete = false;
  87. AddComboBox(NameCombo, CreateLabel(LoadStr(ADD_BOOKMARK_PROMPT)));
  88. NameCombo->Items = PeerBookmarks;
  89. if (AllowShared)
  90. {
  91. SharedCheck = new TCheckBox(this);
  92. SharedCheck->Caption = LoadStr(ADD_BOOKMARK_SHARED);
  93. AddButtonControl(SharedCheck);
  94. }
  95. else
  96. {
  97. SharedCheck = NULL;
  98. }
  99. }
  100. //---------------------------------------------------------------------
  101. void __fastcall TBookmarkNameDialog::DoValidate()
  102. {
  103. if (NameCombo->Text.IsEmpty() || IsNumber(NameCombo->Text))
  104. {
  105. throw Exception(FMTLOAD(BOOKMARK_INVALID_NAME, (NameCombo->Text)));
  106. }
  107. TCustomDialog::DoValidate();
  108. }
  109. //---------------------------------------------------------------------
  110. bool __fastcall TBookmarkNameDialog::Execute(UnicodeString & Name, bool & Shared)
  111. {
  112. NameCombo->Text = Name;
  113. if (SharedCheck != NULL)
  114. {
  115. SharedCheck->Checked = Shared;
  116. }
  117. bool Result = TCustomDialog::Execute();
  118. if (Result)
  119. {
  120. Name = NameCombo->Text;
  121. if (SharedCheck != NULL)
  122. {
  123. Shared = SharedCheck->Checked;
  124. }
  125. }
  126. return Result;
  127. }
  128. //---------------------------------------------------------------------------
  129. //---------------------------------------------------------------------------
  130. class TBookmarkFolderDialog : public TCustomDialog
  131. {
  132. public:
  133. __fastcall TBookmarkFolderDialog(TStrings * Folders);
  134. bool __fastcall Execute(UnicodeString & Name);
  135. protected:
  136. virtual void __fastcall DoValidate();
  137. private:
  138. TComboBox * NameCombo;
  139. };
  140. //---------------------------------------------------------------------
  141. __fastcall TBookmarkFolderDialog::TBookmarkFolderDialog(TStrings * Folders) :
  142. TCustomDialog(HELP_LOCATION_PROFILE_MOVE)
  143. {
  144. Caption = LoadStr(MOVE_BOOKMARK_CAPTION);
  145. NameCombo = new TComboBox(this);
  146. NameCombo->AutoComplete = false;
  147. AddComboBox(NameCombo, CreateLabel(LoadStr(MOVE_BOOKMARK_PROMPT)));
  148. NameCombo->Items = Folders;
  149. }
  150. //---------------------------------------------------------------------
  151. void __fastcall TBookmarkFolderDialog::DoValidate()
  152. {
  153. BookmarkFolderValidateName(NameCombo->Text, true);
  154. TCustomDialog::DoValidate();
  155. }
  156. //---------------------------------------------------------------------
  157. bool __fastcall TBookmarkFolderDialog::Execute(UnicodeString & Name)
  158. {
  159. NameCombo->Text = Name;
  160. bool Result = TCustomDialog::Execute();
  161. if (Result)
  162. {
  163. Name = NameCombo->Text;
  164. }
  165. return Result;
  166. }
  167. //---------------------------------------------------------------------
  168. //---------------------------------------------------------------------
  169. __fastcall TLocationProfilesDialog::TLocationProfilesDialog(TComponent * AOwner):
  170. TForm(AOwner)
  171. {
  172. FOperationSide = osLocal;
  173. FBookmarkDragSource = NULL;
  174. FTerminal = NULL;
  175. FSessionBookmarkList = new TBookmarkList();
  176. FSharedBookmarkList = new TBookmarkList();
  177. FChanging = false;
  178. FSessionFolders = new TStringList;
  179. FSessionFolders->CaseSensitive = false;
  180. FSessionFolders->Sorted = true;
  181. FSessionFolders->Duplicates = dupIgnore;
  182. FSharedFolders = new TStringList;
  183. FSharedFolders->CaseSensitive = false;
  184. FSharedFolders->Sorted = true;
  185. FSharedFolders->Duplicates = dupIgnore;
  186. FSessionScrollOnDragOver = new TTreeViewScrollOnDragOver(SessionProfilesView, true);
  187. FSharedScrollOnDragOver = new TTreeViewScrollOnDragOver(SharedProfilesView, true);
  188. UseSystemSettings(this);
  189. InstallPathWordBreakProc(LocalDirectoryEdit);
  190. InstallPathWordBreakProc(RemoteDirectoryEdit);
  191. }
  192. //---------------------------------------------------------------------
  193. __fastcall TLocationProfilesDialog::~TLocationProfilesDialog()
  194. {
  195. SAFE_DESTROY(FSharedScrollOnDragOver);
  196. SAFE_DESTROY(FSessionScrollOnDragOver);
  197. SAFE_DESTROY(FSharedBookmarkList);
  198. SAFE_DESTROY(FSessionBookmarkList);
  199. SAFE_DESTROY(FSharedFolders);
  200. SAFE_DESTROY(FSessionFolders);
  201. }
  202. //---------------------------------------------------------------------------
  203. void __fastcall TLocationProfilesDialog::SetLocalDirectory(UnicodeString value)
  204. {
  205. if (LocalDirectory != value)
  206. {
  207. LocalDirectoryEdit->Text = value;
  208. FindProfile();
  209. UpdateControls();
  210. }
  211. }
  212. //---------------------------------------------------------------------------
  213. UnicodeString __fastcall TLocationProfilesDialog::GetLocalDirectory()
  214. {
  215. return ExcludeTrailingBackslash(LocalDirectoryEdit->Text);
  216. }
  217. //---------------------------------------------------------------------------
  218. void __fastcall TLocationProfilesDialog::SetRemoteDirectory(UnicodeString value)
  219. {
  220. if (RemoteDirectory != value)
  221. {
  222. RemoteDirectoryEdit->Text = value;
  223. FindProfile();
  224. UpdateControls();
  225. }
  226. }
  227. //---------------------------------------------------------------------------
  228. UnicodeString __fastcall TLocationProfilesDialog::GetRemoteDirectory()
  229. {
  230. return UnixExcludeTrailingBackslash(RemoteDirectoryEdit->Text);
  231. }
  232. //---------------------------------------------------------------------------
  233. void __fastcall TLocationProfilesDialog::SetRemoteDirectories(TStrings * value)
  234. {
  235. RemoteDirectoryEdit->Items = value;
  236. }
  237. //---------------------------------------------------------------------------
  238. TStrings * __fastcall TLocationProfilesDialog::GetRemoteDirectories()
  239. {
  240. return RemoteDirectoryEdit->Items;
  241. }
  242. //---------------------------------------------------------------------------
  243. void __fastcall TLocationProfilesDialog::SetLocalDirectories(TStrings * value)
  244. {
  245. LocalDirectoryEdit->Items = value;
  246. }
  247. //---------------------------------------------------------------------------
  248. TStrings * __fastcall TLocationProfilesDialog::GetLocalDirectories()
  249. {
  250. return LocalDirectoryEdit->Items;
  251. }
  252. //---------------------------------------------------------------------------
  253. bool __fastcall TLocationProfilesDialog::ProfileMatch(TTreeNode * Node)
  254. {
  255. bool Result = false;
  256. if (Node->Data)
  257. {
  258. TBookmark * Bookmark = (TBookmark *)Node->Data;
  259. Result =
  260. (Bookmark->Local == LocalDirectory) &&
  261. (Bookmark->Remote == RemoteDirectory);
  262. }
  263. return Result;
  264. }
  265. //---------------------------------------------------------------------------
  266. void __fastcall TLocationProfilesDialog::FindProfile(TTreeView * ProfilesView)
  267. {
  268. if ((ProfilesView->Selected == NULL) ||
  269. !ProfileMatch(ProfilesView->Selected))
  270. {
  271. TTreeNode * Match = NULL;
  272. for (int Index = 0; Index < ProfilesView->Items->Count; Index++)
  273. {
  274. TTreeNode * Node = ProfilesView->Items->Item[Index];
  275. if (ProfileMatch(Node))
  276. {
  277. Match = Node;
  278. break;
  279. }
  280. }
  281. if (Match)
  282. {
  283. ProfilesView->Selected = Match;
  284. Match->MakeVisible();
  285. }
  286. else
  287. {
  288. ProfilesView->Selected = NULL;
  289. }
  290. }
  291. }
  292. //---------------------------------------------------------------------------
  293. void __fastcall TLocationProfilesDialog::FindProfile()
  294. {
  295. FindProfile(SessionProfilesView);
  296. FindProfile(SharedProfilesView);
  297. }
  298. //---------------------------------------------------------------------------
  299. void __fastcall TLocationProfilesDialog::ControlChange(TObject * /*Sender*/)
  300. {
  301. UpdateControls();
  302. }
  303. //---------------------------------------------------------------------------
  304. void __fastcall TLocationProfilesDialog::UpdateProfilesControls(
  305. TTreeView * ProfilesView,
  306. TButton * AddBookmarkButton, TButton * RemoveBookmarkButton,
  307. TButton * RenameBookmarkButton, TButton * BookmarkMoveToButton,
  308. TButton * ShortCutBookmarkButton,
  309. TButton * UpBookmarkButton, TButton * DownBookmarkButton)
  310. {
  311. EnableControl(AddBookmarkButton,
  312. !LocalDirectory.IsEmpty() || !RemoteDirectory.IsEmpty());
  313. EnableControl(RemoveBookmarkButton, ProfilesView->Selected);
  314. EnableControl(RenameBookmarkButton, ProfilesView->Selected);
  315. EnableControl(BookmarkMoveToButton, ProfilesView->Selected && ProfilesView->Selected->Data);
  316. if (ShortCutBookmarkButton != NULL)
  317. {
  318. EnableControl(ShortCutBookmarkButton, ProfilesView->Selected && ProfilesView->Selected->Data);
  319. }
  320. EnableControl(UpBookmarkButton, ProfilesView->Selected &&
  321. ProfilesView->Selected->Data && ProfilesView->Selected->getPrevSibling() &&
  322. ProfilesView->Selected->getPrevSibling()->Data);
  323. EnableControl(DownBookmarkButton, ProfilesView->Selected &&
  324. ProfilesView->Selected->Data && ProfilesView->Selected->getNextSibling() &&
  325. ProfilesView->Selected->getNextSibling()->Data);
  326. }
  327. //---------------------------------------------------------------------------
  328. void __fastcall TLocationProfilesDialog::UpdateControls()
  329. {
  330. EnableControl(OKBtn, !LocalDirectory.IsEmpty() || !RemoteDirectory.IsEmpty());
  331. UpdateProfilesControls(SessionProfilesView,
  332. AddSessionBookmarkButton, RemoveSessionBookmarkButton,
  333. RenameSessionBookmarkButton, SessionBookmarkMoveToButton, NULL,
  334. UpSessionBookmarkButton, DownSessionBookmarkButton);
  335. UpdateProfilesControls(SharedProfilesView,
  336. AddSharedBookmarkButton, RemoveSharedBookmarkButton,
  337. RenameSharedBookmarkButton, SharedBookmarkMoveToButton,
  338. ShortCutSharedBookmarkButton,
  339. UpSharedBookmarkButton, DownSharedBookmarkButton);
  340. }
  341. //---------------------------------------------------------------------------
  342. void __fastcall TLocationProfilesDialog::LoadBookmarks(
  343. TTreeView * ProfilesView, TStringList * Folders, TBookmarkList * BookmarkList,
  344. TBookmarkList * Source)
  345. {
  346. if (Source != NULL)
  347. {
  348. BookmarkList->Assign(Source);
  349. }
  350. else
  351. {
  352. BookmarkList->Clear();
  353. }
  354. Configuration->Usage->SetMax(L"MaxBookmarks", BookmarkList->Count);
  355. assert(BookmarkList != NULL);
  356. Folders->Clear();
  357. for (int Index = 0; Index < BookmarkList->Count; Index++)
  358. {
  359. TBookmark * Bookmark = BookmarkList->Bookmarks[Index];
  360. if (!Bookmark->Node.IsEmpty())
  361. {
  362. Folders->Add(Bookmark->Node);
  363. }
  364. }
  365. ProfilesView->Items->Clear();
  366. for (int Index = 0; Index < Folders->Count; Index++)
  367. {
  368. Folders->Objects[Index] = ProfilesView->Items->Add(NULL, Folders->Strings[Index]);
  369. }
  370. for (int Index = 0; Index < BookmarkList->Count; Index++)
  371. {
  372. TBookmark * Bookmark = BookmarkList->Bookmarks[Index];
  373. TTreeNode * Parent = NULL;
  374. if (!Bookmark->Node.IsEmpty())
  375. {
  376. assert(Folders->IndexOf(Bookmark->Node) >= 0);
  377. Parent = dynamic_cast<TTreeNode *>(Folders->Objects[Folders->IndexOf(Bookmark->Node)]);
  378. }
  379. ProfilesView->Items->AddChildObject(Parent, BookmarkText(Bookmark), Bookmark);
  380. if ((Parent != NULL) && (Parent->Count == 1))
  381. {
  382. // only now, when folder node has its first child, we can eventually expand it
  383. Parent->Expanded = BookmarkList->NodeOpened[Parent->Text];
  384. }
  385. }
  386. }
  387. //---------------------------------------------------------------------------
  388. bool __fastcall TLocationProfilesDialog::Execute()
  389. {
  390. bool Result;
  391. UnicodeString SessionKey;
  392. if (Terminal)
  393. {
  394. // cache session key, in case terminal is closed while the window is open
  395. SessionKey = Terminal->SessionData->SessionKey;
  396. LoadBookmarks(SessionProfilesView, FSessionFolders, FSessionBookmarkList, WinConfiguration->Bookmarks[SessionKey]);
  397. LoadBookmarks(SharedProfilesView, FSharedFolders, FSharedBookmarkList, WinConfiguration->SharedBookmarks);
  398. }
  399. if (Mode == odAddBookmark)
  400. {
  401. AddAsBookmark(GetProfilesSheet(), true);
  402. }
  403. PageControl->ActivePage = GetProfilesSheet();
  404. Result = (ShowModal() == mrOk);
  405. if (Terminal)
  406. {
  407. WinConfiguration->Bookmarks[SessionKey] = FSessionBookmarkList;
  408. WinConfiguration->SharedBookmarks = FSharedBookmarkList;
  409. WinConfiguration->UseSharedBookmarks = (PageControl->ActivePage == SharedProfilesSheet);
  410. }
  411. return Result;
  412. }
  413. //---------------------------------------------------------------------------
  414. TTabSheet * TLocationProfilesDialog::GetProfilesSheet()
  415. {
  416. return WinConfiguration->UseSharedBookmarks ? SharedProfilesSheet : SessionProfilesSheet;
  417. }
  418. //---------------------------------------------------------------------------
  419. template<class T>
  420. typename T * GetProfilesObject(TObject * Sender, T * SessionObject, T * SharedObject)
  421. {
  422. TControl * Control = dynamic_cast<TControl *>(Sender);
  423. assert(Control != NULL);
  424. switch (abs(Control->Tag))
  425. {
  426. case 1: return SessionObject;
  427. case 2: return SharedObject;
  428. default: assert(false); return NULL;
  429. }
  430. }
  431. //---------------------------------------------------------------------------
  432. TBookmarkList * TLocationProfilesDialog::GetBookmarkList(TObject * Sender)
  433. {
  434. return GetProfilesObject(Sender, FSessionBookmarkList, FSharedBookmarkList);
  435. }
  436. //---------------------------------------------------------------------------
  437. TStringList * TLocationProfilesDialog::GetFolders(TObject * Sender)
  438. {
  439. return GetProfilesObject(Sender, FSessionFolders, FSharedFolders);
  440. }
  441. //---------------------------------------------------------------------------
  442. TTreeView * TLocationProfilesDialog::GetProfilesView(TObject * Sender)
  443. {
  444. return GetProfilesObject(Sender, SessionProfilesView, SharedProfilesView);
  445. }
  446. //---------------------------------------------------------------------------
  447. TTreeViewScrollOnDragOver * TLocationProfilesDialog::GetScrollOnDragOver(TObject * Sender)
  448. {
  449. return GetProfilesObject(Sender, FSessionScrollOnDragOver, FSharedScrollOnDragOver);
  450. }
  451. //---------------------------------------------------------------------------
  452. bool __fastcall TLocationProfilesDialog::AddAsBookmark(TObject * Sender, bool Initial)
  453. {
  454. TBookmarkList * BookmarkList = GetBookmarkList(Sender);
  455. TTreeView * ProfilesView = GetProfilesView(Sender);
  456. assert(!LocalDirectory.IsEmpty() || !RemoteDirectory.IsEmpty());
  457. bool Result;
  458. UnicodeString BookmarkName;
  459. if ((OperationSide == osLocal && !LocalDirectory.IsEmpty()) ||
  460. RemoteDirectory.IsEmpty())
  461. {
  462. BookmarkName = LocalDirectory;
  463. }
  464. else
  465. {
  466. BookmarkName = RemoteDirectory;
  467. }
  468. TTreeNode * Selected = ProfilesView->Selected;
  469. TBookmark * SelectedBookmark = NULL;
  470. UnicodeString SelectedNode;
  471. if (Selected != NULL)
  472. {
  473. assert(!Initial);
  474. SelectedBookmark = (TBookmark *)Selected->Data;
  475. if (SelectedBookmark != NULL)
  476. {
  477. SelectedNode = SelectedBookmark->Node;
  478. }
  479. else
  480. {
  481. SelectedNode = Selected->Text;
  482. }
  483. }
  484. TStrings * PeerBookmarks = new TStringList();
  485. try
  486. {
  487. for (int Index = 0; Index < BookmarkList->Count; Index++)
  488. {
  489. TBookmark * Bookmark = BookmarkList->Bookmarks[Index];
  490. if (Bookmark->Node == SelectedNode)
  491. {
  492. PeerBookmarks->Add(Bookmark->Name);
  493. }
  494. }
  495. TBookmarkNameDialog * Dialog = new TBookmarkNameDialog(PeerBookmarks, Initial);
  496. try
  497. {
  498. bool Shared = WinConfiguration->UseSharedBookmarks;
  499. Result = Dialog->Execute(BookmarkName, Shared);
  500. if (Result)
  501. {
  502. if (Initial)
  503. {
  504. WinConfiguration->UseSharedBookmarks = Shared;
  505. BookmarkList = GetBookmarkList(GetProfilesSheet());
  506. ProfilesView = GetProfilesView(GetProfilesSheet());
  507. }
  508. TBookmark * Bookmark = BookmarkList->FindByName(SelectedNode, BookmarkName);
  509. if (Bookmark != NULL)
  510. {
  511. Bookmark->Local = LocalDirectory;
  512. Bookmark->Remote = RemoteDirectory;
  513. for (int Index = 0; Index < ProfilesView->Items->Count; Index++)
  514. {
  515. TTreeNode * Node = ProfilesView->Items->Item[Index];
  516. if (Node->Data == Bookmark)
  517. {
  518. Selected = Node;
  519. break;
  520. }
  521. }
  522. }
  523. else
  524. {
  525. Bookmark = new TBookmark();
  526. Bookmark->Name = BookmarkName;
  527. Bookmark->Local = LocalDirectory;
  528. Bookmark->Remote = RemoteDirectory;
  529. if (SelectedBookmark != NULL)
  530. {
  531. Bookmark->Node = SelectedBookmark->Node;
  532. BookmarkList->InsertBefore(SelectedBookmark, Bookmark);
  533. Selected = ProfilesView->Items->InsertObject(Selected, BookmarkText(Bookmark), Bookmark);
  534. }
  535. else if ((Selected != NULL) && (SelectedBookmark == NULL))
  536. {
  537. // must be a folder
  538. assert(!Selected->Parent); // more than one level of folders is not supported
  539. Bookmark->Node = Selected->Text;
  540. BookmarkList->Add(Bookmark);
  541. Selected = ProfilesView->Items->AddChildObject(Selected, BookmarkText(Bookmark), Bookmark);
  542. }
  543. else
  544. {
  545. BookmarkList->Add(Bookmark);
  546. Selected = ProfilesView->Items->AddObject(NULL, BookmarkText(Bookmark), Bookmark);
  547. }
  548. }
  549. ProfilesView->Selected = Selected;
  550. }
  551. }
  552. __finally
  553. {
  554. delete Dialog;
  555. }
  556. }
  557. __finally
  558. {
  559. delete PeerBookmarks;
  560. }
  561. UpdateControls();
  562. return Result;
  563. }
  564. //---------------------------------------------------------------------------
  565. void __fastcall TLocationProfilesDialog::AddBookmarkButtonClick(TObject * Sender)
  566. {
  567. AddAsBookmark(Sender, false);
  568. }
  569. //---------------------------------------------------------------------------
  570. void __fastcall TLocationProfilesDialog::RemoveBookmark(TObject * Sender)
  571. {
  572. TBookmarkList * BookmarkList = GetBookmarkList(Sender);
  573. TTreeView * ProfilesView = GetProfilesView(Sender);
  574. TStringList * Folders = GetFolders(Sender);
  575. assert(ProfilesView->Selected);
  576. TTreeNode * Node = ProfilesView->Selected;
  577. if (Node->Data)
  578. {
  579. BookmarkList->Delete((TBookmark *)Node->Data);
  580. TTreeNode * ParentNode = Node->Parent;
  581. Node->Delete();
  582. if (ParentNode && !ParentNode->Count)
  583. {
  584. assert(Folders->IndexOfObject(ParentNode) >= 0);
  585. Folders->Delete(Folders->IndexOfObject(ParentNode));
  586. ParentNode->Delete();
  587. }
  588. }
  589. else
  590. {
  591. if (MessageDialog(LoadStr(DELETE_BOOKMARK_FOLDER), qtConfirmation,
  592. qaYes | qaNo, HELP_LOCATION_PROFILE_DELETE) == qaYes)
  593. {
  594. assert(Node->Count);
  595. for (int i = 0; i < Node->Count; i++)
  596. {
  597. BookmarkList->Delete((TBookmark *)Node->Item[i]->Data);
  598. }
  599. assert(Folders->IndexOfObject(Node) >= 0);
  600. Folders->Delete(Folders->IndexOfObject(Node));
  601. Node->Delete();
  602. }
  603. }
  604. UpdateControls();
  605. }
  606. //---------------------------------------------------------------------------
  607. void __fastcall TLocationProfilesDialog::RemoveBookmarkButtonClick(TObject * Sender)
  608. {
  609. RemoveBookmark(Sender);
  610. }
  611. //---------------------------------------------------------------------------
  612. void __fastcall TLocationProfilesDialog::BookmarkMove(TObject * Sender,
  613. TTreeNode * Source, TTreeNode * Dest)
  614. {
  615. TBookmarkList * BookmarkList = GetBookmarkList(Sender);
  616. TTreeView * ProfilesView = GetProfilesView(Sender);
  617. TStringList * Folders = GetFolders(Sender);
  618. assert(Source && Source->Data);
  619. TBookmark * Bookmark = (TBookmark *)Source->Data;
  620. TTreeNode * PrevFolderNode = Source->Parent;
  621. if (!Dest || !Dest->Data)
  622. {
  623. Bookmark->Node = Dest ? Dest->Text : UnicodeString();
  624. BookmarkList->MoveTo(BookmarkList->Bookmarks[BookmarkList->Count - 1],
  625. Bookmark, false);
  626. ProfilesView->Selected->MoveTo(Dest, naAddChild);
  627. }
  628. else
  629. {
  630. TBookmark * DestBookmark = (TBookmark *)Dest->Data;
  631. Bookmark->Node = DestBookmark->Node;
  632. BookmarkList->MoveTo(DestBookmark, Bookmark,
  633. Source->AbsoluteIndex > Dest->AbsoluteIndex);
  634. if (Source->AbsoluteIndex > Dest->AbsoluteIndex)
  635. {
  636. Source->MoveTo(Dest, naInsert);
  637. }
  638. else if (Dest->getNextSibling() != NULL)
  639. {
  640. Source->MoveTo(Dest->getNextSibling(), naInsert);
  641. }
  642. else
  643. {
  644. Source->MoveTo(Dest, naAdd);
  645. }
  646. }
  647. if (PrevFolderNode && !PrevFolderNode->Count)
  648. {
  649. assert(Folders->IndexOfObject(PrevFolderNode) >= 0);
  650. Folders->Delete(Folders->IndexOfObject(PrevFolderNode));
  651. PrevFolderNode->Delete();
  652. }
  653. Source->MakeVisible();
  654. UpdateControls();
  655. }
  656. //---------------------------------------------------------------------------
  657. void __fastcall TLocationProfilesDialog::BookmarkButtonClick(TObject * Sender)
  658. {
  659. TControl * Control = dynamic_cast<TControl *>(Sender);
  660. TTreeNode * Node = GetProfilesView(Sender)->Selected;
  661. assert(Node);
  662. assert(Node->Data);
  663. TTreeNode * TargetNode;
  664. if (Control->Tag < 0)
  665. {
  666. TargetNode = Node->getPrevSibling();
  667. assert(TargetNode);
  668. }
  669. else
  670. {
  671. TargetNode = Node->getNextSibling();
  672. }
  673. BookmarkMove(Sender, Node, TargetNode ? TargetNode : Node->Parent);
  674. }
  675. //---------------------------------------------------------------------------
  676. void __fastcall TLocationProfilesDialog::ProfilesViewStartDrag(
  677. TObject * Sender, TDragObject *& /*DragObject*/)
  678. {
  679. TTreeView * ProfilesView = GetProfilesView(Sender);
  680. if (!ProfilesView->Selected->Data)
  681. {
  682. Abort();
  683. }
  684. FBookmarkDragSource = ProfilesView->Selected;
  685. GetScrollOnDragOver(Sender)->StartDrag();
  686. }
  687. //---------------------------------------------------------------------------
  688. void __fastcall TLocationProfilesDialog::ProfilesViewDragOver(
  689. TObject * Sender, TObject * Source, int X, int Y,
  690. TDragState /*State*/, bool & Accept)
  691. {
  692. TTreeView * ProfilesView = GetProfilesView(Sender);
  693. if (Source == ProfilesView)
  694. {
  695. Accept = (ProfilesView->DropTarget != NULL) &&
  696. (FBookmarkDragSource != ProfilesView->DropTarget);
  697. GetScrollOnDragOver(Sender)->DragOver(TPoint(X, Y));
  698. }
  699. }
  700. //---------------------------------------------------------------------------
  701. void __fastcall TLocationProfilesDialog::ProfilesViewDragDrop(
  702. TObject * Sender, TObject * Source, int /*X*/, int /*Y*/)
  703. {
  704. TTreeView * ProfilesView = GetProfilesView(Sender);
  705. if ((Source == ProfilesView) && (ProfilesView->DropTarget != NULL) &&
  706. (FBookmarkDragSource != ProfilesView->DropTarget))
  707. {
  708. assert(FBookmarkDragSource);
  709. TTreeNode * Target = ProfilesView->DropTarget;
  710. BookmarkMove(Sender, FBookmarkDragSource, Target);
  711. FBookmarkDragSource = NULL;
  712. }
  713. }
  714. //---------------------------------------------------------------------------
  715. void __fastcall TLocationProfilesDialog::ProfilesViewDblClick(TObject * Sender)
  716. {
  717. TTreeView * ProfilesView = GetProfilesView(Sender);
  718. TPoint P = ProfilesView->ScreenToClient(Mouse->CursorPos);
  719. TTreeNode * Node = ProfilesView->GetNodeAt(P.x, P.y);
  720. if (OKBtn->Enabled && Node && Node->Data && Node->Selected)
  721. {
  722. ModalResult = mrOk;
  723. }
  724. }
  725. //---------------------------------------------------------------------------
  726. void __fastcall TLocationProfilesDialog::FormShow(TObject * /*Sender*/)
  727. {
  728. FindProfile();
  729. if (OperationSide == osLocal)
  730. {
  731. ActiveControl = LocalDirectoryEdit;
  732. }
  733. else
  734. {
  735. ActiveControl = RemoteDirectoryEdit;
  736. }
  737. UpdateControls();
  738. }
  739. //---------------------------------------------------------------------------
  740. void __fastcall TLocationProfilesDialog::ProfilesViewKeyDown(TObject * Sender,
  741. WORD & Key, TShiftState /*Shift*/)
  742. {
  743. TTreeView * ProfilesView = GetProfilesView(Sender);
  744. if (!ProfilesView->IsEditing())
  745. {
  746. if ((ProfilesView->Selected != NULL) && (Key == VK_DELETE))
  747. {
  748. RemoveBookmark(Sender);
  749. Key = 0;
  750. }
  751. else if ((ProfilesView->Selected != NULL) && (Key == VK_F2))
  752. {
  753. RenameBookmark(Sender);
  754. Key = 0;
  755. }
  756. }
  757. }
  758. //---------------------------------------------------------------------------
  759. void __fastcall TLocationProfilesDialog::DirectoryEditChange(TObject * /*Sender*/)
  760. {
  761. if (!FChanging)
  762. {
  763. FindProfile();
  764. UpdateControls();
  765. }
  766. }
  767. //---------------------------------------------------------------------------
  768. void __fastcall TLocationProfilesDialog::ProfilesViewChange(
  769. TObject * /*Sender*/, TTreeNode * Node)
  770. {
  771. if (Node && Node->Data)
  772. {
  773. assert(!FChanging);
  774. FChanging = true;
  775. try
  776. {
  777. LocalDirectoryEdit->Text = ((TBookmark *)Node->Data)->Local;
  778. RemoteDirectoryEdit->Text = ((TBookmark *)Node->Data)->Remote;
  779. }
  780. __finally
  781. {
  782. FChanging = false;
  783. }
  784. // try to locate the same profile in the other set
  785. FindProfile();
  786. }
  787. UpdateControls();
  788. }
  789. //---------------------------------------------------------------------------
  790. void __fastcall TLocationProfilesDialog::BookmarkMoveToButtonClick(TObject * Sender)
  791. {
  792. TTreeView * ProfilesView = GetProfilesView(Sender);
  793. TStringList * Folders = GetFolders(Sender);
  794. assert(ProfilesView->Selected->Data);
  795. TBookmark * Bookmark = (TBookmark *)ProfilesView->Selected->Data;
  796. TBookmarkFolderDialog * Dialog = new TBookmarkFolderDialog(Folders);
  797. try
  798. {
  799. UnicodeString NodeName = Bookmark->Node;
  800. if (Dialog->Execute(NodeName) &&
  801. (NodeName != Bookmark->Node))
  802. {
  803. TTreeNode * FolderNode;
  804. int I = Folders->IndexOf(NodeName);
  805. if (NodeName.IsEmpty())
  806. {
  807. FolderNode = NULL;
  808. }
  809. else if (I >= 0)
  810. {
  811. FolderNode = dynamic_cast<TTreeNode *>(Folders->Objects[I]);
  812. assert(FolderNode);
  813. }
  814. else
  815. {
  816. I = Folders->Add(NodeName);
  817. TTreeNode * NextNode;
  818. // duplicated in RenameButtonClick()
  819. if (I < Folders->Count-1)
  820. {
  821. NextNode = dynamic_cast<TTreeNode *>(Folders->Objects[I+1]);
  822. assert(NextNode);
  823. }
  824. else if (Folders->Count > 1)
  825. {
  826. NextNode = (dynamic_cast<TTreeNode *>(Folders->Objects[I-1]))->getNextSibling();
  827. }
  828. else
  829. {
  830. assert(ProfilesView->Items->Count);
  831. NextNode = ProfilesView->Items->Item[0];
  832. }
  833. FolderNode = ProfilesView->Items->Insert(NextNode, NodeName);
  834. assert(FolderNode);
  835. Folders->Objects[I] = FolderNode;
  836. }
  837. BookmarkMove(Sender, ProfilesView->Selected, FolderNode);
  838. }
  839. }
  840. __finally
  841. {
  842. delete Dialog;
  843. }
  844. }
  845. //---------------------------------------------------------------------------
  846. void __fastcall TLocationProfilesDialog::RenameBookmark(TObject * Sender)
  847. {
  848. TTreeView * ProfilesView = GetProfilesView(Sender);
  849. assert(ProfilesView->Selected != NULL);
  850. if (ProfilesView->Selected != NULL)
  851. {
  852. ProfilesView->SetFocus();
  853. ProfilesView->Selected->EditText();
  854. }
  855. }
  856. //---------------------------------------------------------------------------
  857. void __fastcall TLocationProfilesDialog::RenameBookmarkButtonClick(TObject * Sender)
  858. {
  859. RenameBookmark(Sender);
  860. }
  861. //---------------------------------------------------------------------------
  862. void __fastcall TLocationProfilesDialog::ProfilesViewGetImageIndex(
  863. TObject * /*Sender*/, TTreeNode * Node)
  864. {
  865. Node->ImageIndex = Node->Data ? 0 : (Node->Expanded ? 1 : 2);
  866. }
  867. //---------------------------------------------------------------------------
  868. void __fastcall TLocationProfilesDialog::ProfilesViewGetSelectedIndex(
  869. TObject * /*Sender*/, TTreeNode * Node)
  870. {
  871. Node->SelectedIndex = Node->Data ? 0 : (Node->Expanded ? 1 : 2);
  872. }
  873. //---------------------------------------------------------------------------
  874. void __fastcall TLocationProfilesDialog::LocalDirectoryBrowseButtonClick(
  875. TObject * /*Sender*/)
  876. {
  877. UnicodeString Directory = LocalDirectoryEdit->Text;
  878. if (SelectDirectory(Directory, LoadStr(SELECT_LOCAL_DIRECTORY), true))
  879. {
  880. LocalDirectoryEdit->Text = Directory;
  881. DirectoryEditChange(LocalDirectoryEdit);
  882. }
  883. }
  884. //---------------------------------------------------------------------------
  885. void __fastcall TLocationProfilesDialog::SwitchButtonClick(TObject * /*Sender*/)
  886. {
  887. WinConfiguration->UseLocationProfiles = false;
  888. }
  889. //---------------------------------------------------------------------------
  890. void __fastcall TLocationProfilesDialog::HelpButtonClick(TObject * /*Sender*/)
  891. {
  892. FormHelp(this);
  893. }
  894. //---------------------------------------------------------------------------
  895. void __fastcall TLocationProfilesDialog::ProfilesViewCollapsed(
  896. TObject * Sender, TTreeNode * Node)
  897. {
  898. assert(Node != NULL);
  899. assert(Node->Data == NULL);
  900. GetBookmarkList(Sender)->NodeOpened[Node->Text] = false;
  901. }
  902. //---------------------------------------------------------------------------
  903. void __fastcall TLocationProfilesDialog::ProfilesViewExpanded(
  904. TObject * Sender, TTreeNode * Node)
  905. {
  906. assert(Node != NULL);
  907. assert(Node->Data == NULL);
  908. GetBookmarkList(Sender)->NodeOpened[Node->Text] = true;
  909. }
  910. //---------------------------------------------------------------------------
  911. void __fastcall TLocationProfilesDialog::ProfilesViewEdited(
  912. TObject * Sender, TTreeNode * Node, UnicodeString & S)
  913. {
  914. TTreeView * ProfilesView = GetProfilesView(Sender);
  915. TStringList * Folders = GetFolders(Sender);
  916. if (Node->Data != NULL)
  917. {
  918. BookmarkNameValidateName(S);
  919. // raises exception in case of duplicate name??
  920. ((TBookmark *)Node->Data)->Name = S;
  921. }
  922. else
  923. {
  924. BookmarkFolderValidateName(S, false);
  925. if (S.IsEmpty())
  926. {
  927. throw Exception(FMTLOAD(BOOKMARK_FOLDER_INVALID_NAME, (S)));
  928. }
  929. if ((Folders->IndexOf(S) >= 0) && AnsiCompareText(S, Node->Text))
  930. {
  931. throw Exception(FMTLOAD(DUPLICATE_BOOKMARK_FOLDER, (S)));
  932. }
  933. assert(Node->Count);
  934. Folders->Delete(Folders->IndexOf(Node->Text));
  935. int I = Folders->AddObject(S, Node);
  936. TTreeNode * NextNode;
  937. // duplicated in MoveToButtonClick()
  938. if (I < Folders->Count-1)
  939. {
  940. NextNode = dynamic_cast<TTreeNode *>(Folders->Objects[I+1]);
  941. assert(NextNode);
  942. }
  943. else if (Folders->Count > 1)
  944. {
  945. NextNode = (dynamic_cast<TTreeNode *>(Folders->Objects[I-1]))->getNextSibling();
  946. }
  947. else
  948. {
  949. assert(ProfilesView->Items->Count);
  950. NextNode = ProfilesView->Items->Item[0];
  951. }
  952. if (NextNode != Node)
  953. {
  954. Node->MoveTo(NextNode, NextNode ? naInsert : naAddChild);
  955. }
  956. for (int i = 0; i < Node->Count; i++)
  957. {
  958. ((TBookmark *)Node->Item[i]->Data)->Node = S;
  959. }
  960. Node->MakeVisible();
  961. }
  962. }
  963. //---------------------------------------------------------------------------
  964. void __fastcall TLocationProfilesDialog::ProfilesViewEditing(
  965. TObject * /*Sender*/, TTreeNode * /*Node*/, bool & /*AllowEdit*/)
  966. {
  967. OKBtn->Default = false;
  968. CancelBtn->Cancel = false;
  969. }
  970. //---------------------------------------------------------------------------
  971. void __fastcall TLocationProfilesDialog::UpdateActions()
  972. {
  973. TForm::UpdateActions();
  974. if ((!OKBtn->Default || !CancelBtn->Cancel) &&
  975. !GetProfilesView(PageControl->ActivePage)->IsEditing())
  976. {
  977. OKBtn->Default = true;
  978. CancelBtn->Cancel = true;
  979. }
  980. }
  981. //---------------------------------------------------------------------------
  982. void __fastcall TLocationProfilesDialog::ProfilesViewEndDrag(
  983. TObject * Sender, TObject * /*Target*/, int /*X*/, int /*Y*/)
  984. {
  985. GetScrollOnDragOver(Sender)->EndDrag();
  986. }
  987. //---------------------------------------------------------------------------
  988. void __fastcall TLocationProfilesDialog::ShortCutBookmarkButtonClick(
  989. TObject * Sender)
  990. {
  991. TBookmarkList * BookmarkList = GetBookmarkList(Sender);
  992. TTreeView * ProfilesView = GetProfilesView(Sender);
  993. assert(ProfilesView->Selected != NULL);
  994. TTreeNode * Node = ProfilesView->Selected;
  995. assert(Node->Data != NULL);
  996. TBookmark * Bookmark = static_cast<TBookmark *>(Node->Data);
  997. TShortCuts ShortCuts;
  998. WinConfiguration->CustomCommandList->ShortCuts(ShortCuts);
  999. BookmarkList->ShortCuts(ShortCuts);
  1000. TShortCut ShortCut = Bookmark->ShortCut;
  1001. if (DoShortCutDialog(ShortCut, ShortCuts, HelpKeyword))
  1002. {
  1003. Bookmark->ShortCut = ShortCut;
  1004. Node->Text = BookmarkText(Bookmark);
  1005. UpdateControls();
  1006. }
  1007. }
  1008. //---------------------------------------------------------------------------
  1009. UnicodeString __fastcall TLocationProfilesDialog::BookmarkText(TBookmark * Bookmark)
  1010. {
  1011. UnicodeString Result = Bookmark->Name;
  1012. if (!Result.IsEmpty() && (Bookmark->ShortCut != 0))
  1013. {
  1014. Result = FORMAT(L"%s (%s)", (Result, ShortCutToText(Bookmark->ShortCut)));
  1015. }
  1016. return Result;
  1017. }
  1018. //---------------------------------------------------------------------------