diff --git a/packages/delphi11/heidisql.dpr b/packages/delphi11/heidisql.dpr
index c852cab9..c45d4bf8 100644
--- a/packages/delphi11/heidisql.dpr
+++ b/packages/delphi11/heidisql.dpr
@@ -39,6 +39,7 @@ uses
view in '..\..\source\view.pas' {frmView},
selectdbobject in '..\..\source\selectdbobject.pas' {frmSelectDBObject},
texteditor in '..\..\source\texteditor.pas' {frmTextEditor},
+ bineditor in '..\..\source\bineditor.pas' {frmBinEditor},
grideditlinks in '..\..\source\grideditlinks.pas',
uVistaFuncs in '..\..\source\uVistaFuncs.pas';
diff --git a/packages/delphi11/heidisql.dproj b/packages/delphi11/heidisql.dproj
index 1bd03e09..6719e95c 100644
--- a/packages/delphi11/heidisql.dproj
+++ b/packages/delphi11/heidisql.dproj
@@ -63,6 +63,9 @@
+
+
+
@@ -109,7 +112,6 @@
-
@@ -140,6 +142,9 @@
+
+
+
@@ -152,4 +157,4 @@
-
\ No newline at end of file
+
diff --git a/source/bineditor.dfm b/source/bineditor.dfm
new file mode 100644
index 00000000..59304bac
--- /dev/null
+++ b/source/bineditor.dfm
@@ -0,0 +1,97 @@
+object frmBinEditor: TfrmBinEditor
+ Left = 0
+ Top = 0
+ BorderStyle = bsSizeToolWin
+ Caption = 'Binary editor'
+ ClientHeight = 95
+ ClientWidth = 215
+ Color = clBtnFace
+ Constraints.MinHeight = 100
+ Constraints.MinWidth = 130
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ OldCreateOrder = False
+ Position = poMainFormCenter
+ OnCloseQuery = FormCloseQuery
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ OnShow = FormShow
+ DesignSize = (
+ 215
+ 95)
+ PixelsPerInch = 96
+ TextHeight = 13
+ object lblTextLength: TLabel
+ Left = 103
+ Top = 77
+ Width = 65
+ Height = 13
+ Anchors = [akLeft, akBottom]
+ BiDiMode = bdLeftToRight
+ Caption = 'lblTextLength'
+ ParentBiDiMode = False
+ end
+ object memoText: TTntMemo
+ Left = 0
+ Top = 0
+ Width = 215
+ Height = 72
+ Align = alTop
+ Anchors = [akLeft, akTop, akRight, akBottom]
+ Lines.Strings = (
+ 'memoText')
+ ScrollBars = ssBoth
+ TabOrder = 0
+ WantTabs = True
+ OnChange = memoTextChange
+ OnKeyDown = memoTextKeyDown
+ end
+ object tlbStandard: TToolBar
+ Left = 0
+ Top = 73
+ Width = 97
+ Height = 22
+ Align = alNone
+ Anchors = [akLeft, akBottom]
+ Caption = 'tlbStandard'
+ Images = MainForm.PngImageListMain
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 1
+ object btnWrap: TToolButton
+ Left = 0
+ Top = 0
+ Hint = 'Wrap long lines'
+ Caption = 'Wrap long lines'
+ ImageIndex = 62
+ OnClick = btnWrapClick
+ end
+ object btnLoadBinary: TToolButton
+ Left = 23
+ Top = 0
+ Hint = 'Load binary file'
+ Caption = 'Load binary file'
+ ImageIndex = 52
+ OnClick = btnLoadBinaryClick
+ end
+ object btnCancel: TToolButton
+ Left = 46
+ Top = 0
+ Hint = 'Cancel'
+ Caption = 'Cancel'
+ ImageIndex = 26
+ OnClick = btnCancelClick
+ end
+ object btnApply: TToolButton
+ Left = 69
+ Top = 0
+ Hint = 'Apply changes'
+ Caption = 'Apply changes'
+ ImageIndex = 55
+ OnClick = btnApplyClick
+ end
+ end
+end
diff --git a/source/bineditor.pas b/source/bineditor.pas
new file mode 100644
index 00000000..dab8b345
--- /dev/null
+++ b/source/bineditor.pas
@@ -0,0 +1,198 @@
+unit bineditor;
+
+interface
+
+uses
+ Windows, Classes, Graphics, Forms, Controls, helpers, StdCtrls, TntStdCtrls, Registry, VirtualTrees,
+ ComCtrls, ToolWin, Dialogs, SysUtils;
+
+{$I const.inc}
+
+type
+ TfrmBinEditor = class(TMemoEditor)
+ memoText: TTntMemo;
+ tlbStandard: TToolBar;
+ btnWrap: TToolButton;
+ btnLoadBinary: TToolButton;
+ btnApply: TToolButton;
+ btnCancel: TToolButton;
+ lblTextLength: TLabel;
+ procedure btnApplyClick(Sender: TObject);
+ procedure btnCancelClick(Sender: TObject);
+ procedure btnLoadBinaryClick(Sender: TObject);
+ procedure btnWrapClick(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure FormShow(Sender: TObject);
+ procedure memoTextChange(Sender: TObject);
+ procedure memoTextKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
+ procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+ procedure FormCreate(Sender: TObject);
+ private
+ { Private declarations }
+ FModified: Boolean;
+ procedure SetModified(NewVal: Boolean);
+ property Modified: Boolean read FModified write SetModified;
+ public
+ function GetText: WideString; override;
+ procedure SetText(text: WideString); override;
+ procedure SetMaxLength(len: integer); override;
+ procedure SetFont(font: TFont); override;
+ end;
+
+
+implementation
+
+uses main;
+
+{$R *.dfm}
+
+
+function TfrmBinEditor.GetText: WideString;
+begin
+ Result := '0x' + memoText.Text;
+end;
+
+procedure TfrmBinEditor.SetText(text: WideString);
+begin
+ // Skip '0x'.
+ memoText.Text := Copy(text, 3);
+end;
+
+procedure TfrmBinEditor.SetMaxLength(len: integer);
+begin
+ // Input: Length in bytes.
+ memoText.MaxLength := len * 2;
+end;
+
+procedure TfrmBinEditor.SetFont(font: TFont);
+begin
+ memoText.Font := font;
+end;
+
+procedure TfrmBinEditor.FormCreate(Sender: TObject);
+begin
+ InheritFont(Font);
+end;
+
+
+procedure TfrmBinEditor.FormDestroy(Sender: TObject);
+var
+ reg: TRegistry;
+begin
+ reg := TRegistry.Create;
+ if reg.OpenKey(REGPATH, False) then begin
+ reg.WriteInteger( REGNAME_EDITOR_WIDTH, Width );
+ reg.WriteInteger( REGNAME_EDITOR_HEIGHT, Height );
+ reg.CloseKey;
+ end;
+ reg.Free;
+end;
+
+
+procedure TfrmBinEditor.FormShow(Sender: TObject);
+begin
+ // Restore form dimensions
+ Width := Mainform.GetRegValue(REGNAME_EDITOR_WIDTH, DEFAULT_EDITOR_WIDTH);
+ Height := Mainform.GetRegValue(REGNAME_EDITOR_HEIGHT, DEFAULT_EDITOR_HEIGHT);
+ // Fix label position:
+ lblTextLength.Top := tlbStandard.Top + (tlbStandard.Height-lblTextLength.Height) div 2;
+ SetWindowSizeGrip(Handle, True);
+ memoText.SelectAll;
+ memoText.SetFocus;
+ memoTextChange(Sender);
+ Modified := False;
+end;
+
+
+procedure TfrmBinEditor.memoTextKeyDown(Sender: TObject; var Key: Word; Shift:
+ TShiftState);
+begin
+ case Key of
+ // Cancel by Escape
+ VK_ESCAPE: btnCancelClick(Sender);
+ // Apply changes and end editing by Ctrl + Enter
+ VK_RETURN: if ssCtrl in Shift then btnApplyClick(Sender);
+ end;
+end;
+
+procedure TfrmBinEditor.btnWrapClick(Sender: TObject);
+var
+ WasModified: Boolean;
+begin
+ Screen.Cursor := crHourglass;
+ // Changing the scrollbars invoke the OnChange event. We avoid thinking the text was really modified.
+ WasModified := Modified;
+ if memoText.ScrollBars = ssBoth then
+ memoText.ScrollBars := ssVertical
+ else
+ memoText.ScrollBars := ssBoth;
+ TToolbutton(Sender).Down := memoText.ScrollBars = ssVertical;
+ Modified := WasModified;
+ Screen.Cursor := crDefault;
+end;
+
+
+procedure TfrmBinEditor.btnLoadBinaryClick(Sender: TObject);
+var
+ d: TOpenDialog;
+begin
+ d := TOpenDialog.Create(Self);
+ d.Filter := 'All binary files (*.*)|*.*';
+ d.FilterIndex := 0;
+ if d.Execute then try
+ Screen.Cursor := crHourglass;
+ memoText.Text := BinToWideHex(ReadBinaryFile(d.FileName, memoText.MaxLength));
+ finally
+ Screen.Cursor := crDefault;
+ end;
+ d.Free;
+end;
+
+
+procedure TfrmBinEditor.btnCancelClick(Sender: TObject);
+var
+ DoPost: Boolean;
+begin
+ if Modified then
+ DoPost := MessageDlg('Apply modifications?', mtConfirmation, [mbYes, mbNo], 0) = mrYes
+ else
+ DoPost := False;
+ if DoPost then
+ TCustomVirtualStringTree(Owner).EndEditNode
+ else
+ TCustomVirtualStringTree(Owner).CancelEditNode;
+end;
+
+
+procedure TfrmBinEditor.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+begin
+ btnCancelClick(Sender);
+ CanClose := False; // Done by editor link
+end;
+
+
+procedure TfrmBinEditor.btnApplyClick(Sender: TObject);
+begin
+ TCustomVirtualStringTree(Owner).EndEditNode;
+end;
+
+
+procedure TfrmBinEditor.memoTextChange(Sender: TObject);
+begin
+ lblTextLength.Caption := FormatNumber(Length(memoText.Text) / 2) + ' bytes.';
+ if memoText.MaxLength > 0 then
+ lblTextLength.Caption := lblTextLength.Caption + ' (Max: '+FormatNumber(memoText.MaxLength / 2)+')';
+ Modified := True;
+end;
+
+
+procedure TfrmBinEditor.SetModified(NewVal: Boolean);
+begin
+ if FModified <> NewVal then begin
+ FModified := NewVal;
+ btnApply.Enabled := FModified;
+ end;
+end;
+
+
+end.
diff --git a/source/childwin.pas b/source/childwin.pas
index 0581843a..358debf1 100644
--- a/source/childwin.pas
+++ b/source/childwin.pas
@@ -1204,7 +1204,11 @@ begin
rx.Expression := '^((tiny|medium|long)?text|(var)?char)\b(\(\d+\))?';
if rx.Exec(ColType) then begin
FDataGridResult.Columns[idx].IsText := True;
- if ColType = 'tinytext' then
+ if rx.Match[4] <> '' then
+ FDataGridResult.Columns[idx].MaxLength := MakeInt(rx.Match[4])
+ else if ColType = 'tinytext' then
+ // 255 is the width in bytes. If characters that use multiple bytes are
+ // contained, the width in characters is decreased below this number.
FDataGridResult.Columns[idx].MaxLength := 255
else if ColType = 'text' then
FDataGridResult.Columns[idx].MaxLength := 65535
@@ -1212,14 +1216,13 @@ begin
FDataGridResult.Columns[idx].MaxLength := 16777215
else if ColType = 'longtext' then
FDataGridResult.Columns[idx].MaxLength := 4294967295
- else if rx.Match[4] <> '' then
- FDataGridResult.Columns[idx].MaxLength := MakeInt(rx.Match[4])
- else // Fallback for unknown column types
+ else
+ // Fallback for unknown column types
FDataGridResult.Columns[idx].MaxLength := MaxInt;
end;
rx.Expression := '^((tiny|medium|long)?blob|(var)?binary|bit)\b';
if rx.Exec(ColType) then
- FDataGridResult.Columns[idx].IsBlob := True;
+ FDataGridResult.Columns[idx].IsBinary := True;
if Copy(ColType, 1, 5) = 'enum(' then begin
FDataGridResult.Columns[idx].IsEnum := True;
FDataGridResult.Columns[idx].EnumVals := WideStrings.TWideStringList.Create;
@@ -2482,7 +2485,7 @@ begin
else if ds.Fields[i].DataType in [ftWideString, ftMemo, ftWideMemo] then
FQueryGridResult.Columns[i].IsText := True
else if ds.Fields[i].DataType in [ftBlob] then
- FQueryGridResult.Columns[i].IsBlob := True;
+ FQueryGridResult.Columns[i].IsBinary := True;
end;
SetLength(FQueryGridResult.Rows, 0);
SetLength(FQueryGridResult.Rows, ds.RecordCount);
@@ -2491,8 +2494,8 @@ begin
FQueryGridResult.Rows[i].Loaded := True;
SetLength(FQueryGridResult.Rows[i].Cells, ds.FieldCount);
for j:=0 to ds.FieldCount-1 do begin
- if FQueryGridResult.Columns[j].IsBlob then
- FQueryGridResult.Rows[i].Cells[j].Text := Utf8Decode(ds.Fields[j].AsString)
+ if FQueryGridResult.Columns[j].IsBinary then
+ FQueryGridResult.Rows[i].Cells[j].Text := '0x' + BinToWideHex(ds.Fields[j].AsString)
else
FQueryGridResult.Rows[i].Cells[j].Text := ds.Fields[j].AsWideString;
FQueryGridResult.Rows[i].Cells[j].IsNull := ds.Fields[j].IsNull;
@@ -3575,6 +3578,12 @@ begin
end;
// Create instance of the progress form (but don't show it yet)
+ // Todo: This apparently causes an exception if invoked via an event handler?
+ // Classes.TStream.ReadComponent(???)
+ // Classes.InternalReadComponentRes(???,???,???)
+ // Classes.InitComponent(TfrmQueryProgress)
+ // Classes.InitInheritedComponent($17E0710,TForm)
+ // Forms.TCustomForm.Create(???)
FProgressForm := TFrmQueryProgress.Create(Self);
{ Launch a thread of execution that passes the query to the server
@@ -5478,8 +5487,8 @@ begin
for i := start to start + limit - 1 do begin
SetLength(FDataGridResult.Rows[i].Cells, ds.Fields.Count);
for j := 0 to ds.Fields.Count - 1 do begin
- if FDataGridResult.Columns[j].IsBlob then
- FDataGridResult.Rows[i].Cells[j].Text := Utf8Decode(ds.Fields[j].AsString)
+ if FDataGridResult.Columns[j].IsBinary then
+ FDataGridResult.Rows[i].Cells[j].Text := '0x' + BinToWideHex(ds.Fields[j].AsString)
else
FDataGridResult.Rows[i].Cells[j].Text := ds.Fields[j].AsWideString;
FDataGridResult.Rows[i].Cells[j].IsNull := ds.Fields[j].IsNull;
@@ -5489,6 +5498,7 @@ begin
end;
MainForm.ShowStatus( STATUS_MSG_READY );
+ // Todo: Seen an AV next line when this method was invoked via an event handler.
FreeAndNil(ds);
end;
end;
@@ -5573,7 +5583,7 @@ begin
else if r.Columns[Column].isText then
if isNull then cl := $60CC60 else cl := clGreen
// Text field
- else if r.Columns[Column].isBlob then
+ else if r.Columns[Column].isBinary then
if isNull then cl := $CC60CC else cl := clPurple
else
if isNull then cl := COLOR_NULLVALUE else cl := clWindowText;
@@ -5723,7 +5733,8 @@ begin
if Row.Cells[i].Modified then begin
Val := Row.Cells[i].NewText;
if FDataGridResult.Columns[i].IsFloat then Val := FloatStr(Val);
- Val := esc(Val);
+ if not FDataGridResult.Columns[i].IsBinary then Val := esc(Val);
+ if FDataGridResult.Columns[i].IsBinary then CheckHex(Copy(Val, 3), 'Invalid hexadecimal string given in field "' + FDataGridResult.Columns[i].Name + '".');
if Row.Cells[i].NewIsNull then Val := 'NULL';
sql := sql + ' ' + mask(FDataGridResult.Columns[i].Name) + '=' + Val + ', ';
end;
@@ -5759,8 +5770,8 @@ begin
ds := ExecSelectQuery(sql);
if ds.RecordCount = 1 then begin
for i := 0 to ds.FieldCount - 1 do begin
- if FDataGridResult.Columns[i].IsBlob then
- Row.Cells[i].Text := Utf8Decode(ds.Fields[i].AsString)
+ if FDataGridResult.Columns[i].IsBinary then
+ Row.Cells[i].Text := '0x' + BinToWideHex(ds.Fields[i].AsString)
else
Row.Cells[i].Text := ds.Fields[i].AsWideString;
Row.Cells[i].IsNull := ds.Fields[i].IsNull;
@@ -5814,7 +5825,7 @@ begin
KeyVal := Row.Cells[j].Text;
// Quote if needed
if FDataGridResult.Columns[j].IsFloat then KeyVal := FloatStr(KeyVal);
- KeyVal := esc(KeyVal);
+ if not FDataGridResult.Columns[j].IsBinary then KeyVal := esc(KeyVal);
if Row.Cells[j].IsNull then KeyVal := ' IS NULL'
else KeyVal := '=' + KeyVal;
Result := Result + mask(KeyCols[i]) + KeyVal + ' AND ';
@@ -5898,7 +5909,8 @@ begin
Cols := Cols + mask(FDataGridResult.Columns[i].Name) + ', ';
Val := Row.Cells[i].NewText;
if FDataGridResult.Columns[i].IsFloat then Val := FloatStr(Val);
- Val := esc(Val);
+ if not FDataGridResult.Columns[i].IsBinary then Val := esc(Val);
+ if FDataGridResult.Columns[i].IsBinary then CheckHex(Copy(Val, 3), 'Invalid hexadecimal string given in field "' + FDataGridResult.Columns[i].Name + '".');
if Row.Cells[i].NewIsNull then Val := 'NULL';
Vals := Vals + Val + ', ';
end;
@@ -6080,7 +6092,10 @@ var
DateTimeEditor: TDateTimeEditorLink;
EnumEditor: TEnumEditorLink;
begin
- if FDataGridResult.Columns[Column].IsText then begin
+ if
+ FDataGridResult.Columns[Column].IsText or
+ FDataGridResult.Columns[Column].IsBinary
+ then begin
MemoEditor := TMemoEditorLink.Create;
MemoEditor.MaxLength := FDataGridResult.Columns[Column].MaxLength;
EditLink := MemoEditor;
diff --git a/source/grideditlinks.pas b/source/grideditlinks.pas
index 5ceaaa4d..ab2c74d1 100644
--- a/source/grideditlinks.pas
+++ b/source/grideditlinks.pas
@@ -4,8 +4,8 @@ unit grideditlinks;
interface
-uses Windows, Forms, Graphics, messages, VirtualTrees, texteditor, ComCtrls, SysUtils, Classes,
- mysql_structures, Main, helpers, TntStdCtrls, WideStrings, StdCtrls;
+uses Windows, Forms, Graphics, messages, VirtualTrees, texteditor, bineditor, ComCtrls, SysUtils, Classes,
+ mysql_structures, Main, ChildWin, helpers, TntStdCtrls, WideStrings, StdCtrls;
type
TMemoEditorLink = class(TInterfacedObject, IVTEditLink)
@@ -95,6 +95,7 @@ end;
function TMemoEditorLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
// Retrieves the true text bounds from the owner tree.
var
+ IsBinary: Boolean;
Text: WideString;
F: TFont;
begin
@@ -110,11 +111,15 @@ begin
F := TFont.Create;
FTree.GetTextInfo(Node, Column, F, FTextBounds, Text);
+ IsBinary := MainForm.ChildWin.FDataGridResult.Columns[Column].IsBinary;
+
// Get wide text of the node.
Text := FTree.Text[FNode, FColumn];
- // Create the editor form
- FForm := TfrmTextEditor.Create(Ftree);
+ // Create the text editor form
+ if IsBinary then FForm := TfrmBinEditor.Create(Ftree)
+ else FForm := TfrmTextEditor.Create(Ftree);
+
FForm.SetFont(F);
FForm.SetText(Text);
FForm.SetMaxLength(MaxLength);
diff --git a/source/helpers.pas b/source/helpers.pas
index 10f8add8..4d64c5f1 100644
--- a/source/helpers.pas
+++ b/source/helpers.pas
@@ -51,7 +51,7 @@ type
DataType: Byte; // @see constants in mysql_structures.pas
MaxLength: Cardinal;
IsPriPart: Boolean;
- IsBlob: Boolean;
+ IsBinary: Boolean;
IsText: Boolean;
IsEnum: Boolean;
IsInt: Boolean;
@@ -150,8 +150,12 @@ type
function GetFileCharset(Stream: TFileStream): TFileCharset;
function ReadTextfileChunk(Stream: TFileStream; FileCharset: TFileCharset; ChunkSize: Int64 = 0): WideString;
function ReadTextfile(Filename: String): WideString;
+ function ReadBinaryFile(Filename: String; MaxBytes: Int64): string;
procedure CopyToClipboard(Value: WideString);
procedure StreamToClipboard(S: TMemoryStream);
+ function WideHexToBin(text: WideString): string;
+ function BinToWideHex(bin: string): WideString;
+ procedure CheckHex(text: WideString; errorMessage: string);
var
MYSQL_KEYWORDS : TStringList;
@@ -194,6 +198,38 @@ var
+function WideHexToBin(text: WideString): string;
+var
+ buf: string;
+begin
+ // Todo: test.
+ buf := text;
+ SetLength(Result, Length(text) div 2);
+ HexToBin(@buf[1], @Result[1], Length(Result));
+end;
+
+function BinToWideHex(bin: string): WideString;
+var
+ buf: string;
+begin
+ SetLength(buf, Length(bin) * 2);
+ BinToHex(@bin[1], @buf[1], Length(buf));
+ Result := buf;
+end;
+
+ procedure CheckHex(text: WideString; errorMessage: string);
+const
+ allowed: string = '0123456789abcdefABCDEF';
+var
+ i: Cardinal;
+begin
+ for i := 1 to Length(text) do begin
+ if Pos(text[i], allowed) < 1 then begin
+ raise Exception.Create(errorMessage);
+ end;
+ end;
+end;
+
{***
Convert a TStringList to a string using a separator-string
@@ -2444,6 +2480,17 @@ begin
Stream.Free;
end;
+function ReadBinaryFile(Filename: String; MaxBytes: Int64): string;
+var
+ Stream: TFileStream;
+begin
+ Stream := TFileStream.Create(Filename, fmOpenRead or fmShareDenyNone);
+ Stream.Position := 0;
+ if (MaxBytes < 1) or (MaxBytes > Stream.Size) then MaxBytes := Stream.Size;
+ SetLength(Result, MaxBytes);
+ Stream.Read(PChar(Result)^, Length(Result));
+ Stream.Free;
+end;
{ TUniClipboard }
diff --git a/source/main.pas b/source/main.pas
index 621edcbc..6ed4a8cd 100644
--- a/source/main.pas
+++ b/source/main.pas
@@ -1230,7 +1230,7 @@ var
f : Textfile;
tmppath : array[0..MAX_PATH] of char;
Content : WideString;
- IsBlob : Boolean;
+ IsBinary : Boolean;
begin
g := ChildWin.ActiveGrid;
if g = nil then begin messagebeep(MB_ICONASTERISK); exit; end;
@@ -1238,19 +1238,19 @@ begin
showstatus('Saving contents to file...');
if g = Childwin.DataGrid then begin
Content := Childwin.FDataGridResult.Rows[Childwin.DataGrid.FocusedNode.Index].Cells[Childwin.DataGrid.FocusedColumn].Text;
- IsBlob := Childwin.FDataGridResult.Columns[Childwin.DataGrid.FocusedColumn].IsBlob;
+ IsBinary := Childwin.FDataGridResult.Columns[Childwin.DataGrid.FocusedColumn].IsBinary;
end else begin
Content := Childwin.FQueryGridResult.Rows[Childwin.QueryGrid.FocusedNode.Index].Cells[Childwin.QueryGrid.FocusedColumn].Text;
- IsBlob := Childwin.FQueryGridResult.Columns[Childwin.QueryGrid.FocusedColumn].IsBlob;
+ IsBinary := Childwin.FQueryGridResult.Columns[Childwin.QueryGrid.FocusedColumn].IsBinary;
end;
childwin.logsql(g.Name);
GetTempPath(MAX_PATH, tmppath);
filename := tmppath;
filename := filename+'\'+APPNAME+'-preview.';
- if IsBlob then begin
+ if IsBinary then begin
if pos('JFIF', copy(Content, 0, 20)) <> 0 then
- filename := filename + 'jpg'
+ filename := filename + 'jpeg'
else if StrCmpBegin('GIF', Content) then
filename := filename + 'gif'
else if StrCmpBegin('BM', Content) then
diff --git a/source/texteditor.pas b/source/texteditor.pas
index 0829a9f5..20047ec4 100644
--- a/source/texteditor.pas
+++ b/source/texteditor.pas
@@ -4,7 +4,7 @@ interface
uses
Windows, Classes, Graphics, Forms, Controls, helpers, StdCtrls, TntStdCtrls, Registry, VirtualTrees,
- ComCtrls, ToolWin, Dialogs;
+ ComCtrls, ToolWin, Dialogs, SysUtils;
{$I const.inc}
@@ -60,6 +60,7 @@ end;
procedure TfrmTextEditor.SetMaxLength(len: integer);
begin
+ // Input: Length in number of bytes.
memoText.MaxLength := len;
end;