1
0

Properties.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. //---------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "WinInterface.h"
  5. #include "Properties.h"
  6. #include <VCLCommon.h>
  7. #include <Common.h>
  8. #include <Terminal.h>
  9. #include <TextsWin.h>
  10. #include <GUITools.h>
  11. #include <CoreMain.h>
  12. #include <Tools.h>
  13. #include <BaseUtils.hpp>
  14. //---------------------------------------------------------------------
  15. #pragma link "PathLabel"
  16. #pragma link "Rights"
  17. #pragma link "RightsExt"
  18. #ifndef NO_RESOURCES
  19. #pragma resource "*.dfm"
  20. #endif
  21. //---------------------------------------------------------------------
  22. bool __fastcall DoPropertiesDialog(TStrings * FileList,
  23. const UnicodeString Directory, const TRemoteTokenList * GroupList,
  24. const TRemoteTokenList * UserList, TStrings * ChecksumAlgs,
  25. TRemoteProperties * Properties,
  26. int AllowedChanges, bool UserGroupByID, TCalculateSizeEvent OnCalculateSize,
  27. TCalculateChecksumEvent OnCalculateChecksum)
  28. {
  29. bool Result;
  30. TPropertiesDialog * PropertiesDialog = new TPropertiesDialog(Application,
  31. FileList, Directory, GroupList, UserList, ChecksumAlgs, AllowedChanges, UserGroupByID,
  32. OnCalculateSize, OnCalculateChecksum);
  33. try
  34. {
  35. Result = PropertiesDialog->Execute(*Properties);
  36. }
  37. __finally
  38. {
  39. delete PropertiesDialog;
  40. }
  41. return Result;
  42. }
  43. //---------------------------------------------------------------------
  44. __fastcall TPropertiesDialog::TPropertiesDialog(TComponent* AOwner,
  45. TStrings * FileList, const UnicodeString Directory,
  46. const TRemoteTokenList * GroupList, const TRemoteTokenList * UserList,
  47. TStrings * ChecksumAlgs,
  48. int AllowedChanges, bool UserGroupByID, TCalculateSizeEvent OnCalculateSize,
  49. TCalculateChecksumEvent OnCalculateChecksum)
  50. : TForm(AOwner)
  51. {
  52. FOnCalculateSize = OnCalculateSize;
  53. FOnCalculateChecksum = OnCalculateChecksum;
  54. RightsFrame->OnChange = ControlChange;
  55. FFileList = new TStringList();
  56. FFileList->Assign(FileList);
  57. FAllowedChanges = AllowedChanges;
  58. FUserGroupByID = UserGroupByID;
  59. FAllowCalculateStats = false;
  60. FStatsNotCalculated = false;
  61. FChecksumLoaded = false;
  62. FMultipleChecksum = false;
  63. LocationLabel->Caption = Directory;
  64. FGroupList = GroupList;
  65. FUserList = UserList;
  66. FChecksumAlgs = ChecksumAlgs;
  67. ReadOnlyControl(ChecksumEdit);
  68. ChecksumUnknownLabel->Caption = LoadStr(PROPERTIES_CHECKSUM_UNKNOWN);
  69. LoadInfo();
  70. UseSystemSettings(this);
  71. }
  72. //---------------------------------------------------------------------------
  73. __fastcall TPropertiesDialog::~TPropertiesDialog()
  74. {
  75. delete FFileList;
  76. FFileList = NULL;
  77. }
  78. //---------------------------------------------------------------------
  79. bool __fastcall TPropertiesDialog::Execute(TRemoteProperties & Properties)
  80. {
  81. SetFileProperties(Properties);
  82. PageControl->ActivePage = CommonSheet;
  83. if (FAllowedChanges & cpGroup) ActiveControl = GroupComboBox;
  84. else
  85. if (FAllowedChanges & cpOwner) ActiveControl = OwnerComboBox;
  86. else
  87. if (FAllowedChanges & cpMode) ActiveControl = RightsFrame;
  88. else ActiveControl = CancelButton;
  89. if (DebugAlwaysTrue(FChecksumAlgs != NULL))
  90. {
  91. ChecksumAlgEdit->Items->Assign(FChecksumAlgs);
  92. int ChecksumIndex = FChecksumAlgs->IndexOf(GUIConfiguration->ChecksumAlg);
  93. if (ChecksumIndex < 0)
  94. {
  95. ChecksumIndex = 0;
  96. }
  97. ChecksumAlgEdit->ItemIndex = ChecksumIndex;
  98. }
  99. ResetChecksum();
  100. UpdateControls();
  101. bool Result = (ShowModal() == DefaultResult());
  102. if (Result)
  103. {
  104. Properties = GetFileProperties();
  105. }
  106. return Result;
  107. }
  108. //---------------------------------------------------------------------------
  109. TModalResult __fastcall TPropertiesDialog::DefaultResult()
  110. {
  111. // Fallback when ChecksumButton is default
  112. return ::DefaultResult(this, OkButton);
  113. }
  114. //---------------------------------------------------------------------------
  115. UnicodeString __fastcall TPropertiesDialog::LoadRemoteToken(
  116. const TRemoteToken & Token)
  117. {
  118. UnicodeString Result;
  119. if (FUserGroupByID)
  120. {
  121. if (Token.IDValid)
  122. {
  123. if (Token.NameValid)
  124. {
  125. Result = FORMAT(L"%s [%d]", (Token.Name, int(Token.ID)));
  126. }
  127. else
  128. {
  129. Result = FORMAT(L"[%d]", (int(Token.ID)));
  130. }
  131. }
  132. else
  133. {
  134. // be it valid or not
  135. Result = Token.Name;
  136. }
  137. }
  138. else
  139. {
  140. // what if name is not filled in?
  141. Result = Token.Name;
  142. }
  143. return Result;
  144. }
  145. //---------------------------------------------------------------------------
  146. void __fastcall TPropertiesDialog::LoadRemoteToken(
  147. TComboBox * ComboBox, bool Valid, const TRemoteToken & Token)
  148. {
  149. if (Valid)
  150. {
  151. ComboBox->Text = LoadRemoteToken(Token);
  152. }
  153. else
  154. {
  155. ComboBox->Text = L"";
  156. }
  157. }
  158. //---------------------------------------------------------------------------
  159. void __fastcall TPropertiesDialog::LoadRemoteTokens(TComboBox * ComboBox,
  160. const TRemoteTokenList * List)
  161. {
  162. TStrings * Items = ComboBox->Items;
  163. Items->BeginUpdate();
  164. try
  165. {
  166. Items->Clear();
  167. if (List != NULL)
  168. {
  169. int Count = List->Count();
  170. for (int Index = 0; Index < Count; Index++)
  171. {
  172. Items->Add(LoadRemoteToken(*List->Token(Index)));
  173. }
  174. }
  175. }
  176. __finally
  177. {
  178. Items->EndUpdate();
  179. }
  180. }
  181. //---------------------------------------------------------------------------
  182. void __fastcall TPropertiesDialog::LoadInfo()
  183. {
  184. DebugAssert(FFileList->Count > 0);
  185. FMultiple = FFileList->Count > 1;
  186. FMultipleChecksum = FMultiple;
  187. FAllowCalculateStats = false;
  188. FStatsNotCalculated = false;
  189. __int64 FilesSize = 0;
  190. TCalculateSizeStats Stats;
  191. for (int Index = 0; Index < FFileList->Count; Index++)
  192. {
  193. TRemoteFile * File = (TRemoteFile *)(FFileList->Objects[Index]);
  194. if (File->IsDirectory)
  195. {
  196. Stats.Directories++;
  197. // we should use TTerminal::CanRecurseToDirectory instead
  198. if (!File->IsSymLink)
  199. {
  200. FAllowCalculateStats = true;
  201. FStatsNotCalculated = true;
  202. FMultipleChecksum = true;
  203. }
  204. }
  205. else
  206. {
  207. Stats.Files++;
  208. }
  209. if (File->IsSymLink)
  210. {
  211. Stats.SymLinks++;
  212. }
  213. FilesSize += File->Size;
  214. }
  215. LoadRemoteTokens(GroupComboBox, FGroupList);
  216. LoadRemoteTokens(OwnerComboBox, FUserList);
  217. RightsFrame->AllowAddXToDirectories = (Stats.Directories > 0);
  218. RecursiveCheck->Visible = (Stats.Directories > 0);
  219. RecursiveBevel->Visible = (Stats.Directories > 0);
  220. LoadStats(FilesSize, Stats);
  221. RightsFrame->AllowUndef = FMultiple;
  222. if (!FMultiple)
  223. {
  224. TRemoteFile * File = (TRemoteFile *)(FFileList->Objects[0]);
  225. DebugAssert(File);
  226. UpdateFileImage();
  227. LinksToLabelLabel->Visible = File->IsSymLink;
  228. LinksToLabel->Visible = File->IsSymLink;
  229. if (File->IsSymLink)
  230. {
  231. LinksToLabel->Caption = File->LinkTo;
  232. }
  233. RightsFrame->AllowAddXToDirectories = File->IsDirectory;
  234. Caption = FMTLOAD(PROPERTIES_FILE_CAPTION, (File->FileName));
  235. RecursiveCheck->Visible = File->IsDirectory;
  236. RecursiveBevel->Visible = File->IsDirectory;
  237. }
  238. else
  239. {
  240. Caption = FMTLOAD(PROPERTIES_FILES_CAPTION, (FFileList->Strings[0]));
  241. LinksToLabelLabel->Hide();
  242. LinksToLabel->Hide();
  243. LoadDialogImage(FileIconImage, L"Multiple Files");
  244. }
  245. ChecksumGroup->Visible = !FMultipleChecksum;
  246. ChecksumView->Visible = FMultipleChecksum;
  247. }
  248. //---------------------------------------------------------------------------
  249. void __fastcall TPropertiesDialog::UpdateFileImage()
  250. {
  251. TImageList * ImageList = ShellImageListForControl(this, ilsLarge);
  252. FileIconImage->Picture->Bitmap = NULL;
  253. TRemoteFile * File = (TRemoteFile *)(FFileList->Objects[0]);
  254. // shell image list does not have fixed large icon size
  255. // (it is probably 32x32 min, but can be larger, on xp it is 48x48 if
  256. // large icons are enabled, on vista can be even larger).
  257. // so we stretch (shrink) the icon to 32x32 here to be sure.
  258. Graphics::TBitmap * Bitmap = new Graphics::TBitmap;
  259. try
  260. {
  261. ImageList->GetBitmap(File->IconIndex, Bitmap);
  262. int Size = DialogImageSize(this);
  263. // Use exact DPI-scaled size, not approximate scaling by font size.
  264. // Otherwise we stretch icons unnecessarily because the canvas
  265. // is one or two pixels off the icon size
  266. FileIconImage->Width = Size;
  267. FileIconImage->Height = Size;
  268. FileIconImage->Picture->Bitmap->Width = Size;
  269. FileIconImage->Picture->Bitmap->Height = Size;
  270. FileIconImage->Picture->Bitmap->Canvas->StretchDraw(
  271. TRect(0, 0, Size, Size),
  272. Bitmap);
  273. }
  274. __finally
  275. {
  276. delete Bitmap;
  277. }
  278. }
  279. //---------------------------------------------------------------------------
  280. void __fastcall TPropertiesDialog::LoadStats(__int64 FilesSize,
  281. const TCalculateSizeStats & Stats)
  282. {
  283. UnicodeString SizeStr;
  284. UnicodeString FilesStr;
  285. if (FStatsNotCalculated)
  286. {
  287. SizeStr = LoadStr(PROPERTIES_UNKNOWN_SIZE);
  288. }
  289. else
  290. {
  291. SizeStr = FormatBytes(FilesSize);
  292. UnicodeString SizeUnorderedStr = FormatBytes(FilesSize, fbNone);
  293. if (SizeStr != SizeUnorderedStr)
  294. {
  295. SizeStr = FORMAT(L"%s (%s)", (SizeStr, SizeUnorderedStr));
  296. }
  297. }
  298. if (((Stats.Files + Stats.Directories) == 0) && !FMultiple)
  299. {
  300. TRemoteFile * File = (TRemoteFile *)(FFileList->Objects[0]);
  301. DebugAssert(File != NULL);
  302. FilesStr = File->FileName;
  303. }
  304. else
  305. {
  306. if (Stats.Files > 0)
  307. {
  308. FilesStr = (Stats.Files == 1) ? FMTLOAD(PROPERTIES_FILE, (Stats.Files)) :
  309. FMTLOAD(PROPERTIES_FILES, (Stats.Files));
  310. if (Stats.Directories > 0)
  311. {
  312. FilesStr = FORMAT(L"%s, ", (FilesStr));
  313. }
  314. }
  315. if (Stats.Directories > 0)
  316. {
  317. FilesStr += (Stats.Directories == 1) ? FMTLOAD(PROPERTIES_DIRECTORY, (Stats.Directories)) :
  318. FMTLOAD(PROPERTIES_DIRECTORIES, (Stats.Directories));
  319. }
  320. if (Stats.SymLinks > 0)
  321. {
  322. UnicodeString SymLinksStr;
  323. SymLinksStr = (Stats.SymLinks == 1) ? FMTLOAD(PROPERTIES_SYMLINK, (Stats.SymLinks)) :
  324. FMTLOAD(PROPERTIES_SYMLINKS, (Stats.SymLinks));
  325. FilesStr = FORMAT(L"%s (%s)", (FilesStr, SymLinksStr));
  326. }
  327. }
  328. SizeLabel->Caption = SizeStr;
  329. FileLabel->Caption = FilesStr;
  330. }
  331. //---------------------------------------------------------------------------
  332. void __fastcall TPropertiesDialog::SetFileProperties(const TRemoteProperties & value)
  333. {
  334. TValidProperties Valid;
  335. if (value.Valid.Contains(vpRights) && FAllowedChanges & cpMode) Valid << vpRights;
  336. if (value.Valid.Contains(vpOwner) && FAllowedChanges & cpOwner) Valid << vpOwner;
  337. if (value.Valid.Contains(vpGroup) && FAllowedChanges & cpGroup) Valid << vpGroup;
  338. FOrigProperties = value;
  339. FOrigProperties.Valid = Valid;
  340. FOrigProperties.Recursive = false;
  341. if (value.Valid.Contains(vpRights))
  342. {
  343. RightsFrame->Rights = value.Rights;
  344. RightsFrame->AddXToDirectories = value.AddXToDirectories;
  345. }
  346. else
  347. {
  348. RightsFrame->Rights = TRights();
  349. RightsFrame->AddXToDirectories = false;
  350. }
  351. LoadRemoteToken(GroupComboBox, value.Valid.Contains(vpGroup), value.Group);
  352. LoadRemoteToken(OwnerComboBox, value.Valid.Contains(vpOwner), value.Owner);
  353. RecursiveCheck->Checked = value.Recursive;
  354. UpdateControls();
  355. }
  356. //---------------------------------------------------------------------------
  357. void __fastcall TPropertiesDialog::StoreRemoteToken(unsigned int ID,
  358. const UnicodeString & Text, const TRemoteTokenList * List, TRemoteToken & Result)
  359. {
  360. DebugAssert(List != NULL);
  361. const TRemoteToken * Token = List->Find(ID);
  362. if (Token == NULL)
  363. {
  364. Result.ID = ID;
  365. Result.Name = Text;
  366. }
  367. else
  368. {
  369. Result = *Token;
  370. }
  371. }
  372. //---------------------------------------------------------------------------
  373. TRemoteToken __fastcall TPropertiesDialog::StoreRemoteToken(const TRemoteToken & Orig,
  374. UnicodeString Text, int Message, const TRemoteTokenList * List)
  375. {
  376. TRemoteToken Result;
  377. Text = Text.Trim();
  378. if (!Text.IsEmpty())
  379. {
  380. if (FUserGroupByID)
  381. {
  382. DebugAssert(List != NULL);
  383. int IDStart = Text.LastDelimiter(L"[");
  384. if (!Text.IsEmpty() && (IDStart >= 0) && (Text[Text.Length()] == L']'))
  385. {
  386. int ID;
  387. UnicodeString IDStr = Text.SubString(IDStart + 1, Text.Length() - IDStart - 1);
  388. if (!TryStrToInt(IDStr, ID))
  389. {
  390. throw Exception(Message);
  391. }
  392. else
  393. {
  394. StoreRemoteToken(ID, Text.SubString(1, IDStart - 1).Trim(), List, Result);
  395. }
  396. }
  397. else
  398. {
  399. const TRemoteToken * Token = List->Find(Text);
  400. if (Token == NULL)
  401. {
  402. int ID;
  403. if (TryStrToInt(Text, ID))
  404. {
  405. StoreRemoteToken(ID, Text, List, Result);
  406. }
  407. else
  408. {
  409. throw Exception(MainInstructions(FMTLOAD(PROPERTIES_UNKNOWN_TOKEN, (Text))));
  410. }
  411. }
  412. else
  413. {
  414. Result = *Token;
  415. }
  416. }
  417. }
  418. else
  419. {
  420. Result.Name = Text;
  421. }
  422. }
  423. if (LoadRemoteToken(Result) == LoadRemoteToken(Orig))
  424. {
  425. Result = Orig;
  426. }
  427. return Result;
  428. }
  429. //---------------------------------------------------------------------------
  430. void __fastcall TPropertiesDialog::StoreRemoteToken(TComboBox * ComboBox,
  431. int ChangeFlag, TValidProperty PropertyFlag, const TRemoteToken & Orig,
  432. TRemoteToken & Token, int Message, const TRemoteTokenList * List,
  433. TRemoteProperties & Properties)
  434. {
  435. UnicodeString Text = ComboBox->Text.Trim();
  436. if (FLAGSET(FAllowedChanges, ChangeFlag))
  437. {
  438. Token = StoreRemoteToken(Orig, Text, Message, List);
  439. if (Token.IsSet)
  440. {
  441. Properties.Valid << PropertyFlag;
  442. }
  443. }
  444. }
  445. //---------------------------------------------------------------------------
  446. TRemoteProperties __fastcall TPropertiesDialog::GetFileProperties()
  447. {
  448. TRemoteProperties Result;
  449. if (FAllowedChanges & cpMode)
  450. {
  451. Result.Valid << vpRights;
  452. Result.Rights = RightsFrame->Rights;
  453. Result.AddXToDirectories = RightsFrame->AddXToDirectories;
  454. }
  455. StoreRemoteToken(GroupComboBox, cpGroup, vpGroup, FOrigProperties.Group,
  456. Result.Group, PROPERTIES_INVALID_GROUP, FGroupList, Result);
  457. StoreRemoteToken(OwnerComboBox, cpOwner, vpOwner, FOrigProperties.Owner,
  458. Result.Owner, PROPERTIES_INVALID_OWNER, FUserList, Result);
  459. Result.Recursive = RecursiveCheck->Checked;
  460. return Result;
  461. }
  462. //---------------------------------------------------------------------------
  463. void __fastcall TPropertiesDialog::ControlChange(TObject * /*Sender*/)
  464. {
  465. if (Visible)
  466. {
  467. UpdateControls();
  468. }
  469. }
  470. //---------------------------------------------------------------------------
  471. void __fastcall TPropertiesDialog::UpdateControls()
  472. {
  473. // No point enabling recursive check if there's no change allowed (supported),
  474. // i.e. with WebDAV.
  475. EnableControl(RecursiveCheck, ((FAllowedChanges & (cpGroup | cpOwner | cpMode)) != 0));
  476. bool Allow;
  477. try
  478. {
  479. Allow =
  480. !TRemoteProperties::ChangedProperties(FOrigProperties, GetFileProperties()).Valid.Empty() ||
  481. (RecursiveCheck->Enabled && RecursiveCheck->Checked);
  482. }
  483. catch(...)
  484. {
  485. // when properties are invalid allow submitting the form,
  486. // because that reveals the cause to the user, otherwise he/she
  487. // may not be able to tell what is wrong
  488. Allow = true;
  489. }
  490. EnableControl(OkButton, Allow);
  491. EnableControl(GroupComboBox, FAllowedChanges & cpGroup);
  492. EnableControl(OwnerComboBox, FAllowedChanges & cpOwner);
  493. EnableControl(RightsFrame, FAllowedChanges & cpMode);
  494. CalculateSizeButton->Visible = FAllowCalculateStats;
  495. if (!FMultiple)
  496. {
  497. // when setting properties for one file only, allow undef state
  498. // only when the input right explicitly requires it or
  499. // when "recursive" is on (possible for directory only).
  500. bool AllowUndef =
  501. (FOrigProperties.Valid.Contains(vpRights) &&
  502. FOrigProperties.Rights.AllowUndef) ||
  503. (RecursiveCheck->Checked);
  504. if (!AllowUndef)
  505. {
  506. // when disallowing undef state, make sure, all undef are turned into unset
  507. RightsFrame->Rights = TRights(RightsFrame->Rights.NumberSet);
  508. }
  509. RightsFrame->AllowUndef = AllowUndef;
  510. }
  511. EnableControl(ChecksumSheet, ChecksumSupported());
  512. EnableControl(ChecksumButton, ChecksumSheet->Enabled &&
  513. !ChecksumAlgEdit->Text.IsEmpty());
  514. ChecksumEdit->Visible = !ChecksumEdit->Text.IsEmpty();
  515. ChecksumUnknownLabel->Visible = !ChecksumEdit->Visible;
  516. DefaultButton(ChecksumButton, ChecksumAlgEdit->Focused());
  517. DefaultButton(OkButton, !ChecksumAlgEdit->Focused());
  518. }
  519. //---------------------------------------------------------------------------
  520. void __fastcall TPropertiesDialog::FormCloseQuery(TObject * /*Sender*/,
  521. bool & /*CanClose*/)
  522. {
  523. if (ModalResult == DefaultResult())
  524. {
  525. ExitActiveControl(this);
  526. }
  527. }
  528. //---------------------------------------------------------------------------
  529. void __fastcall TPropertiesDialog::CalculateSizeButtonClick(
  530. TObject * /*Sender*/)
  531. {
  532. DebugAssert(FOnCalculateSize != NULL);
  533. bool DoClose = false;
  534. Enabled = false;
  535. try
  536. {
  537. __int64 Size;
  538. TCalculateSizeStats Stats;
  539. FOnCalculateSize(FFileList, Size, Stats, DoClose);
  540. FStatsNotCalculated = false;
  541. LoadStats(Size, Stats);
  542. }
  543. __finally
  544. {
  545. Enabled = true;
  546. if (DoClose)
  547. {
  548. Close();
  549. }
  550. }
  551. }
  552. //---------------------------------------------------------------------------
  553. void __fastcall TPropertiesDialog::HelpButtonClick(TObject * /*Sender*/)
  554. {
  555. FormHelp(this);
  556. }
  557. //---------------------------------------------------------------------------
  558. void __fastcall TPropertiesDialog::ResetChecksum()
  559. {
  560. ChecksumView->Items->Clear();
  561. ChecksumEdit->Text = UnicodeString();
  562. AutoSizeListColumnsWidth(ChecksumView);
  563. }
  564. //---------------------------------------------------------------------------
  565. void __fastcall TPropertiesDialog::CalculateChecksum()
  566. {
  567. DebugAssert(FOnCalculateChecksum != NULL);
  568. ResetChecksum();
  569. FChecksumLoaded = true;
  570. FAlgUsed = UnicodeString();
  571. bool DoClose = false;
  572. try
  573. {
  574. FOnCalculateChecksum(ChecksumAlgEdit->Text, FFileList, CalculatedChecksum, DoClose);
  575. }
  576. __finally
  577. {
  578. if (DoClose)
  579. {
  580. Close();
  581. }
  582. }
  583. // If we successfully used the selected checksum, remember it (in normalized form)
  584. if (!FAlgUsed.IsEmpty())
  585. {
  586. GUIConfiguration->ChecksumAlg = FAlgUsed;
  587. }
  588. AutoSizeListColumnsWidth(ChecksumView);
  589. }
  590. //---------------------------------------------------------------------------
  591. void __fastcall TPropertiesDialog::CalculatedChecksum(
  592. const UnicodeString & FileName, const UnicodeString & Alg,
  593. const UnicodeString & Hash)
  594. {
  595. if (FMultipleChecksum)
  596. {
  597. TListItem * Item = ChecksumView->Items->Add();
  598. Item->Caption = FileName;
  599. Item->SubItems->Add(Hash);
  600. // optimization
  601. int TopIndex = ListView_GetTopIndex(ChecksumView->Handle);
  602. int Index = Item->Index;
  603. if ((TopIndex <= Index) &&
  604. (Index <= TopIndex + ChecksumView->VisibleRowCount))
  605. {
  606. AutoSizeListColumnsWidth(ChecksumView);
  607. }
  608. }
  609. else
  610. {
  611. ChecksumEdit->Text = Hash;
  612. }
  613. FAlgUsed = Alg;
  614. UpdateControls();
  615. }
  616. //---------------------------------------------------------------------------
  617. void __fastcall TPropertiesDialog::NeedChecksum()
  618. {
  619. if (!FChecksumLoaded && ChecksumSupported())
  620. {
  621. CalculateChecksum();
  622. }
  623. }
  624. //---------------------------------------------------------------------------
  625. bool __fastcall TPropertiesDialog::ChecksumSupported()
  626. {
  627. return (FOnCalculateChecksum != NULL);
  628. }
  629. //---------------------------------------------------------------------------
  630. void __fastcall TPropertiesDialog::ChecksumButtonClick(TObject * /*Sender*/)
  631. {
  632. CalculateChecksum();
  633. }
  634. //---------------------------------------------------------------------------
  635. void __fastcall TPropertiesDialog::PageControlChange(TObject * /*Sender*/)
  636. {
  637. if (PageControl->ActivePage == ChecksumSheet)
  638. {
  639. NeedChecksum();
  640. }
  641. }
  642. //---------------------------------------------------------------------------
  643. void __fastcall TPropertiesDialog::ChecksumAlgEditChange(TObject * /*Sender*/)
  644. {
  645. ResetChecksum();
  646. UpdateControls();
  647. }
  648. //---------------------------------------------------------------------------
  649. void __fastcall TPropertiesDialog::CopyClick(TObject * Sender)
  650. {
  651. TInstantOperationVisualizer Visualizer;
  652. TListView * ListView = dynamic_cast<TListView *>(GetPopupComponent(Sender));
  653. DebugAssert(ListView != NULL);
  654. int Count = 0;
  655. UnicodeString SingleText;
  656. UnicodeString Text;
  657. TListItem * Item = ListView->GetNextItem(NULL, sdAll, TItemStates() << isSelected);
  658. while (Item != NULL)
  659. {
  660. DebugAssert(Item->Selected);
  661. SingleText = Item->SubItems->Strings[0];
  662. Text += FORMAT(L"%s = %s\r\n", (Item->Caption, Item->SubItems->Strings[0]));
  663. Count++;
  664. Item = ListView->GetNextItem(Item, sdAll, TItemStates() << isSelected);
  665. }
  666. CopyToClipboard(Count == 1 ? SingleText : Text);
  667. }
  668. //---------------------------------------------------------------------------
  669. void __fastcall TPropertiesDialog::ChecksumViewContextPopup(
  670. TObject * Sender, TPoint & MousePos, bool & Handled)
  671. {
  672. MenuPopup(Sender, MousePos, Handled);
  673. }
  674. //---------------------------------------------------------------------------
  675. void __fastcall TPropertiesDialog::ResolveRemoteToken(
  676. const TRemoteToken & Orig, int Message, TComboBox * ComboBox,
  677. const TRemoteTokenList * List)
  678. {
  679. try
  680. {
  681. ComboBox->Text =
  682. LoadRemoteToken(StoreRemoteToken(Orig, ComboBox->Text, Message, List));
  683. }
  684. catch(...)
  685. {
  686. ComboBox->SetFocus();
  687. throw;
  688. }
  689. }
  690. //---------------------------------------------------------------------------
  691. void __fastcall TPropertiesDialog::GroupComboBoxExit(TObject * Sender)
  692. {
  693. ResolveRemoteToken(FOrigProperties.Group, PROPERTIES_INVALID_GROUP,
  694. dynamic_cast<TComboBox *>(Sender), FGroupList);
  695. }
  696. //---------------------------------------------------------------------------
  697. void __fastcall TPropertiesDialog::OwnerComboBoxExit(TObject * Sender)
  698. {
  699. ResolveRemoteToken(FOrigProperties.Owner, PROPERTIES_INVALID_OWNER,
  700. dynamic_cast<TComboBox *>(Sender), FUserList);
  701. }
  702. //---------------------------------------------------------------------------
  703. void __fastcall TPropertiesDialog::FormShow(TObject * /*Sender*/)
  704. {
  705. UpdateControls();
  706. }
  707. //---------------------------------------------------------------------------
  708. void __fastcall TPropertiesDialog::CMDpiChanged(TMessage & Message)
  709. {
  710. TForm::Dispatch(&Message);
  711. if (!FMultiple)
  712. {
  713. UpdateFileImage();
  714. }
  715. }
  716. //---------------------------------------------------------------------------
  717. void __fastcall TPropertiesDialog::Dispatch(void * Message)
  718. {
  719. TMessage * M = reinterpret_cast<TMessage*>(Message);
  720. if (M->Msg == CM_DPICHANGED)
  721. {
  722. CMDpiChanged(*M);
  723. }
  724. else
  725. {
  726. TForm::Dispatch(Message);
  727. }
  728. }
  729. //---------------------------------------------------------------------------