SynchronizeChecklist.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. //---------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Common.h>
  5. #include "WinInterface.h"
  6. #include "SynchronizeChecklist.h"
  7. #include <Terminal.h>
  8. #include <TextsWin.h>
  9. #include <CoreMain.h>
  10. #include <VCLCommon.h>
  11. #include <Tools.h>
  12. #include <CustomWinConfiguration.h>
  13. //---------------------------------------------------------------------
  14. #pragma link "IEListView"
  15. #pragma link "NortonLikeListView"
  16. #pragma resource "*.dfm"
  17. //---------------------------------------------------------------------
  18. bool __fastcall DoSynchronizeChecklistDialog(TSynchronizeChecklist * Checklist,
  19. TSynchronizeMode Mode, int Params, const AnsiString LocalDirectory,
  20. const AnsiString RemoteDirectory)
  21. {
  22. bool Result;
  23. TSynchronizeChecklistDialog * Dialog = new TSynchronizeChecklistDialog(
  24. Application, Mode, Params, LocalDirectory, RemoteDirectory);
  25. try
  26. {
  27. Result = Dialog->Execute(Checklist);
  28. }
  29. __finally
  30. {
  31. delete Dialog;
  32. }
  33. return Result;
  34. }
  35. //---------------------------------------------------------------------
  36. __fastcall TSynchronizeChecklistDialog::TSynchronizeChecklistDialog(
  37. TComponent * AOwner, TSynchronizeMode Mode, int Params,
  38. const AnsiString LocalDirectory, const AnsiString RemoteDirectory)
  39. : TForm(AOwner)
  40. {
  41. FFormRestored = false;
  42. FMode = Mode;
  43. FParams = Params;
  44. FLocalDirectory = ExcludeTrailingBackslash(LocalDirectory);
  45. FRemoteDirectory = UnixExcludeTrailingBackslash(RemoteDirectory);
  46. UseSystemSettings(this);
  47. FChecklist = NULL;
  48. FChangingItem = NULL;
  49. FChangingItemIgnore = false;
  50. FChangingItemMass = false;
  51. FGeneralHint = StatusBar->Hint;
  52. FOrigListViewWindowProc = ListView->WindowProc;
  53. ListView->WindowProc = ListViewWindowProc;
  54. FSystemImageList = new TImageList(this);
  55. SHFILEINFO FileInfo;
  56. FSystemImageList->Handle = SHGetFileInfo(NULL, 0, &FileInfo, sizeof(FileInfo),
  57. SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
  58. FSystemImageList->ShareImages = true;
  59. ListView->SmallImages = FSystemImageList;
  60. // header images mut be assigned after the small images, so it cannot
  61. // be done via DFM
  62. ListView->HeaderImages = ArrowImages;
  63. }
  64. //---------------------------------------------------------------------
  65. __fastcall TSynchronizeChecklistDialog::~TSynchronizeChecklistDialog()
  66. {
  67. delete FSystemImageList;
  68. ListView->WindowProc = FOrigListViewWindowProc;
  69. }
  70. //---------------------------------------------------------------------
  71. bool __fastcall TSynchronizeChecklistDialog::Execute(TSynchronizeChecklist * Checklist)
  72. {
  73. FChecklist = Checklist;
  74. bool Result = (ShowModal() != mrCancel);
  75. if (Result)
  76. {
  77. for (int Index = 0; Index < ListView->Items->Count; Index++)
  78. {
  79. TListItem * Item = ListView->Items->Item[Index];
  80. // const violation !
  81. TSynchronizeChecklist::TItem * ChecklistItem =
  82. static_cast<TSynchronizeChecklist::TItem *>(Item->Data);
  83. ChecklistItem->Checked = Item->Checked;
  84. }
  85. TSynchronizeChecklistConfiguration FormConfiguration =
  86. CustomWinConfiguration->SynchronizeChecklist;
  87. FormConfiguration.ListParams = ListView->ColProperties->ParamsStr;
  88. AnsiString WindowParams = FormConfiguration.WindowParams;
  89. // if there is no main window, keep previous "custom pos" indication,
  90. bool CustomPos = (StrToIntDef(::CutToChar(WindowParams, ';', true), 0) != 0);
  91. if (Application->MainForm != NULL)
  92. {
  93. CustomPos = (Application->MainForm->BoundsRect != BoundsRect);
  94. }
  95. FormConfiguration.WindowParams =
  96. FORMAT("%d;%s", ((CustomPos ? 1 : 0), StoreForm(this)));
  97. CustomWinConfiguration->SynchronizeChecklist = FormConfiguration;
  98. }
  99. return Result;
  100. }
  101. //---------------------------------------------------------------------
  102. void __fastcall TSynchronizeChecklistDialog::UpdateControls()
  103. {
  104. StatusBar->Invalidate();
  105. bool AllChecked = true;
  106. bool AllUnchecked = true;
  107. TListItem * Item = ListView->Selected;
  108. while (Item != NULL)
  109. {
  110. if (Item->Checked)
  111. {
  112. AllUnchecked = false;
  113. }
  114. else
  115. {
  116. AllChecked = false;
  117. }
  118. Item = ListView->GetNextItem(Item, sdAll, TItemStates() << isSelected);
  119. }
  120. EnableControl(OkButton, (FChecked[0] > 0));
  121. EnableControl(CheckButton, !AllChecked);
  122. EnableControl(UncheckButton, !AllUnchecked);
  123. EnableControl(CheckAllButton, (FChecked[0] < FTotals[0]));
  124. EnableControl(UncheckAllButton, (FChecked[0] > 0));
  125. CheckItem->Enabled = CheckButton->Enabled;
  126. UncheckItem->Enabled = UncheckButton->Enabled;
  127. SelectAllItem->Enabled = (ListView->SelCount < ListView->Items->Count);
  128. }
  129. //---------------------------------------------------------------------------
  130. void __fastcall TSynchronizeChecklistDialog::CreateParams(TCreateParams & Params)
  131. {
  132. if (!FFormRestored)
  133. {
  134. FFormRestored = True;
  135. AnsiString WindowParams = CustomWinConfiguration->SynchronizeChecklist.WindowParams;
  136. bool CustomPos = (StrToIntDef(::CutToChar(WindowParams, ';', true), 0) != 0);
  137. if (!CustomPos && (Application->MainForm != NULL))
  138. {
  139. BoundsRect = Application->MainForm->BoundsRect;
  140. }
  141. else
  142. {
  143. RestoreForm(WindowParams, this);
  144. }
  145. }
  146. TForm::CreateParams(Params);
  147. }
  148. //---------------------------------------------------------------------------
  149. void __fastcall TSynchronizeChecklistDialog::HelpButtonClick(TObject * /*Sender*/)
  150. {
  151. FormHelp(this);
  152. }
  153. //---------------------------------------------------------------------------
  154. void __fastcall TSynchronizeChecklistDialog::LoadItem(TListItem * Item)
  155. {
  156. AnsiString S;
  157. const TSynchronizeChecklist::TItem * ChecklistItem = FChecklist->Item[Item->Index];
  158. Item->Data = const_cast<TSynchronizeChecklist::TItem *>(ChecklistItem);
  159. Item->Checked = ChecklistItem->Checked;
  160. if (ChecklistItem->ImageIndex >= 0)
  161. {
  162. Item->ImageIndex = ChecklistItem->ImageIndex;
  163. }
  164. else
  165. {
  166. Item->ImageIndex = FakeFileImageIndex(ChecklistItem->FileName,
  167. FLAGMASK(ChecklistItem->IsDirectory, FILE_ATTRIBUTE_DIRECTORY));
  168. }
  169. S = ChecklistItem->FileName;
  170. if (ChecklistItem->IsDirectory)
  171. {
  172. S = IncludeTrailingBackslash(S);
  173. }
  174. Item->Caption = S;
  175. if (ChecklistItem->Action == TSynchronizeChecklist::saDeleteRemote)
  176. {
  177. Item->SubItems->Add("");
  178. Item->SubItems->Add("");
  179. Item->SubItems->Add("");
  180. }
  181. else
  182. {
  183. S = ChecklistItem->Local.Directory;
  184. if (AnsiSameText(FLocalDirectory, S.SubString(1, FLocalDirectory.Length())))
  185. {
  186. S[1] = '.';
  187. S.Delete(2, FLocalDirectory.Length() - 1);
  188. }
  189. else
  190. {
  191. assert(false);
  192. }
  193. Item->SubItems->Add(S);
  194. if (ChecklistItem->Action == TSynchronizeChecklist::saDownloadNew)
  195. {
  196. Item->SubItems->Add("");
  197. Item->SubItems->Add("");
  198. }
  199. else
  200. {
  201. if (ChecklistItem->IsDirectory)
  202. {
  203. Item->SubItems->Add("");
  204. }
  205. else
  206. {
  207. Item->SubItems->Add(FormatFloat("#,##0", ChecklistItem->Local.Size));
  208. }
  209. Item->SubItems->Add(UserModificationStr(ChecklistItem->Local.Modification,
  210. ChecklistItem->Local.ModificationFmt));
  211. }
  212. }
  213. Item->SubItems->Add("");
  214. if (ChecklistItem->Action == TSynchronizeChecklist::saDeleteLocal)
  215. {
  216. Item->SubItems->Add("");
  217. Item->SubItems->Add("");
  218. Item->SubItems->Add("");
  219. }
  220. else
  221. {
  222. S = ChecklistItem->Remote.Directory;
  223. if (AnsiSameText(FRemoteDirectory, S.SubString(1, FRemoteDirectory.Length())))
  224. {
  225. S[1] = '.';
  226. S.Delete(2, FRemoteDirectory.Length() - 1);
  227. }
  228. else
  229. {
  230. assert(false);
  231. }
  232. Item->SubItems->Add(S);
  233. if (ChecklistItem->Action == TSynchronizeChecklist::saUploadNew)
  234. {
  235. Item->SubItems->Add("");
  236. Item->SubItems->Add("");
  237. }
  238. else
  239. {
  240. if (ChecklistItem->IsDirectory)
  241. {
  242. Item->SubItems->Add("");
  243. }
  244. else
  245. {
  246. Item->SubItems->Add(FormatFloat("#,##0", ChecklistItem->Remote.Size));
  247. }
  248. Item->SubItems->Add(UserModificationStr(ChecklistItem->Remote.Modification,
  249. ChecklistItem->Remote.ModificationFmt));
  250. }
  251. }
  252. }
  253. //---------------------------------------------------------------------------
  254. void __fastcall TSynchronizeChecklistDialog::LoadList()
  255. {
  256. memset(&FTotals, 0, sizeof(FTotals));
  257. memset(&FChecked, 0, sizeof(FChecked));
  258. FTotals[0] = FChecklist->Count;
  259. FChecked[0] = 0;
  260. ListView->Items->BeginUpdate();
  261. try
  262. {
  263. ListView->Items->Clear();
  264. for (int Index = 0; Index < FChecklist->Count; Index++)
  265. {
  266. const TSynchronizeChecklist::TItem * ChecklistItem =
  267. FChecklist->Item[ListView->Items->Count];
  268. FChangingItemIgnore = true;
  269. try
  270. {
  271. LoadItem(ListView->Items->Add());
  272. }
  273. __finally
  274. {
  275. FChangingItemIgnore = false;
  276. }
  277. FTotals[int(ChecklistItem->Action)]++;
  278. if (ChecklistItem->Checked)
  279. {
  280. FChecked[int(ChecklistItem->Action)]++;
  281. FChecked[0]++;
  282. }
  283. }
  284. }
  285. __finally
  286. {
  287. ListView->Items->EndUpdate();
  288. }
  289. ListView->AlphaSort();
  290. UpdateControls();
  291. }
  292. //---------------------------------------------------------------------------
  293. void __fastcall TSynchronizeChecklistDialog::FormShow(TObject * /*Sender*/)
  294. {
  295. ListView->ColProperties->ParamsStr = CustomWinConfiguration->SynchronizeChecklist.ListParams;
  296. LoadList();
  297. }
  298. //---------------------------------------------------------------------------
  299. void __fastcall TSynchronizeChecklistDialog::ListViewWindowProc(TMessage & Message)
  300. {
  301. if (Message.Msg == CN_NOTIFY)
  302. {
  303. TWMNotify & NotifyMessage = reinterpret_cast<TWMNotify &>(Message);
  304. if (NotifyMessage.NMHdr->code == NM_CUSTOMDRAW)
  305. {
  306. // Due to a bug in VCL, OnAdvancedCustomDrawSubItem is not called for any
  307. // other stage except for cdPrePaint. So we must call it ourselves.
  308. TNMLVCustomDraw * CustomDraw =
  309. reinterpret_cast<TNMLVCustomDraw *>(NotifyMessage.NMHdr);
  310. if (FLAGSET(CustomDraw->nmcd.dwDrawStage, CDDS_ITEM) &&
  311. FLAGSET(CustomDraw->nmcd.dwDrawStage, CDDS_SUBITEM) &&
  312. FLAGSET(CustomDraw->nmcd.dwDrawStage, CDDS_ITEMPOSTPAINT))
  313. {
  314. TListItem * Item = ListView->Items->Item[CustomDraw->nmcd.dwItemSpec];
  315. bool DefaultDraw = true; // not used
  316. // do not know how to convert CustomDraw->nmcd.uItemState to TCustomDrawState
  317. ListViewAdvancedCustomDrawSubItem(ListView, Item, CustomDraw->iSubItem,
  318. TCustomDrawState(), cdPostPaint, DefaultDraw);
  319. }
  320. }
  321. }
  322. FOrigListViewWindowProc(Message);
  323. }
  324. //---------------------------------------------------------------------------
  325. void __fastcall TSynchronizeChecklistDialog::ListViewAdvancedCustomDrawSubItem(
  326. TCustomListView * /*Sender*/, TListItem * Item, int SubItem,
  327. TCustomDrawState /*State*/, TCustomDrawStage Stage, bool & /*DefaultDraw*/)
  328. {
  329. if ((SubItem == 4) && (Stage == cdPostPaint))
  330. {
  331. if (ActionImages->Width <= ListView->Columns->Items[SubItem]->Width)
  332. {
  333. const TSynchronizeChecklist::TItem * ChecklistItem =
  334. static_cast<const TSynchronizeChecklist::TItem *>(Item->Data);
  335. TRect R = Item->DisplayRect(drBounds);
  336. for (int Index = 0; Index < SubItem; Index++)
  337. {
  338. R.Left += ListView->Columns->Items[Index]->Width;
  339. }
  340. R.Left +=
  341. (ListView->Columns->Items[SubItem]->Width - ActionImages->Width) / 2;
  342. ImageList_Draw(reinterpret_cast<HIMAGELIST>(ActionImages->Handle),
  343. int(ChecklistItem->Action), ListView->Canvas->Handle,
  344. R.Left, R.Top, ILD_TRANSPARENT);
  345. }
  346. }
  347. }
  348. //---------------------------------------------------------------------------
  349. void __fastcall TSynchronizeChecklistDialog::StatusBarDrawPanel(
  350. TStatusBar * StatusBar, TStatusPanel * Panel, const TRect & Rect)
  351. {
  352. bool Possible;
  353. TSynchronizeChecklist::TAction Action = TSynchronizeChecklist::TAction(Panel->Index);
  354. switch (Action)
  355. {
  356. case TSynchronizeChecklist::saNone:
  357. Possible = true;
  358. break;
  359. case TSynchronizeChecklist::saUploadNew:
  360. Possible = ((FMode == smRemote) || (FMode == smBoth)) &&
  361. FLAGCLEAR(FParams, spTimestamp);
  362. break;
  363. case TSynchronizeChecklist::saDownloadNew:
  364. Possible = ((FMode == smLocal) || (FMode == smBoth)) &&
  365. FLAGCLEAR(FParams, spTimestamp);
  366. break;
  367. case TSynchronizeChecklist::saUploadUpdate:
  368. Possible = ((FMode == smRemote) || (FMode == smBoth));
  369. break;
  370. case TSynchronizeChecklist::saDownloadUpdate:
  371. Possible = ((FMode == smLocal) || (FMode == smBoth));
  372. break;
  373. case TSynchronizeChecklist::saDeleteRemote:
  374. Possible = (FMode == smRemote) &&
  375. FLAGCLEAR(FParams, spTimestamp);
  376. break;
  377. case TSynchronizeChecklist::saDeleteLocal:
  378. Possible = (FMode == smLocal) &&
  379. FLAGCLEAR(FParams, spTimestamp);
  380. break;
  381. default:
  382. assert(false);
  383. Possible = false;
  384. break;
  385. }
  386. int ImageIndex = Panel->Index;
  387. AnsiString PanelText;
  388. if (Possible)
  389. {
  390. PanelText = FORMAT(LoadStrPart(SYNCHRONIZE_SELECTED_ACTIONS, 1),
  391. (FormatFloat("#,##0", FChecked[Panel->Index]),
  392. FormatFloat("#,##0", FTotals[Panel->Index])));
  393. }
  394. else
  395. {
  396. PanelText = LoadStrPart(SYNCHRONIZE_SELECTED_ACTIONS, 2);
  397. }
  398. StatusBar->Canvas->TextRect(Rect, Rect.left + 18, Rect.top + 1, PanelText);
  399. ActionImages->Draw(StatusBar->Canvas,
  400. Rect.Left + 1, Rect.Top, ImageIndex, Possible);
  401. }
  402. //---------------------------------------------------------------------------
  403. int __fastcall TSynchronizeChecklistDialog::PanelAt(int X)
  404. {
  405. int Result = 0;
  406. while ((X > StatusBar->Panels->Items[Result]->Width) &&
  407. (Result < StatusBar->Panels->Count - 1))
  408. {
  409. X -= StatusBar->Panels->Items[Result]->Width;
  410. Result++;
  411. }
  412. return ((Result < StatusBar->Panels->Count - 1) ? Result : -1);
  413. }
  414. //---------------------------------------------------------------------------
  415. void __fastcall TSynchronizeChecklistDialog::StatusBarMouseMove(
  416. TObject * /*Sender*/, TShiftState /*Shift*/, int X, int /*Y*/)
  417. {
  418. AnsiString Hint;
  419. int IPanel = PanelAt(X);
  420. if (IPanel >= 0)
  421. {
  422. Hint = StatusBar->Panels->Items[IPanel]->Text;
  423. if (IPanel > 0)
  424. {
  425. Hint = FORMAT("%s\n%s", (Hint, FGeneralHint));
  426. }
  427. }
  428. if (Hint != StatusBar->Hint)
  429. {
  430. Application->CancelHint();
  431. StatusBar->Hint = Hint;
  432. }
  433. }
  434. //---------------------------------------------------------------------------
  435. void __fastcall TSynchronizeChecklistDialog::ListViewChange(
  436. TObject * /*Sender*/, TListItem * Item, TItemChange Change)
  437. {
  438. if ((Change == ctState) && (FChangingItem == Item) && (FChangingItem != NULL))
  439. {
  440. if (!FChangingItemIgnore)
  441. {
  442. assert(Item->Data != NULL);
  443. if ((FChangingItemChecked != Item->Checked) && (Item->Data != NULL))
  444. {
  445. const TSynchronizeChecklist::TItem * ChecklistItem =
  446. static_cast<const TSynchronizeChecklist::TItem *>(Item->Data);
  447. if (Item->Checked)
  448. {
  449. FChecked[int(ChecklistItem->Action)]++;
  450. FChecked[0]++;
  451. }
  452. else
  453. {
  454. FChecked[int(ChecklistItem->Action)]--;
  455. FChecked[0]--;
  456. }
  457. if (!FChangingItemMass)
  458. {
  459. UpdateControls();
  460. }
  461. }
  462. }
  463. FChangingItem = NULL;
  464. }
  465. }
  466. //---------------------------------------------------------------------------
  467. void __fastcall TSynchronizeChecklistDialog::ListViewChanging(
  468. TObject * /*Sender*/, TListItem * Item, TItemChange Change,
  469. bool & /*AllowChange*/)
  470. {
  471. if (Change == ctState)
  472. {
  473. FChangingItem = Item;
  474. FChangingItemChecked = Item->Checked;
  475. }
  476. else
  477. {
  478. assert(FChangingItem == NULL);
  479. FChangingItem = NULL;
  480. }
  481. }
  482. //---------------------------------------------------------------------------
  483. void __fastcall TSynchronizeChecklistDialog::CheckAll(bool Check)
  484. {
  485. FChangingItemMass = true;
  486. try
  487. {
  488. for (int Index = 0; Index < ListView->Items->Count; Index++)
  489. {
  490. ListView->Items->Item[Index]->Checked = Check;
  491. }
  492. }
  493. __finally
  494. {
  495. FChangingItemMass = false;
  496. }
  497. UpdateControls();
  498. }
  499. //---------------------------------------------------------------------------
  500. void __fastcall TSynchronizeChecklistDialog::CheckAllButtonClick(TObject * Sender)
  501. {
  502. CheckAll(Sender == CheckAllButton);
  503. }
  504. //---------------------------------------------------------------------------
  505. void __fastcall TSynchronizeChecklistDialog::CheckButtonClick(
  506. TObject * Sender)
  507. {
  508. FChangingItemMass = true;
  509. try
  510. {
  511. TListItem * Item = ListView->Selected;
  512. while (Item != NULL)
  513. {
  514. TComponent * Component = dynamic_cast<TComponent *>(Sender);
  515. assert(Component != NULL);
  516. Item->Checked = (Component->Tag != 0);
  517. Item = ListView->GetNextItem(Item, sdAll, TItemStates() << isSelected);
  518. }
  519. }
  520. __finally
  521. {
  522. FChangingItemMass = false;
  523. }
  524. UpdateControls();
  525. }
  526. //---------------------------------------------------------------------------
  527. void __fastcall TSynchronizeChecklistDialog::ListViewSelectItem(
  528. TObject * /*Sender*/, TListItem * /*Item*/, bool /*Selected*/)
  529. {
  530. // Delayed update of button status in case many items are being selected at once
  531. // Also change of selection causes buttons to flash, as for short period of time,
  532. // no item is selected
  533. UpdateTimer->Enabled = true;
  534. }
  535. //---------------------------------------------------------------------------
  536. void __fastcall TSynchronizeChecklistDialog::StatusBarResize(
  537. TObject * Sender)
  538. {
  539. RepaintStatusBar(dynamic_cast<TCustomStatusBar *>(Sender));
  540. }
  541. //---------------------------------------------------------------------------
  542. void __fastcall TSynchronizeChecklistDialog::UpdateTimerTimer(
  543. TObject * /*Sender*/)
  544. {
  545. UpdateTimer->Enabled = false;
  546. UpdateControls();
  547. }
  548. //---------------------------------------------------------------------------
  549. TListItem * __fastcall TSynchronizeChecklistDialog::SelectAll(bool Select, int Action,
  550. bool OnlyTheAction)
  551. {
  552. TListItem * Result = NULL;
  553. for (int Index = 0; Index < ListView->Items->Count; Index++)
  554. {
  555. TListItem * Item = ListView->Items->Item[Index];
  556. if (Action == 0)
  557. {
  558. Item->Selected = Select;
  559. if (Result == NULL)
  560. {
  561. Result = Item;
  562. }
  563. }
  564. else
  565. {
  566. const TSynchronizeChecklist::TItem * ChecklistItem =
  567. static_cast<const TSynchronizeChecklist::TItem *>(Item->Data);
  568. bool WantedAction = (int(ChecklistItem->Action) == Action);
  569. if (WantedAction || !OnlyTheAction)
  570. {
  571. Item->Selected = Select && WantedAction;
  572. if (WantedAction && (Result == NULL))
  573. {
  574. Result = Item;
  575. }
  576. }
  577. }
  578. }
  579. return Result;
  580. }
  581. //---------------------------------------------------------------------------
  582. void __fastcall TSynchronizeChecklistDialog::SelectAllItemClick(
  583. TObject * /*Sender*/)
  584. {
  585. SelectAll(true);
  586. }
  587. //---------------------------------------------------------------------------
  588. void __fastcall TSynchronizeChecklistDialog::StatusBarMouseDown(
  589. TObject * /*Sender*/, TMouseButton /*Button*/, TShiftState Shift, int X,
  590. int /*Y*/)
  591. {
  592. int IPanel = PanelAt(X);
  593. if (IPanel >= 0)
  594. {
  595. TListItem * Item = SelectAll(true, IPanel, Shift.Contains(ssCtrl));
  596. if (Item != NULL)
  597. {
  598. Item->MakeVisible(false);
  599. Item->Focused = true;
  600. ListView->SetFocus();
  601. }
  602. }
  603. }
  604. //---------------------------------------------------------------------------
  605. int __fastcall TSynchronizeChecklistDialog::CompareNumber(__int64 Value1,
  606. __int64 Value2)
  607. {
  608. int Result;
  609. if (Value1 < Value2)
  610. {
  611. Result = -1;
  612. }
  613. else if (Value1 == Value2)
  614. {
  615. Result = 0;
  616. }
  617. else
  618. {
  619. Result = 1;
  620. }
  621. return Result;
  622. }
  623. //---------------------------------------------------------------------------
  624. void __fastcall TSynchronizeChecklistDialog::ListViewCompare(
  625. TObject * /*Sender*/, TListItem * Item1, TListItem * Item2, int /*Data*/,
  626. int & Compare)
  627. {
  628. const TSynchronizeChecklist::TItem * ChecklistItem1 =
  629. static_cast<const TSynchronizeChecklist::TItem *>(Item1->Data);
  630. const TSynchronizeChecklist::TItem * ChecklistItem2 =
  631. static_cast<const TSynchronizeChecklist::TItem *>(Item2->Data);
  632. TIEListViewColProperties * ColProperties =
  633. dynamic_cast<TIEListViewColProperties *>(ListView->ColProperties);
  634. switch (ColProperties->SortColumn)
  635. {
  636. case 0: // name
  637. Compare = CompareText(ChecklistItem1->FileName, ChecklistItem2->FileName);
  638. break;
  639. // sorting by local and remote dir is the same
  640. case 1: // local dir
  641. case 5: // remote dir
  642. Compare = 0; // default sorting
  643. break;
  644. case 2: // local size
  645. Compare = CompareNumber(ChecklistItem1->Local.Size, ChecklistItem2->Local.Size);
  646. break;
  647. case 3: // local changed
  648. Compare = CompareFileTime(ChecklistItem1->Local.Modification,
  649. ChecklistItem2->Local.Modification);
  650. break;
  651. case 4: // action
  652. Compare = CompareNumber(ChecklistItem1->Action, ChecklistItem2->Action);
  653. break;
  654. case 6: // remote size
  655. Compare = CompareNumber(ChecklistItem1->Remote.Size, ChecklistItem2->Remote.Size);
  656. break;
  657. case 7: // remote changed
  658. Compare = CompareFileTime(ChecklistItem1->Remote.Modification,
  659. ChecklistItem2->Remote.Modification);
  660. break;
  661. }
  662. if (Compare == 0)
  663. {
  664. if (!ChecklistItem1->Local.Directory.IsEmpty())
  665. {
  666. Compare = CompareText(ChecklistItem1->Local.Directory, ChecklistItem2->Local.Directory);
  667. }
  668. else
  669. {
  670. assert(!ChecklistItem1->Remote.Directory.IsEmpty());
  671. Compare = CompareText(ChecklistItem1->Remote.Directory, ChecklistItem2->Remote.Directory);
  672. }
  673. if (Compare == 0)
  674. {
  675. Compare = CompareText(ChecklistItem1->FileName, ChecklistItem2->FileName);
  676. }
  677. }
  678. if (!ColProperties->SortAscending)
  679. {
  680. Compare = -Compare;
  681. }
  682. }
  683. //---------------------------------------------------------------------------
  684. void __fastcall TSynchronizeChecklistDialog::ListViewSecondaryColumnHeader(
  685. TCustomIEListView * /*Sender*/, int Index, int & SecondaryColumn)
  686. {
  687. // "remote dir" column is sorting alias for "local dir" column
  688. if (Index == 5)
  689. {
  690. SecondaryColumn = 1;
  691. }
  692. else
  693. {
  694. SecondaryColumn = -1;
  695. }
  696. }
  697. //---------------------------------------------------------------------------
  698. void __fastcall TSynchronizeChecklistDialog::ListViewContextPopup(
  699. TObject * Sender, TPoint & MousePos, bool & Handled)
  700. {
  701. // to update source popup menu before TBX menu is created
  702. UpdateControls();
  703. MenuPopup(Sender, MousePos, Handled);
  704. }
  705. //---------------------------------------------------------------------------