Skip to content

Commit

Permalink
Introduce read-only mode for grid editors. Closes #631
Browse files Browse the repository at this point in the history
  • Loading branch information
ansgarbecker committed Feb 6, 2020
1 parent 568e1a6 commit 56e541a
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 58 deletions.
2 changes: 1 addition & 1 deletion source/connections.pas
Expand Up @@ -737,7 +737,7 @@ procedure Tconnform.ListSessionsCreateEditor(Sender: TBaseVirtualTree; Node: PVi
Column: TColumnIndex; out EditLink: IVTEditLink);
begin
// Use our own text editor to rename a session
EditLink := TInplaceEditorLink.Create(Sender as TVirtualStringTree);
EditLink := TInplaceEditorLink.Create(Sender as TVirtualStringTree, True);
end;


Expand Down
14 changes: 14 additions & 0 deletions source/dbconnection.pas
Expand Up @@ -706,6 +706,7 @@ TDBQuery = class(TComponent)
function HasResult: Boolean; virtual; abstract;
function GetWhereClause: String;
procedure CheckEditable;
function IsEditable: Boolean;
procedure DeleteRow;
function InsertRow: Int64;
procedure SetCol(Column: Integer; NewText: String; Null: Boolean; IsFunction: Boolean);
Expand Down Expand Up @@ -7989,6 +7990,19 @@ procedure TDBQuery.CheckEditable;
end;
end;

function TDBQuery.IsEditable: Boolean;
begin
try
CheckEditable;
Result := True;
except
on E:EDbError do begin
FConnection.Log(lcDebug, E.Message);
Result := False;
end;
end;
end;


function TDBQuery.GetWhereClause: String;
var
Expand Down
79 changes: 51 additions & 28 deletions source/grideditlinks.pas
Expand Up @@ -36,16 +36,20 @@ TBaseGridEditorLink = class(TInterfacedObject, IVTEditLink)
FOldWindowProc: TWndMethod; // Temporary switched to TempWindowProc to be able to catch Tab key
FTableColumn: TTableColumn;
FModified: Boolean;
FAllowEdit: Boolean;
FBeginEditTime: Cardinal;
procedure TempWindowProc(var Message: TMessage);
procedure DoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure DoEndEdit(Sender: TObject);
procedure DoCancelEdit(Sender: TObject);
function GetCellRect(InnerTextBounds: Boolean): TRect;
public
property TableColumn: TTableColumn read FTableColumn write FTableColumn; // The table column of the cell being edited. Mostly used in data grids.
constructor Create; overload; // The original constructor, not used any more, throws an exception if you do
constructor Create(Tree: TVirtualStringTree); overload; virtual; // The right constructor, we need the Tree reference
// The table column of the cell being edited. Mostly used in data grids.
property TableColumn: TTableColumn read FTableColumn write FTableColumn;
// The original constructor, not used any more, throws an exception if you do
constructor Create; overload;
// The right constructor, we need the Tree reference
constructor Create(Tree: TVirtualStringTree; AllowEdit: Boolean); overload; virtual;
destructor Destroy; override;
function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; stdcall;
function BeginEdit: Boolean; virtual; stdcall;
Expand All @@ -63,7 +67,7 @@ THexEditorLink = class(TBaseGridEditorLink)
public
MaxLength: Integer;
TitleText: String;
constructor Create(Tree: TVirtualStringTree); override;
constructor Create(Tree: TVirtualStringTree; AllowEdit: Boolean); override;
destructor Destroy; override;
function BeginEdit: Boolean; override;
function CancelEdit: Boolean; override;
Expand All @@ -90,7 +94,7 @@ TDateTimeEditorLink = class(TBaseGridEditorLink)
procedure TextChange(Sender: TObject);
function MicroSecondsPrecision: Integer;
public
constructor Create(Tree: TVirtualStringTree); override;
constructor Create(Tree: TVirtualStringTree; AllowEdit: Boolean); override;
destructor Destroy; override;
function BeginEdit: Boolean; override;
function EndEdit: Boolean; override;
Expand All @@ -102,10 +106,11 @@ TEnumEditorLink = class(TBaseGridEditorLink)
private
FCombo: TComboBox;
procedure DoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure DoSelect(Sender: TObject);
public
ValueList, DisplayList: TStringList;
AllowCustomText: Boolean;
constructor Create(Tree: TVirtualStringTree); override;
constructor Create(Tree: TVirtualStringTree; AllowEdit: Boolean); override;
destructor Destroy; override;
function BeginEdit: Boolean; override;
function EndEdit: Boolean; override;
Expand All @@ -123,7 +128,7 @@ TSetEditorLink = class(TBaseGridEditorLink)
procedure BtnCancelClick(Sender: TObject);
public
ValueList: TStringList;
constructor Create(Tree: TVirtualStringTree); override;
constructor Create(Tree: TVirtualStringTree; AllowEdit: Boolean); override;
destructor Destroy; override;
function BeginEdit: Boolean; override;
function EndEdit: Boolean; override;
Expand All @@ -144,7 +149,7 @@ TInplaceEditorLink = class(TBaseGridEditorLink)
public
ButtonVisible: Boolean;
TitleText: String;
constructor Create(Tree: TVirtualStringTree); override;
constructor Create(Tree: TVirtualStringTree; AllowEdit: Boolean); override;
destructor Destroy; override;
function BeginEdit: Boolean; override;
function CancelEdit: Boolean; override;
Expand Down Expand Up @@ -173,7 +178,7 @@ TColumnDefaultEditorLink = class(TBaseGridEditorLink)
public
DefaultType, OnUpdateType: TColumnDefaultType;
DefaultText, OnUpdateText: String;
constructor Create(Tree: TVirtualStringTree); override;
constructor Create(Tree: TVirtualStringTree; AllowEdit: Boolean); override;
destructor Destroy; override;
function BeginEdit: Boolean; override;
function EndEdit: Boolean; override;
Expand All @@ -199,7 +204,7 @@ TDataTypeEditorLink = class(TBaseGridEditorLink)
PVirtualNode; OldColumn, NewColumn: TColumnIndex; var Allowed: Boolean);
procedure DoTreeSelectFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex);
public
constructor Create(Tree: TVirtualStringTree); override;
constructor Create(Tree: TVirtualStringTree; AllowEdit: Boolean); override;
destructor Destroy; override;
function BeginEdit: Boolean; override;
function EndEdit: Boolean; override;
Expand Down Expand Up @@ -232,7 +237,7 @@ constructor TBaseGridEditorLink.Create;
[Self.ClassName, 'Create', Self.ClassName, 'Create(VirtualStringTree)']);
end;

constructor TBaseGridEditorLink.Create(Tree: TVirtualStringTree);
constructor TBaseGridEditorLink.Create(Tree: TVirtualStringTree; AllowEdit: Boolean);
begin
inherited Create;
FTree := Tree;
Expand All @@ -243,6 +248,7 @@ constructor TBaseGridEditorLink.Create(Tree: TVirtualStringTree);
FParentForm.Repaint;
SendMessage(FParentForm.Handle, WM_SETREDRAW, 0, 0);
FModified := False;
FAllowEdit := AllowEdit;
end;

destructor TBaseGridEditorLink.Destroy;
Expand Down Expand Up @@ -333,7 +339,7 @@ function TBaseGridEditorLink.EndEditHelper(NewText: String): Boolean;
Result := not FStopping;
if FStopping then Exit;
FStopping := True;
if FModified then
if FModified and FAllowEdit then
FTree.Text[FNode, FColumn] := NewText;
if FTree.CanFocus and (FLastKeyDown <> VK_TAB) then
FTree.SetFocus;
Expand Down Expand Up @@ -440,9 +446,9 @@ procedure TBaseGridEditorLink.DoCancelEdit(Sender: TObject);



constructor THexEditorLink.Create(Tree: TVirtualStringTree);
constructor THexEditorLink.Create(Tree: TVirtualStringTree; AllowEdit: Boolean);
begin
inherited Create(Tree);
inherited;
end;

destructor THexEditorLink.Destroy;
Expand All @@ -465,6 +471,7 @@ function THexEditorLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode;
FForm.SetText(FCellText);
FForm.SetTitleText(TitleText);
FForm.SetMaxLength(MaxLength);
FForm.memoText.ReadOnly := not FAllowEdit;
end;


Expand Down Expand Up @@ -501,9 +508,9 @@ procedure THexEditorLink.SetBounds(R: TRect); stdcall;

{ DateTime editor }

constructor TDateTimeEditorLink.Create(Tree: TVirtualStringTree);
constructor TDateTimeEditorLink.Create(Tree: TVirtualStringTree; AllowEdit: Boolean);
begin
inherited Create(Tree);
inherited;

FPanel := TPanel.Create(FParentForm);
FPanel.Parent := FParentForm;
Expand All @@ -519,6 +526,7 @@ constructor TDateTimeEditorLink.Create(Tree: TVirtualStringTree);
FMaskEdit.OnKeyDown := DoKeyDown;
FMaskEdit.OnKeyUp := DoKeyUp;
FMaskEdit.OnChange := TextChange;
FMaskEdit.ReadOnly := not FAllowEdit;
FMainControl := FMaskEdit;

FUpDown := TUpDown.Create(FPanel);
Expand Down Expand Up @@ -840,15 +848,16 @@ function TDateTimeEditorLink.MicroSecondsPrecision: Integer;

{ Enum editor }

constructor TEnumEditorLink.Create(Tree: TVirtualStringTree);
constructor TEnumEditorLink.Create(Tree: TVirtualStringTree; AllowEdit: Boolean);
begin
inherited Create(Tree);
inherited;
AllowCustomText := False;
FCombo := TComboBox.Create(FParentForm);
FCombo.Hide;
FCombo.Parent := FParentForm;
FCombo.OnKeyDown := DoKeyDown;
FCombo.OnExit := DoEndEdit;
FCombo.OnSelect := DoSelect;
// Show some more than the default 8 items
FCombo.DropDownCount := 16;
ValueList := TStringList.Create;
Expand Down Expand Up @@ -878,7 +887,7 @@ function TEnumEditorLink.EndEdit: Boolean; stdcall;
var
NewText: String;
begin
if AllowCustomText then
if AllowCustomText and FAllowEdit then
NewText := FCombo.Text
else if (ValueList.Count > 0) and (FCombo.ItemIndex > -1) then
NewText := ValueList[FCombo.ItemIndex]
Expand All @@ -902,7 +911,7 @@ function TEnumEditorLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode;
Items := ValueList;
for i:=0 to Items.Count - 1 do
FCombo.Items.Add(Items[i]);
if AllowCustomText then begin
if AllowCustomText and FAllowEdit then begin
FCombo.Style := csDropDown;
FCombo.Text := FCellText;
end else begin
Expand Down Expand Up @@ -930,12 +939,21 @@ procedure TEnumEditorLink.DoKeyDown(Sender: TObject; var Key: Word; Shift: TShif
end;


procedure TEnumEditorLink.DoSelect(Sender: TObject);
begin
// Read only mode?
if not FAllowEdit then begin
FCombo.ItemIndex := ValueList.IndexOf(FCellText);
end;
end;



{ SET editor }

constructor TSetEditorLink.Create(Tree: TVirtualStringTree);
constructor TSetEditorLink.Create(Tree: TVirtualStringTree; AllowEdit: Boolean);
begin
inherited Create(Tree);
inherited;
ValueList := TStringList.Create;

FPanel := TPanel.Create(FParentForm);
Expand Down Expand Up @@ -1016,6 +1034,7 @@ function TSetEditorLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode;
SelValues.DelimitedText := FCellText;
for i:=0 to FCheckList.Items.Count-1 do begin
FCheckList.Checked[i] := SelValues.IndexOf(FCheckList.Items[i]) > -1;
FCheckList.ItemEnabled[i] := FAllowEdit;
end;
SelValues.Free;
end;
Expand All @@ -1034,6 +1053,7 @@ procedure TSetEditorLink.SetBounds(R: TRect); stdcall;
FBtnOk.Left := margin;
FBtnOk.Height := 24;
FBtnOk.Top := FPanel.Height - 2*margin - FBtnOk.Height;
FBtnOk.Enabled := FAllowEdit;

FBtnCancel.Width := FBtnOk.Width;
FBtnCancel.Left := 2*margin + FBtnOk.Width;
Expand All @@ -1044,6 +1064,7 @@ procedure TSetEditorLink.SetBounds(R: TRect); stdcall;
FCheckList.Left := margin;
FCheckList.Width := FPanel.Width - 2*margin;
FCheckList.Height := FBtnOk.Top - margin - FCheckList.Top;
// FCheckList.Enabled := FAllowEdit; // crashes with "cannot focus if disabled"
end;


Expand All @@ -1066,9 +1087,9 @@ procedure TSetEditorLink.BtnCancelClick(Sender: TObject);

{ TInplaceEditorLink }

constructor TInplaceEditorLink.Create(Tree: TVirtualStringTree);
constructor TInplaceEditorLink.Create(Tree: TVirtualStringTree; AllowEdit: Boolean);
begin
inherited Create(Tree);
inherited;
ButtonVisible := false;
FTextEditor := nil;

Expand All @@ -1084,6 +1105,7 @@ constructor TInplaceEditorLink.Create(Tree: TVirtualStringTree);
FEdit.ParentColor := True;
FEdit.BorderStyle := bsNone;
FEdit.OnKeyDown := DoKeyDown;
FEdit.ReadOnly := not FAllowEdit;
FMainControl := FEdit;

FButton := TButton.Create(FPanel);
Expand Down Expand Up @@ -1162,6 +1184,7 @@ procedure TInplaceEditorLink.ButtonClick(Sender: TObject);
FTextEditor.SetTitleText(TitleText);
FTextEditor.Modified := FEdit.Modified;
FTextEditor.SetMaxLength(Self.FMaxLength);
FTextEditor.memoText.ReadOnly := not FAllowEdit;
FTextEditor.ShowModal;
end;

Expand Down Expand Up @@ -1197,13 +1220,13 @@ procedure TInplaceEditorLink.SetBounds(R: TRect);

{ Column default editor }

constructor TColumnDefaultEditorLink.Create(Tree: TVirtualStringTree);
constructor TColumnDefaultEditorLink.Create(Tree: TVirtualStringTree; AllowEdit: Boolean);
const
m = 5;
var
i: Integer;
begin
inherited Create(Tree);
inherited;

FPanel := TPanel.Create(FParentForm);
FPanel.Hide;
Expand Down Expand Up @@ -1547,9 +1570,9 @@ procedure TColumnDefaultEditorLink.BtnCancelClick(Sender: TObject);


{ Datatype selector }
constructor TDataTypeEditorLink.Create(Tree: TVirtualStringTree);
constructor TDataTypeEditorLink.Create(Tree: TVirtualStringTree; AllowEdit: Boolean);
begin
inherited Create(Tree);
inherited;

FTreeSelect := TVirtualStringTree.Create(FParentForm);
FTreeSelect.Hide;
Expand Down
2 changes: 1 addition & 1 deletion source/insertfiles.pas
Expand Up @@ -272,7 +272,7 @@ procedure TfrmInsertFiles.ListColumnsCreateEditor(Sender: TBaseVirtualTree; Node
// Start cell editor
Grid := Sender as TVirtualStringTree;
if Column = ColValue then begin
EnumEditor := TEnumEditorLink.Create(Grid);
EnumEditor := TEnumEditorLink.Create(Grid, True);
EnumEditor.AllowCustomText := True;
EnumEditor.ValueList := TStringList.Create;
EnumEditor.ValueList.Text := 'NULL'+CRLF+
Expand Down

0 comments on commit 56e541a

Please sign in to comment.