mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
707 lines
23 KiB
ObjectPascal
707 lines
23 KiB
ObjectPascal
unit insertfiles;
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls,
|
|
Math, Graphics, ComCtrls, ToolWin, LCLType, extra_controls,
|
|
dbconnection, dbstructures, laz.VirtualTrees, RegExpr, apphelpers;
|
|
|
|
type
|
|
TColInfo = class
|
|
public
|
|
Name: String;
|
|
Datatype: TDBDatatype;
|
|
Value: String;
|
|
end;
|
|
PColInfo = ^TColInfo;
|
|
|
|
TFileInfo = class(TObject)
|
|
public
|
|
Filename: String;
|
|
ImageIndex: Integer;
|
|
Size: Int64;
|
|
IsBinary: Boolean;
|
|
end;
|
|
PFileInfo = ^TFileInfo;
|
|
|
|
TfrmInsertFiles = class(TExtForm)
|
|
btnInsert: TButton;
|
|
btnCancel: TButton;
|
|
OpenDialog: TOpenDialog;
|
|
grpSelectObject: TGroupBox;
|
|
lblTable: TLabel;
|
|
comboDBs: TComboBox;
|
|
comboTables: TComboBox;
|
|
GroupBox2: TGroupBox;
|
|
lblDropHint: TLabel;
|
|
lblFileCount: TLabel;
|
|
ListFiles: TLazVirtualStringTree;
|
|
ToolBar1: TToolBar;
|
|
btnAddFiles: TToolButton;
|
|
btnRemoveFiles: TToolButton;
|
|
btnClearFiles: TToolButton;
|
|
ListColumns: TLazVirtualStringTree;
|
|
lblFilecontents: TLabel;
|
|
procedure FormShow(Sender: TObject);
|
|
procedure comboDBsChange(Sender: TObject);
|
|
procedure comboTablesChange(Sender: TObject);
|
|
procedure Modified;
|
|
procedure btnAddFilesClick(Sender: TObject);
|
|
procedure btnRemoveFilesClick(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure btnInsertClick(Sender: TObject);
|
|
procedure AddFile(Filename: String);
|
|
procedure ListFilesGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
|
|
procedure ListFilesGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
|
|
TextType: TVSTTextType; var CellText: string);
|
|
procedure ListFilesGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
|
|
procedure ListFilesHeaderClick(Sender: TVTHeader; HitInfo: TVTHeaderHitInfo);
|
|
procedure ListFilesCompareNodes(Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode;
|
|
Column: TColumnIndex; var Result: Integer);
|
|
procedure ListFilesDblClick(Sender: TObject);
|
|
procedure ListFilesKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
procedure ListFilesFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
|
procedure ListFilesBeforeCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas;
|
|
Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect;
|
|
var ContentRect: TRect);
|
|
procedure ListFilesChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
|
procedure ListFilesStructureChange(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Reason: TChangeReason);
|
|
procedure ListColumnsGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
|
|
procedure ListColumnsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
|
|
TextType: TVSTTextType; var CellText: string);
|
|
procedure ListColumnsFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
|
procedure GridAfterCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas;
|
|
Node: PVirtualNode; Column: TColumnIndex; CellRect: TRect);
|
|
procedure GridClick(Sender: TObject);
|
|
procedure GridKeyPress(Sender: TObject; var Key: Char);
|
|
procedure GridHandleClickOrKeyPress(Sender: TVirtualStringTree;
|
|
Node: PVirtualNode; Column: TColumnIndex; HitPositions: THitPositions);
|
|
procedure ListColumnsEditing(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
|
|
var Allowed: Boolean);
|
|
procedure ListColumnsCreateEditor(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Column: TColumnIndex; out EditLink: IVTEditLink);
|
|
procedure ListColumnsNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
|
|
NewText: string);
|
|
procedure ListColumnsPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas;
|
|
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
|
|
procedure FormDestroy(Sender: TObject);
|
|
private
|
|
FConnection: TDBConnection;
|
|
FMaxFileSize: Int64;
|
|
public
|
|
{ Public declarations }
|
|
//procedure AcceptFiles( var msg : TMessage ); message WM_DROPFILES;
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
uses main;
|
|
|
|
const
|
|
ColColname = 0;
|
|
ColDatatype = 1;
|
|
ColValue = 2;
|
|
ColFilename = 0;
|
|
ColBinary = 1;
|
|
ColFilesize = 2;
|
|
|
|
{$R *.lfm}
|
|
|
|
|
|
|
|
procedure TfrmInsertFiles.FormCreate(Sender: TObject);
|
|
begin
|
|
HasSizeGrip := True;
|
|
//ListFiles.Images := GetSystemImageList;
|
|
//DragAcceptFiles(Handle, True);
|
|
Width := AppSettings.ReadInt(asFileImportWindowWidth);
|
|
Height := AppSettings.ReadInt(asFileImportWindowHeight);
|
|
RestoreListSetup(ListColumns);
|
|
RestoreListSetup(ListFiles);
|
|
FixVT(ListFiles);
|
|
FixVT(ListColumns);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.FormDestroy(Sender: TObject);
|
|
begin
|
|
AppSettings.WriteIntDpiAware(asFileImportWindowWidth, Self, Width);
|
|
AppSettings.WriteIntDpiAware(asFileImportWindowHeight, Self, Height);
|
|
SaveListSetup(ListColumns);
|
|
SaveListSetup(listFiles);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.FormShow(Sender: TObject);
|
|
begin
|
|
FConnection := Mainform.ActiveConnection;
|
|
Caption := FConnection.Parameters.SessionName + ' - ' + MainForm.actInsertFiles.Caption;
|
|
comboDBs.Items.Clear;
|
|
comboDBs.Items.Assign(FConnection.AllDatabases);
|
|
comboDBs.ItemIndex := comboDBs.Items.IndexOf(FConnection.Database);
|
|
if comboDBs.ItemIndex = -1 then
|
|
comboDBs.ItemIndex := 0;
|
|
comboDBs.OnChange(Sender);
|
|
ListFilesChange(ListFiles, nil);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListColumnsFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
|
var
|
|
ColInfo: PColInfo;
|
|
begin
|
|
// Free some memory
|
|
ColInfo := Sender.GetNodeData(Node);
|
|
ColInfo.Free;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListColumnsGetNodeDataSize(Sender: TBaseVirtualTree;
|
|
var NodeDataSize: Integer);
|
|
begin
|
|
NodeDataSize := SizeOf(TColInfo);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListColumnsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
|
|
var
|
|
ColInfo: PColInfo;
|
|
begin
|
|
// Display cell value
|
|
ColInfo := Sender.GetNodeData(Node);
|
|
case Column of
|
|
ColColname: CellText := ColInfo.Name;
|
|
ColDatatype: CellText := ColInfo.Datatype.Name;
|
|
ColValue: CellText := ColInfo.Value;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListColumnsPaintText(Sender: TBaseVirtualTree;
|
|
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
|
|
var
|
|
ColInfo: PColInfo;
|
|
begin
|
|
// Datatype specific font color
|
|
if Column = ColDatatype then begin
|
|
ColInfo := Sender.GetNodeData(Node);
|
|
TargetCanvas.Font.Color := DatatypeCategories[ColInfo.DataType.Category].Color;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.GridAfterCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas;
|
|
Node: PVirtualNode; Column: TColumnIndex; CellRect: TRect);
|
|
var
|
|
ImageIndex, X, Y: Integer;
|
|
Grid: TVirtualStringTree;
|
|
FileInfo: PFileInfo;
|
|
PaintCheckbox, CheckState: Boolean;
|
|
begin
|
|
// Paint checkbox image in certain columns
|
|
Grid := Sender as TVirtualStringTree;
|
|
PaintCheckbox := False;
|
|
CheckState := False;
|
|
if (Grid = listFiles) and (Column = ColBinary) then begin
|
|
FileInfo := Sender.GetNodeData(Node);
|
|
CheckState := FileInfo.IsBinary;
|
|
PaintCheckbox := True;
|
|
end;
|
|
|
|
if PaintCheckbox then begin
|
|
if CheckState then
|
|
ImageIndex := 128
|
|
else
|
|
ImageIndex := 127;
|
|
X := CellRect.Left + (Grid.Header.Columns[Column].Width div 2) - (MainForm.VirtualImageListMain.Width div 2);
|
|
Y := CellRect.Top + Integer(Grid.NodeHeight[Node] div 2) - (MainForm.VirtualImageListMain.Height div 2);
|
|
MainForm.VirtualImageListMain.Draw(TargetCanvas, X, Y, ImageIndex);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListColumnsEditing(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Column: TColumnIndex; var Allowed: Boolean);
|
|
begin
|
|
// Editor only allowed for "value"
|
|
Allowed := Column = ColValue;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.GridKeyPress(Sender: TObject; var Key: Char);
|
|
var
|
|
Grid: TVirtualStringTree;
|
|
begin
|
|
// Space/click on checkbox column
|
|
Grid := Sender as TVirtualStringTree;
|
|
if Ord(Key) = VK_SPACE then
|
|
GridHandleClickOrKeyPress(Grid, Grid.FocusedNode, Grid.FocusedColumn, []);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.GridClick(Sender: TObject);
|
|
var
|
|
Grid: TVirtualStringTree;
|
|
Click: THitInfo;
|
|
begin
|
|
// Handle click event
|
|
Grid := Sender as TVirtualStringTree;
|
|
Grid.GetHitTestInfoAt(Mouse.CursorPos.X-Grid.ClientOrigin.X, Mouse.CursorPos.Y-Grid.ClientOrigin.Y, True, Click);
|
|
GridHandleClickOrKeyPress(Grid, Click.HitNode, Click.HitColumn, Click.HitPositions);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListColumnsCreateEditor(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Column: TColumnIndex; out EditLink: IVTEditLink);
|
|
var
|
|
Grid: TVirtualStringTree;
|
|
//EnumEditor: TEnumEditorLink;
|
|
begin
|
|
// Start cell editor
|
|
Grid := Sender as TVirtualStringTree;
|
|
if Column = ColValue then begin
|
|
{EnumEditor := TEnumEditorLink.Create(Grid, True, nil);
|
|
EnumEditor.AllowCustomText := True;
|
|
EnumEditor.ValueList := TStringList.Create;
|
|
EnumEditor.ValueList.Text := 'NULL'+CRLF+
|
|
'''%filecontent%'''+CRLF+
|
|
'''%filename%'''+CRLF+
|
|
'''%filepath%'''+CRLF+
|
|
'''%filesize%'''+CRLF+
|
|
'''%filedate%'''+CRLF+
|
|
'''%filedatetime%'''+CRLF+
|
|
'''%filetime%'''+CRLF+
|
|
'NOW()'+CRLF+
|
|
'LOWER(''%filename%'')'+CRLF+
|
|
'UPPER(''%filenname%'')'+CRLF+
|
|
'UNIX_TIMESTAMP(''%filedatetime%'')'+CRLF+
|
|
'ENCODE(''%filename%'', ''password'')';
|
|
EditLink := EnumEditor;}
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListColumnsNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Column: TColumnIndex; NewText: string);
|
|
var
|
|
ColInfo: PColInfo;
|
|
begin
|
|
// User entered new value
|
|
ColInfo := Sender.GetNodeData(Node);
|
|
if Column = ColValue then
|
|
ColInfo.Value := NewText;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.GridHandleClickOrKeyPress(Sender: TVirtualStringTree;
|
|
Node: PVirtualNode; Column: TColumnIndex; HitPositions: THitPositions);
|
|
var
|
|
FileInfo: PFileInfo;
|
|
Grid: TVirtualStringTree;
|
|
begin
|
|
// "quote" checkbox, cell editor disabled, instead toggle its state
|
|
if (not Assigned(Node)) or (Column = NoColumn) then
|
|
Exit;
|
|
Grid := Sender as TVirtualStringTree;
|
|
if (Grid = listFiles) and (Column = ColBinary) then begin
|
|
FileInfo := Grid.GetNodeData(Node);
|
|
FileInfo.IsBinary := not FileInfo.IsBinary;
|
|
Grid.OnChange(Sender, Node);
|
|
end;
|
|
Grid.InvalidateNode(Node);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.comboDBsChange(Sender: TObject);
|
|
var
|
|
DBObjects: TDBObjectList;
|
|
i: Integer;
|
|
begin
|
|
// read tables from db
|
|
comboTables.Items.Clear;
|
|
DBObjects := FConnection.GetDBObjects(comboDBs.Text);
|
|
for i:=0 to DBObjects.Count-1 do begin
|
|
if DBObjects[i].NodeType in [lntTable, lntView] then
|
|
comboTables.Items.Add(DBObjects[i].Name);
|
|
end;
|
|
if comboTables.Items.Count > 0 then
|
|
comboTables.ItemIndex := 0;
|
|
comboTables.OnChange(Sender);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.comboTablesChange(Sender: TObject);
|
|
var
|
|
Selected: TDBObject;
|
|
Columns: TTableColumnList;
|
|
Col: TTableColumn;
|
|
ColInfo: TColInfo;
|
|
Node: PVirtualNode;
|
|
begin
|
|
// Populate combobox with columns from selected table
|
|
ListColumns.Clear;
|
|
if comboTables.ItemIndex > -1 then begin
|
|
Selected := FConnection.FindObject(comboDBs.Text, comboTables.Text);
|
|
Columns := Selected.TableColumns;
|
|
Node := nil;
|
|
for Col in Columns do begin
|
|
ColInfo := TColInfo.Create;
|
|
ColInfo.Name := Col.Name;
|
|
ColInfo.Datatype := Col.DataType;
|
|
ColInfo.Value := '';
|
|
Node := ListColumns.InsertNode(Node, amInsertAfter, PColInfo(ColInfo));
|
|
end;
|
|
Modified;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.Modified;
|
|
begin
|
|
// Buttons need to be checked for being enabled
|
|
btnInsert.Enabled := (ListColumns.RootNodeCount > 0) and (ListFiles.RootNodeCount > 0);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.AddFile(Filename: String);
|
|
var
|
|
FileInfo: TFileInfo;
|
|
NewNode: PVirtualNode;
|
|
rx: TRegExpr;
|
|
begin
|
|
if DirectoryExists(filename) then
|
|
Exit;
|
|
FileInfo := TFileInfo.Create;
|
|
FileInfo.Filename := Filename;
|
|
//FileInfo.ImageIndex := GetSystemImageIndex(Filename);
|
|
FileInfo.Size := _GetFileSize(Filename);
|
|
rx := TRegExpr.Create;
|
|
// Decide if file is binary by excluding common text format file extensions
|
|
rx.Expression := '\.(te?xt|html?|xml|cmd|bat|sql|ini|pas|php|h|conf|log|csv|reg|latex|wiki|patch)$';
|
|
rx.ModifierI := True;
|
|
FileInfo.IsBinary := not rx.Exec(Filename);
|
|
NewNode := ListFiles.InsertNode(ListFiles.FocusedNode, amInsertAfter, PFileInfo(FileInfo));
|
|
SelectNode(ListFiles, NewNode);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.btnAddFilesClick(Sender: TObject);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
// Add file(s) to list
|
|
if OpenDialog.Execute then begin
|
|
Screen.Cursor := crHourglass;
|
|
ListFiles.BeginUpdate;
|
|
try
|
|
for i:=0 to OpenDialog.Files.Count-1 do
|
|
AddFile(OpenDialog.Files[i]);
|
|
finally
|
|
ListFiles.EndUpdate;
|
|
end;
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListFilesBeforeCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas;
|
|
Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect;
|
|
var ContentRect: TRect);
|
|
var
|
|
FileInfo: PFileInfo;
|
|
begin
|
|
// Display bar in filesize column
|
|
if Column = ColFilesize then begin
|
|
FileInfo := Sender.GetNodeData(Node);
|
|
MainForm.PaintColorBar(FileInfo.Size, FMaxFileSize, TargetCanvas, CellRect);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListFilesStructureChange(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Reason: TChangeReason);
|
|
begin
|
|
(Sender as TVirtualStringTree).OnChange(Sender, Node);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListFilesChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
|
var
|
|
FileInfo: PFileInfo;
|
|
Bytes: Int64;
|
|
Grid: TVirtualStringTree;
|
|
LNode: PVirtualNode;
|
|
Binaries: Int64;
|
|
CheckState: TCheckState;
|
|
begin
|
|
// Node focus or selection has changed
|
|
Grid := Sender as TVirtualStringTree;
|
|
btnRemoveFiles.Enabled := Grid.SelectedCount > 0;
|
|
btnClearFiles.Enabled := Grid.RootNodeCount > 0;
|
|
LNode := Grid.GetFirst;
|
|
Bytes := 0;
|
|
FMaxFileSize := 0;
|
|
Binaries := 0;
|
|
while Assigned(LNode) do begin
|
|
FileInfo := Grid.GetNodeData(LNode);
|
|
Inc(Bytes, FileInfo.Size);
|
|
FMaxFileSize := Max(FMaxFileSize, FileInfo.Size);
|
|
if FileInfo.IsBinary then
|
|
Inc(Binaries);
|
|
LNode := Grid.GetNextSibling(LNode);
|
|
end;
|
|
// Set column header checkstate
|
|
if Binaries = 0 then
|
|
CheckState := csUncheckedNormal
|
|
else if Binaries = Grid.RootNodeCount then
|
|
CheckState := csCheckedNormal
|
|
else
|
|
CheckState := csMixedNormal;
|
|
Grid.Header.Columns[ColBinary].CheckState := CheckState;
|
|
|
|
lblFileCount.Caption := f_('%u files, %s, %u files selected.', [Grid.RootNodeCount, FormatByteNumber(Bytes), Grid.SelectedCount]);
|
|
Modified;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListFilesCompareNodes(Sender: TBaseVirtualTree; Node1,
|
|
Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
|
|
begin
|
|
MainForm.AnyGridCompareNodes(Sender, Node1, Node2, Column, Result);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListFilesDblClick(Sender: TObject);
|
|
var
|
|
FileInfo: PFileInfo;
|
|
begin
|
|
// Run file on doubleclick
|
|
if Assigned(ListFiles.FocusedNode) then begin
|
|
FileInfo := ListFiles.GetNodeData(ListFiles.FocusedNode);
|
|
ShellExec(FileInfo.Filename);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListFilesFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
|
var
|
|
FileInfo: PFileInfo;
|
|
begin
|
|
// Free some memory when file gets removed
|
|
FileInfo := Sender.GetNodeData(Node);
|
|
FileInfo.Free;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.btnRemoveFilesClick(Sender: TObject);
|
|
begin
|
|
// Remove selected or all files from list
|
|
Screen.Cursor := crHourglass;
|
|
if Sender = btnRemoveFiles then
|
|
ListFiles.DeleteSelectedNodes
|
|
else
|
|
ListFiles.Clear;
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListFilesGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
|
|
var
|
|
FileInfo: PFileInfo;
|
|
Grid: TVirtualStringTree;
|
|
begin
|
|
Grid := Sender as TVirtualStringTree;
|
|
if not (Kind in [ikNormal, ikSelected]) then
|
|
Exit;
|
|
if Column <> Grid.Header.MainColumn then
|
|
Exit;
|
|
FileInfo := Sender.GetNodeData(Node);
|
|
ImageIndex := FileInfo.ImageIndex;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListFilesGetNodeDataSize(Sender: TBaseVirtualTree;
|
|
var NodeDataSize: Integer);
|
|
begin
|
|
NodeDataSize := SizeOf(TFileInfo);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListFilesGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
|
|
var
|
|
FileInfo: PFileInfo;
|
|
begin
|
|
FileInfo := Sender.GetNodeData(Node);
|
|
case Column of
|
|
ColFilename: CellText := FileInfo.Filename;
|
|
ColBinary: CellText := '';
|
|
ColFilesize: CellText := FormatByteNumber(FileInfo.Size);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListFilesHeaderClick(Sender: TVTHeader; HitInfo: TVTHeaderHitInfo);
|
|
var
|
|
Node: PVirtualNode;
|
|
FileInfo: PFileInfo;
|
|
CheckState: TCheckState;
|
|
Tree: TBaseVirtualTree;
|
|
begin
|
|
// Header column click / check
|
|
MainForm.AnyGridHeaderClick(Sender, HitInfo);
|
|
CheckState := Sender.Columns[HitInfo.Column].CheckState;
|
|
if (HitInfo.Column = ColBinary) and (not (CheckState in [csMixedNormal, csMixedPressed])) then begin
|
|
Tree := TBaseVirtualTree(Sender.Treeview);
|
|
Node := Tree.GetFirst;
|
|
while Assigned(Node) do begin
|
|
FileInfo := Tree.GetNodeData(Node);
|
|
FileInfo.IsBinary := CheckState in CheckedStates;
|
|
Node := Tree.GetNextSibling(Node);
|
|
end;
|
|
Tree.InvalidateChildren(nil, false);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.ListFilesKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
begin
|
|
// Remove focused file
|
|
if Key = VK_DELETE then
|
|
btnRemoveFiles.OnClick(btnRemoveFiles);
|
|
end;
|
|
|
|
|
|
procedure TfrmInsertFiles.btnInsertClick(Sender: TObject);
|
|
const
|
|
ChunkSize = 131072;
|
|
var
|
|
Value, sql, FileContent: String;
|
|
FileDate: TDateTime;
|
|
y, m, d, h, mi, s, ms: Word;
|
|
Node, ColNode, DoneNode: PVirtualNode;
|
|
FileInfo: PFileInfo;
|
|
ColInfo: PColInfo;
|
|
FileReadDone: Boolean;
|
|
FileSize: Int64;
|
|
begin
|
|
// Insert files
|
|
Screen.Cursor := crHourglass;
|
|
MainForm.EnableProgress(ListFiles.RootNodeCount);
|
|
|
|
Node := ListFiles.GetFirst;
|
|
while Assigned(Node) do begin
|
|
ListFiles.FocusedNode := Node;
|
|
FileInfo := ListFiles.GetNodeData(Node);
|
|
if not FileExists(FileInfo.Filename) then begin
|
|
ErrorDialog('File does not exist: '+FileInfo.Filename);
|
|
Node := ListFiles.GetNextSibling(Node);
|
|
Continue;
|
|
end;
|
|
FileSize := _GetFileSize(FileInfo.Filename);
|
|
FileReadDone := False;
|
|
sql := 'INSERT INTO '+FConnection.QuotedDbAndTableName(comboDBs.Text, comboTables.Text) + ' (';
|
|
ColNode := ListColumns.GetFirst;
|
|
while Assigned(ColNode) do begin
|
|
ColInfo := ListColumns.GetNodeData(ColNode);
|
|
if ColInfo.Value <> '' then
|
|
sql := sql + FConnection.QuoteIdent(ColInfo.Name) + ', ';
|
|
ColNode := ListColumns.GetNextSibling(ColNode);
|
|
end;
|
|
Delete(sql, Length(sql)-1, 2);
|
|
sql := sql + ') VALUES (';
|
|
|
|
ColNode := ListColumns.GetFirst;
|
|
while Assigned(ColNode) do begin
|
|
ColInfo := ListColumns.GetNodeData(ColNode);
|
|
if ColInfo.Value <> '' then begin
|
|
Value := ColInfo.Value;
|
|
if pos('%', Value) > 0 then begin
|
|
|
|
if Pos('%filecontent%', ColInfo.Value) > 0 then begin
|
|
if not FileReadDone then begin
|
|
// Import binaries as-is (byte for byte), and auto-detect encoding of text files.
|
|
if FileInfo.IsBinary then begin
|
|
FileContent := '';
|
|
if FConnection.Parameters.IsAnyMySQL then
|
|
FileContent := '_binary ';
|
|
FileContent := FileContent + '0x' + BinToWideHex(ReadBinaryFile(FileInfo.Filename, 0))
|
|
end else
|
|
FileContent := FConnection.EscapeString(ReadTextfile(FileInfo.Filename, nil));
|
|
FileReadDone := True;
|
|
end;
|
|
Value := FileContent;
|
|
end else begin
|
|
Value := StringReplace(Value, '%filesize%', IntToStr(FileSize), [rfReplaceAll]);
|
|
Value := StringReplace(Value, '%filename%', FConnection.EscapeString(ExtractFileName(FileInfo.Filename), False, False), [rfReplaceAll]);
|
|
Value := StringReplace(Value, '%filepath%', FConnection.EscapeString(ExtractFilePath(FileInfo.Filename), False, False), [rfReplaceAll]);
|
|
FileAge(FileInfo.Filename, FileDate);
|
|
DecodeDate(FileDate, y, m, d);
|
|
DecodeTime(FileDate, h, mi, s, ms);
|
|
Value := StringReplace(Value, '%filedate%', FConnection.EscapeString(Format('%.4d-%.2d-%.2d', [y,m,d]), False, False), [rfReplaceAll]);
|
|
Value := StringReplace(Value, '%filedatetime%', FConnection.EscapeString(Format('%.4d-%.2d-%.2d %.2d:%.2d:%.2d', [y,m,d,h,mi,s]), False, False), [rfReplaceAll]);
|
|
Value := StringReplace(Value, '%filetime%', FConnection.EscapeString(Format('%.2d:%.2d:%.2d', [h,mi,s]), False, False), [rfReplaceAll]);
|
|
end;
|
|
end;
|
|
sql := sql + Value + ', ';
|
|
end;
|
|
ColNode := ListColumns.GetNextSibling(ColNode);
|
|
end;
|
|
// Strip last comma + space
|
|
Delete(sql, Length(sql)-1, 2);
|
|
sql := sql + ')';
|
|
try
|
|
FConnection.Query(sql);
|
|
FConnection.ShowWarnings;
|
|
Mainform.ProgressStep;
|
|
except
|
|
on E:EDbError do begin
|
|
Screen.Cursor := crDefault;
|
|
MainForm.SetProgressState(pbsError);
|
|
ErrorDialog(E.Message);
|
|
ModalResult := mrNone;
|
|
break;
|
|
end;
|
|
end;
|
|
DoneNode := Node;
|
|
Node := ListFiles.GetNextSibling(Node);
|
|
ListFiles.DeleteNode(DoneNode);
|
|
end;
|
|
Screen.Cursor := crDefault;
|
|
MainForm.DisableProgress;
|
|
end;
|
|
|
|
|
|
{procedure TfrmInsertFiles.AcceptFiles(var msg : TMessage);
|
|
const
|
|
MaxFileNameLen = 255;
|
|
var
|
|
i, FileCount: integer;
|
|
FileName: array [0..MaxFileNameLen] of char;
|
|
begin
|
|
// Files dropped onto form
|
|
Screen.Cursor := crHourglass;
|
|
FileCount := DragQueryFile(msg.WParam, $FFFFFFFF, FileName, MaxFileNameLen);
|
|
// Query Windows one at a time for the file name
|
|
ListFiles.BeginUpdate;
|
|
try
|
|
for i:=0 to FileCount-1 do begin
|
|
DragQueryFile(msg.WParam, i, FileName, MaxFileNameLen);
|
|
AddFile(FileName);
|
|
end;
|
|
finally
|
|
ListFiles.EndUpdate;
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
DragFinish(msg.WParam);
|
|
end;}
|
|
|
|
|
|
end.
|