Rights.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Common.h>
  5. #include "Rights.h"
  6. #include <VCLCommon.h>
  7. #include <Tools.h>
  8. #include <TextsWin.h>
  9. //---------------------------------------------------------------------------
  10. #pragma package(smart_init)
  11. #pragma link "GrayedCheckBox"
  12. #pragma link "PngImageList"
  13. #pragma resource "*.dfm"
  14. //---------------------------------------------------------------------------
  15. __fastcall TRightsFrame::TRightsFrame(TComponent* Owner)
  16. : TFrame(Owner)
  17. {
  18. FAddXToDirectoriesSuffix = L"+x";
  19. FOnChange = NULL;
  20. FAllowAddXToDirectories = true;
  21. FPopup = false;
  22. FPopupParent = NULL;
  23. FDefaultButton = NULL;
  24. FCancelButton = NULL;
  25. // to avoid duplication of reference in forms that uses the frame
  26. PopupMenu = RightsPopup;
  27. FPopingContextMenu = false;
  28. FInitialized = false;
  29. FAcl = false;
  30. #define COPY_HINT(R) \
  31. Checks[TRights::rrGroup ## R]->Hint = Checks[TRights::rrUser ## R]->Hint; \
  32. Checks[TRights::rrOther ## R]->Hint = Checks[TRights::rrUser ## R]->Hint;
  33. COPY_HINT(Read);
  34. COPY_HINT(Write);
  35. COPY_HINT(Exec);
  36. #undef COPY_HINT
  37. }
  38. //---------------------------------------------------------------------------
  39. __fastcall TRightsFrame::~TRightsFrame()
  40. {
  41. }
  42. //---------------------------------------------------------------------------
  43. void __fastcall TRightsFrame::SetStates(TRights::TRight Right, TRights::TState value)
  44. {
  45. DebugAssert(((value == TRights::rsNo) || (value == TRights::rsYes) || (value == TRights::rsUndef)));
  46. TCheckBox * CheckBox = Checks[Right];
  47. if (CheckBox != NULL)
  48. {
  49. switch (value) {
  50. case TRights::rsNo: CheckBox->State = cbUnchecked; break;
  51. case TRights::rsYes: CheckBox->State = cbChecked; break;
  52. case TRights::rsUndef: CheckBox->State = cbGrayed; break;
  53. }
  54. }
  55. }
  56. //---------------------------------------------------------------------------
  57. TRights::TState __fastcall TRightsFrame::GetStates(TRights::TRight Right)
  58. {
  59. TCheckBox * CheckBox = Checks[Right];
  60. if (CheckBox != NULL)
  61. {
  62. switch (CheckBox->State) {
  63. case cbUnchecked: return TRights::rsNo;
  64. case cbChecked: return TRights::rsYes;
  65. case cbGrayed:
  66. default: return TRights::rsUndef;
  67. }
  68. }
  69. else
  70. {
  71. return TRights::rsNo;
  72. }
  73. }
  74. //---------------------------------------------------------------------------
  75. void __fastcall TRightsFrame::SetRights(const TRights & value)
  76. {
  77. bool Changed = (AllowUndef != value.AllowUndef);
  78. AllowUndef = true; // temporarily
  79. for (int Right = TRights::rrFirst; Right <= TRights::rrLast; Right++)
  80. {
  81. TRights::TRight R = static_cast<TRights::TRight>(Right);
  82. if (States[R] != value.RightUndef[R])
  83. {
  84. States[R] = value.RightUndef[R];
  85. Changed = true;
  86. }
  87. }
  88. AllowUndef = value.AllowUndef;
  89. if (Changed || !FInitialized)
  90. {
  91. UpdateControls();
  92. }
  93. }
  94. //---------------------------------------------------------------------------
  95. TRights __fastcall TRightsFrame::GetRights()
  96. {
  97. TRights Result;
  98. Result.AllowUndef = AllowUndef;
  99. for (int Right = TRights::rrFirst; Right <= TRights::rrLast; Right++)
  100. {
  101. Result.RightUndef[static_cast<TRights::TRight>(Right)] =
  102. States[static_cast<TRights::TRight>(Right)];
  103. }
  104. return Result;
  105. }
  106. //---------------------------------------------------------------------------
  107. void __fastcall TRightsFrame::SetAllowUndef(bool value)
  108. {
  109. for (int Right = TRights::rrFirst; Right <= TRights::rrLast; Right++)
  110. {
  111. TCheckBox * CheckBox = Checks[static_cast<TRights::TRight>(Right)];
  112. if (CheckBox != NULL)
  113. {
  114. CheckBox->AllowGrayed = value;
  115. }
  116. }
  117. }
  118. //---------------------------------------------------------------------------
  119. bool __fastcall TRightsFrame::GetAllowUndef()
  120. {
  121. bool Result = false, First = true;
  122. for (int Right = TRights::rrFirst; Right <= TRights::rrLast; Right++)
  123. {
  124. TCheckBox * Check = Checks[static_cast<TRights::TRight>(Right)];
  125. if (Check != NULL)
  126. {
  127. if (First)
  128. {
  129. Result = Check->AllowGrayed;
  130. First = false;
  131. }
  132. else if (Result != Check->AllowGrayed)
  133. {
  134. DebugFail();
  135. }
  136. }
  137. }
  138. return Result;
  139. }
  140. //---------------------------------------------------------------------------
  141. TCheckBox * __fastcall TRightsFrame::GetChecks(TRights::TRight Right)
  142. {
  143. for (int Index = 0; Index < ControlCount; Index++)
  144. {
  145. if (Controls[Index]->InheritsFrom(__classid(TCheckBox)) &&
  146. (Controls[Index]->Tag == TRights::RightToFlag(Right)))
  147. {
  148. return ((TCheckBox *)Controls[Index]);
  149. }
  150. }
  151. return NULL;
  152. }
  153. //---------------------------------------------------------------------------
  154. void __fastcall TRightsFrame::SetAddXToDirectories(bool value)
  155. {
  156. DirectoriesXCheck->Checked = value;
  157. }
  158. //---------------------------------------------------------------------------
  159. bool __fastcall TRightsFrame::GetAddXToDirectories()
  160. {
  161. return DirectoriesXCheck->Checked;
  162. }
  163. //---------------------------------------------------------------------------
  164. void __fastcall TRightsFrame::ControlChange(TObject * /*Sender*/)
  165. {
  166. UpdateControls();
  167. }
  168. //---------------------------------------------------------------------------
  169. bool __fastcall TRightsFrame::DirectoriesXEffective()
  170. {
  171. return !((Rights.NumberSet & TRights::rfExec) == TRights::rfExec);
  172. }
  173. //---------------------------------------------------------------------------
  174. void __fastcall TRightsFrame::UpdateControls()
  175. {
  176. if (!OctalEdit->Focused())
  177. {
  178. UpdateOctalEdit();
  179. }
  180. Color = (FPopup ? clWindow : clBtnFace);
  181. DirectoriesXCheck->Visible = AllowAddXToDirectories;
  182. EnableControl(DirectoriesXCheck,
  183. Enabled && DirectoriesXEffective());
  184. FInitialized = true;
  185. DoChange();
  186. }
  187. //---------------------------------------------------------------------------
  188. void TRightsFrame::CycleRights(TRights::TRightGroup RightGroup)
  189. {
  190. int Last = FAcl ? TRights::rlLastAcl : TRights::rlLastNormal;
  191. TRights::TState State = TRights::TState(); // shut up
  192. bool Any = false;
  193. bool Same = true;
  194. for (int RightLevelI = TRights::rlFirst; RightLevelI <= Last; RightLevelI++)
  195. {
  196. TRights::TRightLevel RightLevel = static_cast<TRights::TRightLevel>(RightLevelI);
  197. TRights::TRight Right = TRights::CalculateRight(RightGroup, RightLevel);
  198. if (Checks[Right]->Visible)
  199. {
  200. TRights::TState RightState = States[Right];
  201. if (!Any)
  202. {
  203. State = RightState;
  204. Any = true;
  205. }
  206. else if (State != RightState)
  207. {
  208. Same = false;
  209. break;
  210. }
  211. }
  212. }
  213. if (DebugAlwaysTrue(Any))
  214. {
  215. if (!Same)
  216. {
  217. State = TRights::rsYes;
  218. }
  219. else
  220. {
  221. switch (State)
  222. {
  223. case TRights::rsYes:
  224. State = TRights::rsNo;
  225. break;
  226. case TRights::rsNo:
  227. State = AllowUndef ? TRights::rsUndef : TRights::rsYes;
  228. break;
  229. case TRights::rsUndef:
  230. State = TRights::rsYes;
  231. break;
  232. }
  233. }
  234. for (int RightLevelI = TRights::rlFirst; RightLevelI <= Last; RightLevelI++)
  235. {
  236. TRights::TRightLevel RightLevel = static_cast<TRights::TRightLevel>(RightLevelI);
  237. TRights::TRight Right = TRights::CalculateRight(RightGroup, RightLevel);
  238. States[Right] = State;
  239. }
  240. UpdateControls();
  241. }
  242. }
  243. //---------------------------------------------------------------------------
  244. void __fastcall TRightsFrame::RightsButtonsClick(TObject * Sender)
  245. {
  246. CycleRights(static_cast<TRights::TRightGroup>(dynamic_cast<TComponent *>(Sender)->Tag - 1));
  247. }
  248. //---------------------------------------------------------------------------
  249. void __fastcall TRightsFrame::SetAllowAddXToDirectories(bool value)
  250. {
  251. if ((FAllowAddXToDirectories != value) || !FInitialized)
  252. {
  253. FAllowAddXToDirectories = value;
  254. UpdateControls();
  255. }
  256. }
  257. //---------------------------------------------------------------------------
  258. void __fastcall TRightsFrame::DoChange()
  259. {
  260. if (FOnChange)
  261. {
  262. FOnChange(this);
  263. }
  264. }
  265. //---------------------------------------------------------------------------
  266. void __fastcall TRightsFrame::SetEnabled(bool Value)
  267. {
  268. TFrame::SetEnabled(Value);
  269. UpdateControls();
  270. }
  271. //---------------------------------------------------------------------------
  272. void __fastcall TRightsFrame::ForceUpdate()
  273. {
  274. UpdateOctalEdit();
  275. }
  276. //---------------------------------------------------------------------------
  277. bool __fastcall TRightsFrame::HasFocus()
  278. {
  279. return
  280. (Focused() ||
  281. ((Screen->ActiveControl != NULL) && (Screen->ActiveControl->Parent == this))) ||
  282. ((PopupParent != NULL) && PopupParent->Focused());
  283. }
  284. //---------------------------------------------------------------------------
  285. void __fastcall TRightsFrame::RightsActionsExecute(TBasicAction * Action,
  286. bool & Handled)
  287. {
  288. // prevent shortcuts to be evaluated when frame does not have a focus
  289. if (HasFocus())
  290. {
  291. bool Changed = true;
  292. TRights R = Rights;
  293. R.Number = TRights::rfNo;
  294. Handled = true;
  295. if (Action == NoRightsAction)
  296. {
  297. R = TRights::rfNo;
  298. }
  299. else if (Action == DefaultRightsAction)
  300. {
  301. R = TRights::rfDefault;
  302. }
  303. else if (Action == AllRightsAction)
  304. {
  305. R = TRights::rfAll;
  306. }
  307. else if (Action == LeaveRightsAsIsAction)
  308. {
  309. R.AllUndef();
  310. }
  311. else if (Action == CopyTextAction)
  312. {
  313. TInstantOperationVisualizer Visualizer;
  314. CopyToClipboard(Text);
  315. Changed = false;
  316. }
  317. else if (Action == CopyOctalAction)
  318. {
  319. TRights R = Rights;
  320. DebugAssert(!R.IsUndef);
  321. if (!R.IsUndef)
  322. {
  323. TInstantOperationVisualizer Visualizer;
  324. CopyToClipboard(R.Octal);
  325. }
  326. Changed = false;
  327. }
  328. else if (Action == PasteAction)
  329. {
  330. UnicodeString S;
  331. if (TextFromClipboard(S, true))
  332. {
  333. Text = S;
  334. }
  335. // trigger on change event, even if no change actually occurred to
  336. // allow parent form to visualize feedback of an action
  337. DoChange();
  338. // Update octal edit in Rights frame even if it has focus
  339. ForceUpdate();
  340. Changed = false;
  341. }
  342. else
  343. {
  344. Handled = false;
  345. }
  346. if (Changed)
  347. {
  348. Rights = R;
  349. ForceUpdate();
  350. DoChange();
  351. }
  352. }
  353. }
  354. //---------------------------------------------------------------------------
  355. void __fastcall TRightsFrame::RightsActionsUpdate(TBasicAction *Action,
  356. bool &Handled)
  357. {
  358. TRights R = Rights;
  359. Handled = true;
  360. if (Action == NoRightsAction)
  361. {
  362. // explicitly enable as action gets disabled, if its shortcut is pressed,
  363. // while the form does not have a focus and OnExecute handler denies the execution
  364. NoRightsAction->Enabled = !FAcl;
  365. NoRightsAction->Checked = !R.IsUndef && (R.NumberSet == TRights::rfNo);
  366. }
  367. else if (Action == DefaultRightsAction)
  368. {
  369. DefaultRightsAction->Enabled = !FAcl;
  370. DefaultRightsAction->Checked = !R.IsUndef && (R.NumberSet == TRights::rfDefault);
  371. }
  372. else if (Action == AllRightsAction)
  373. {
  374. AllRightsAction->Enabled = !FAcl;
  375. AllRightsAction->Checked = !R.IsUndef && (R.NumberSet == TRights::rfAll);
  376. }
  377. else if (Action == LeaveRightsAsIsAction)
  378. {
  379. LeaveRightsAsIsAction->Enabled = !FAcl;
  380. LeaveRightsAsIsAction->Visible = R.AllowUndef;
  381. LeaveRightsAsIsAction->Checked = (R.NumberSet == TRights::rfNo) &&
  382. (R.NumberUnset == TRights::rfNo);
  383. }
  384. else if (Action == CopyTextAction)
  385. {
  386. CopyTextAction->Enabled = !FAcl && !R.IsUndef;
  387. }
  388. else if (Action == CopyOctalAction)
  389. {
  390. CopyOctalAction->Enabled = !FAcl && !R.IsUndef;
  391. }
  392. else if (Action == PasteAction)
  393. {
  394. PasteAction->Enabled = !FAcl && IsFormatInClipboard(CF_TEXT);
  395. }
  396. else
  397. {
  398. Handled = false;
  399. }
  400. }
  401. //---------------------------------------------------------------------------
  402. void __fastcall TRightsFrame::CreateParams(TCreateParams & Params)
  403. {
  404. TFrame::CreateParams(Params);
  405. if (FPopup)
  406. {
  407. Params.Style |= WS_BORDER;
  408. }
  409. }
  410. //---------------------------------------------------------------------------
  411. void __fastcall TRightsFrame::CreateWnd()
  412. {
  413. if (FPopup)
  414. {
  415. Width += 2 * GetSystemMetricsForControl(Parent, SM_CXBORDER);
  416. Height += 2 * GetSystemMetricsForControl(Parent, SM_CYBORDER);
  417. }
  418. TFrame::CreateWnd();
  419. UpdateButtons();
  420. }
  421. //---------------------------------------------------------------------------
  422. void __fastcall TRightsFrame::SetPopup(bool value)
  423. {
  424. if (Popup != value)
  425. {
  426. FPopup = value;
  427. Visible = !FPopup;
  428. CloseButton->Visible = value;
  429. CloseButton->Cancel = value;
  430. CloseButton->Default = value;
  431. }
  432. }
  433. //---------------------------------------------------------------------------
  434. void __fastcall TRightsFrame::DoCloseUp()
  435. {
  436. Hide();
  437. if (FDefaultButton != NULL)
  438. {
  439. FDefaultButton->Default = true;
  440. FDefaultButton = NULL;
  441. }
  442. if (FCancelButton != NULL)
  443. {
  444. FCancelButton->Cancel = true;
  445. FCancelButton = NULL;
  446. }
  447. }
  448. //---------------------------------------------------------------------------
  449. void __fastcall TRightsFrame::DoExit()
  450. {
  451. // this is bit hack to make frame hide when ComboEdit button is pressed while
  452. // from is poped-up already.
  453. if (FPopup && !IsAncestor(Screen->ActiveControl, FPopupParent))
  454. {
  455. DoCloseUp();
  456. }
  457. TFrame::DoExit();
  458. }
  459. //---------------------------------------------------------------------------
  460. bool __fastcall TRightsFrame::IsAncestor(TControl * Control, TControl * Ancestor)
  461. {
  462. while ((Control != NULL) &&
  463. (Control->Parent != Ancestor))
  464. {
  465. Control = Control->Parent;
  466. }
  467. return (Control != NULL);
  468. }
  469. //---------------------------------------------------------------------------
  470. void __fastcall TRightsFrame::WMContextMenu(TWMContextMenu & Message)
  471. {
  472. FPopingContextMenu = true;
  473. try
  474. {
  475. TFrame::Dispatch(&Message);
  476. }
  477. __finally
  478. {
  479. FPopingContextMenu = false;
  480. }
  481. }
  482. //---------------------------------------------------------------------------
  483. void __fastcall TRightsFrame::CMDialogKey(TCMDialogKey & Message)
  484. {
  485. if (FPopup && Visible &&
  486. ((Message.CharCode == VK_RETURN) ||
  487. (Message.CharCode == VK_ESCAPE)) &&
  488. KeyDataToShiftState(Message.KeyData).Empty())
  489. {
  490. CloseUp();
  491. Message.Result = 1;
  492. }
  493. else
  494. {
  495. TFrame::Dispatch(&Message);
  496. }
  497. if (Message.CharCode == VK_MENU)
  498. {
  499. UpdateButtons();
  500. }
  501. }
  502. //---------------------------------------------------------------------------
  503. bool TRightsFrame::IsButtonAccel(TCMDialogChar & Message, TSpeedButton * Button, TWinControl * FocusControl)
  504. {
  505. bool Result = IsAccel(Message.CharCode, Button->Caption) && Button->Visible && Button->Enabled;
  506. if (Result)
  507. {
  508. Perform(WM_CHANGEUISTATE, MAKELONG(UIS_CLEAR, UISF_HIDEFOCUS), 0);
  509. FocusControl->SetFocus();
  510. }
  511. return Result;
  512. }
  513. //---------------------------------------------------------------------------
  514. void TRightsFrame::CMDialogChar(TCMDialogChar & Message)
  515. {
  516. if (IsButtonAccel(Message, OwnerButton, OwnerReadCheck) ||
  517. IsButtonAccel(Message, GroupButton, GroupReadCheck) ||
  518. IsButtonAccel(Message, OthersButton, OthersReadCheck))
  519. {
  520. Message.Result = 1;
  521. }
  522. else
  523. {
  524. TFrame::Dispatch(&Message);
  525. }
  526. }
  527. //---------------------------------------------------------------------------
  528. void __fastcall TRightsFrame::CMCancelMode(TCMCancelMode & Message)
  529. {
  530. if (FPopup && Visible && !FPopingContextMenu &&
  531. ((Message.Sender == NULL) ||
  532. (!IsAncestor(Message.Sender, this) &&
  533. !IsAncestor(Message.Sender, FPopupParent) &&
  534. (Message.Sender != this))))
  535. {
  536. CloseUp();
  537. }
  538. TFrame::Dispatch(&Message);
  539. }
  540. //---------------------------------------------------------------------------
  541. void TRightsFrame::CMDPIChanged(TMessage & Message)
  542. {
  543. TFrame::Dispatch(&Message);
  544. UpdateButtons();
  545. }
  546. //---------------------------------------------------------------------------
  547. void TRightsFrame::WMUpdateUIState(TMessage & Message)
  548. {
  549. TFrame::Dispatch(&Message);
  550. UpdateButtons();
  551. }
  552. //---------------------------------------------------------------------------
  553. void TRightsFrame::UpdateButton(TSpeedButton * Button, UnicodeString & Caption)
  554. {
  555. if (Caption.IsEmpty())
  556. {
  557. Caption = Button->Caption;
  558. DebugAssert(Caption.Pos(L"&") >= 0);
  559. }
  560. int Padding = ScaleByTextHeight(Button, 4);
  561. std::unique_ptr<TCanvas> Canvas(CreateControlCanvas(Button));
  562. UnicodeString ACaption = Caption;
  563. UnicodeString StrippedCaption = StripHotkey(ACaption);
  564. if ((SendMessage(Handle, WM_QUERYUISTATE, 0, 0) & UISF_HIDEACCEL) != 0)
  565. {
  566. ACaption = StrippedCaption;
  567. }
  568. Button->Caption = ACaption;
  569. Button->Width = Padding + Canvas->TextWidth(StrippedCaption) + Padding;
  570. Button->Left = OctalLabel->Left - Padding;
  571. }
  572. //---------------------------------------------------------------------------
  573. void TRightsFrame::UpdateButtons()
  574. {
  575. UpdateButton(OwnerButton, FOwnerCaption);
  576. UpdateButton(GroupButton, FGroupCaption);
  577. UpdateButton(OthersButton, FOthersCaption);
  578. }
  579. //---------------------------------------------------------------------------
  580. void __fastcall TRightsFrame::Dispatch(void * Message)
  581. {
  582. TMessage & AMessage = *static_cast<TMessage *>(Message);
  583. switch (AMessage.Msg)
  584. {
  585. case CM_CANCELMODE:
  586. CMCancelMode(*(TCMCancelMode *)Message);
  587. break;
  588. case CM_DIALOGKEY:
  589. CMDialogKey(*(TCMDialogKey *)Message);
  590. break;
  591. case CM_DIALOGCHAR:
  592. CMDialogChar(*(TCMDialogChar *)Message);
  593. break;
  594. case WM_CONTEXTMENU:
  595. WMContextMenu(*(TWMContextMenu *)Message);
  596. break;
  597. case CM_DPICHANGED:
  598. CMDPIChanged(AMessage);
  599. break;
  600. case WM_UPDATEUISTATE:
  601. WMUpdateUIState(AMessage);
  602. break;
  603. default:
  604. TFrame::Dispatch(Message);
  605. break;
  606. }
  607. }
  608. //---------------------------------------------------------------------------
  609. void __fastcall TRightsFrame::DropDown()
  610. {
  611. TCustomForm * Form = GetParentForm(this);
  612. // Due to lack of better idea, we clear "default" and "cancel" flags of respective
  613. // form buttons to prevent them to handle ESC/ENTER keys.
  614. // Could use FindStandardButton.
  615. for (int Index = 0; Index < Form->ControlCount; Index++)
  616. {
  617. TButton * Button = dynamic_cast<TButton *>(Form->Controls[Index]);
  618. if (Button != NULL)
  619. {
  620. if (Button->Default)
  621. {
  622. DebugAssert(FDefaultButton == NULL);
  623. FDefaultButton = Button;
  624. Button->Default = false;
  625. }
  626. if (Button->Cancel)
  627. {
  628. DebugAssert(FCancelButton == NULL);
  629. FCancelButton = Button;
  630. Button->Cancel = false;
  631. }
  632. }
  633. }
  634. TPoint Origin(PopupParent->Left, PopupParent->Top + PopupParent->Height);
  635. Origin = Parent->ScreenToClient(PopupParent->Parent->ClientToScreen(Origin));
  636. if (Origin.x + Width > Parent->ClientWidth)
  637. {
  638. Origin.x += PopupParent->Width - Width;
  639. }
  640. Left = Origin.x;
  641. Top = Origin.y;
  642. Show();
  643. SetFocus();
  644. }
  645. //---------------------------------------------------------------------------
  646. void __fastcall TRightsFrame::CloseUp()
  647. {
  648. DebugAssert(FPopup);
  649. DebugAssert(Visible);
  650. if (!Focused())
  651. {
  652. // this can happen only if called from on-click handler of drop down button
  653. DoCloseUp();
  654. }
  655. FPopupParent->SetFocus();
  656. }
  657. //---------------------------------------------------------------------------
  658. UnicodeString __fastcall TRightsFrame::GetText()
  659. {
  660. UnicodeString Result = Rights.Text;
  661. if (AllowAddXToDirectories && DirectoriesXEffective() && AddXToDirectories)
  662. {
  663. Result = FORMAT(L"%s (%s)", (Result, FAddXToDirectoriesSuffix));
  664. }
  665. return Result;
  666. }
  667. //---------------------------------------------------------------------------
  668. void __fastcall TRightsFrame::SetText(UnicodeString value)
  669. {
  670. if (Text != value)
  671. {
  672. UnicodeString RightsStr = value;
  673. int P = RightsStr.LowerCase().Pos(FAddXToDirectoriesSuffix);
  674. bool AAddXToDirectories = (P > 0);
  675. if (AAddXToDirectories)
  676. {
  677. RightsStr.Delete(P, FAddXToDirectoriesSuffix.Length());
  678. }
  679. RightsStr = DeleteChar(DeleteChar(RightsStr, L'('), L')').Trim();
  680. TRights R = Rights;
  681. if (((RightsStr.Length() == 3) || (RightsStr.Length() == 4)) &&
  682. IsNumber(RightsStr))
  683. {
  684. R.Octal = RightsStr;
  685. }
  686. else
  687. {
  688. R.Text = RightsStr;
  689. }
  690. Rights = R;
  691. AddXToDirectories = AAddXToDirectories;
  692. }
  693. }
  694. //---------------------------------------------------------------------------
  695. void __fastcall TRightsFrame::RightsPopupPopup(TObject * /*Sender*/)
  696. {
  697. if (!HasFocus())
  698. {
  699. SetFocus();
  700. }
  701. }
  702. //---------------------------------------------------------------------------
  703. void __fastcall TRightsFrame::FrameContextPopup(TObject * Sender,
  704. TPoint & MousePos, bool & Handled)
  705. {
  706. if (!FAcl)
  707. {
  708. SelectScaledImageList(RightsImages);
  709. MenuPopup(Sender, MousePos, Handled);
  710. }
  711. else
  712. {
  713. Handled = true;
  714. }
  715. }
  716. //---------------------------------------------------------------------------
  717. void __fastcall TRightsFrame::UpdateByOctal()
  718. {
  719. if (!OctalEdit->Text.IsEmpty())
  720. {
  721. TRights R = Rights;
  722. R.Octal = OctalEdit->Text;
  723. Rights = R;
  724. }
  725. UpdateControls();
  726. OctalEdit->Modified = false;
  727. }
  728. //---------------------------------------------------------------------------
  729. void __fastcall TRightsFrame::UpdateOctalEdit()
  730. {
  731. TRights R = Rights;
  732. OctalEdit->Text = R.IsUndef ? UnicodeString() : R.Octal;
  733. OctalEdit->Modified = false;
  734. OctalEdit->SelectAll();
  735. }
  736. //---------------------------------------------------------------------------
  737. void __fastcall TRightsFrame::OctalEditChange(TObject *)
  738. {
  739. if (OctalEdit->Modified && OctalEdit->Text.Length() >= 3)
  740. {
  741. try
  742. {
  743. UpdateByOctal();
  744. }
  745. catch(...)
  746. {
  747. OctalEdit->Modified = true;
  748. }
  749. }
  750. }
  751. //---------------------------------------------------------------------------
  752. void __fastcall TRightsFrame::OctalEditExit(TObject *)
  753. {
  754. if ((!Visible && DebugAlwaysTrue(Popup)) || // Popup assert: should happen only if popup is closed by esc key
  755. IsCancelButtonBeingClicked(this) || // CloseButton
  756. ((FCancelButton != NULL) && IsButtonBeingClicked(FCancelButton)))
  757. {
  758. // cancel changes
  759. ForceUpdate();
  760. }
  761. else if (OctalEdit->Modified)
  762. {
  763. // Now the text in OctalEdit is almost necessarily invalid, otherwise
  764. // OctalEditChange would have already cleared Modified flag
  765. try
  766. {
  767. UpdateByOctal();
  768. }
  769. catch(...)
  770. {
  771. OctalEdit->SelectAll();
  772. OctalEdit->SetFocus();
  773. throw;
  774. }
  775. }
  776. else
  777. {
  778. UpdateControls();
  779. }
  780. }
  781. //---------------------------------------------------------------------------
  782. void __fastcall TRightsFrame::CloseButtonClick(TObject *)
  783. {
  784. CloseUp();
  785. }
  786. //---------------------------------------------------------------------------
  787. void TRightsFrame::DisplayAsAcl(TRights::TRight ReadRight, TRights::TRight WriteRight, TRights::TRight ExecRight, TRights::TRight SpecialRight)
  788. {
  789. TCheckBox * ReadCheck = Checks[ReadRight];
  790. TCheckBox * WriteCheck = Checks[WriteRight];
  791. TCheckBox * ReadAclCheck = Checks[ExecRight];
  792. TCheckBox * WriteAclCheck = Checks[SpecialRight];
  793. WriteCheck->Visible = false;
  794. int ReadAclLeft = (3*ReadCheck->Left + 2*WriteAclCheck->Left) / 5;
  795. int Shift = ReadAclLeft - ReadAclCheck->Left;
  796. ReadAclCheck->Left = ReadAclLeft;
  797. ReadAclCheck->Width = ReadAclCheck->Width - Shift;
  798. ReadAclCheck->Caption = L"R ACL";
  799. ReadAclCheck->Hint = LoadStr(PROPERTIES_S3_R_ACL_HINT);
  800. WriteAclCheck->Caption = L"W ACL";
  801. WriteAclCheck->Hint = LoadStr(PROPERTIES_S3_W_ACL_HINT);
  802. WriteAclCheck->ShowHint = true;
  803. FGroupCaption = LoadStr(PROPERTIES_S3_USERS);
  804. FOthersCaption = LoadStr(PROPERTIES_S3_EVERYONE);
  805. UpdateButtons();
  806. }
  807. //---------------------------------------------------------------------------
  808. void TRightsFrame::DisplayAsAcl()
  809. {
  810. AllowAddXToDirectories = false;
  811. OctalLabel->Visible = false;
  812. OctalEdit->Visible = false;
  813. DisplayAsAcl(TRights::rrUserRead, TRights::rrUserWrite, TRights::rrUserExec, TRights::rrUserIDExec);
  814. DisplayAsAcl(TRights::rrGroupRead, TRights::rrGroupWrite, TRights::rrGroupExec, TRights::rrGroupIDExec);
  815. DisplayAsAcl(TRights::rrOtherRead, TRights::rrOtherWrite, TRights::rrOtherExec, TRights::rrStickyBit);
  816. FAcl = true;
  817. }