| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711 | //---------------------------------------------------------------------------#include <vcl.h>#pragma hdrstop#include <Common.h>#include "Rights.h"#include <VCLCommon.h>#include <Tools.h>#include <GUITools.h>//---------------------------------------------------------------------------#pragma package(smart_init)#pragma link "GrayedCheckBox"#pragma link "PngImageList"#ifndef NO_RESOURCES#pragma resource "*.dfm"#endif//---------------------------------------------------------------------------__fastcall TRightsFrame::TRightsFrame(TComponent* Owner)        : TFrame(Owner){  FAddXToDirectoriesSuffix = L"+x";  FOnChange = NULL;  FAllowAddXToDirectories = true;  FPopup = false;  FPopupParent = NULL;  FDefaultButton = NULL;  FCancelButton = NULL;  // to avoid duplication of reference in forms that uses the frame  PopupMenu = RightsPopup;  FPopingContextMenu = false;  FInitialized = false;  #define COPY_HINT(R) \    Checks[TRights::rrGroup ## R]->Hint = Checks[TRights::rrUser ## R]->Hint; \    Checks[TRights::rrOther ## R]->Hint = Checks[TRights::rrUser ## R]->Hint;  COPY_HINT(Read);  COPY_HINT(Write);  COPY_HINT(Exec);  #undef COPY_HINT  UpgradeSpeedButton(OwnerButton);  UpgradeSpeedButton(GroupButton);  UpgradeSpeedButton(OthersButton);}//---------------------------------------------------------------------------__fastcall TRightsFrame::~TRightsFrame(){}//---------------------------------------------------------------------------void __fastcall TRightsFrame::SetStates(TRights::TRight Right, TRights::TState value){  DebugAssert(((value == TRights::rsNo) || (value == TRights::rsYes) || (value == TRights::rsUndef)));  TCheckBox * CheckBox = Checks[Right];  if (CheckBox != NULL)  {    switch (value) {      case TRights::rsNo: CheckBox->State = cbUnchecked; break;      case TRights::rsYes: CheckBox->State = cbChecked; break;      case TRights::rsUndef: CheckBox->State = cbGrayed; break;    }  }}//---------------------------------------------------------------------------TRights::TState __fastcall TRightsFrame::GetStates(TRights::TRight Right){  TCheckBox * CheckBox = Checks[Right];  if (CheckBox != NULL)  {    switch (CheckBox->State) {      case cbUnchecked: return TRights::rsNo;      case cbChecked: return TRights::rsYes;      case cbGrayed:      default: return TRights::rsUndef;    }  }  else  {    return TRights::rsNo;  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::SetRights(const TRights & value){  bool Changed = (AllowUndef != value.AllowUndef);  AllowUndef = true; // temporarily  for (int Right = TRights::rrFirst; Right <= TRights::rrLast; Right++)  {    TRights::TRight R = static_cast<TRights::TRight>(Right);    if (States[R] != value.RightUndef[R])    {      States[R] = value.RightUndef[R];      Changed = true;    }  }  AllowUndef = value.AllowUndef;  if (Changed || !FInitialized)  {    UpdateControls();  }}//---------------------------------------------------------------------------TRights __fastcall TRightsFrame::GetRights(){  TRights Result;  Result.AllowUndef = AllowUndef;  for (int Right = TRights::rrFirst; Right <= TRights::rrLast; Right++)  {    Result.RightUndef[static_cast<TRights::TRight>(Right)] =      States[static_cast<TRights::TRight>(Right)];  }  return Result;}//---------------------------------------------------------------------------void __fastcall TRightsFrame::SetAllowUndef(bool value){  for (int Right = TRights::rrFirst; Right <= TRights::rrLast; Right++)  {    TCheckBox * CheckBox = Checks[static_cast<TRights::TRight>(Right)];    if (CheckBox != NULL)    {      CheckBox->AllowGrayed = value;    }  }}//---------------------------------------------------------------------------bool __fastcall TRightsFrame::GetAllowUndef(){  bool Result = false, First = true;  for (int Right = TRights::rrFirst; Right <= TRights::rrLast; Right++)  {    TCheckBox * Check = Checks[static_cast<TRights::TRight>(Right)];    if (Check != NULL)    {      if (First)      {        Result = Check->AllowGrayed;        First = false;      }      else if (Result != Check->AllowGrayed)      {        DebugFail();      }    }  }  return Result;}//---------------------------------------------------------------------------TCheckBox * __fastcall TRightsFrame::GetChecks(TRights::TRight Right){  for (int Index = 0; Index < ControlCount; Index++)  {    if (Controls[Index]->InheritsFrom(__classid(TCheckBox)) &&        (Controls[Index]->Tag == TRights::RightToFlag(Right)))    {      return ((TCheckBox *)Controls[Index]);    }  }  return NULL;}//---------------------------------------------------------------------------void __fastcall TRightsFrame::SetAddXToDirectories(bool value){  DirectoriesXCheck->Checked = value;}//---------------------------------------------------------------------------bool __fastcall TRightsFrame::GetAddXToDirectories(){  return DirectoriesXCheck->Checked;}//---------------------------------------------------------------------------void __fastcall TRightsFrame::ControlChange(TObject * /*Sender*/){  UpdateControls();}//---------------------------------------------------------------------------bool __fastcall TRightsFrame::DirectoriesXEffective(){  return !((Rights.NumberSet & TRights::rfExec) == TRights::rfExec);}//---------------------------------------------------------------------------void __fastcall TRightsFrame::UpdateControls(){  if (!OctalEdit->Focused())  {    UpdateOctalEdit();  }  Color = (FPopup ? clWindow : clBtnFace);  DirectoriesXCheck->Visible = AllowAddXToDirectories;  EnableControl(DirectoriesXCheck,    Enabled && DirectoriesXEffective());  FInitialized = true;  DoChange();}//---------------------------------------------------------------------------void __fastcall TRightsFrame::CycleRights(int Group){  TRights::TState State;  bool Same = true;  for (int Right = 0; Right < 3; Right++)  {    TRights::TState CState = States[static_cast<TRights::TRight>(      TRights::rrUserRead + Right + ((Group - 1) * 3))];    if (Right == 0) State = CState;      else    if (State != CState) Same = False;  }  if (!Same)  {    State = TRights::rsYes;  }  else  {    switch (State) {      case TRights::rsYes:        State = TRights::rsNo;        break;      case TRights::rsNo:        State = AllowUndef ? TRights::rsUndef : TRights::rsYes;        break;      case TRights::rsUndef:        State = TRights::rsYes;        break;    }  }  for (int Right = 0; Right < 3; Right++)  {    States[static_cast<TRights::TRight>(      TRights::rrUserRead + Right + ((Group - 1) * 3))] = State;  }  UpdateControls();}//---------------------------------------------------------------------------void __fastcall TRightsFrame::RightsButtonsClick(TObject *Sender){  CycleRights(((TComponent*)Sender)->Tag);}//---------------------------------------------------------------------------void __fastcall TRightsFrame::SetAllowAddXToDirectories(bool value){  if ((FAllowAddXToDirectories != value) || !FInitialized)  {    FAllowAddXToDirectories = value;    UpdateControls();  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::DoChange(){  if (FOnChange)  {    FOnChange(this);  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::SetEnabled(bool Value){  TFrame::SetEnabled(Value);  UpdateControls();}//---------------------------------------------------------------------------void __fastcall TRightsFrame::ForceUpdate(){  UpdateOctalEdit();}//---------------------------------------------------------------------------bool __fastcall TRightsFrame::HasFocus(){  return    (Focused() ||    ((Screen->ActiveControl != NULL) && (Screen->ActiveControl->Parent == this))) ||    ((PopupParent != NULL) && PopupParent->Focused());}//---------------------------------------------------------------------------void __fastcall TRightsFrame::RightsActionsExecute(TBasicAction * Action,  bool & Handled){  // prevent shortcuts to be evaluated when frame does not have a focus  if (HasFocus())  {    bool Changed = true;    TRights R = Rights;    R.Number = TRights::rfNo;    Handled = true;    if (Action == NoRightsAction)    {      R = TRights::rfNo;    }    else if (Action == DefaultRightsAction)    {      R = TRights::rfDefault;    }    else if (Action == AllRightsAction)    {      R = TRights::rfAll;    }    else if (Action == LeaveRightsAsIsAction)    {      R.AllUndef();    }    else if (Action == CopyTextAction)    {      TInstantOperationVisualizer Visualizer;      CopyToClipboard(Text);      Changed = false;    }    else if (Action == CopyOctalAction)    {      TRights R = Rights;      DebugAssert(!R.IsUndef);      if (!R.IsUndef)      {        TInstantOperationVisualizer Visualizer;        CopyToClipboard(R.Octal);      }      Changed = false;    }    else if (Action == PasteAction)    {      UnicodeString S;      if (TextFromClipboard(S, true))      {        Text = S;      }      // trigger on change event, even if no change actually occurred to      // allow parent form to visualize feedback of an action      DoChange();      // Update octal edit in Rights frame even if it has focus      ForceUpdate();      Changed = false;    }    else    {      Handled = false;    }    if (Changed)    {      Rights = R;      ForceUpdate();      DoChange();    }  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::RightsActionsUpdate(TBasicAction *Action,      bool &Handled){  TRights R = Rights;  Handled = true;  if (Action == NoRightsAction)  {    // explicitly enable as action gets disabled, if its shortcut is pressed,    // while the form does not have a focus and OnExecute handler denies the execution    NoRightsAction->Enabled = true;    NoRightsAction->Checked = !R.IsUndef && (R.NumberSet == TRights::rfNo);  }  else if (Action == DefaultRightsAction)  {    DefaultRightsAction->Enabled = true;    DefaultRightsAction->Checked = !R.IsUndef && (R.NumberSet == TRights::rfDefault);  }  else if (Action == AllRightsAction)  {    AllRightsAction->Enabled = true;    AllRightsAction->Checked = !R.IsUndef && (R.NumberSet == TRights::rfAll);  }  else if (Action == LeaveRightsAsIsAction)  {    LeaveRightsAsIsAction->Enabled = true;    LeaveRightsAsIsAction->Visible = R.AllowUndef;    LeaveRightsAsIsAction->Checked = (R.NumberSet == TRights::rfNo) &&      (R.NumberUnset == TRights::rfNo);  }  else if (Action == CopyTextAction)  {    CopyTextAction->Enabled = !R.IsUndef;  }  else if (Action == CopyOctalAction)  {    CopyOctalAction->Enabled = !R.IsUndef;  }  else if (Action == PasteAction)  {    PasteAction->Enabled = IsFormatInClipboard(CF_TEXT);  }  else  {    Handled = false;  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::CreateParams(TCreateParams & Params){  TFrame::CreateParams(Params);  if (FPopup)  {    Params.Style |= WS_BORDER;  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::CreateWnd(){  if (FPopup)  {    Width += 2 * GetSystemMetricsForControl(Parent, SM_CXBORDER);    Height += 2 * GetSystemMetricsForControl(Parent, SM_CYBORDER);  }  TFrame::CreateWnd();}//---------------------------------------------------------------------------void __fastcall TRightsFrame::SetPopup(bool value){  if (Popup != value)  {    FPopup = value;    Visible = !FPopup;    CloseButton->Visible = value;    CloseButton->Cancel = value;    CloseButton->Default = value;  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::DoCloseUp(){  Hide();  if (FDefaultButton != NULL)  {    FDefaultButton->Default = true;    FDefaultButton = NULL;  }  if (FCancelButton != NULL)  {    FCancelButton->Cancel = true;    FCancelButton = NULL;  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::DoExit(){  // this is bit hack to make frame hide when ComboEdit button is pressed while  // from is poped-up already.  if (FPopup && !IsAncestor(Screen->ActiveControl, FPopupParent))  {    DoCloseUp();  }  TFrame::DoExit();}//---------------------------------------------------------------------------bool __fastcall TRightsFrame::IsAncestor(TControl * Control, TControl * Ancestor){  while ((Control != NULL) &&         (Control->Parent != Ancestor))  {    Control = Control->Parent;  }  return (Control != NULL);}//---------------------------------------------------------------------------void __fastcall TRightsFrame::WMContextMenu(TWMContextMenu & Message){  FPopingContextMenu = true;  try  {    TFrame::Dispatch(&Message);  }  __finally  {    FPopingContextMenu = false;  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::CMDialogKey(TCMDialogKey & Message){  if (FPopup && Visible &&      ((Message.CharCode == VK_RETURN) ||       (Message.CharCode == VK_ESCAPE)) &&      KeyDataToShiftState(Message.KeyData).Empty())  {    CloseUp();    Message.Result = 1;  }  else  {    TFrame::Dispatch(&Message);  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::CMCancelMode(TCMCancelMode & Message){  if (FPopup && Visible && !FPopingContextMenu &&      ((Message.Sender == NULL) ||       (!IsAncestor(Message.Sender, this) &&        !IsAncestor(Message.Sender, FPopupParent) &&        (Message.Sender != this))))  {    CloseUp();  }  TFrame::Dispatch(&Message);}//---------------------------------------------------------------------------void __fastcall TRightsFrame::Dispatch(void * Message){  TMessage & AMessage = *static_cast<TMessage *>(Message);  switch (AMessage.Msg)  {    case CM_CANCELMODE:      CMCancelMode(*(TCMCancelMode *)Message);      break;    case CM_DIALOGKEY:      CMDialogKey(*(TCMDialogKey *)Message);      break;    case WM_CONTEXTMENU:      WMContextMenu(*(TWMContextMenu *)Message);      break;    default:      TFrame::Dispatch(Message);      break;  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::DropDown(){  TCustomForm * Form = GetParentForm(this);  // due to lack of better idea, we clear "default" and "cancel" flags of respective  // form buttons to prevent them to handle ESC/ENTER keys.  for (int Index = 0; Index < Form->ControlCount; Index++)  {    TButton * Button = dynamic_cast<TButton *>(Form->Controls[Index]);    if (Button != NULL)    {      if (Button->Default)      {        DebugAssert(FDefaultButton == NULL);        FDefaultButton = Button;        Button->Default = false;      }      if (Button->Cancel)      {        DebugAssert(FCancelButton == NULL);        FCancelButton = Button;        Button->Cancel = false;      }    }  }  TPoint Origin(PopupParent->Left, PopupParent->Top + PopupParent->Height);  Origin = Parent->ScreenToClient(PopupParent->Parent->ClientToScreen(Origin));  if (Origin.x + Width > Parent->ClientWidth)  {    Origin.x += PopupParent->Width - Width;  }  Left = Origin.x;  Top = Origin.y;  Show();  SetFocus();}//---------------------------------------------------------------------------void __fastcall TRightsFrame::CloseUp(){  DebugAssert(FPopup);  DebugAssert(Visible);  if (!Focused())  {    // this can happen only if called from on-click handler of drop down button    DoCloseUp();  }  FPopupParent->SetFocus();}//---------------------------------------------------------------------------UnicodeString __fastcall TRightsFrame::GetText(){  UnicodeString Result = Rights.Text;  if (AllowAddXToDirectories && DirectoriesXEffective() && AddXToDirectories)  {    Result = FORMAT(L"%s (%s)", (Result, FAddXToDirectoriesSuffix));  }  return Result;}//---------------------------------------------------------------------------void __fastcall TRightsFrame::SetText(UnicodeString value){  if (Text != value)  {    UnicodeString RightsStr = value;    int P = RightsStr.LowerCase().Pos(FAddXToDirectoriesSuffix);    bool AAddXToDirectories = (P > 0);    if (AAddXToDirectories)    {      RightsStr.Delete(P, FAddXToDirectoriesSuffix.Length());    }    RightsStr = DeleteChar(DeleteChar(RightsStr, L'('), L')').Trim();    TRights R = Rights;    if (((RightsStr.Length() == 3) || (RightsStr.Length() == 4)) &&        IsNumber(RightsStr))    {      R.Octal = RightsStr;    }    else    {      R.Text = RightsStr;    }    Rights = R;    AddXToDirectories = AAddXToDirectories;  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::RightsPopupPopup(TObject * /*Sender*/){  if (!HasFocus())  {    SetFocus();  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::FrameContextPopup(TObject * Sender,  TPoint & MousePos, bool & Handled){  SelectScaledImageList(RightsImages);  MenuPopup(Sender, MousePos, Handled);}//---------------------------------------------------------------------------void __fastcall TRightsFrame::UpdateByOctal(){  if (!OctalEdit->Text.IsEmpty())  {    TRights R = Rights;    R.Octal = OctalEdit->Text;    Rights = R;  }  UpdateControls();  OctalEdit->Modified = false;}//---------------------------------------------------------------------------void __fastcall TRightsFrame::UpdateOctalEdit(){  TRights R = Rights;  OctalEdit->Text = R.IsUndef ? UnicodeString() : R.Octal;  OctalEdit->Modified = false;  OctalEdit->SelectAll();}//---------------------------------------------------------------------------void __fastcall TRightsFrame::OctalEditChange(TObject *){  if (OctalEdit->Modified && OctalEdit->Text.Length() >= 3)  {    try    {      UpdateByOctal();    }    catch(...)    {      OctalEdit->Modified = true;    }  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::OctalEditExit(TObject *){  if (!Visible)  {    // should happen only if popup is closed by esc key    DebugAssert(Popup);    // cancel changes    ForceUpdate();  }  else if (OctalEdit->Modified)  {    // Now the text in OctalEdit is almost necessarily invalid, otherwise    // OctalEditChange would have already cleared Modified flag    try    {      UpdateByOctal();    }    catch(...)    {      OctalEdit->SelectAll();      OctalEdit->SetFocus();      throw;    }  }  else  {    UpdateControls();  }}//---------------------------------------------------------------------------void __fastcall TRightsFrame::CloseButtonClick(TObject *){  CloseUp();}//---------------------------------------------------------------------------
 |