Rights.cpp 24 KB

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