Properties.cpp 20 KB

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