home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d56 / RMCTL.ZIP / rmKeyBindingsEditForm.pas < prev    next >
Pascal/Delphi Source File  |  2001-06-22  |  15KB  |  533 lines

  1. {================================================================================
  2. Copyright (C) 1997-2001 Mills Enterprise
  3.  
  4. Unit     : rmKeyBindingsEditForm
  5. Purpose  : Runtime editing form for looking at the assigned key bindings. 
  6. Date     : 05-03-2000
  7. Author   : Ryan J. Mills
  8. Version  : 1.80
  9. ================================================================================}
  10.  
  11. unit rmKeyBindingsEditForm;
  12.  
  13. interface
  14.  
  15. {$I CompilerDefines.INC}
  16.  
  17. uses
  18.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  19.   StdCtrls, rmLabel, rmKeyBindings, imglist, ActnList, rmTreeNonView, CheckLst;
  20.  
  21. type
  22.   TFrmEditKeyBindings = class(TForm)
  23.     Label1: TLabel;
  24.     Label2: TLabel;
  25.     lbxCategories: TListBox;
  26.     lbxCommands: TListBox;
  27.     btnClose: TButton;
  28.     btnChange: TButton;
  29.     btnResetAll: TButton;
  30.     lblErrorInfo: TrmLabel;
  31.     ActionList1: TActionList;
  32.     actChange: TAction;
  33.     actResetAll: TAction;
  34.     GroupBox1: TGroupBox;
  35.     lblDescription: TrmLabel;
  36.     GroupBox2: TGroupBox;
  37.     lblKeys: TrmLabel;
  38.     cbxDesignLock: TCheckBox;
  39.     btnSave: TButton;
  40.     btnLoad: TButton;
  41.     actSaveBindings: TAction;
  42.     actLoadBindings: TAction;
  43.     procedure ActionList1Update(Action: TBasicAction; var Handled: Boolean);
  44.     procedure lbxCategoriesClick(Sender: TObject);
  45.     procedure lbxCommandsDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
  46.     procedure lbxCommandsClick(Sender: TObject);
  47.     procedure actChangeExecute(Sender: TObject);
  48.     procedure actResetAllExecute(Sender: TObject);
  49.     procedure cbxDesignLockClick(Sender: TObject);
  50.     procedure actSaveBindingsExecute(Sender: TObject);
  51.     procedure actLoadBindingsExecute(Sender: TObject);
  52.   private
  53.     { Private declarations }
  54.     fItems,fItems2: TrmKeyBindingCollection;
  55.     fnvTree: TrmTreeNonView;
  56.     fImages: TCustomImageList;
  57.     fDisplayName: boolean;
  58.     fModified: boolean;
  59.     fDesigning: boolean;
  60.     fMultiBinding: boolean;
  61.  
  62.     procedure SetItems(const Value: TrmKeyBindingCollection);
  63.     function GetItems: TrmKeyBindingCollection;
  64.     procedure SetImages(const Value: TCustomImageList);
  65.     procedure UpdateKeyInfo(Index: integer);
  66.     procedure BuildTree;
  67.     procedure SetDesigning(const Value: boolean);
  68.     procedure SaveBindingsToFile(FileName:string; Binary:Boolean);
  69.     procedure LoadBindingsFromFile(FileName:string; Binary:boolean);
  70.   protected
  71.     { Protected declarations }
  72.     procedure notification(AComponent: TComponent; Operation: TOperation); override;
  73.   public
  74.     { Public declarations }
  75.     constructor create(AOwner: TComponent); override;
  76.     destructor destroy; override;
  77.     property Items: TrmKeyBindingCollection read GetItems write SetItems;
  78.     property Images: TCustomImageList read fImages write SetImages;
  79.     property DisplayName: boolean read fDisplayName write fDisplayName default false;
  80.     property Designing : boolean read fDesigning write SetDesigning;
  81.     property MultiBinding : boolean read fMultiBinding write fMultiBinding default true;
  82.   end;
  83.  
  84. implementation
  85.  
  86. {$R *.DFM}
  87.  
  88. uses rmFormEditBinding,Menus;
  89.  
  90. constructor TFrmEditKeyBindings.create(AOwner: TComponent);
  91. begin
  92.   inherited;
  93.   fnvTree := TrmTreeNonView.create(self);
  94.   fitems := TrmKeyBindingCollection.create(self);
  95.   fItems2 := TrmKeyBindingCollection.create(self);
  96.   fDisplayName := false;
  97.   fMultiBinding := true;
  98.   fModified := false;
  99. end;
  100.  
  101. destructor TFrmEditKeyBindings.destroy;
  102. begin
  103.   fnvTree.Items.Clear;
  104.   fnvTree.Free;
  105.   fItems2.clear;
  106.   fItems2.free;
  107.   fitems.Clear;
  108.   fItems.Free;
  109.   inherited;
  110. end;
  111.  
  112. procedure TFrmEditKeyBindings.SetItems(const Value: TrmKeyBindingCollection);
  113. begin
  114.   fItems.clear;
  115.   fItems2.clear;
  116.  
  117.   if assigned(value) then
  118.   begin
  119.     fItems.Assign(Value);
  120.     fItems2.assign(value);
  121.     BuildTree;
  122.     if assigned(fImages) then
  123.        lbxCommands.ItemHeight := fImages.Height;
  124.   end;
  125. end;
  126.  
  127. function TFrmEditKeyBindings.GetItems: TrmKeyBindingCollection;
  128. begin
  129.   result := fItems;
  130. end;
  131.  
  132. procedure TFrmEditKeyBindings.SetImages(const Value: TCustomImageList);
  133. begin
  134.   fimages := value;
  135.   if assigned(fImages) then
  136.     fImages.FreeNotification(self);
  137. end;
  138.  
  139. procedure TFrmEditKeyBindings.notification(AComponent: TComponent;
  140.   Operation: TOperation);
  141. begin
  142.   if (operation = opRemove) then
  143.   begin
  144.     if aComponent = fImages then
  145.       fimages := nil;
  146.   end;
  147.  
  148.   inherited;
  149. end;
  150.  
  151. procedure TFrmEditKeyBindings.ActionList1Update(Action: TBasicAction;
  152.   var Handled: Boolean);
  153. begin
  154.    UpdateKeyInfo(lbxCommands.ItemIndex);
  155.  
  156.    if lbxCategories.itemindex = -1 then
  157.       lbxCommands.clear;
  158.  
  159.    if not fDesigning then
  160.       actChange.enabled := (lbxCommands.ItemIndex <> -1) and (not cbxDesignLock.checked)
  161.    else
  162.    begin
  163.       actChange.Enabled := (lbxCommands.ItemIndex <> -1);
  164.       cbxDesignLock.enabled := actChange.enabled;
  165.    end;
  166.  
  167.    actResetAll.Enabled := fModified;
  168.  
  169.    if fModified then
  170.      btnClose.ModalResult := mrok
  171.    else
  172.      btnClose.ModalResult := mrCancel;
  173.    handled := true;
  174. end;
  175.  
  176. procedure TFrmEditKeyBindings.lbxCategoriesClick(Sender: TObject);
  177. var
  178.   wSNode: TrmTreeNonViewNode;
  179. begin
  180.   lbxCommands.Clear;
  181.   if lbxCategories.itemindex <> -1 then
  182.   begin
  183.     wSNode := fnvTree.Items.GetFirstNode;
  184.     while (wSNode <> nil) and (wsNode.text <> lbxCategories.items[lbxCategories.ItemIndex]) do
  185.       wsNode := wSNode.GetNextSibling;
  186.  
  187.     if wSNode <> nil then
  188.     begin
  189.       wSNode := wSNode.GetFirstChild;
  190.       while wSNode <> nil do
  191.       begin
  192.         lbxCommands.Items.AddObject(wSNode.Text,TrmKeyBindingItem(wSNode.Data));
  193.         wSNode := wSNode.GetNextSibling;
  194.       end;
  195.     end;
  196.   end;
  197. end;
  198.  
  199. procedure TFrmEditKeyBindings.lbxCommandsDrawItem(Control: TWinControl;
  200.   Index: Integer; Rect: TRect; State: TOwnerDrawState);
  201. var
  202.   wDisplayText: string;
  203.   wKeyData : TrmKeyBindingItem;
  204. begin
  205.   lbxCommands.Canvas.Font.assign(lbxCommands.font);
  206.   wKeyData := TrmKeyBindingItem(lbxCommands.Items.objects[index]);
  207.  
  208.   if odSelected in State then
  209.   begin
  210.     lbxCommands.Canvas.Brush.Color := clHighlight;
  211.     lbxCommands.Canvas.Font.Color := clHighlightText;
  212.   end
  213.   else
  214.   begin
  215.     lbxCommands.Canvas.Brush.Color := clWindow;
  216.     lbxCommands.Canvas.Font.Color := clWindowText;
  217.   end;
  218.   lbxCommands.Canvas.FillRect(rect);
  219.  
  220.   if (wKeyData.DesignLocked) then
  221.   begin
  222.      lbxCommands.Canvas.Font.Style := [fsitalic];
  223.      lbxCommands.Canvas.Font.color := clGrayText;
  224.   end;
  225.  
  226.   if assigned(fImages) then
  227.   begin
  228.      fImages.Draw(lbxCommands.Canvas,rect.left,rect.top,wKeyData.ImageIndex);
  229.      rect.Left := rect.left + (fimages.width) + 1;
  230.   end
  231.   else
  232.      rect.Left := rect.left + 1;
  233.  
  234.  
  235.   if displayName then
  236.     wDisplayText := wKeyData.ActionName
  237.   else
  238.     wDisplayText := StriphotKey(wKeyData.ActionCaption);
  239.  
  240.   lbxCommands.Canvas.TextRect(rect,rect.left,rect.top,wDisplayText);
  241. end;
  242.  
  243. procedure TFrmEditKeyBindings.UpdateKeyInfo(Index: integer);
  244. var
  245.   wKeyData, wLoopData: TrmKeyBindingItem;
  246.   wAlsoUsedBy: string;
  247.   loop: integer;
  248. begin
  249.   if Index > -1 then
  250.   begin
  251.     wKeyData := TrmKeyBindingItem(lbxCommands.Items.objects[index]);
  252.     lblKeys.caption := ShortCutToText(wKeyData.KeyBinding);
  253.     if lblKeys.caption = '' then
  254.        lblKeys.Caption := '(None)';
  255.     lblDescription.caption := wKeyData.Description;
  256.     cbxDesignLock.checked := wKeyData.DesignLocked;
  257.     wAlsoUsedBy := '';
  258.     if wKeyData.KeyBinding <> 0 then
  259.     begin
  260.       for loop := 0 to fItems.count - 1 do
  261.       begin
  262.         wLoopData := fItems[loop];
  263.         if (wLoopData <> wKeyData) and (wKeyData.KeyBinding = wLoopData.KeyBinding) then
  264.         begin
  265.           if DisplayName then
  266.             wAlsoUsedBy := ', ' + wLoopData.ActionName + wAlsoUsedBy
  267.           else
  268.             wAlsoUsedBy := ', "' + wLoopData.ActionCaption + '" ' + wAlsoUsedBy
  269.         end;
  270.       end;
  271.       if wAlsoUsedBy <> '' then
  272.       begin
  273.         delete(wAlsoUsedBy,1,1);
  274.         lblErrorInfo.Caption := 'The same binding is also used by' + wAlsoUsedBy;
  275.       end
  276.       else
  277.         lblErrorInfo.Caption := '';
  278.     end
  279.     else
  280.       lblErrorInfo.Caption := '';
  281.   end
  282.   else
  283.   begin
  284.     lblKeys.caption := '(None)';
  285.     lblErrorInfo.caption := '';
  286.     lblDescription.caption := '';
  287.   end;
  288. end;
  289.  
  290. procedure TFrmEditKeyBindings.lbxCommandsClick(Sender: TObject);
  291. begin
  292.   UpdateKeyInfo(lbxCommands.ItemIndex);
  293. end;
  294.  
  295. procedure TFrmEditKeyBindings.actChangeExecute(Sender: TObject);
  296. var
  297.   wForm: TrmFrmEditBinding;
  298.   wKeyData: TrmKeyBindingItem;
  299.   wFound : boolean;
  300.   loop : integer;
  301. begin
  302.   wForm := TrmFrmEditBinding.create(self);
  303.   try
  304.     wKeyData := TrmKeyBindingItem(lbxCommands.items.objects[lbxCommands.itemindex]);
  305.     wForm.Binding := wKeyData.KeyBinding;
  306.     if fMultiBinding then
  307.     begin
  308.        if wForm.showModal = mrok then
  309.        begin
  310.          wKeyData.KeyBinding := wForm.Binding;
  311.          fModified := true;
  312.        end;
  313.     end
  314.     else
  315.     begin
  316.        wFound := true;
  317.        while wFound do
  318.        begin
  319.           if wForm.showModal = mrok then
  320.           begin
  321.             for loop := 0 to fitems.count-1 do
  322.             begin
  323.                wFound := (wForm.Binding = fItems[loop].KeyBinding);
  324.                if wFound then
  325.                begin
  326.                   if not fDesigning then
  327.                   begin
  328.                      MessageDlg('That binding is already in use.', mtError, [mbok], 0);
  329.                      break;
  330.                   end
  331.                   else
  332.                   begin
  333.                      if MessageDlg('That binding is already in use.'#13#10#13#10'Do you wish to set it anyways?', mtConfirmation, [mbyes, mbNo], 0) = idyes then
  334.                         wFound := false;
  335.                      break;
  336.                   end;
  337.                end
  338.             end;
  339.             if not wFound then
  340.             begin
  341.                wKeyData.KeyBinding := wForm.Binding;
  342.                fModified := true;
  343.             end;
  344.           end
  345.           else
  346.           wFound := false;
  347.        end;
  348.     end;
  349.   finally
  350.     wForm.free;
  351.   end;
  352. end;
  353.  
  354. procedure TFrmEditKeyBindings.BuildTree;
  355. var
  356.   wPNode: TrmTreeNonViewNode;
  357.   loop: integer;
  358.   wkeydata: TrmKeyBindingItem;
  359. begin
  360.   fnvTree.Items.clear;
  361.   lbxCommands.Clear;
  362.   lbxCategories.Clear;
  363.   for loop := 0 to fItems.Count - 1 do
  364.   begin
  365.     wPNode := fnvTree.Items.GetFirstNode;
  366.     wKeyData := fItems[loop];
  367.  
  368.     while (wPNode <> nil) and (wPNode.Text <> wKeyData.Category) do
  369.       wPNode := wPNode.GetNextSibling;
  370.  
  371.     if wPNode = nil then
  372.     begin
  373.       if pos('_hidden',lowercase(wKeyData.Category)) = 0 then
  374.       begin
  375.          wPNode := fnvTree.Items.Add(nil,wKeyData.Category);
  376.          lbxCategories.items.add(wKeyData.Category);
  377.       end;
  378.     end;
  379.  
  380.     if wPNode <> nil then
  381.        fnvTree.Items.AddChildObject(wPNode,wKeyData.ActionCaption,wKeyData);
  382.   end;
  383.  
  384. end;
  385.  
  386. procedure TFrmEditKeyBindings.actResetAllExecute(Sender: TObject);
  387. begin
  388.   fItems.assign(fItems2);
  389.   BuildTree;
  390.   fModified := false;
  391. end;
  392.  
  393. procedure TFrmEditKeyBindings.SetDesigning(const Value: boolean);
  394. begin
  395.   fDesigning := Value;
  396.   if not fDesigning then
  397.   begin
  398.      cbxDesignLock.Visible := false;
  399.      lblKeys.Align := alClient;
  400.      btnSave.visible := false;
  401.      btnLoad.visible := false;
  402.   end;
  403. end;
  404.  
  405. procedure TFrmEditKeyBindings.cbxDesignLockClick(Sender: TObject);
  406. var
  407.    wKeyData : TrmKeyBindingItem;
  408. begin
  409.    if not cbxDesignLock.Focused then exit;
  410.    wKeyData := TrmKeyBindingItem(lbxCommands.Items.objects[lbxCommands.ItemIndex]);
  411.    wKeyData.DesignLocked := not wKeyData.DesignLocked;
  412.    fModified := true;
  413.    lbxCommands.Invalidate;
  414. end;
  415.  
  416. procedure TFrmEditKeyBindings.actSaveBindingsExecute(Sender: TObject);
  417. var
  418.    wSaveBinary : boolean;
  419.    wFilename : string;
  420. begin
  421.    with TSaveDialog.create(nil) do
  422.    try
  423.       Title := 'Save bindings to file...';
  424.       Filter := 'Binary File|*.bin|Text File|*.txt';
  425.       if Execute then
  426.       begin
  427.          wSaveBinary := FilterIndex = 1;
  428.          if wSaveBinary then
  429.             wFileName := ChangeFileExt(filename,'.bin')
  430.          else
  431.             wFileName := ChangeFileExt(filename,'.txt');
  432.          SaveBindingsToFile(wfilename, wSaveBinary);
  433.       end;
  434.    finally
  435.       free;
  436.    end;
  437. end;
  438.  
  439. procedure TFrmEditKeyBindings.SaveBindingsToFile(FileName: string;
  440.   Binary: Boolean);
  441. var
  442.    wStorage : TrmBindingStorage;
  443.    wTemp : TMemoryStream;
  444.    wStrm : TFileStream;
  445. begin
  446.    wStrm := TFileStream.Create(filename, fmCreate);
  447.    try
  448.       wStorage := TrmBindingStorage.create(self);
  449.       try
  450.          wStrm.Position := 0;
  451.          wStorage.Items := fItems;
  452.          if Binary then
  453.             wStrm.WriteComponent(wStorage)
  454.          else
  455.          begin
  456.             wTemp := TMemoryStream.create;
  457.             try
  458.                wTemp.WriteComponent(wStorage);
  459.                wTemp.Position := 0;
  460.                ObjectBinaryToText(wTemp, wStrm)
  461.             finally
  462.                wTemp.free;
  463.             end;
  464.          end;
  465.       finally
  466.          wStorage.free;
  467.       end;
  468.    finally
  469.       wStrm.free;
  470.    end;
  471. end;
  472.  
  473. procedure TFrmEditKeyBindings.LoadBindingsFromFile(FileName: string; Binary: boolean);
  474. var
  475.    wStorage : TComponent;
  476.    wTemp : TMemoryStream;
  477.    wStrm : TFileStream;
  478. begin
  479.    wStrm := TFileStream.create(filename, fmOpenRead);
  480.    try
  481.       wStrm.Position := 0;
  482.  
  483.       if Binary then
  484.          wStorage := TrmBindingStorage(wStrm.ReadComponent(nil))
  485.       else
  486.       begin
  487.          wTemp := TMemoryStream.create;
  488.          try
  489.             ObjectTextToBinary(wStrm, wTemp);
  490.             wTemp.position := 0;
  491.             wStorage := TrmBindingStorage(wTemp.ReadComponent(nil));
  492.          finally
  493.             wTemp.free;
  494.          end;
  495.       end;
  496.  
  497.       try
  498.          fItems.Assign(TrmBindingStorage(wStorage).items);
  499.       finally
  500.          wStorage.free;
  501.       end;
  502.    finally
  503.       wStrm.free;
  504.    end;
  505.    BuildTree;
  506. end;
  507.  
  508. procedure TFrmEditKeyBindings.actLoadBindingsExecute(Sender: TObject);
  509. var
  510.    wLoadBinary : boolean;
  511.    wFilename : string;
  512. begin
  513.    with TOpenDialog.create(nil) do
  514.    try
  515.       Title := 'Load bindings from file...';
  516.       Filter := 'Binary File|*.bin|Text File|*.txt';
  517.       if Execute then
  518.       begin
  519.          wLoadBinary := FilterIndex = 1;
  520.          if wLoadBinary then
  521.             wFileName := ChangeFileExt(filename,'.bin')
  522.          else
  523.             wFileName := ChangeFileExt(filename,'.txt');
  524.          LoadBindingsFromFile(wfilename, wLoadBinary);
  525.       end;
  526.    finally
  527.       free;
  528.    end;
  529. end;
  530.  
  531. end.
  532.  
  533.