disqlite3_drive_catalog_form_main.pas
来自「DELPHI 访问SQLITE3 数据库的VCL控件」· PAS 代码 · 共 2,023 行 · 第 1/5 页
PAS
2,023 行
end;
VK_RETURN:
FileTree_NodeAction(FileTree.FocusedNode);
end;
end;
//------------------------------------------------------------------------------
procedure TfrmMain.FileTree_NewText(
Sender: TBaseVirtualTree;
Node: PVirtualNode;
Column: TColumnIndex;
NewText: WideString);
var
NodeData: PNodeData;
begin
case Column of
0:
begin
NodeData := FileTree.GetNodeData(Node);
FDb.UpdateName(NodeData^.ID, NewText);
end;
end;
end;
//------------------------------------------------------------------------------
procedure TfrmMain.FileTree_NodeAction(const ANode: PVirtualNode);
var
NodeData: PNodeData;
FileData: PFileData;
begin
if Assigned(ANode) then
begin
NodeData := FileTree.GetNodeData(ANode);
FileData := FDb.GetFileData(NodeData^.ID);
if FileData^.Attri and FILE_ATTRIBUTE_DIRECTORY <> 0 then
FolderTree_FocusID(NodeData^.ID);
end;
end;
//------------------------------------------------------------------------------
procedure TfrmMain.FileTree_Purge;
var
Node, NextNode, NewFocusedNode: PVirtualNode;
NodeData: PNodeData;
Stmt: TDISQLite3Statement;
begin
FileTree.BeginUpdate;
try
Node := FileTree.GetFirst;
if Assigned(Node) then
begin
Stmt := FDb.Prepare('SELECT "ID" FROM "Files" WHERE "ID"=?;');
try
NewFocusedNode := FileTree.FocusedNode;
repeat
NodeData := FileTree.GetNodeData(Node);
Stmt.bind_Int64(1, NodeData^.ID);
if not Stmt.Step = SQLITE_ROW then
begin
{ If node is not in the DB anymore, find a new focused node
and delete the node. }
if NewFocusedNode = Node then
begin
NewFocusedNode := FileTree.GetNextSibling(Node);
if not Assigned(NewFocusedNode) then
NewFocusedNode := FileTree.GetPreviousSibling(Node);
end;
NextNode := FileTree.GetNextSibling(Node);
FileTree.DeleteNode(Node);
Node := NextNode;
end
else
Node := FileTree.GetNextSibling(Node);
Stmt.Reset;
until not Assigned(Node);
if NewFocusedNode <> FileTree.FocusedNode then
begin
FileTree.ClearSelection;
FileTree.Selected[NewFocusedNode] := True;
FileTree.FocusedNode := NewFocusedNode;
end;
finally
Stmt.Free;
end;
end;
finally
FileTree.EndUpdate;
end;
end;
//------------------------------------------------------------------------------
procedure TfrmMain.FileTree_RemoveSelected;
var
Node, NewFocusedNode: PVirtualNode;
NodeData: PNodeData;
begin
BeginUpdate;
try
Node := FileTree.GetFirstSelected;
if Assigned(Node) then
begin
FDb.StartTransaction;
try
{ Delete selected nodes from DB. }
NewFocusedNode := FileTree.FocusedNode;
repeat
NodeData := FileTree.GetNodeData(Node);
FDb.Delete(NodeData^.ID);
if NewFocusedNode = Node then
begin
NewFocusedNode := FileTree.GetNextSibling(Node);
if not Assigned(NewFocusedNode) then
NewFocusedNode := FileTree.GetPreviousSibling(Node);
end;
Node := FileTree.GetNextSelected(Node);
until not Assigned(Node);
FDb.Commit;
{ Delete selected nodes from tree, set new focus and selection. }
FileTree.DeleteSelectedNodes;
if NewFocusedNode <> FileTree.FocusedNode then
begin
FileTree.Selected[NewFocusedNode] := True;
FileTree.FocusedNode := NewFocusedNode;
end;
FolderTree_UpdateNodePath(FolderTree.FocusedNode);
SearchResultTree_Purge;
FDb.Invalidate;
except
FDb.Rollback;
raise;
end;
end;
finally
EndUpdate;
end;
end;
//------------------------------------------------------------------------------
function TfrmMain.FileTree_ShowFiles(const AParentID: Int64): Cardinal;
var
Node: PVirtualNode;
NodeData: PNodeData;
Stmt: TDISQLite3Statement;
SQL: AnsiString;
begin
Result := 0;
FileTree.BeginUpdate;
try
FFileTreeParentID := AParentID;
FileTree.Clear;
{ Construct the SQL statement according to the current sorting. }
// SQL := 'SELECT "ID" FROM "Files" WHERE "Parent"=? AND "Type" IN (0,1) ORDER BY ';
SQL := 'SELECT "ID" FROM "Files" WHERE "Parent"=? AND ("Type"=0 OR "Type"=1) ORDER BY ';
case FileTree.Header.SortColumn of
1:
if FileTree.Header.SortDirection = sdAscending then
SQL := SQL + '"Size";'
else
SQL := SQL + '"Size" DESC;';
2:
if FileTree.Header.SortDirection = sdAscending then
SQL := SQL + '"Time";'
else
SQL := SQL + '"Time" DESC;';
3:
if FileTree.Header.SortDirection = sdAscending then
SQL := SQL + '"Attr";'
else
SQL := SQL + '"Attr" DESC;'
else
if FileTree.Header.SortDirection = sdAscending then
SQL := SQL + '"Type" DESC, "Name" COLLATE NOCASE;'
else
SQL := SQL + '"Type", "Name" COLLATE NOCASE DESC;'
end;
Stmt := FDb.Prepare(SQL);
try
Stmt.bind_Int64(1, AParentID);
while Stmt.Step = SQLITE_ROW do
begin
Node := FileTree.AddChild(nil);
NodeData := FileTree.GetNodeData(Node);
NodeData^.ID := Stmt.column_int64(0);
Inc(Result);
end;
finally
Stmt.Free;
end;
FileTree.FocusedNode := FileTree.GetFirst;
finally
FileTree.EndUpdate;
end;
end;
//------------------------------------------------------------------------------
procedure TfrmMain.FileTree_Sort;
var
Node: PVirtualNode;
NodeData: PNodeData;
NodeID: Int64;
begin
{ For a great many files, reloading the tree is actually faster than
sorting it in memory. This is because the sorting routine will
eventually touch all files and cause their full details to be loaded. }
if FileTree.VisibleCount > 512 then
begin
Node := FileTree.FocusedNode;
if Assigned(Node) then
begin
NodeData := FileTree.GetNodeData(Node);
NodeID := NodeData^.ID;
end
else
NodeID := -1;
FileTree_ShowFiles(FFileTreeParentID);
if NodeID >= 0 then
FileTree_FocusID(NodeID);
end
else
with FileTree, Header do
begin
Sort(nil, SortColumn, SortDirection);
ScrollIntoView(FocusedNode, False);
end;
end;
//------------------------------------------------------------------------------
// SearchResultTree
//------------------------------------------------------------------------------
procedure TfrmMain.SearchResultTree_Change(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
UpdateStatusBar;
end;
//------------------------------------------------------------------------------
procedure TfrmMain.SearchResultTree_CompareNodes(
Sender: TBaseVirtualTree;
Node1, Node2: PVirtualNode;
Column: TColumnIndex;
var Result: Integer);
var
NodeData1, NodeData2: PNodeData;
FileData1, FileData2: PFileData;
v, p, vp1, vp2: WideString;
begin
NodeData1 := FileTree.GetNodeData(Node1);
FileData1 := FDb.GetFileData(NodeData1^.ID);
NodeData2 := FileTree.GetNodeData(Node2);
FileData2 := FDb.GetFileData(NodeData2^.ID);
case Column of
0: // Name
begin
Result := (FileData2^.Attri and FILE_ATTRIBUTE_DIRECTORY) - (FileData1^.Attri and FILE_ATTRIBUTE_DIRECTORY);
if Result = 0 then
Result := WideCompareText(FileData1^.Name, FileData2^.Name);
end;
1:
begin
FDb.GetVolumeFullPath(FileData1^.Parent, v, p);
vp1 := v + p;
FDb.GetVolumeFullPath(FileData2^.Parent, v, p);
vp2 := v + p;
Result := WideCompareText(vp1, vp2);
end;
2: // Size:
if FileData1^.Size > FileData2^.Size then
Result := 1
else
if FileData1^.Size < FileData2^.Size then
Result := -1
else
Result := 0;
3: // Time
if FileData1^.Time > FileData2^.Time then
Result := 1
else
if FileData1^.Time < FileData2^.Time then
Result := -1
else
Result := 0;
4: // Attributes
if FileData1^.Attri > FileData2^.Attri then
Result := 1
else
if FileData1^.Attri < FileData2^.Attri then
Result := -1
else
Result := 0;
end;
end;
//------------------------------------------------------------------------------
procedure TfrmMain.SearchResultTree_DblClick(Sender: TObject);
var
CP: TPoint;
HitInfo: THitInfo;
begin
if GetCursorPos(CP) then
begin
CP := SearchResultTree.ScreenToClient(CP);
SearchResultTree.GetHitTestInfoAt(CP.x, CP.y, True, HitInfo);
SearchResultTree_NodeAction(HitInfo.HitNode);
end;
end;
//------------------------------------------------------------------------------
procedure TfrmMain.SearchResultTree_GetImageIndex(
Sender: TBaseVirtualTree;
Node: PVirtualNode;
Kind: TVTImageKind;
Column: TColumnIndex;
var Ghosted: Boolean;
var ImageIndex: Integer);
var
NodeData: PNodeData;
FileData: PFileData;
begin
case Kind of
ikNormal, ikSelected:
if Column = SearchResultTree.Header.MainColumn then
begin
NodeData := SearchResultTree.GetNodeData(Node);
FileData := FDb.GetFileData(NodeData^.ID);
if FileData^.Attri and FILE_ATTRIBUTE_DIRECTORY <> 0 then
ImageIndex := FNormalFolderIconIndex
else
ImageIndex := FileData^.IconIdx;
if FileData^.Attri and FILE_ATTRIBUTE_HIDDEN <> 0 then
Ghosted := True;
end;
end;
end;
//------------------------------------------------------------------------------
procedure TfrmMain.SearchResultTree_GetText(
Sender: TBaseVirtualTree;
Node: PVirtualNode;
Column: TColumnIndex;
TextType: TVSTTextType;
var CellText: WideString);
var
NodeData: PNodeData;
FileData: PFileData;
Volume, FullPath: WideString;
d: Double;
begin
NodeData := SearchResultTree.GetNodeData(Node);
FileData := FDb.GetFileData(NodeData^.ID);
case Column of
0: // Name
begin
CellText := FileData^.Name;
end;
1: // Path
begin
if FDb.GetVolumeFullPath(FileData^.Parent, Volume, FullPath) then
CellText := Volume + ' - ' + FullPath; ;
end;
2: // Size
if FileData^.Size >= 0 then
begin
d := (FileData^.Size + 1023) div 1024;
CellText := {$IFDEF COMPILER_9_UP}WideFormat{$ELSE}Tnt_WideFormat{$ENDIF}('%.0n KB', [d]);
end;
3: // Time
begin
CellText := JulianDateToDateTimeString(FileData^.Time);
end;
4: // Attributes
begin
CellText := FileAttributesToString(FileData^.Attri);
end;
end;
end;
//------------------------------------------------------------------------------
procedure TfrmMain.SearchResultTree_HeaderClick(
Sender: TVTHeader;
Column: TColumnIndex;
Button: TMouseButton;
Shift: TShiftState;
x, y: Integer);
begin
if Button = mbLeft then
with SearchResultTree, Header do
begin
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?