OpenDirectory.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. //---------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <ScpMain.h>
  5. #include <Configuration.h>
  6. #include <RemoteFiles.h>
  7. #include <VCLCommon.h>
  8. #include <TextsWin.h>
  9. #include <Common.h>
  10. #include "OpenDirectory.h"
  11. #include "WinConfiguration.h"
  12. //---------------------------------------------------------------------
  13. #pragma link "XPThemes"
  14. #pragma link "IEComboBox"
  15. #pragma resource "*.dfm"
  16. //---------------------------------------------------------------------
  17. bool __fastcall DoOpenDirectoryDialog(TOpenDirectoryMode Mode, TOperationSide Side,
  18. AnsiString & Directory, TStrings * Directories, TTerminal * Terminal,
  19. bool AllowSwitch)
  20. {
  21. bool Result;
  22. TOpenDirectoryDialog * Dialog = new TOpenDirectoryDialog(Application);
  23. try
  24. {
  25. Dialog->Mode = Mode;
  26. Dialog->OperationSide = Side;
  27. Dialog->Directory = Directory;
  28. Dialog->Directories = Directories;
  29. Dialog->Terminal = Terminal;
  30. Dialog->AllowSwitch = AllowSwitch;
  31. Result = Dialog->Execute();
  32. if (Result)
  33. {
  34. Directory = Dialog->Directory;
  35. }
  36. }
  37. __finally
  38. {
  39. delete Dialog;
  40. }
  41. return Result;
  42. }
  43. //---------------------------------------------------------------------
  44. __fastcall TOpenDirectoryDialog::TOpenDirectoryDialog(TComponent * AOwner):
  45. TForm(AOwner)
  46. {
  47. FOperationSide = osCurrent;
  48. OperationSide = osLocal;
  49. FBookmarkDragDest = -1;
  50. FTerminal = NULL;
  51. FBookmarkList = new TBookmarkList();
  52. UseSystemSettings(this);
  53. InstallPathWordBreakProc(LocalDirectoryEdit);
  54. InstallPathWordBreakProc(RemoteDirectoryEdit);
  55. }
  56. //---------------------------------------------------------------------
  57. __fastcall TOpenDirectoryDialog::~TOpenDirectoryDialog()
  58. {
  59. SAFE_DESTROY(FBookmarkList);
  60. }
  61. //---------------------------------------------------------------------
  62. void __fastcall TOpenDirectoryDialog::SetOperationSide(TOperationSide value)
  63. {
  64. if (OperationSide != value)
  65. {
  66. AnsiString ADirectory = Directory;
  67. FOperationSide = value;
  68. Directory = ADirectory;
  69. RemoteDirectoryEdit->Visible = False;
  70. LocalDirectoryEdit->Visible = False;
  71. CurrentEdit->Visible = True;
  72. EditLabel->FocusControl = CurrentEdit;
  73. UpdateControls();
  74. }
  75. }
  76. //---------------------------------------------------------------------------
  77. void __fastcall TOpenDirectoryDialog::SetDirectory(AnsiString value)
  78. {
  79. if (OperationSide == osRemote)
  80. {
  81. RemoteDirectoryEdit->Text = value;
  82. }
  83. else
  84. {
  85. LocalDirectoryEdit->Text = value;
  86. }
  87. DirectoryEditChange(NULL);
  88. }
  89. //---------------------------------------------------------------------------
  90. AnsiString __fastcall TOpenDirectoryDialog::GetDirectory()
  91. {
  92. if (OperationSide == osRemote)
  93. return UnixExcludeTrailingBackslash(RemoteDirectoryEdit->Text);
  94. else
  95. return ExcludeTrailingBackslash(LocalDirectoryEdit->Text);
  96. }
  97. //---------------------------------------------------------------------------
  98. TWinControl * __fastcall TOpenDirectoryDialog::GetCurrentEdit()
  99. {
  100. if (OperationSide == osRemote) return RemoteDirectoryEdit;
  101. else return LocalDirectoryEdit;
  102. }
  103. //---------------------------------------------------------------------------
  104. void __fastcall TOpenDirectoryDialog::ControlChange(TObject * /*Sender*/)
  105. {
  106. UpdateControls();
  107. }
  108. //---------------------------------------------------------------------------
  109. void __fastcall TOpenDirectoryDialog::UpdateControls(bool ListBoxUpdate)
  110. {
  111. EnableControl(OKBtn, !Directory.IsEmpty());
  112. EnableControl(AddBookmarkButton,
  113. !Directory.IsEmpty() && (FindBookmark(Directory) < 0));
  114. EnableControl(RemoveBookmarkButton, BookmarksList->ItemIndex >= 0);
  115. EnableControl(UpBookmarkButton, BookmarksList->ItemIndex > 0);
  116. EnableControl(DownBookmarkButton, BookmarksList->ItemIndex >= 0 &&
  117. BookmarksList->ItemIndex < BookmarksList->Items->Count-1);
  118. LocalDirectoryBrowseButton->Visible = (OperationSide == osLocal);
  119. SwitchButton->Visible = AllowSwitch;
  120. if (ListBoxUpdate)
  121. {
  122. int MaxWidth = 0;
  123. for (int i = 0; i < BookmarksList->Items->Count; i++)
  124. {
  125. int Width = BookmarksList->Canvas->TextExtent(BookmarksList->Items->Strings[i]).cx;
  126. if (Width > MaxWidth)
  127. {
  128. MaxWidth = Width;
  129. }
  130. }
  131. BookmarksList->ScrollWidth = MaxWidth;
  132. MaxWidth += 6;
  133. if (BookmarksList->Items->Count > BookmarksList->ClientHeight / BookmarksList->ItemHeight)
  134. {
  135. MaxWidth += GetSystemMetrics(SM_CXVSCROLL);
  136. }
  137. if (MaxWidth > BookmarksList->Width)
  138. {
  139. int CWidth = ClientWidth + (MaxWidth - BookmarksList->Width);
  140. ClientWidth = CWidth > 600 ? 600 : CWidth;
  141. }
  142. }
  143. }
  144. //---------------------------------------------------------------------------
  145. void __fastcall TOpenDirectoryDialog::SetDirectories(TStrings * value)
  146. {
  147. dynamic_cast<TCustomComboBox*>(CurrentEdit)->Items = value;
  148. }
  149. //---------------------------------------------------------------------------
  150. TStrings * __fastcall TOpenDirectoryDialog::GetDirectories()
  151. {
  152. return RemoteDirectoryEdit->Items;
  153. }
  154. //---------------------------------------------------------------------------
  155. void __fastcall TOpenDirectoryDialog::LoadBookmarks()
  156. {
  157. BookmarksList->Items->Clear();
  158. for (int i = 0; i < FBookmarkList->Count; i++)
  159. {
  160. TBookmark * Bookmark = FBookmarkList->Bookmarks[i];
  161. AnsiString Directory = OperationSide == osLocal ? Bookmark->Local : Bookmark->Remote;
  162. if (!Directory.IsEmpty() && (BookmarksList->Items->IndexOf(Directory) < 0))
  163. {
  164. BookmarksList->Items->AddObject(Directory, Bookmark);
  165. }
  166. }
  167. }
  168. //---------------------------------------------------------------------------
  169. bool __fastcall TOpenDirectoryDialog::Execute()
  170. {
  171. bool Result;
  172. AnsiString SessionKey;
  173. if (Terminal)
  174. {
  175. TBookmarkList * BookmarkList;
  176. // cache session key, in case terminal is closed while the window is open
  177. SessionKey = Terminal->SessionData->SessionKey;
  178. BookmarkList = WinConfiguration->Bookmarks[SessionKey];
  179. if (BookmarkList)
  180. {
  181. FBookmarkList->Assign(BookmarkList);
  182. }
  183. else
  184. {
  185. FBookmarkList->Clear();
  186. }
  187. LoadBookmarks();
  188. DirectoryEditChange(NULL);
  189. if (Mode == odAddBookmark)
  190. {
  191. AddAsBookmark();
  192. }
  193. }
  194. Result = (ShowModal() == mrOk);
  195. if (Terminal)
  196. {
  197. WinConfiguration->Bookmarks[SessionKey] = FBookmarkList;
  198. }
  199. return Result;
  200. }
  201. //---------------------------------------------------------------------------
  202. void __fastcall TOpenDirectoryDialog::AddAsBookmark()
  203. {
  204. if (Directory.IsEmpty() || (FindBookmark(Directory) >= 0))
  205. {
  206. return;
  207. }
  208. TBookmark * Bookmark = new TBookmark;
  209. if (OperationSide == osRemote)
  210. {
  211. RemoteDirectoryEdit->SelectAll();
  212. Bookmark->Remote = Directory;
  213. }
  214. else
  215. {
  216. LocalDirectoryEdit->SelectAll();
  217. Bookmark->Local = Directory;
  218. }
  219. Bookmark->Name = Directory;
  220. if (BookmarksList->ItemIndex >= 0)
  221. {
  222. int PrevItemIndex = BookmarksList->ItemIndex;
  223. FBookmarkList->InsertBefore(
  224. dynamic_cast<TBookmark *>(BookmarksList->Items->Objects[BookmarksList->ItemIndex]),
  225. Bookmark);
  226. BookmarksList->Items->InsertObject(BookmarksList->ItemIndex, Directory, Bookmark);
  227. BookmarksList->ItemIndex = PrevItemIndex;
  228. }
  229. else
  230. {
  231. FBookmarkList->Add(Bookmark);
  232. BookmarksList->Items->AddObject(Directory, Bookmark);
  233. BookmarksList->ItemIndex = BookmarksList->Items->Count-1;
  234. }
  235. UpdateControls(true);
  236. }
  237. //---------------------------------------------------------------------------
  238. void __fastcall TOpenDirectoryDialog::AddBookmarkButtonClick(TObject */*Sender*/)
  239. {
  240. AddAsBookmark();
  241. }
  242. //---------------------------------------------------------------------------
  243. void __fastcall TOpenDirectoryDialog::RemoveBookmarkButtonClick(TObject * /*Sender*/)
  244. {
  245. int PrevItemIndex = BookmarksList->ItemIndex;
  246. TBookmark * Bookmark;
  247. Bookmark = dynamic_cast<TBookmark *>(BookmarksList->Items->Objects[PrevItemIndex]);
  248. assert(Bookmark);
  249. FBookmarkList->Delete(Bookmark);
  250. BookmarksList->Items->Delete(PrevItemIndex);
  251. if (PrevItemIndex < BookmarksList->Items->Count)
  252. {
  253. BookmarksList->ItemIndex = PrevItemIndex;
  254. }
  255. else
  256. {
  257. BookmarksList->ItemIndex = BookmarksList->Items->Count-1;
  258. }
  259. UpdateControls(true);
  260. BookmarksListClick(NULL);
  261. }
  262. //---------------------------------------------------------------------------
  263. Integer __fastcall TOpenDirectoryDialog::FindBookmark(const AnsiString Bookmark)
  264. {
  265. if (OperationSide == osRemote)
  266. {
  267. for (int Index = 0; Index < BookmarksList->Items->Count; Index++)
  268. {
  269. if (AnsiCompareStr(BookmarksList->Items->Strings[Index], Bookmark) == 0)
  270. {
  271. return Index;
  272. }
  273. }
  274. }
  275. else
  276. {
  277. for (int Index = 0; Index < BookmarksList->Items->Count; Index++)
  278. {
  279. if (AnsiCompareText(BookmarksList->Items->Strings[Index], Bookmark) == 0)
  280. {
  281. return Index;
  282. }
  283. }
  284. }
  285. return -1;
  286. }
  287. //---------------------------------------------------------------------------
  288. void __fastcall TOpenDirectoryDialog::BookmarksListClick(TObject * /*Sender*/)
  289. {
  290. if (BookmarksList->ItemIndex >= 0)
  291. {
  292. Directory = BookmarksList->Items->Strings[BookmarksList->ItemIndex];
  293. }
  294. UpdateControls();
  295. }
  296. //---------------------------------------------------------------------------
  297. void __fastcall TOpenDirectoryDialog::BookmarkMove(int Source, int Dest)
  298. {
  299. if (Source >= 0 && Source < BookmarksList->Items->Count &&
  300. Dest >= 0 && Dest < BookmarksList->Items->Count)
  301. {
  302. FBookmarkList->MoveTo(
  303. dynamic_cast<TBookmark *>(BookmarksList->Items->Objects[Dest]),
  304. dynamic_cast<TBookmark *>(BookmarksList->Items->Objects[Source]),
  305. Source > Dest);
  306. BookmarksList->Items->Move(Source, Dest);
  307. BookmarksList->ItemIndex = Dest;
  308. BookmarksList->SetFocus();
  309. UpdateControls();
  310. }
  311. }
  312. //---------------------------------------------------------------------------
  313. void __fastcall TOpenDirectoryDialog::BookmarkButtonClick(TObject *Sender)
  314. {
  315. BookmarkMove(BookmarksList->ItemIndex,
  316. BookmarksList->ItemIndex + (Sender == UpBookmarkButton ? -1 : 1));
  317. UpdateControls();
  318. }
  319. //---------------------------------------------------------------------------
  320. bool __fastcall TOpenDirectoryDialog::AllowBookmarkDrag(int X, int Y)
  321. {
  322. FBookmarkDragDest = BookmarksList->ItemAtPos(TPoint(X, Y), true);
  323. return (FBookmarkDragDest >= 0) && (FBookmarkDragDest != FBookmarkDragSource);
  324. }
  325. //---------------------------------------------------------------------------
  326. void __fastcall TOpenDirectoryDialog::BookmarksListStartDrag(
  327. TObject * /*Sender*/ , TDragObject *& /*DragObject*/)
  328. {
  329. FBookmarkDragSource = BookmarksList->ItemIndex;
  330. FBookmarkDragDest = -1;
  331. }
  332. //---------------------------------------------------------------------------
  333. void __fastcall TOpenDirectoryDialog::BookmarksListDragOver(
  334. TObject */*Sender*/, TObject *Source, int X, int Y, TDragState /*State*/,
  335. bool &Accept)
  336. {
  337. if (Source == BookmarksList) Accept = AllowBookmarkDrag(X, Y);
  338. }
  339. //---------------------------------------------------------------------------
  340. void __fastcall TOpenDirectoryDialog::BookmarksListDragDrop(
  341. TObject * /*Sender*/, TObject *Source, int X, int Y)
  342. {
  343. if (Source == BookmarksList)
  344. {
  345. if (AllowBookmarkDrag(X, Y)) BookmarkMove(FBookmarkDragSource, FBookmarkDragDest);
  346. }
  347. }
  348. //---------------------------------------------------------------------------
  349. void __fastcall TOpenDirectoryDialog::DirectoryEditChange(TObject * /*Sender*/)
  350. {
  351. int ItemIndex = FindBookmark(Directory);
  352. if (ItemIndex >= 0) BookmarksList->ItemIndex = ItemIndex;
  353. UpdateControls();
  354. }
  355. //---------------------------------------------------------------------------
  356. void __fastcall TOpenDirectoryDialog::BookmarksListDblClick(TObject * /*Sender*/)
  357. {
  358. if (BookmarksList->ItemIndex >= 0) ModalResult = mrOk;
  359. }
  360. //---------------------------------------------------------------------------
  361. void __fastcall TOpenDirectoryDialog::SetMode(TOpenDirectoryMode value)
  362. {
  363. FMode = value;
  364. Caption = LoadStr(Mode == odBrowse ?
  365. OPEN_DIRECTORY_BROWSE_CAPTION : OPEN_DIRECTORY_ADD_BOOMARK_ACTION );
  366. }
  367. //---------------------------------------------------------------------------
  368. void __fastcall TOpenDirectoryDialog::FormShow(TObject * /*Sender*/)
  369. {
  370. UpdateControls(true);
  371. if (Mode == odBrowse)
  372. {
  373. CurrentEdit->SetFocus();
  374. }
  375. else
  376. {
  377. BookmarksList->SetFocus();
  378. }
  379. }
  380. //---------------------------------------------------------------------------
  381. void __fastcall TOpenDirectoryDialog::BookmarksListKeyDown(TObject * /*Sender*/,
  382. WORD &Key, TShiftState /*Shift*/)
  383. {
  384. if ((BookmarksList->ItemIndex >= 0) && (Key == VK_DELETE))
  385. {
  386. RemoveBookmarkButtonClick(NULL);
  387. }
  388. }
  389. //---------------------------------------------------------------------------
  390. void __fastcall TOpenDirectoryDialog::LocalDirectoryBrowseButtonClick(
  391. TObject * /*Sender*/)
  392. {
  393. AnsiString Directory = LocalDirectoryEdit->Text;
  394. if (SelectDirectory(Directory, LoadStr(SELECT_LOCAL_DIRECTORY), true))
  395. {
  396. LocalDirectoryEdit->Text = Directory;
  397. DirectoryEditChange(LocalDirectoryEdit);
  398. }
  399. }
  400. //---------------------------------------------------------------------------
  401. void __fastcall TOpenDirectoryDialog::SwitchButtonClick(TObject * /*Sender*/)
  402. {
  403. WinConfiguration->UseLocationProfiles = true;
  404. }
  405. //---------------------------------------------------------------------------
  406. void __fastcall TOpenDirectoryDialog::HelpButtonClick(TObject * /*Sender*/)
  407. {
  408. FormHelp(this);
  409. }
  410. //---------------------------------------------------------------------------