Properties.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  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. //---------------------------------------------------------------------
  12. #pragma link "PathLabel"
  13. #pragma link "Rights"
  14. #pragma link "RightsExt"
  15. #pragma resource "*.dfm"
  16. //---------------------------------------------------------------------
  17. bool __fastcall DoPropertiesDialog(TStrings * FileList,
  18. const AnsiString Directory, TStrings * GroupList, TStrings * UserList,
  19. TRemoteProperties * Properties, int AllowedChanges,
  20. TTerminal * Terminal)
  21. {
  22. bool Result;
  23. TPropertiesDialog * PropertiesDialog = new TPropertiesDialog(Application);
  24. try
  25. {
  26. PropertiesDialog->AllowedChanges = AllowedChanges;
  27. PropertiesDialog->Directory = Directory;
  28. PropertiesDialog->FileList = FileList;
  29. PropertiesDialog->GroupList = GroupList;
  30. PropertiesDialog->UserList = UserList;
  31. PropertiesDialog->FileProperties = *Properties;
  32. PropertiesDialog->Terminal = Terminal;
  33. Result = PropertiesDialog->Execute();
  34. if (Result)
  35. {
  36. *Properties = PropertiesDialog->FileProperties;
  37. }
  38. }
  39. __finally
  40. {
  41. delete PropertiesDialog;
  42. }
  43. return Result;
  44. }
  45. //---------------------------------------------------------------------
  46. __fastcall TPropertiesDialog::TPropertiesDialog(TComponent* AOwner)
  47. : TForm(AOwner)
  48. {
  49. RightsFrame->OnChange = ControlChange;
  50. FGroupsSet = False;
  51. TSHFileInfo FileInfo;
  52. FShellImageList = new TImageList(this);
  53. FShellImageList->Handle = SHGetFileInfo("", 0, &FileInfo, sizeof(FileInfo),
  54. SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
  55. FShellImageList->ShareImages = True;
  56. FFileList = new TStringList();
  57. FAllowCalculateStats = false;
  58. FStatsNotCalculated = false;
  59. UseSystemSettings(this);
  60. }
  61. //---------------------------------------------------------------------------
  62. __fastcall TPropertiesDialog::~TPropertiesDialog()
  63. {
  64. delete FFileList;
  65. FFileList = NULL;
  66. delete FShellImageList;
  67. FShellImageList = NULL;
  68. }
  69. //---------------------------------------------------------------------
  70. bool __fastcall TPropertiesDialog::Execute()
  71. {
  72. bool Result;
  73. FPrevTerminalClose = NULL;;
  74. if (FTerminal)
  75. {
  76. FPrevTerminalClose = FTerminal->OnClose;
  77. // used instead of previous TTerminalManager::OnChangeTerminal
  78. FTerminal->OnClose = TerminalClose;
  79. }
  80. try
  81. {
  82. if (AllowedChanges & cpGroup) ActiveControl = GroupComboBox;
  83. else
  84. if (AllowedChanges & cpOwner) ActiveControl = OwnerComboBox;
  85. else
  86. if (AllowedChanges & cpMode) ActiveControl = RightsFrame;
  87. else ActiveControl = OkButton;
  88. UpdateControls();
  89. Result = (ShowModal() == mrOk);
  90. }
  91. __finally
  92. {
  93. if (FTerminal)
  94. {
  95. assert(FTerminal->OnClose == TerminalClose);
  96. FTerminal->OnClose = FPrevTerminalClose;
  97. }
  98. }
  99. return Result;
  100. }
  101. //---------------------------------------------------------------------------
  102. void __fastcall TPropertiesDialog::TerminalClose(TObject * Sender)
  103. {
  104. Close();
  105. Terminal = NULL;
  106. if (FPrevTerminalClose)
  107. {
  108. FPrevTerminalClose(Sender);
  109. }
  110. }
  111. //---------------------------------------------------------------------------
  112. void __fastcall TPropertiesDialog::SetFileList(TStrings * value)
  113. {
  114. if (FFileList != value)
  115. {
  116. FFileList->Assign(value);
  117. LoadInfo();
  118. FGroupsSet = false;
  119. FUsersSet = false;
  120. }
  121. }
  122. //---------------------------------------------------------------------------
  123. void __fastcall TPropertiesDialog::LoadInfo()
  124. {
  125. if (FFileList)
  126. {
  127. assert(FFileList->Count > 0);
  128. FAllowCalculateStats = false;
  129. FStatsNotCalculated = false;
  130. FileIconImage->Picture->Bitmap = NULL;
  131. __int64 FilesSize;
  132. TCalculateSizeStats Stats;
  133. RightsFrame->AllowUndef = Multiple;
  134. if (!Multiple)
  135. {
  136. TRemoteFile * File = (TRemoteFile *)(FFileList->Objects[0]);
  137. assert(File && FShellImageList);
  138. FShellImageList->GetIcon(File->IconIndex, FileIconImage->Picture->Icon);
  139. if (!FUsersSet)
  140. {
  141. OwnerComboBox->Items->Text = File->Owner;
  142. }
  143. if (!FGroupsSet)
  144. {
  145. GroupComboBox->Items->Text = File->Group;
  146. }
  147. FilesSize = File->Size;
  148. LinksToLabelLabel->Visible = File->IsSymLink;
  149. LinksToLabel->Visible = File->IsSymLink;
  150. if (File->IsSymLink)
  151. {
  152. LinksToLabel->Caption = File->LinkTo;
  153. }
  154. if (File->IsDirectory && !File->IsSymLink)
  155. {
  156. FAllowCalculateStats = true;
  157. FStatsNotCalculated = true;
  158. }
  159. RightsFrame->AllowAddXToDirectories = File->IsDirectory;
  160. Caption = FMTLOAD(PROPERTIES_FILE_CAPTION, (File->FileName));
  161. RecursiveCheck->Visible = File->IsDirectory;
  162. RecursiveBevel->Visible = File->IsDirectory;
  163. }
  164. else
  165. {
  166. Caption = FFileList->Count ?
  167. FMTLOAD(PROPERTIES_FILES_CAPTION, (FFileList->Strings[0])) : AnsiString();
  168. LinksToLabelLabel->Hide();
  169. LinksToLabel->Hide();
  170. TStrings *GroupList = new TStringList();
  171. ((TStringList*)GroupList)->Duplicates = dupIgnore;
  172. ((TStringList*)GroupList)->Sorted = True;
  173. TStrings *OwnerList = new TStringList();
  174. ((TStringList*)OwnerList)->Duplicates = dupIgnore;
  175. ((TStringList*)OwnerList)->Sorted = True;
  176. try
  177. {
  178. FilesSize = 0;
  179. for (int Index = 0; Index < FFileList->Count; Index++)
  180. {
  181. TRemoteFile * File = (TRemoteFile *)(FFileList->Objects[Index]);
  182. assert(File);
  183. GroupList->Add(File->Group);
  184. OwnerList->Add(File->Owner);
  185. if (File->IsDirectory)
  186. {
  187. Stats.Directories++;
  188. if (!File->IsSymLink)
  189. {
  190. FAllowCalculateStats = true;
  191. FStatsNotCalculated = true;
  192. }
  193. }
  194. else
  195. {
  196. Stats.Files++;
  197. }
  198. if (File->IsSymLink)
  199. {
  200. Stats.SymLinks++;
  201. }
  202. FilesSize += File->Size;
  203. }
  204. if (!FUsersSet)
  205. {
  206. OwnerComboBox->Items = OwnerList;
  207. }
  208. if (!FGroupsSet)
  209. {
  210. GroupComboBox->Items = GroupList;
  211. }
  212. RightsFrame->AllowAddXToDirectories = (Stats.Directories > 0);
  213. RecursiveCheck->Visible = (Stats.Directories > 0);
  214. RecursiveBevel->Visible = (Stats.Directories > 0);
  215. }
  216. __finally
  217. {
  218. delete GroupList;
  219. delete OwnerList;
  220. }
  221. }
  222. LoadStats(FilesSize, Stats);
  223. FilesIconImage->Visible = Multiple;
  224. FileIconImage->Visible = !Multiple;
  225. }
  226. }
  227. //---------------------------------------------------------------------------
  228. void __fastcall TPropertiesDialog::LoadStats(__int64 FilesSize,
  229. const TCalculateSizeStats & Stats)
  230. {
  231. AnsiString SizeStr;
  232. AnsiString FilesStr;
  233. if (FStatsNotCalculated)
  234. {
  235. SizeStr = LoadStr(PROPERTIES_UNKNOWN_SIZE);
  236. }
  237. else
  238. {
  239. SizeStr = FormatBytes(FilesSize);
  240. AnsiString SizeUnorderedStr = FormatBytes(FilesSize, false);
  241. if (SizeStr != SizeUnorderedStr)
  242. {
  243. SizeStr = FORMAT("%s (%s)", (SizeStr, SizeUnorderedStr));
  244. }
  245. }
  246. if (((Stats.Files + Stats.Directories) == 0) && !Multiple)
  247. {
  248. TRemoteFile * File = (TRemoteFile *)(FFileList->Objects[0]);
  249. assert(File != NULL);
  250. FilesStr = File->FileName;
  251. }
  252. else
  253. {
  254. if (Stats.Files > 0)
  255. {
  256. FilesStr = (Stats.Files == 1) ? FMTLOAD(PROPERTIES_FILE, (Stats.Files)) :
  257. FMTLOAD(PROPERTIES_FILES, (Stats.Files));
  258. if (Stats.Directories > 0)
  259. {
  260. FilesStr = FORMAT("%s, ", (FilesStr));
  261. }
  262. }
  263. if (Stats.Directories > 0)
  264. {
  265. FilesStr += (Stats.Directories == 1) ? FMTLOAD(PROPERTIES_DIRECTORY, (Stats.Directories)) :
  266. FMTLOAD(PROPERTIES_DIRECTORIES, (Stats.Directories));
  267. }
  268. if (Stats.SymLinks > 0)
  269. {
  270. AnsiString SymLinksStr;
  271. SymLinksStr = (Stats.SymLinks == 1) ? FMTLOAD(PROPERTIES_SYMLINK, (Stats.SymLinks)) :
  272. FMTLOAD(PROPERTIES_SYMLINKS, (Stats.SymLinks));
  273. FilesStr = FORMAT("%s (%s)", (FilesStr, SymLinksStr));
  274. }
  275. }
  276. SizeLabel->Caption = SizeStr;
  277. FileLabel->Caption = FilesStr;
  278. }
  279. //---------------------------------------------------------------------------
  280. void __fastcall TPropertiesDialog::SetDirectory(AnsiString value)
  281. {
  282. LocationLabel->Caption = value;
  283. }
  284. //---------------------------------------------------------------------------
  285. AnsiString __fastcall TPropertiesDialog::GetDirectory()
  286. {
  287. return LocationLabel->Caption;
  288. }
  289. //---------------------------------------------------------------------------
  290. void __fastcall TPropertiesDialog::SetFileProperties(TRemoteProperties value)
  291. {
  292. TValidProperties Valid;
  293. if (value.Valid.Contains(vpRights) && FAllowedChanges & cpMode) Valid << vpRights;
  294. if (value.Valid.Contains(vpOwner) && FAllowedChanges & cpOwner) Valid << vpOwner;
  295. if (value.Valid.Contains(vpGroup) && FAllowedChanges & cpGroup) Valid << vpGroup;
  296. FOrigProperties = value;
  297. FOrigProperties.Valid = Valid;
  298. FOrigProperties.Recursive = false;
  299. if (value.Valid.Contains(vpRights))
  300. {
  301. RightsFrame->Rights = value.Rights;
  302. RightsFrame->AddXToDirectories = value.AddXToDirectories;
  303. }
  304. else
  305. {
  306. RightsFrame->Rights = TRights();
  307. RightsFrame->AddXToDirectories = false;
  308. }
  309. GroupComboBox->Text = value.Valid.Contains(vpGroup) ? value.Group : AnsiString();
  310. OwnerComboBox->Text = value.Valid.Contains(vpOwner) ? value.Owner : AnsiString();
  311. RecursiveCheck->Checked = value.Recursive;
  312. UpdateControls();
  313. }
  314. //---------------------------------------------------------------------------
  315. TRemoteProperties __fastcall TPropertiesDialog::GetFileProperties()
  316. {
  317. TRemoteProperties Result;
  318. if (AllowedChanges & cpMode)
  319. {
  320. Result.Valid << vpRights;
  321. Result.Rights = RightsFrame->Rights;
  322. Result.AddXToDirectories = RightsFrame->AddXToDirectories;
  323. }
  324. #define STORE_NAME(PROPERTY) \
  325. if (!PROPERTY ## ComboBox->Text.Trim().IsEmpty() && \
  326. AllowedChanges & cp ## PROPERTY) \
  327. { \
  328. Result.Valid << vp ## PROPERTY; \
  329. Result.PROPERTY = PROPERTY ## ComboBox->Text.Trim(); \
  330. }
  331. STORE_NAME(Group);
  332. STORE_NAME(Owner);
  333. #undef STORE_NAME
  334. Result.Recursive = RecursiveCheck->Checked;
  335. return Result;
  336. }
  337. //---------------------------------------------------------------------------
  338. void __fastcall TPropertiesDialog::ControlChange(TObject * /*Sender*/)
  339. {
  340. UpdateControls();
  341. }
  342. //---------------------------------------------------------------------------
  343. void __fastcall TPropertiesDialog::UpdateControls()
  344. {
  345. EnableControl(OkButton,
  346. // group name is specified or we set multiple-file properties and
  347. // no valid group was specified (there are at least two different groups)
  348. (!GroupComboBox->Text.Trim().IsEmpty() ||
  349. (Multiple && !FOrigProperties.Valid.Contains(vpGroup)) ||
  350. (FOrigProperties.Group == GroupComboBox->Text)) &&
  351. // same but with owner
  352. (!OwnerComboBox->Text.Trim().IsEmpty() ||
  353. (Multiple && !FOrigProperties.Valid.Contains(vpOwner)) ||
  354. (FOrigProperties.Owner == OwnerComboBox->Text)) &&
  355. ((FileProperties != FOrigProperties) || RecursiveCheck->Checked)
  356. );
  357. EnableControl(GroupComboBox, FAllowedChanges & cpGroup);
  358. EnableControl(OwnerComboBox, FAllowedChanges & cpOwner);
  359. EnableControl(RightsFrame, FAllowedChanges & cpMode);
  360. CalculateSizeButton->Visible = Terminal && FAllowCalculateStats;
  361. if (!Multiple)
  362. {
  363. // when setting properties for one file only, allow undef state
  364. // only when the input right explicitly requires it or
  365. // when "recursive" is on (possible for directory only).
  366. RightsFrame->AllowUndef =
  367. (FOrigProperties.Valid.Contains(vpRights) &&
  368. FOrigProperties.Rights.AllowUndef) ||
  369. (RecursiveCheck->Checked);
  370. }
  371. }
  372. //---------------------------------------------------------------------------
  373. bool __fastcall TPropertiesDialog::GetMultiple()
  374. {
  375. return (FFileList->Count != 1);
  376. }
  377. //---------------------------------------------------------------------------
  378. void __fastcall TPropertiesDialog::SetGroupList(TStrings * value)
  379. {
  380. if (FGroupsSet || ((value != NULL) && (value->Count > 0)))
  381. {
  382. GroupComboBox->Items = value;
  383. FGroupsSet = true;
  384. }
  385. }
  386. //---------------------------------------------------------------------------
  387. TStrings * __fastcall TPropertiesDialog::GetGroupList()
  388. {
  389. return GroupComboBox->Items;
  390. }
  391. //---------------------------------------------------------------------------
  392. void __fastcall TPropertiesDialog::SetUserList(TStrings * value)
  393. {
  394. if (FUsersSet || ((value != NULL) && (value->Count > 0)))
  395. {
  396. OwnerComboBox->Items = value;
  397. FUsersSet = true;
  398. }
  399. }
  400. //---------------------------------------------------------------------------
  401. TStrings * __fastcall TPropertiesDialog::GetUserList()
  402. {
  403. return OwnerComboBox->Items;
  404. }
  405. //---------------------------------------------------------------------------
  406. void __fastcall TPropertiesDialog::FormCloseQuery(TObject * /*Sender*/,
  407. bool & /*CanClose*/)
  408. {
  409. if (ModalResult == mrOk)
  410. {
  411. #define CHECK_VALID_NAME(Property, Message) \
  412. if (FOrigProperties.Valid.Contains(vp ## Property) && Property ## ComboBox->Text.Trim().IsEmpty()) { \
  413. Property ## ComboBox->SetFocus(); throw Exception(Message); }
  414. CHECK_VALID_NAME(Group, PROPERTIES_INVALID_GROUP);
  415. CHECK_VALID_NAME(Owner, PROPERTIES_INVALID_OWNER);
  416. #undef CHECK_VALID_NAME
  417. }
  418. }
  419. //---------------------------------------------------------------------------
  420. void __fastcall TPropertiesDialog::SetAllowedChanges(int value)
  421. {
  422. if (FAllowedChanges != value)
  423. {
  424. FAllowedChanges = value;
  425. UpdateControls();
  426. }
  427. }
  428. //---------------------------------------------------------------------------
  429. void __fastcall TPropertiesDialog::CalculateSizeButtonClick(
  430. TObject * /*Sender*/)
  431. {
  432. assert(Terminal);
  433. __int64 Size;
  434. TCalculateSizeStats Stats;
  435. Terminal->CalculateFilesSize(FileList, Size, 0, NULL, &Stats);
  436. FStatsNotCalculated = false;
  437. LoadStats(Size, Stats);
  438. }
  439. //---------------------------------------------------------------------------
  440. void __fastcall TPropertiesDialog::HelpButtonClick(TObject * /*Sender*/)
  441. {
  442. FormHelp(this);
  443. }
  444. //---------------------------------------------------------------------------