Fix issue #1211: Table editor, length/set should be ignored or suppressed for datatypes which don't support that. Also, make relevant code for cell editing allowance and cell background painting more easy and less redundant.

This commit is contained in:
Ansgar Becker
2009-06-09 20:13:35 +00:00
parent a9ded30c49
commit c6743e087b
2 changed files with 50 additions and 27 deletions

View File

@ -92,6 +92,7 @@ object frmTableEditor: TfrmTableEditor
TreeOptions.SelectionOptions = [toExtendedFocus, toFullRowSelect, toRightClickSelect] TreeOptions.SelectionOptions = [toExtendedFocus, toFullRowSelect, toRightClickSelect]
WantTabs = True WantTabs = True
OnAfterCellPaint = listColumnsAfterCellPaint OnAfterCellPaint = listColumnsAfterCellPaint
OnBeforeCellPaint = listColumnsBeforeCellPaint
OnBeforePaint = listColumnsBeforePaint OnBeforePaint = listColumnsBeforePaint
OnClick = listColumnsClick OnClick = listColumnsClick
OnCreateEditor = listColumnsCreateEditor OnCreateEditor = listColumnsCreateEditor

View File

@ -106,6 +106,9 @@ type
procedure editNumEditChange(Sender: TObject); procedure editNumEditChange(Sender: TObject);
procedure comboEngineSelect(Sender: TObject); procedure comboEngineSelect(Sender: TObject);
procedure listColumnsClick(Sender: TObject); procedure listColumnsClick(Sender: TObject);
procedure listColumnsBeforeCellPaint(Sender: TBaseVirtualTree;
TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
procedure listColumnsAfterCellPaint(Sender: TBaseVirtualTree; procedure listColumnsAfterCellPaint(Sender: TBaseVirtualTree;
TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
CellRect: TRect); CellRect: TRect);
@ -151,6 +154,7 @@ type
property Modified: Boolean read FModified write SetModified; property Modified: Boolean read FModified write SetModified;
procedure SetStatus(msg: WideString = ''); procedure SetStatus(msg: WideString = '');
procedure UpdateSQLcode; procedure UpdateSQLcode;
function CellEditingAllowed(Node: PVirtualNode; Column: TColumnIndex): Boolean;
public public
{ Public declarations } { Public declarations }
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
@ -778,6 +782,19 @@ begin
end; end;
procedure TfrmTableEditor.listColumnsBeforeCellPaint(Sender: TBaseVirtualTree;
TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
begin
// Darken cell background to signalize it doesn't allow length/set
// Exclude non editable checkbox columns - grey looks ugly there.
if (not CellEditingAllowed(Node, Column)) and (not (Column in [4, 5])) then begin
TargetCanvas.Brush.Color := clBtnFace;
TargetCanvas.FillRect(CellRect);
end;
end;
procedure TfrmTableEditor.listColumnsAfterCellPaint(Sender: TBaseVirtualTree; procedure TfrmTableEditor.listColumnsAfterCellPaint(Sender: TBaseVirtualTree;
TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
CellRect: TRect); CellRect: TRect);
@ -785,26 +802,18 @@ var
Props: TWideStringlist; Props: TWideStringlist;
ImageIndex, X, Y: Integer; ImageIndex, X, Y: Integer;
VT: TVirtualStringTree; VT: TVirtualStringTree;
dt: TMysqlDataTypeRecord;
begin begin
// Paint checkbox image in certain columns // Paint checkbox image in certain columns
if not (Column in [4, 5]) then // while restricting "Allow NULL" checkbox to numeric datatypes
Exit; if (Column in [4, 5]) and CellEditingAllowed(Node, Column) then begin
Props := TWideStringlist(Columns.Objects[Node.Index]); Props := TWideStringlist(Columns.Objects[Node.Index]);
if StrToBool(Props[Column-2]) then ImageIndex := 128
// Restrict "Allow NULL" checkbox to numeric datatypes else ImageIndex := 127;
if Column = 4 then begin VT := TVirtualStringTree(Sender);
dt := GetDatatypeByName(Props[0]); X := CellRect.Left + (VT.Header.Columns[Column].Width div 2) - (VT.Images.Width div 2);
if not dt.HasUnsigned then Y := CellRect.Top + Integer(VT.NodeHeight[Node] div 2) - (VT.Images.Height div 2);
Exit; VT.Images.Draw(TargetCanvas, X, Y, ImageIndex);
end; end;
if StrToBool(Props[Column-2]) then ImageIndex := 128
else ImageIndex := 127;
VT := TVirtualStringTree(Sender);
X := CellRect.Left + (VT.Header.Columns[Column].Width div 2) - (VT.Images.Width div 2);
Y := CellRect.Top + Integer(VT.NodeHeight[Node] div 2) - (VT.Images.Height div 2);
VT.Images.Draw(TargetCanvas, X, Y, ImageIndex);
end; end;
@ -850,12 +859,26 @@ end;
procedure TfrmTableEditor.listColumnsEditing(Sender: TBaseVirtualTree; procedure TfrmTableEditor.listColumnsEditing(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean); Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
begin begin
// Allow text editing? Explicitely block that in checkbox columns
Allowed := CellEditingAllowed(Node, Column) and (not (Column in [4,5]));
end;
function TfrmTableEditor.CellEditingAllowed(Node: PVirtualNode; Column: TColumnIndex): Boolean;
var
Props: TWideStringlist;
dt: TMysqlDataTypeRecord;
begin
Props := TWideStringlist(Columns.Objects[Node.Index]);
dt := GetDatatypeByName(Props[0]);
case Column of case Column of
// No editor for very first column and checkbox columns // No editor for very first column and checkbox columns
0, 4, 5: Allowed := False; 0: Result := False;
3: Result := dt.HasLength;
4: Result := dt.HasUnsigned;
// No editing of collation allowed if "Convert data" was checked // No editing of collation allowed if "Convert data" was checked
8: Allowed := not chkCharsetConvert.Checked; 8: Result := not chkCharsetConvert.Checked;
else Allowed := True; else Result := True;
end; end;
end; end;
@ -949,6 +972,11 @@ begin
end else if Column > 1 then begin end else if Column > 1 then begin
Properties := TWideStringList(Columns.Objects[Node.Index]); Properties := TWideStringList(Columns.Objects[Node.Index]);
Properties[Column-2] := NewText; Properties[Column-2] := NewText;
if (Column = 2) and (not CellEditingAllowed(Node, 3)) then begin
// Reset length/set for column types which don't support that
Properties[1] := '';
end;
end; end;
end; end;
@ -957,7 +985,6 @@ procedure TfrmTableEditor.listColumnsClick(Sender: TObject);
var var
VT: TVirtualStringTree; VT: TVirtualStringTree;
Props: TWideStringlist; Props: TWideStringlist;
dt: TMySQLDataTypeRecord;
Click: THitInfo; Click: THitInfo;
begin begin
// Handle click event // Handle click event
@ -968,8 +995,7 @@ begin
if Click.HitColumn in [4, 5] then begin if Click.HitColumn in [4, 5] then begin
// For checkboxes, cell editors are disabled, instead toggle their state // For checkboxes, cell editors are disabled, instead toggle their state
Props := TWideStringList(Columns.Objects[Click.HitNode.Index]); Props := TWideStringList(Columns.Objects[Click.HitNode.Index]);
dt := GetDatatypeByName(Props[0]); if CellEditingAllowed(Click.HitNode, Click.HitColumn) then begin
if dt.HasUnsigned or (Click.HitColumn = 5) then begin
Props[Click.HitColumn-2] := BoolToStr(not StrToBool(Props[Click.HitColumn-2])); Props[Click.HitColumn-2] := BoolToStr(not StrToBool(Props[Click.HitColumn-2]));
VT.InvalidateNode(Click.HitNode); VT.InvalidateNode(Click.HitNode);
end; end;
@ -1520,10 +1546,6 @@ end;
procedure TfrmTableEditor.chkCharsetConvertClick(Sender: TObject); procedure TfrmTableEditor.chkCharsetConvertClick(Sender: TObject);
begin begin
if chkCharsetConvert.Checked then
listColumns.Header.Columns[8].Color := clBtnFace
else
listColumns.Header.Columns[8].Color := clWindow;
chkCharsetConvert.Enabled := (FAlterTablename <> '') and (comboCollation.ItemIndex > -1); chkCharsetConvert.Enabled := (FAlterTablename <> '') and (comboCollation.ItemIndex > -1);
listColumns.Repaint; listColumns.Repaint;
Modification(Sender); Modification(Sender);