Skip to content

Commit 5c1b51c

Browse files
author
Joachim Marder
authored
Merge pull request #647 from maciej-izak/master
New option to set the way of selecting next cell for editing, minor fix to prevent AV
2 parents 7f6eb06 + 06b7d58 commit 5c1b51c

File tree

1 file changed

+87
-4
lines changed

1 file changed

+87
-4
lines changed

Source/VirtualTrees.pas

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,12 @@ TCheckStateHelper = record helper for TCheckState
516516
);
517517
TVTSelectionOptions = set of TVTSelectionOption;
518518

519+
TVTEditOptions = (
520+
toDefaultEdit, // Standard behaviour for end of editing (after VK_RETURN stay on edited cell).
521+
toVerticalEdit, // After VK_RETURN switch to next column.
522+
toHorizontalEdit // After VK_RETURN switch to next row.
523+
);
524+
519525
// Options which do not fit into any of the other groups:
520526
TVTMiscOption = (
521527
toAcceptOLEDrop, // Register tree as OLE accepting drop target
@@ -599,6 +605,7 @@ TCustomVirtualTreeOptions = class(TPersistent)
599605
FSelectionOptions: TVTSelectionOptions;
600606
FMiscOptions: TVTMiscOptions;
601607
FExportMode: TVTExportMode;
608+
FEditOptions: TVTEditOptions;
602609
procedure SetAnimationOptions(const Value: TVTAnimationOptions);
603610
procedure SetAutoOptions(const Value: TVTAutoOptions);
604611
procedure SetMiscOptions(const Value: TVTMiscOptions);
@@ -614,6 +621,7 @@ TCustomVirtualTreeOptions = class(TPersistent)
614621
property MiscOptions: TVTMiscOptions read FMiscOptions write SetMiscOptions default DefaultMiscOptions;
615622
property PaintOptions: TVTPaintOptions read FPaintOptions write SetPaintOptions default DefaultPaintOptions;
616623
property SelectionOptions: TVTSelectionOptions read FSelectionOptions write SetSelectionOptions default DefaultSelectionOptions;
624+
property EditOptions: TVTEditOptions read FEditOptions write FEditOptions;
617625

618626
property Owner: TBaseVirtualTree read FOwner;
619627
end;
@@ -966,6 +974,8 @@ TVirtualTreeColumn = class(TCollectionItem)
966974
FMargin,
967975
FSpacing: Integer;
968976
FOptions: TVTColumnOptions;
977+
FEditOptions: TVTEditOptions;
978+
FEditNextColumn: Integer;
969979
FTag: NativeInt;
970980
FAlignment: TAlignment;
971981
FCaptionAlignment: TAlignment; // Alignment of the caption.
@@ -1052,6 +1062,8 @@ TVirtualTreeColumn = class(TCollectionItem)
10521062
property MaxWidth: Integer read FMaxWidth write SetMaxWidth default 10000;
10531063
property MinWidth: Integer read FMinWidth write SetMinWidth default 10;
10541064
property Options: TVTColumnOptions read FOptions write SetOptions default DefaultColumnOptions;
1065+
property EditOptions: TVTEditOptions read FEditOptions write FEditOptions default toDefaultEdit;
1066+
property EditNextColumn: Integer read FEditNextColumn write FEditNextColumn default -1;
10551067
property Position: TColumnPosition read FPosition write SetPosition;
10561068
property Spacing: Integer read FSpacing write SetSpacing default 3;
10571069
property Style: TVirtualTreeColumnStyle read FStyle write SetStyle default vsText;
@@ -3199,6 +3211,7 @@ TStringTreeOptions = class(TCustomStringTreeOptions)
31993211
property PaintOptions;
32003212
property SelectionOptions;
32013213
property StringOptions;
3214+
property EditOptions;
32023215
end;
32033216

32043217
TCustomVirtualStringTree = class;
@@ -6710,6 +6723,7 @@ constructor TVirtualTreeColumn.Create(Collection: TCollection);
67106723
FCheckBox := False;
67116724
FHasImage := False;
67126725
FDefaultSortDirection := sdAscending;
6726+
fEditNextColumn := -1;
67136727

67146728
inherited Create(Collection);
67156729

@@ -7651,6 +7665,8 @@ procedure TVirtualTreeColumn.Assign(Source: TPersistent);
76517665
CaptionAlignment := TVirtualTreeColumn(Source).CaptionAlignment;
76527666
Color := TVirtualTreeColumn(Source).Color;
76537667
Tag := TVirtualTreeColumn(Source).Tag;
7668+
EditOptions := TVirtualTreeColumn(Source).EditOptions;
7669+
EditNextColumn := TVirtualTreeColumn(Source).EditNextColumn;
76547670

76557671
// Order is important. Assign options last.
76567672
FOptions := OldOptions;
@@ -32682,7 +32698,10 @@ procedure TCustomStringTreeOptions.AssignTo(Dest: TPersistent);
3268232698
if Dest is TCustomStringTreeOptions then
3268332699
begin
3268432700
with Dest as TCustomStringTreeOptions do
32701+
begin
3268532702
StringOptions := Self.StringOptions;
32703+
EditOptions := Self.EditOptions;
32704+
end;
3268632705
end;
3268732706

3268832707
// Let ancestors assign their options to the destination class.
@@ -32801,6 +32820,9 @@ procedure TVTEdit.WMKeyDown(var Message: TWMKeyDown);
3280132820
EndEdit: Boolean;
3280232821
Tree: TBaseVirtualTree;
3280332822
NextNode: PVirtualNode;
32823+
ColumnCandidate: Integer;
32824+
EditOptions: TVTEditOptions;
32825+
Column: TVirtualTreeColumn;
3280432826
begin
3280532827
Tree := FLink.FTree;
3280632828
case Message.CharCode of
@@ -32823,8 +32845,65 @@ procedure TVTEdit.WMKeyDown(var Message: TWMKeyDown);
3282332845
begin
3282432846
Tree := FLink.FTree;
3282532847
FLink.FTree.InvalidateNode(FLink.FNode);
32848+
NextNode := Tree.GetNextVisible(FLink.FNode, True);
3282632849
FLink.FTree.DoEndEdit;
32827-
Tree.SetFocus;
32850+
32851+
// get edit options for column as priority. If column has toDefaultEdit
32852+
// use global edit options for tree
32853+
Column := Tree.Header.Columns[Tree.FocusedColumn];
32854+
if Column.EditOptions <> toDefaultEdit then
32855+
EditOptions := Column.EditOptions
32856+
else
32857+
EditOptions := Tree.TreeOptions.EditOptions;
32858+
32859+
// next column candidate for toVerticalEdit and toHorizontalEdit
32860+
if Column.EditNextColumn <> -1 then
32861+
ColumnCandidate := Column.EditNextColumn
32862+
else
32863+
ColumnCandidate := -1;
32864+
32865+
case EditOptions of
32866+
toDefaultEdit: Tree.SetFocus;
32867+
toVerticalEdit:
32868+
if NextNode <> nil then
32869+
begin
32870+
Tree.FocusedNode := NextNode;
32871+
32872+
// for toVerticalEdit ColumnCandidate is also proper,
32873+
// select ColumnCandidate column in row below
32874+
if ColumnCandidate <> -1 then
32875+
begin
32876+
Tree.FocusedColumn := ColumnCandidate;
32877+
Tree.EditColumn := ColumnCandidate;
32878+
end;
32879+
32880+
if Tree.CanEdit(Tree.FocusedNode, Tree.FocusedColumn) then
32881+
Tree.DoEdit;
32882+
end;
32883+
toHorizontalEdit:
32884+
begin
32885+
if ColumnCandidate = -1 then
32886+
begin
32887+
// for toHorizontalEdit if property EditNextColumn is not used
32888+
// try to use just next column
32889+
ColumnCandidate := Tree.FocusedColumn+1;
32890+
while (ColumnCandidate < Tree.Header.Columns.Count)
32891+
and not Tree.CanEdit(Tree.FocusedNode, ColumnCandidate)
32892+
do
32893+
Inc(ColumnCandidate);
32894+
end
32895+
else
32896+
if not Tree.CanEdit(Tree.FocusedNode, ColumnCandidate) then
32897+
ColumnCandidate := Tree.Header.Columns.Count; // omit "focus/edit column" (see below)
32898+
32899+
if ColumnCandidate < Tree.Header.Columns.Count then
32900+
begin
32901+
Tree.FocusedColumn := ColumnCandidate;
32902+
Tree.EditColumn := ColumnCandidate;
32903+
Tree.DoEdit;
32904+
end;
32905+
end;
32906+
end;
3282832907
end;
3282932908
end;
3283032909
VK_UP:
@@ -32846,9 +32925,13 @@ procedure TVTEdit.WMKeyDown(var Message: TWMKeyDown);
3284632925
Tree.InvalidateNode(FLink.FNode);
3284732926
NextNode := Tree.GetNextVisible(FLink.FNode, True);
3284832927
Tree.EndEditNode;
32849-
Tree.FocusedNode := NextNode;
32850-
if Tree.CanEdit(Tree.FocusedNode, Tree.FocusedColumn) then
32851-
Tree.DoEdit;
32928+
// check NextNode, otherwise we got AV
32929+
if NextNode <> nil then
32930+
begin
32931+
Tree.FocusedNode := NextNode;
32932+
if Tree.CanEdit(Tree.FocusedNode, Tree.FocusedColumn) then
32933+
Tree.DoEdit;
32934+
end;
3285232935
end;
3285332936
end;
3285432937
Ord('A'):

0 commit comments

Comments
 (0)