Properties.cpp 13 KB

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