mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-26 11:17:57 +08:00
Implement a new datatype selector for the table editor, including groups, datatype colors and help hints. Fixes issue #1214 and issue #1165 .
This commit is contained in:
@ -193,6 +193,44 @@ type
|
||||
procedure SetBounds(R: TRect); virtual; stdcall;
|
||||
end;
|
||||
|
||||
TDataTypeEditorLink = class(TInterfacedObject, IVTEditLink)
|
||||
private
|
||||
FTree: TVirtualStringTree;
|
||||
FTreeSelect: TVirtualStringTree;
|
||||
FMemoHelp: TMemo;
|
||||
FNode: PVirtualNode;
|
||||
FColumn: TColumnIndex;
|
||||
FTextBounds: TRect;
|
||||
FStopping: Boolean;
|
||||
FFinalKeyDown: Integer;
|
||||
FOldWndProc: TWndMethod;
|
||||
procedure DoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
procedure EditWndProc(var Message: TMessage);
|
||||
procedure DoTreeSelectGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||
Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
|
||||
procedure DoTreeSelectInitNode(Sender: TBaseVirtualTree;
|
||||
ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
|
||||
procedure DoTreeSelectInitChildren(Sender: TBaseVirtualTree;
|
||||
Node: PVirtualNode; var ChildCount: Cardinal);
|
||||
procedure DoTreeSelectHotChange(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode);
|
||||
procedure DoTreeSelectPaintText(Sender: TBaseVirtualTree;
|
||||
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
|
||||
TextType: TVSTTextType);
|
||||
procedure DoTreeSelectFocusChanging(Sender: TBaseVirtualTree; OldNode, NewNode:
|
||||
PVirtualNode; OldColumn, NewColumn: TColumnIndex; var Allowed: Boolean);
|
||||
procedure DoTreeSelectFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex);
|
||||
public
|
||||
Datatype: TDatatypeIndex;
|
||||
constructor Create(Tree: TVirtualStringTree); overload;
|
||||
destructor Destroy; override;
|
||||
function BeginEdit: Boolean; virtual; stdcall;
|
||||
function CancelEdit: Boolean; virtual; stdcall;
|
||||
function EndEdit: Boolean; virtual; stdcall;
|
||||
function GetBounds: TRect; virtual; stdcall;
|
||||
function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; stdcall;
|
||||
procedure ProcessMessage(var Message: TMessage); virtual; stdcall;
|
||||
procedure SetBounds(R: TRect); virtual; stdcall;
|
||||
end;
|
||||
|
||||
function GetColumnDefaultType(var Text: WideString): TColumnDefaultType;
|
||||
function GetColumnDefaultClause(DefaultType: TColumnDefaultType; Text: WideString): WideString;
|
||||
@ -1413,4 +1451,292 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ Datatype selector }
|
||||
constructor TDataTypeEditorLink.Create(Tree: TVirtualStringTree);
|
||||
var
|
||||
ParentControl: TWinControl;
|
||||
begin
|
||||
inherited Create;
|
||||
FTree := Tree;
|
||||
// Enable mouse scrolling on FtreeSelect, plus ensure the
|
||||
// tree is not partly hidden when it pops up in a bottom cell
|
||||
ParentControl := GetParentForm(FTree);
|
||||
// Avoid flicker
|
||||
SendMessage(ParentControl.Handle, WM_SETREDRAW, 0, 0);
|
||||
|
||||
FTreeSelect := TVirtualStringTree.Create(FTree);
|
||||
FTreeSelect.TreeOptions.PaintOptions := FTreeSelect.TreeOptions.PaintOptions
|
||||
- [toShowTreeLines, toShowButtons, toShowRoot]
|
||||
+ [toHotTrack, toUseExplorerTheme, toHideTreeLinesIfThemed];
|
||||
FTreeSelect.TreeOptions.SelectionOptions := FTreeSelect.TreeOptions.SelectionOptions
|
||||
+ [toFullRowSelect];
|
||||
FTreeSelect.Header.Columns.Add;
|
||||
FTreeSelect.Header.AutoSizeIndex := 0;
|
||||
FTreeSelect.Header.Options := FTreeSelect.Header.Options + [hoAutoResize];
|
||||
FTreeSelect.Parent := ParentControl;
|
||||
FTreeSelect.TextMargin := 0;
|
||||
FTreeSelect.RootNodeCount := Length(DatatypeCategories);
|
||||
FTreeSelect.OnGetText := DoTreeSelectGetText;
|
||||
FTreeSelect.OnInitNode := DoTreeSelectInitNode;
|
||||
FTreeSelect.OnInitChildren := DoTreeSelectInitChildren;
|
||||
FTreeSelect.OnKeyDown := DoKeyDown;
|
||||
FTreeSelect.OnHotChange := DoTreeSelectHotChange;
|
||||
FTreeSelect.OnPaintText := DoTreeSelectPaintText;
|
||||
FTreeSelect.Hide;
|
||||
FOldWndProc := FTreeSelect.WindowProc;
|
||||
FTreeSelect.WindowProc := EditWndProc;
|
||||
|
||||
FMemoHelp := TMemo.Create(FTree);
|
||||
FMemoHelp.Parent := ParentControl;
|
||||
FMemoHelp.Color := clInfoBk;
|
||||
FMemoHelp.Font.Color := clInfoText;
|
||||
FMemoHelp.BorderStyle := bsNone;
|
||||
FMemoHelp.BevelKind := bkFlat;
|
||||
FMemoHelp.BevelInner := bvNone;
|
||||
FMemoHelp.Hide;
|
||||
end;
|
||||
|
||||
|
||||
destructor TDataTypeEditorLink.Destroy;
|
||||
begin
|
||||
inherited;
|
||||
FreeAndNil(FTreeSelect);
|
||||
FreeAndNil(FMemoHelp);
|
||||
if FFinalKeyDown = VK_TAB then begin
|
||||
SendMessage(FTree.Handle, WM_KEYDOWN, FFinalKeyDown, 0);
|
||||
SendMessage(FTree.Handle, WM_KEYDOWN, VK_F2, 0);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function TDataTypeEditorLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean;
|
||||
var
|
||||
NodeText: WideString;
|
||||
dt: TDatatype;
|
||||
CatNode, TypeNode: PVirtualNode;
|
||||
begin
|
||||
Result := not FStopping;
|
||||
if not Result then
|
||||
Exit;
|
||||
FNode := Node;
|
||||
FColumn := Column;
|
||||
FTree.GetTextInfo(FNode, FColumn, FTreeSelect.Font, FTextBounds, NodeText);
|
||||
// Highlighted cell has white font, fix that
|
||||
FTreeSelect.Font.Color := FTree.Font.Color;
|
||||
|
||||
// Find and select current datatype in tree
|
||||
dt := GetDataTypeByName(NodeText);
|
||||
CatNode := FTreeSelect.GetFirst;
|
||||
while Assigned(CatNode) do begin
|
||||
if CatNode.Index = Cardinal(dt.Category) then begin
|
||||
TypeNode := FTreeSelect.GetFirstChild(CatNode);
|
||||
while Assigned(TypeNode) do begin
|
||||
if FTreeSelect.Text[TypeNode, 0] = NodeText then begin
|
||||
FTreeSelect.FocusedNode := TypeNode;
|
||||
FTreeSelect.Selected[TypeNode] := True;
|
||||
break;
|
||||
end;
|
||||
TypeNode := FTreeSelect.GetNextSibling(TypeNode);
|
||||
end;
|
||||
end;
|
||||
CatNode := FTreeSelect.GetNextSibling(CatNode);
|
||||
end;
|
||||
if Assigned(FTreeSelect.FocusedNode) then
|
||||
FTreeSelect.ScrollIntoView(FTreeSelect.FocusedNode, True);
|
||||
FTreeSelect.OnFocusChanging := DoTreeSelectFocusChanging;
|
||||
FTreeSelect.OnFocusChanged := DoTreeSelectFocusChanged;
|
||||
end;
|
||||
|
||||
|
||||
function TDataTypeEditorLink.BeginEdit: Boolean;
|
||||
begin
|
||||
Result := not FStopping;
|
||||
if Result then begin
|
||||
SendMessage(FTreeSelect.Parent.Handle, WM_SETREDRAW, 1, 0);
|
||||
FTreeSelect.Show;
|
||||
FTreeSelect.SetFocus;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function TDataTypeEditorLink.CancelEdit: Boolean;
|
||||
begin
|
||||
Result := not FStopping;
|
||||
if Result then begin
|
||||
FStopping := True;
|
||||
FTree.CancelEditNode;
|
||||
if FTree.CanFocus then
|
||||
FTree.SetFocus;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function TDataTypeEditorLink.EndEdit: Boolean;
|
||||
var
|
||||
newtext: WideString;
|
||||
begin
|
||||
Result := not FStopping;
|
||||
if Not Result then
|
||||
Exit;
|
||||
newtext := FTreeSelect.Text[FTreeSelect.FocusedNode, 0];
|
||||
if newtext <> FTree.Text[FNode, FColumn] then
|
||||
FTree.Text[FNode, FColumn] := newtext;
|
||||
if FTree.CanFocus then
|
||||
FTree.SetFocus;
|
||||
end;
|
||||
|
||||
|
||||
function TDataTypeEditorLink.GetBounds: TRect;
|
||||
begin
|
||||
Result := FTreeSelect.BoundsRect;
|
||||
end;
|
||||
|
||||
|
||||
procedure TDataTypeEditorLink.SetBounds(R: TRect);
|
||||
begin
|
||||
// Set position of tree. As the tree's parent is mainform, not listcolumns, add listcolumn's x + y positions
|
||||
FTreeSelect.SetBounds(R.Left + FTree.ClientOrigin.X,
|
||||
R.Top + FTree.ClientOrigin.Y - FTreeSelect.Header.Height - GetSystemMetrics(SM_CYMENU),
|
||||
R.Right-R.Left,
|
||||
250);
|
||||
end;
|
||||
|
||||
|
||||
procedure TDataTypeEditorLink.ProcessMessage(var Message: TMessage);
|
||||
begin
|
||||
FTreeSelect.WindowProc(Message);
|
||||
end;
|
||||
|
||||
|
||||
procedure TDataTypeEditorLink.DoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
begin
|
||||
FFinalKeyDown := Key;
|
||||
case Key of
|
||||
// Cancel by Escape
|
||||
VK_ESCAPE: FTree.CancelEditNode;
|
||||
// Apply changes and end editing by [Ctrl +] Enter or Tab
|
||||
VK_RETURN, VK_TAB: FTree.EndEditNode;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TDataTypeEditorLink.EditWndProc(var Message: TMessage);
|
||||
begin
|
||||
case Message.Msg of
|
||||
WM_CHAR:
|
||||
if not (TWMChar(Message).CharCode in [VK_ESCAPE, VK_TAB]) then
|
||||
FOldWndProc(Message);
|
||||
WM_GETDLGCODE:
|
||||
Message.Result := Message.Result or DLGC_WANTARROWS or DLGC_WANTALLKEYS or DLGC_WANTTAB;
|
||||
else
|
||||
FOldWndProc(Message);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TDataTypeEditorLink.DoTreeSelectInitNode(Sender: TBaseVirtualTree;
|
||||
ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
|
||||
begin
|
||||
// First level nodes always expanded
|
||||
if Sender.GetNodeLevel(Node) = 0 then
|
||||
InitialStates := InitialStates + [ivsExpanded, ivsHasChildren];
|
||||
end;
|
||||
|
||||
|
||||
procedure TDataTypeEditorLink.DoTreeSelectInitChildren(Sender: TBaseVirtualTree;
|
||||
Node: PVirtualNode; var ChildCount: Cardinal);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
// Tell number of datatypes per category
|
||||
ChildCount := 0;
|
||||
if Sender.GetNodeLevel(Node) = 0 then for i:=Low(Datatypes) to High(Datatypes) do begin
|
||||
if Datatypes[i].Category = DatatypeCategories[Node.Index].Index then
|
||||
Inc(ChildCount);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TDataTypeEditorLink.DoTreeSelectGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||
Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
|
||||
var
|
||||
i: Integer;
|
||||
Counter: Cardinal;
|
||||
begin
|
||||
// Get cell text
|
||||
case Sender.GetNodeLevel(Node) of
|
||||
0: CellText := DatatypeCategories[Node.Index].Name;
|
||||
1: begin
|
||||
Counter := 0;
|
||||
for i:=Low(Datatypes) to High(Datatypes) do begin
|
||||
if Datatypes[i].Category = DatatypeCategories[Node.Parent.Index].Index then begin
|
||||
Inc(Counter);
|
||||
if Counter = Node.Index+1 then begin
|
||||
CellText := Datatypes[i].Name;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TDataTypeEditorLink.DoTreeSelectHotChange(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode);
|
||||
var
|
||||
R: TRect;
|
||||
NodeText: WideString;
|
||||
bmp: TBitMap;
|
||||
begin
|
||||
// Display help box for hovered datatype
|
||||
FMemoHelp.Clear;
|
||||
if Assigned(NewNode) and (Sender.GetNodeLevel(NewNode) = 1) then begin
|
||||
R := FTreeSelect.GetDisplayRect(NewNode, 0, False);
|
||||
NodeText := FTreeSelect.Text[NewNode, 0];
|
||||
FMemoHelp.Width := Min(250, FTreeSelect.Left);
|
||||
FMemoHelp.Left := FTreeSelect.Left - FMemoHelp.Width + (Integer(FTreeSelect.Indent) Div 2);
|
||||
FMemoHelp.Top := FTreeSelect.Top + R.Top + 3;
|
||||
FMemoHelp.Text := GetDatatypeByName(NodeText).Description;
|
||||
// Calc height of memo
|
||||
bmp := TBitMap.Create;
|
||||
bmp.Canvas.Font.Assign(FMemoHelp.Font);
|
||||
R := Rect(0, 0, FMemoHelp.Width, 0);
|
||||
DrawText(bmp.Canvas.Handle, PChar(FMemoHelp.Text), Length(FMemoHelp.Text), R, DT_WORDBREAK or DT_CALCRECT);
|
||||
FreeAndNil(bmp);
|
||||
FMemoHelp.Height := R.Bottom + 2;
|
||||
FMemoHelp.Show;
|
||||
end;
|
||||
if FMemoHelp.GetTextLen = 0 then
|
||||
FMemoHelp.Hide;
|
||||
end;
|
||||
|
||||
|
||||
procedure TDataTypeEditorLink.DoTreeSelectPaintText(Sender: TBaseVirtualTree;
|
||||
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
|
||||
TextType: TVSTTextType);
|
||||
begin
|
||||
// Give datatype column specific color, as set in preferences
|
||||
case Sender.GetNodeLevel(Node) of
|
||||
0: TargetCanvas.Font.Style := TargetCanvas.Font.Style + [fsBold];
|
||||
1: if not (vsSelected in Node.States) then
|
||||
TargetCanvas.Font.Color := DatatypeCategories[Node.Parent.Index].Color;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TDataTypeEditorLink.DoTreeSelectFocusChanging(Sender: TBaseVirtualTree; OldNode, NewNode:
|
||||
PVirtualNode; OldColumn, NewColumn: TColumnIndex; var Allowed: Boolean);
|
||||
begin
|
||||
// Allow only 2nd level datatypes to be focused, not their category
|
||||
Allowed := Sender.GetNodeLevel(NewNode) = 1;
|
||||
end;
|
||||
|
||||
procedure TDataTypeEditorLink.DoTreeSelectFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex);
|
||||
begin
|
||||
// Datatype selected - end editing
|
||||
FTree.EndEditNode;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
@ -769,18 +769,6 @@ type
|
||||
prefEnableEnumEditor,
|
||||
prefEnableSetEditor,
|
||||
prefEnableNullBG : Boolean;
|
||||
prefFieldColorNumeric,
|
||||
prefFieldColorText,
|
||||
prefFieldColorBinary,
|
||||
prefFieldColorDatetime,
|
||||
prefFieldColorEnum,
|
||||
prefFieldColorSet,
|
||||
prefNullColorNumeric,
|
||||
prefNullColorText,
|
||||
prefNullColorBinary,
|
||||
prefNullColorDatetime,
|
||||
prefNullColorEnum,
|
||||
prefNullColorSet,
|
||||
prefNullColorDefault,
|
||||
prefNullBG : TColor;
|
||||
CreateDatabaseForm : TCreateDatabaseForm;
|
||||
@ -1336,12 +1324,14 @@ begin
|
||||
FixVT(DataGrid);
|
||||
FixVT(QueryGrid);
|
||||
// Load color settings
|
||||
prefFieldColorNumeric := GetRegValue(REGNAME_FIELDCOLOR_NUMERIC, DEFAULT_FIELDCOLOR_NUMERIC);
|
||||
prefFieldColorText := GetRegValue(REGNAME_FIELDCOLOR_TEXT, DEFAULT_FIELDCOLOR_TEXT);
|
||||
prefFieldColorBinary := GetRegValue(REGNAME_FIELDCOLOR_BINARY, DEFAULT_FIELDCOLOR_BINARY);
|
||||
prefFieldColorDatetime := GetRegValue(REGNAME_FIELDCOLOR_DATETIME, DEFAULT_FIELDCOLOR_DATETIME);
|
||||
prefFieldColorEnum := GetRegValue(REGNAME_FIELDCOLOR_ENUM, DEFAULT_FIELDCOLOR_ENUM);
|
||||
prefFieldColorSet := GetRegValue(REGNAME_FIELDCOLOR_SET, DEFAULT_FIELDCOLOR_SET);
|
||||
DatatypeCategories[Integer(dtcInteger)].Color := GetRegValue(REGNAME_FIELDCOLOR_NUMERIC, DEFAULT_FIELDCOLOR_NUMERIC);
|
||||
DatatypeCategories[Integer(dtcReal)].Color := GetRegValue(REGNAME_FIELDCOLOR_NUMERIC, DEFAULT_FIELDCOLOR_NUMERIC);
|
||||
DatatypeCategories[Integer(dtcText)].Color := GetRegValue(REGNAME_FIELDCOLOR_TEXT, DEFAULT_FIELDCOLOR_TEXT);
|
||||
DatatypeCategories[Integer(dtcBinary)].Color := GetRegValue(REGNAME_FIELDCOLOR_BINARY, DEFAULT_FIELDCOLOR_BINARY);
|
||||
DatatypeCategories[Integer(dtcTemporal)].Color := GetRegValue(REGNAME_FIELDCOLOR_DATETIME, DEFAULT_FIELDCOLOR_DATETIME);
|
||||
DatatypeCategories[Integer(dtcIntegerNamed)].Color := GetRegValue(REGNAME_FIELDCOLOR_ENUM, DEFAULT_FIELDCOLOR_ENUM);
|
||||
DatatypeCategories[Integer(dtcSet)].Color := GetRegValue(REGNAME_FIELDCOLOR_SET, DEFAULT_FIELDCOLOR_SET);
|
||||
DatatypeCategories[Integer(dtcSetNamed)].Color := GetRegValue(REGNAME_FIELDCOLOR_SET, DEFAULT_FIELDCOLOR_SET);
|
||||
prefNullBG := GetRegValue(REGNAME_BG_NULL, DEFAULT_BG_NULL);
|
||||
CalcNullColors;
|
||||
// Editor enablings
|
||||
@ -7368,14 +7358,11 @@ end;
|
||||
|
||||
|
||||
procedure TMainForm.CalcNullColors;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
prefNullColorNumeric := ColorAdjustBrightness(prefFieldColorNumeric, COLORSHIFT_NULLFIELDS);
|
||||
prefNullColorText := ColorAdjustBrightness(prefFieldColorText, COLORSHIFT_NULLFIELDS);
|
||||
prefNullColorBinary := ColorAdjustBrightness(prefFieldColorBinary, COLORSHIFT_NULLFIELDS);
|
||||
prefNullColorDatetime := ColorAdjustBrightness(prefFieldColorDatetime, COLORSHIFT_NULLFIELDS);
|
||||
prefNullColorEnum := ColorAdjustBrightness(prefFieldColorEnum, COLORSHIFT_NULLFIELDS);
|
||||
prefNullColorSet := ColorAdjustBrightness(prefFieldColorSet, COLORSHIFT_NULLFIELDS);
|
||||
prefNullColorDefault := ColorAdjustBrightness(clWindow, COLORSHIFT_NULLFIELDS);
|
||||
for i:=Low(DatatypeCategories) to High(DatatypeCategories) do
|
||||
DatatypeCategories[i].NullColor := ColorAdjustBrightness(DatatypeCategories[i].Color, COLORSHIFT_NULLFIELDS);
|
||||
end;
|
||||
|
||||
|
||||
@ -7387,7 +7374,6 @@ procedure TMainForm.GridPaintText(Sender: TBaseVirtualTree; const
|
||||
TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType:
|
||||
TVSTTextType);
|
||||
var
|
||||
isNull: Boolean;
|
||||
cl: TColor;
|
||||
r: PGridResult;
|
||||
begin
|
||||
@ -7404,34 +7390,15 @@ begin
|
||||
if r.Columns[Column].IsPriPart then
|
||||
TargetCanvas.Font.Style := TargetCanvas.Font.Style + [fsBold];
|
||||
|
||||
// NULL value
|
||||
isNull := r.Rows[Node.Index].Cells[Column].IsNull;
|
||||
|
||||
// Do not apply any color on a selected, highlighted cell to keep readability
|
||||
if (Node = Sender.FocusedNode) and (Column = Sender.FocusedColumn) then
|
||||
cl := clHighlightText
|
||||
else if vsSelected in Node.States then
|
||||
cl := clBlack
|
||||
// Numeric field
|
||||
else if r.Columns[Column].DatatypeCat in [dtcInteger, dtcReal] then
|
||||
if isNull then cl := prefNullColorNumeric else cl := prefFieldColorNumeric
|
||||
// Date field
|
||||
else if r.Columns[Column].DatatypeCat = dtcTemporal then
|
||||
if isNull then cl := prefNullColorDatetime else cl := prefFieldColorDatetime
|
||||
// Text field
|
||||
else if r.Columns[Column].DatatypeCat = dtcText then
|
||||
if isNull then cl := prefNullColorText else cl := prefFieldColorText
|
||||
// Text field
|
||||
else if r.Columns[Column].DatatypeCat = dtcBinary then
|
||||
if isNull then cl := prefNullColorBinary else cl := prefFieldColorBinary
|
||||
// Enum field
|
||||
else if r.Columns[Column].DatatypeCat = dtcIntegerNamed then
|
||||
if isNull then cl := prefNullColorEnum else cl := prefFieldColorEnum
|
||||
// Set field
|
||||
else if r.Columns[Column].DatatypeCat = dtcSetNamed then
|
||||
if isNull then cl := prefNullColorSet else cl := prefFieldColorSet
|
||||
else if r.Rows[Node.Index].Cells[Column].IsNull then
|
||||
cl := DatatypeCategories[Integer(r.Columns[Column].DatatypeCat)].NullColor
|
||||
else
|
||||
if isNull then cl := prefNullColorDefault else cl := clWindowText;
|
||||
cl := DatatypeCategories[Integer(r.Columns[Column].DatatypeCat)].Color;
|
||||
TargetCanvas.Font.Color := cl;
|
||||
end;
|
||||
|
||||
|
@ -7,7 +7,7 @@ unit mysql_structures;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, Widestrings;
|
||||
Classes, Widestrings, Graphics;
|
||||
|
||||
{$I const.inc}
|
||||
|
||||
@ -22,13 +22,14 @@ type
|
||||
dtPoint, dtLinestring, dtPolygon, dtGeometry, dtMultipoint, dtMultilinestring, dtMultipolygon, dtGeometrycollection);
|
||||
|
||||
// MySQL data type categorization
|
||||
TDatatypeCategoryIndex = (dtcInteger, dtcReal, dtcTemporal, dtcText, dtcBinary,
|
||||
dtcIntegerNamed, dtcSet, dtcSetNamed, dtcSpatial);
|
||||
TDatatypeCategoryIndex = (dtcInteger, dtcIntegerNamed, dtcReal, dtcText, dtcBinary, dtcTemporal,
|
||||
dtcSpatial, dtcSet, dtcSetNamed);
|
||||
|
||||
// MySQL data type structure
|
||||
TDatatype = record
|
||||
Index: TDatatypeIndex;
|
||||
Name: String[18];
|
||||
Description: String;
|
||||
HasLength: Boolean; // Can have Length- or Set-attribute?
|
||||
RequiresLength: Boolean; // Must have a Length- or Set-attribute?
|
||||
HasUnsigned: Boolean; // Can be unsigned?
|
||||
@ -43,6 +44,8 @@ type
|
||||
TDatatypeCategory = record
|
||||
Index: TDatatypeCategoryIndex;
|
||||
Name: String[32];
|
||||
Color: TColor;
|
||||
NullColor: TColor;
|
||||
end;
|
||||
|
||||
// MySQL functions structure
|
||||
@ -103,6 +106,9 @@ var
|
||||
(
|
||||
Index: dtTinyint;
|
||||
Name: 'TINYINT';
|
||||
Description: 'TINYINT[(M)] [UNSIGNED] [ZEROFILL]' + CRLF +
|
||||
'A very small integer. The signed range is -128 to 127. ' +
|
||||
'The unsigned range is 0 to 255.';
|
||||
HasLength: True;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: True;
|
||||
@ -114,6 +120,9 @@ var
|
||||
(
|
||||
Index: dtSmallint;
|
||||
Name: 'SMALLINT';
|
||||
Description: 'SMALLINT[(M)] [UNSIGNED] [ZEROFILL]' + CRLF +
|
||||
'A small integer. The signed range is -32768 to 32767. ' +
|
||||
'The unsigned range is 0 to 65535.';
|
||||
HasLength: True;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: True;
|
||||
@ -125,6 +134,9 @@ var
|
||||
(
|
||||
Index: dtMediumint;
|
||||
Name: 'MEDIUMINT';
|
||||
Description: 'MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]' + CRLF +
|
||||
'A medium-sized integer. The signed range is -8388608 to 8388607. ' +
|
||||
'The unsigned range is 0 to 16777215.';
|
||||
HasLength: True;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: True;
|
||||
@ -136,6 +148,9 @@ var
|
||||
(
|
||||
Index: dtInt;
|
||||
Name: 'INT';
|
||||
Description: 'INT[(M)] [UNSIGNED] [ZEROFILL]' + CRLF +
|
||||
'A normal-size integer. The signed range is -2147483648 to 2147483647. ' +
|
||||
'The unsigned range is 0 to 4294967295.';
|
||||
HasLength: True;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: True;
|
||||
@ -147,6 +162,9 @@ var
|
||||
(
|
||||
Index: dtBigint;
|
||||
Name: 'BIGINT';
|
||||
Description: 'BIGINT[(M)] [UNSIGNED] [ZEROFILL]' + CRLF +
|
||||
'A large integer. The signed range is -9223372036854775808 to ' +
|
||||
'9223372036854775807. The unsigned range is 0 to 18446744073709551615.';
|
||||
HasLength: True;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: True;
|
||||
@ -158,6 +176,12 @@ var
|
||||
(
|
||||
Index: dtFloat;
|
||||
Name: 'FLOAT';
|
||||
Description: 'FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]' + CRLF +
|
||||
'A small (single-precision) floating-point number. Allowable values are '+
|
||||
'-3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to '+
|
||||
'3.402823466E+38. These are the theoretical limits, based on the IEEE '+
|
||||
'standard. The actual range might be slightly smaller depending on your '+
|
||||
'hardware or operating system.';
|
||||
HasLength: True;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: True;
|
||||
@ -169,6 +193,12 @@ var
|
||||
(
|
||||
Index: dtDouble;
|
||||
Name: 'DOUBLE';
|
||||
Description: 'DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]' + CRLF +
|
||||
'A normal-size (double-precision) floating-point number. Allowable ' +
|
||||
'values are -1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and ' +
|
||||
'2.2250738585072014E-308 to 1.7976931348623157E+308. These are the ' +
|
||||
'theoretical limits, based on the IEEE standard. The actual range might ' +
|
||||
'be slightly smaller depending on your hardware or operating system.';
|
||||
HasLength: True;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: True;
|
||||
@ -180,6 +210,14 @@ var
|
||||
(
|
||||
Index: dtDecimal;
|
||||
Name: 'DECIMAL';
|
||||
Description: 'DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]' + CRLF +
|
||||
'A packed "exact" fixed-point number. M is the total number of digits ' +
|
||||
'(the precision) and D is the number of digits after the decimal point ' +
|
||||
'(the scale). The decimal point and (for negative numbers) the "-" sign ' +
|
||||
'are not counted in M. If D is 0, values have no decimal point or ' +
|
||||
'fractional part. The maximum number of digits (M) for DECIMAL is 65. ' +
|
||||
'The maximum number of supported decimals (D) is 30. If D is omitted, ' +
|
||||
'the default is 0. If M is omitted, the default is 10.';
|
||||
HasLength: True;
|
||||
RequiresLength: True;
|
||||
HasUnsigned: True;
|
||||
@ -191,6 +229,10 @@ var
|
||||
(
|
||||
Index: dtDate;
|
||||
Name: 'DATE';
|
||||
Description: 'DATE' + CRLF +
|
||||
'A date. The supported range is ''1000-01-01'' to ''9999-12-31''. MySQL ' +
|
||||
'displays DATE values in ''YYYY-MM-DD'' format, but allows assignment of ' +
|
||||
'values to DATE columns using either strings or numbers.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -202,6 +244,10 @@ var
|
||||
(
|
||||
Index: dtTime;
|
||||
Name: 'TIME';
|
||||
Description: 'TIME' + CRLF +
|
||||
'A time. The range is ''-838:59:59'' to ''838:59:59''. MySQL displays TIME ' +
|
||||
'values in ''HH:MM:SS'' format, but allows assignment of values to TIME ' +
|
||||
'columns using either strings or numbers.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -213,6 +259,13 @@ var
|
||||
(
|
||||
Index: dtYear;
|
||||
Name: 'YEAR';
|
||||
Description: 'YEAR[(2|4)]' + CRLF +
|
||||
'A year in two-digit or four-digit format. The default is four-digit ' +
|
||||
'format. In four-digit format, the allowable values are 1901 to 2155, ' +
|
||||
'and 0000. In two-digit format, the allowable values are 70 to 69, ' +
|
||||
'representing years from 1970 to 2069. MySQL displays YEAR values in ' +
|
||||
'YYYY format, but allows you to assign values to YEAR columns using ' +
|
||||
'either strings or numbers.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -224,6 +277,11 @@ var
|
||||
(
|
||||
Index: dtDatetime;
|
||||
Name: 'DATETIME';
|
||||
Description: 'DATETIME' + CRLF +
|
||||
'A date and time combination. The supported range is ''1000-01-01 ' +
|
||||
'00:00:00'' to ''9999-12-31 23:59:59''. MySQL displays DATETIME values in ' +
|
||||
'''YYYY-MM-DD HH:MM:SS'' format, but allows assignment of values to ' +
|
||||
'DATETIME columns using either strings or numbers.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -235,6 +293,13 @@ var
|
||||
(
|
||||
Index: dtTimestamp;
|
||||
Name: 'TIMESTAMP';
|
||||
Description: 'TIMESTAMP' + CRLF +
|
||||
'A timestamp. The range is ''1970-01-01 00:00:01'' UTC to ''2038-01-09 ' +
|
||||
'03:14:07'' UTC. TIMESTAMP values are stored as the number of seconds ' +
|
||||
'since the epoch (''1970-01-01 00:00:00'' UTC). A TIMESTAMP cannot ' +
|
||||
'represent the value ''1970-01-01 00:00:00'' because that is equivalent to ' +
|
||||
'0 seconds from the epoch and the value 0 is reserved for representing ' +
|
||||
'''0000-00-00 00:00:00'', the "zero" TIMESTAMP value.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -246,6 +311,12 @@ var
|
||||
(
|
||||
Index: dtCHAR;
|
||||
Name: 'CHAR';
|
||||
Description: 'CHAR[(M)]' + CRLF +
|
||||
'A fixed-length string that is always right-padded with spaces to the ' +
|
||||
'specified length when stored. M represents the column length in ' +
|
||||
'characters. The range of M is 0 to 255. If M is omitted, the length is 1.' + CRLF + CRLF +
|
||||
'*Note*: Trailing spaces are removed when CHAR values are retrieved ' +
|
||||
'unless the PAD_CHAR_TO_FULL_LENGTH SQL mode is enabled.';
|
||||
HasLength: True;
|
||||
RequiresLength: True;
|
||||
HasUnsigned: False;
|
||||
@ -258,6 +329,16 @@ var
|
||||
(
|
||||
Index: dtVarchar;
|
||||
Name: 'VARCHAR';
|
||||
Description: 'VARCHAR(M)' + CRLF +
|
||||
'A variable-length string. M represents the maximum column length in ' +
|
||||
'characters. The range of M is 0 to 65,535. The effective maximum length ' +
|
||||
'of a VARCHAR is subject to the maximum row size (65,535 bytes, which is ' +
|
||||
'shared among all columns) and the character set used. For example, utf8 ' +
|
||||
'characters can require up to three bytes per character, so a VARCHAR ' +
|
||||
'column that uses the utf8 character set can be declared to be a maximum ' +
|
||||
'of 21,844 characters. ' + CRLF + CRLF +
|
||||
'*Note*: MySQL 5.1 follows the standard SQL specification, and does not ' +
|
||||
'remove trailing spaces from VARCHAR values.';
|
||||
HasLength: True;
|
||||
RequiresLength: True;
|
||||
HasUnsigned: False;
|
||||
@ -270,6 +351,11 @@ var
|
||||
(
|
||||
Index: dtTinytext;
|
||||
Name: 'TINYTEXT';
|
||||
Description: 'TINYTEXT' + CRLF +
|
||||
'A TEXT column with a maximum length of 255 (28 - 1) characters. The ' +
|
||||
'effective maximum length is less if the value contains multi-byte ' +
|
||||
'characters. Each TINYTEXT value is stored using a one-byte length ' +
|
||||
'prefix that indicates the number of bytes in the value.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -281,6 +367,14 @@ var
|
||||
(
|
||||
Index: dtText;
|
||||
Name: 'TEXT';
|
||||
Description: 'TEXT[(M)]' + CRLF +
|
||||
'A TEXT column with a maximum length of 65,535 (216 - 1) characters. The ' +
|
||||
'effective maximum length is less if the value contains multi-byte ' +
|
||||
'characters. Each TEXT value is stored using a two-byte length prefix ' +
|
||||
'that indicates the number of bytes in the value. ' + CRLF +
|
||||
'An optional length M can be given for this type. If this is done, MySQL ' +
|
||||
'creates the column as the smallest TEXT type large enough to hold ' +
|
||||
'values M characters long.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -292,6 +386,11 @@ var
|
||||
(
|
||||
Index: dtMediumtext;
|
||||
Name: 'MEDIUMTEXT';
|
||||
Description: 'MEDIUMTEXT' + CRLF +
|
||||
'A TEXT column with a maximum length of 16,777,215 (224 - 1) characters. ' +
|
||||
'The effective maximum length is less if the value contains multi-byte ' +
|
||||
'characters. Each MEDIUMTEXT value is stored using a three-byte length ' +
|
||||
'prefix that indicates the number of bytes in the value.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -303,6 +402,14 @@ var
|
||||
(
|
||||
Index: dtLongtext;
|
||||
Name: 'LONGTEXT';
|
||||
Description: 'LONGTEXT' + CRLF +
|
||||
'A TEXT column with a maximum length of 4,294,967,295 or 4GB (232 - 1) ' +
|
||||
'characters. The effective maximum length is less if the value contains ' +
|
||||
'multi-byte characters. The effective maximum length of LONGTEXT columns ' +
|
||||
'also depends on the configured maximum packet size in the client/server ' +
|
||||
'protocol and available memory. Each LONGTEXT value is stored using a ' +
|
||||
'four-byte length prefix that indicates the number of bytes in the ' +
|
||||
'value.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -314,6 +421,10 @@ var
|
||||
(
|
||||
Index: dtBinary;
|
||||
Name: 'BINARY';
|
||||
Description: 'BINARY(M)' + CRLF +
|
||||
'The BINARY type is similar to the CHAR type, but stores binary byte ' +
|
||||
'strings rather than non-binary character strings. M represents the ' +
|
||||
'column length in bytes.';
|
||||
HasLength: True;
|
||||
RequiresLength: True;
|
||||
HasUnsigned: False;
|
||||
@ -326,6 +437,10 @@ var
|
||||
(
|
||||
Index: dtVarbinary;
|
||||
Name: 'VARBINARY';
|
||||
Description: 'VARBINARY(M)' + CRLF +
|
||||
'The VARBINARY type is similar to the VARCHAR type, but stores binary ' +
|
||||
'byte strings rather than non-binary character strings. M represents the ' +
|
||||
'maximum column length in bytes.';
|
||||
HasLength: True;
|
||||
RequiresLength: True;
|
||||
HasUnsigned: False;
|
||||
@ -338,6 +453,10 @@ var
|
||||
(
|
||||
Index: dtTinyblob;
|
||||
Name: 'TINYBLOB';
|
||||
Description: 'TINYBLOB' + CRLF +
|
||||
'A BLOB column with a maximum length of 255 (28 - 1) bytes. Each ' +
|
||||
'TINYBLOB value is stored using a one-byte length prefix that indicates ' +
|
||||
'the number of bytes in the value.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -349,6 +468,13 @@ var
|
||||
(
|
||||
Index: dtBlob;
|
||||
Name: 'BLOB';
|
||||
Description: 'BLOB[(M)]' + CRLF +
|
||||
'A BLOB column with a maximum length of 65,535 (216 - 1) bytes. Each ' +
|
||||
'BLOB value is stored using a two-byte length prefix that indicates the ' +
|
||||
'number of bytes in the value. ' + CRLF +
|
||||
'An optional length M can be given for this type. If this is done, MySQL ' +
|
||||
'creates the column as the smallest BLOB type large enough to hold ' +
|
||||
'values M bytes long.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -360,6 +486,10 @@ var
|
||||
(
|
||||
Index: dtMediumblob;
|
||||
Name: 'MEDIUMBLOB';
|
||||
Description: 'MEDIUMBLOB' + CRLF +
|
||||
'A BLOB column with a maximum length of 16,777,215 (224 - 1) bytes. Each ' +
|
||||
'MEDIUMBLOB value is stored using a three-byte length prefix that ' +
|
||||
'indicates the number of bytes in the value.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -371,6 +501,12 @@ var
|
||||
(
|
||||
Index: dtLongblob;
|
||||
Name: 'LONGBLOB';
|
||||
Description: 'LONGBLOB' + CRLF +
|
||||
'A BLOB column with a maximum length of 4,294,967,295 or 4GB (232 - 1) ' +
|
||||
'bytes. The effective maximum length of LONGBLOB columns depends on the ' +
|
||||
'configured maximum packet size in the client/server protocol and ' +
|
||||
'available memory. Each LONGBLOB value is stored using a four-byte ' +
|
||||
'length prefix that indicates the number of bytes in the value.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -382,6 +518,11 @@ var
|
||||
(
|
||||
Index: dtEnum;
|
||||
Name: 'ENUM';
|
||||
Description: 'ENUM(''value1'',''value2'',...)' + CRLF +
|
||||
'An enumeration. A string object that can have only one value, chosen ' +
|
||||
'from the list of values ''value1'', ''value2'', ..., NULL or the special '''' ' +
|
||||
'error value. An ENUM column can have a maximum of 65,535 distinct ' +
|
||||
'values. ENUM values are represented internally as integers.';
|
||||
HasLength: True; // Obviously this is not meant as "length", but as "set of values"
|
||||
RequiresLength: True;
|
||||
HasUnsigned: False;
|
||||
@ -394,6 +535,11 @@ var
|
||||
(
|
||||
Index: dtSet;
|
||||
Name: 'SET';
|
||||
Description: 'SET(''value1'',''value2'',...)' + CRLF +
|
||||
'A set. A string object that can have zero or more values, each of which ' +
|
||||
'must be chosen from the list of values ''value1'', ''value2'', ... A SET ' +
|
||||
'column can have a maximum of 64 members. SET values are represented ' +
|
||||
'internally as integers.';
|
||||
HasLength: True; // Same as for ENUM
|
||||
RequiresLength: True;
|
||||
HasUnsigned: False;
|
||||
@ -406,6 +552,9 @@ var
|
||||
(
|
||||
Index: dtBit;
|
||||
Name: 'BIT';
|
||||
Description: 'BIT[(M)]' + CRLF +
|
||||
'A bit-field type. M indicates the number of bits per value, from 1 to ' +
|
||||
'64. The default is 1 if M is omitted.';
|
||||
HasLength: True;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -417,6 +566,8 @@ var
|
||||
(
|
||||
Index: dtPoint;
|
||||
Name: 'POINT';
|
||||
Description: 'POINT(x,y)' + CRLF +
|
||||
'Constructs a WKB Point using its coordinates.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -428,6 +579,10 @@ var
|
||||
(
|
||||
Index: dtLinestring;
|
||||
Name: 'LINESTRING';
|
||||
Description: 'LINESTRING(pt1,pt2,...)' + CRLF +
|
||||
'Constructs a WKB LineString value from a number of WKB Point arguments. ' +
|
||||
'If any argument is not a WKB Point, the return value is NULL. If the ' +
|
||||
'number of Point arguments is less than two, the return value is NULL.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -439,6 +594,10 @@ var
|
||||
(
|
||||
Index: dtPolygon;
|
||||
Name: 'POLYGON';
|
||||
Description: 'POLYGON(ls1,ls2,...)' + CRLF +
|
||||
'Constructs a WKB Polygon value from a number of WKB LineString ' +
|
||||
'arguments. If any argument does not represent the WKB of a LinearRing ' +
|
||||
'(that is, not a closed and simple LineString) the return value is NULL.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -450,6 +609,7 @@ var
|
||||
(
|
||||
Index: dtGeometry;
|
||||
Name: 'GEOMETRY';
|
||||
Description: '';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -461,6 +621,9 @@ var
|
||||
(
|
||||
Index: dtMultipoint;
|
||||
Name: 'MULTIPOINT';
|
||||
Description: 'MULTIPOINT(pt1,pt2,...)' + CRLF +
|
||||
'Constructs a WKB MultiPoint value using WKB Point arguments. If any ' +
|
||||
'argument is not a WKB Point, the return value is NULL.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -472,6 +635,9 @@ var
|
||||
(
|
||||
Index: dtMultilinestring;
|
||||
Name: 'MULTILINESTRING';
|
||||
Description: 'MULTILINESTRING(ls1,ls2,...)' + CRLF +
|
||||
'Constructs a WKB MultiLineString value using WKB LineString arguments. ' +
|
||||
'If any argument is not a WKB LineString, the return value is NULL.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -483,6 +649,10 @@ var
|
||||
(
|
||||
Index: dtMultipolygon;
|
||||
Name: 'MULTIPOLYGON';
|
||||
Description: 'MULTIPOLYGON(poly1,poly2,...)' + CRLF +
|
||||
'Constructs a WKB MultiPolygon value from a set of WKB Polygon ' +
|
||||
'arguments. If any argument is not a WKB Polygon, the return value is ' +
|
||||
'NULL.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
@ -494,6 +664,9 @@ var
|
||||
(
|
||||
Index: dtGeometrycollection;
|
||||
Name: 'GEOMETRYCOLLECTION';
|
||||
Description: 'GEOMETRYCOLLECTION(g1,g2,...)' + CRLF +
|
||||
'Constructs a WKB GeometryCollection. If any argument is not a ' +
|
||||
'well-formed WKB representation of a geometry, the return value is NULL.';
|
||||
HasLength: False;
|
||||
RequiresLength: False;
|
||||
HasUnsigned: False;
|
||||
|
@ -128,7 +128,7 @@ type
|
||||
|
||||
|
||||
implementation
|
||||
uses main, helpers;
|
||||
uses main, helpers, mysql_structures;
|
||||
{$R *.DFM}
|
||||
|
||||
|
||||
@ -243,12 +243,14 @@ begin
|
||||
Mainform.prefCSVSeparator := editCSVSeparator.Text;
|
||||
Mainform.prefCSVEncloser := editCSVEncloser.Text;
|
||||
Mainform.prefCSVTerminator := editCSVTerminator.Text;
|
||||
Mainform.prefFieldColorNumeric := cboxNumeric.Selected;
|
||||
Mainform.prefFieldColorText := cboxText.Selected;
|
||||
Mainform.prefFieldColorBinary := cboxBinary.Selected;
|
||||
Mainform.prefFieldColorDatetime := cboxDatetime.Selected;
|
||||
Mainform.prefFieldColorEnum := cboxEnum.Selected;
|
||||
Mainform.prefFieldColorSet := cboxSet.Selected;
|
||||
DatatypeCategories[Integer(dtcInteger)].Color := cboxNumeric.Selected;
|
||||
DatatypeCategories[Integer(dtcReal)].Color := cboxNumeric.Selected;
|
||||
DatatypeCategories[Integer(dtcText)].Color := cboxText.Selected;
|
||||
DatatypeCategories[Integer(dtcBinary)].Color := cboxBinary.Selected;
|
||||
DatatypeCategories[Integer(dtcTemporal)].Color := cboxDatetime.Selected;
|
||||
DatatypeCategories[Integer(dtcIntegerNamed)].Color := cboxEnum.Selected;
|
||||
DatatypeCategories[Integer(dtcSet)].Color := cboxSet.Selected;
|
||||
DatatypeCategories[Integer(dtcSetNamed)].Color := cboxSet.Selected;
|
||||
Mainform.prefNullBG := cboxNullBg.Selected;
|
||||
Mainform.CalcNullColors;
|
||||
Mainform.DataGrid.Repaint;
|
||||
|
@ -1040,29 +1040,13 @@ begin
|
||||
TextColor := TargetCanvas.Font.Color;
|
||||
|
||||
case Column of
|
||||
2: case dt.Category of
|
||||
dtcInteger, dtcReal: TextColor := Mainform.prefFieldColorNumeric;
|
||||
dtcTemporal: TextColor := Mainform.prefFieldColorDateTime;
|
||||
dtcText: TextColor := Mainform.prefFieldColorText;
|
||||
dtcBinary: TextColor := Mainform.prefFieldColorBinary;
|
||||
dtcIntegerNamed: TextColor := Mainform.prefFieldColorEnum;
|
||||
dtcSet, dtcSetNamed: TextColor := Mainform.prefFieldColorSet;
|
||||
// TODO: catSpatial
|
||||
else TextColor := TargetCanvas.Font.Color;
|
||||
end;
|
||||
2: TextColor := DatatypeCategories[Integer(dt.Category)].Color;
|
||||
|
||||
6: case GetColumnDefaultType(Default) of
|
||||
cdtNull, cdtNullUpdateTS:
|
||||
case dt.Category of
|
||||
dtcInteger, dtcReal: TextColor := Mainform.prefNullColorNumeric;
|
||||
dtcTemporal: TextColor := Mainform.prefNullColorDateTime;
|
||||
dtcText: TextColor := Mainform.prefNullColorText;
|
||||
dtcBinary: TextColor := Mainform.prefNullColorBinary;
|
||||
dtcIntegerNamed: TextColor := Mainform.prefNullColorEnum;
|
||||
dtcSet, dtcSetNamed: TextColor := Mainform.prefNullColorSet;
|
||||
end;
|
||||
TextColor := DatatypeCategories[Integer(dt.Category)].NullColor;
|
||||
cdtCurTS, cdtCurTSUpdateTS:
|
||||
TextColor := Mainform.prefFieldColorDateTime;
|
||||
TextColor := DatatypeCategories[Integer(dtcTemporal)].Color;
|
||||
cdtAutoInc:
|
||||
TextColor := clNavy;
|
||||
end;
|
||||
@ -1154,17 +1138,15 @@ procedure TfrmTableEditor.listColumnsCreateEditor(Sender: TBaseVirtualTree;
|
||||
var
|
||||
EnumEditor: TEnumEditorLink;
|
||||
DefaultEditor: TColumnDefaultEditorLink;
|
||||
i: Integer;
|
||||
DatatypeEditor: TDatatypeEditorLink;
|
||||
Props: TWideStringlist;
|
||||
begin
|
||||
// Start cell editor
|
||||
case Column of
|
||||
2: begin // Datatype pulldown
|
||||
EnumEditor := TEnumEditorLink.Create;
|
||||
EnumEditor.ValueList := TWideStringList.Create;
|
||||
for i:=Low(Datatypes) to High(Datatypes) do
|
||||
EnumEditor.ValueList.Add(Datatypes[i].Name);
|
||||
EditLink := EnumEditor;
|
||||
DatatypeEditor := TDatatypeEditorLink.Create(Sender as TVirtualStringTree);
|
||||
DatatypeEditor.Datatype := dtDateTime;
|
||||
EditLink := DataTypeEditor;
|
||||
end;
|
||||
8: begin // Collation pulldown
|
||||
EnumEditor := TEnumEditorLink.Create;
|
||||
|
Reference in New Issue
Block a user