disqlite3_drive_catalog_form_main.pas

来自「DELPHI 访问SQLITE3 数据库的VCL控件」· PAS 代码 · 共 2,023 行 · 第 1/5 页

PAS
2,023
字号
        begin
          d := (FileData^.Size + 1023) div 1024;
          CellText := {$IFDEF COMPILER_9_UP}WideFormat{$ELSE}Tnt_WideFormat{$ENDIF}('%.0n KB', [d]);
        end;
  end;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FolderTree_InitChildren(
  Sender: TBaseVirtualTree;
  Node: PVirtualNode;
  var ChildCount: Cardinal);
var
  NodeData: PNodeData;
begin
  NodeData := FolderTree.GetNodeData(Node);
  ChildCount := FolderTree_AddFolders(Node, NodeData^.ID);
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FolderTree_NewText(
  Sender: TBaseVirtualTree;
  Node: PVirtualNode;
  Column: TColumnIndex;
  NewText: WideString);
var
  NodeData: PNodeData;
begin
  case Column of
    0:
      begin
        NodeData := FolderTree.GetNodeData(Node);
        FDb.UpdateName(NodeData^.ID, NewText);
      end;
  end;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FolderTree_RemoveSelected;
var
  Node, NewFocusedNode: PVirtualNode;
  NodeData: PNodeData;
begin
  BeginUpdate;
  try
    Node := FolderTree.GetFirstSelected;
    if Assigned(Node) then
      begin
        FDb.StartTransaction;
        try
          { Delete selected nodes from DB. }
          NewFocusedNode := FolderTree.FocusedNode;
          repeat
            NodeData := FolderTree.GetNodeData(Node);
            FDb.Delete(NodeData^.ID);
            FolderTree_UpdateNodePath(FolderTree.NodeParent[Node]);
            if NewFocusedNode = Node then
              begin
                NewFocusedNode := FolderTree.GetNextSibling(Node);
                if not Assigned(NewFocusedNode) then
                  NewFocusedNode := FolderTree.GetPreviousSibling(Node);
              end;
            Node := FolderTree.GetNextSelected(Node);
          until not Assigned(Node);
          FDb.Commit;

          { Delete selected nodes from tree, set new focus and selection. }
          FolderTree.DeleteSelectedNodes;
          if NewFocusedNode <> FolderTree.FocusedNode then
            begin
              FolderTree.Selected[NewFocusedNode] := True;
              FolderTree.FocusedNode := NewFocusedNode;
            end;
          FileTree_Purge;
          SearchResultTree_Purge;

          FDb.Invalidate;
        except
          FDb.Rollback;
          raise;
        end;
      end;
  finally
    EndUpdate;
  end;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FolderTree_Resize(Sender: TObject);
begin
  StatusBar.Panels[0].Width := FolderTree.Width;
end;

//------------------------------------------------------------------------------

function TfrmMain.FolderTree_SelectAndFocus(const ANode: PVirtualNode): Boolean;
begin
  Result := Assigned(ANode);
  if not Result then Exit;
  with FolderTree do
    begin
      Result := FocusedNode <> ANode;
      if not Result then Exit;
      ClearSelection;
      Selected[ANode] := True;
      FocusedNode := ANode;
    end;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FolderTree_FocusID(const AID: Int64);
var
  IdPath: TInt64DynArray;
  Node: PVirtualNode;
begin
  // FolderTree.BeginUpdate; // Bug in VT: Endupdate does not refresh tree properly.
  try
    IdPath := FDb.GetIdPath(AID);

    while Assigned(IdPath) do
      begin
        Node := FolderTree_GetNodeFromPath(IdPath);
        if Assigned(Node) then
          begin
            FolderTree_SelectAndFocus(Node);
            FolderTree.ScrollIntoView(Node, False);
            Break;
          end;
        SetLength(IdPath, Length(IdPath) - 1);
      end;
  finally
    // FolderTree.EndUpdate; // Bug in VT: Endupdate does not refresh tree properly
  end;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FolderTree_UpdateIdPath(const AFolderID: Int64);
begin
  FolderTree_UpdateNodePath(FolderTree_GetNodeFromID(AFolderID));
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FolderTree_UpdateNodePath(Node: PVirtualNode);
var
  NodeData: PNodeData;
begin
  if Assigned(Node) then
    repeat
      NodeData := FolderTree.GetNodeData(Node);
      FDb.Invalidate(NodeData^.ID);
      Node := FolderTree.NodeParent[Node];
    until not Assigned(Node);
end;

//------------------------------------------------------------------------------
// FileTree related
//------------------------------------------------------------------------------

procedure TfrmMain.FileTree_Change(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
  UpdateStatusBar;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FileTree_CompareNodes(
  Sender: TBaseVirtualTree;
  Node1, Node2: PVirtualNode;
  Column: TColumnIndex;
  var Result: Integer);
var
  NodeData1, NodeData2: PNodeData;
  FileData1, FileData2: PFileData;
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: // Size:
      if FileData1^.Size > FileData2^.Size then
        Result := 1
      else
        if FileData1^.Size < FileData2^.Size then
          Result := -1
        else
          Result := 0;
    2: // Time
      if FileData1^.Time > FileData2^.Time then
        Result := 1
      else
        if FileData1^.Time < FileData2^.Time then
          Result := -1
        else
          Result := 0;
    3: // 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.FileTree_DblClick(Sender: TObject);
var
  CP: TPoint;
  HitInfo: THitInfo;
begin
  if GetCursorPos(CP) then
    begin
      CP := FileTree.ScreenToClient(CP);
      FileTree.GetHitTestInfoAt(CP.x, CP.y, True, HitInfo);
      FileTree_NodeAction(HitInfo.HitNode);
    end;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FileTree_Edited(
  Sender: TBaseVirtualTree;
  Node: PVirtualNode;
  Column: TColumnIndex);
begin
  case Column of
    0: // Name
      with FileTree do
        if Column = Header.SortColumn then
          begin
            FileTree_Sort;
          end;
  end;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FileTree_Editing(
  Sender: TBaseVirtualTree;
  Node: PVirtualNode;
  Column: TColumnIndex;
  var Allowed: Boolean);
begin
  Allowed := Column = 0;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FileTree_FocusID(const AID: Int64);
var
  Node: PVirtualNode;
begin
  Node := FileTree_GetNodeFromID(AID);
  if Assigned(Node) then
    begin
      FileTree.ClearSelection;
      FileTree.Selected[Node] := True;
      FileTree.FocusedNode := Node;
      FileTree.ScrollIntoView(Node, False);
    end;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FileTree_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 = FileTree.Header.MainColumn then
        begin
          NodeData := Sender.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;

//------------------------------------------------------------------------------

function TfrmMain.FileTree_GetNodeFromID(const AID: Int64): PVirtualNode;
var
  NodeData: PNodeData;
begin
  Result := FileTree.GetFirst;
  while Assigned(Result) do
    begin
      NodeData := FileTree.GetNodeData(Result);
      if NodeData^.ID = AID then
        Break;
      Result := FileTree.GetNext(Result);
    end;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FileTree_GetText(
  Sender: TBaseVirtualTree;
  Node: PVirtualNode;
  Column: TColumnIndex;
  TextType: TVSTTextType;
  var CellText: WideString);
var
  NodeData: PNodeData;
  FileData: PFileData;
  d: Double;
begin
  NodeData := FileTree.GetNodeData(Node);
  FileData := FDb.GetFileData(NodeData^.ID);
  case Column of
    0: // Name
      begin
        CellText := FileData^.Name;
      end;
    1: // Size
      begin
        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;
      end;
    2: // Time
      begin
        CellText := JulianDateToDateTimeString(FileData^.Time);
      end;
    3: // Attributes
      begin
        CellText := FileAttributesToString(FileData^.Attri);
      end;
  end;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FileTree_HeaderClick(
  Sender: TVTHeader;
  Column: TColumnIndex;
  Button: TMouseButton;
  Shift: TShiftState;
  x, y: Integer);
begin
  if Button = mbLeft then
    with FileTree, Header do
      begin
        if Column = SortColumn then
          if SortDirection = sdAscending then
            SortDirection := sdDescending
          else
            SortDirection := sdAscending
        else
          begin
            SortDirection := sdAscending;
            SortColumn := Column;
          end;
        FileTree_Sort;
      end;
end;

//------------------------------------------------------------------------------

procedure TfrmMain.FileTree_KeyDown(
  Sender: TObject;
  var Key: Word;
  Shift: TShiftState);
var
  n: PVirtualNode;
  NodeData: PNodeData;
begin
  case Key of
    VK_BACK:
      begin
        NodeData := FolderTree.GetNodeData(FolderTree.FocusedNode);
        n := FolderTree.NodeParent[FolderTree.FocusedNode];
        if FolderTree_SelectAndFocus(n) and Assigned(NodeData) then
          FileTree_FocusID(NodeData^.ID);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?