瀏覽代碼

Bug 1685: Natural order numerical sorting for directory tree

https://winscp.net/tracker/1685

Source commit: 8e271542f57adf405ef86580b16ff15ff2c5aba8
Martin Prikryl 7 年之前
父節點
當前提交
686ac7882f

+ 1 - 0
source/forms/CustomScpExplorer.cpp

@@ -1000,6 +1000,7 @@ void __fastcall TCustomScpExplorerForm::ConfigurationChanged()
   RemoteDriveView->DimmHiddenDirs = WinConfiguration->DimmHiddenFiles;
   RemoteDriveView->ShowHiddenDirs = WinConfiguration->ShowHiddenFiles;
   RemoteDriveView->ShowInaccesibleDirectories = WinConfiguration->ShowInaccesibleDirectories;
+  RemoteDriveView->NaturalOrderNumericalSorting = WinConfiguration->NaturalOrderNumericalSorting;
 
   UpdateSessionsPageControlHeight();
 

+ 1 - 0
source/forms/ScpCommander.cpp

@@ -573,6 +573,7 @@ void __fastcall TScpCommanderForm::ConfigurationChanged()
   RemoteDirView->NortonLike = WinConfiguration->ScpCommander.NortonLikeMode;
 
   LocalDirView->NaturalOrderNumericalSorting = WinConfiguration->NaturalOrderNumericalSorting;
+  LocalDriveView->NaturalOrderNumericalSorting = WinConfiguration->NaturalOrderNumericalSorting;
 
   if (LocalDirView->RowSelect != WinConfiguration->FullRowSelect)
   {

+ 12 - 0
source/packages/filemng/CustomDirView.pas

@@ -511,6 +511,8 @@ function GetNextMask(var Mask: string): string;
 
 procedure DefaultFileFilter(var Filter: TFileFilter);
 
+function CompareLogicalTextPas(const S1, S2: string; NaturalOrderNumericalSorting: Boolean): Integer;
+
 function OverlayImageList(Size: Integer): TImageList;
 
 var
@@ -620,6 +622,16 @@ begin
   end;
 end;
 
+function StrCmpLogicalW(const sz1, sz2: UnicodeString): Integer; stdcall; external 'shlwapi.dll';
+
+function CompareLogicalTextPas(const S1, S2: string; NaturalOrderNumericalSorting: Boolean): Integer;
+begin
+  if NaturalOrderNumericalSorting then
+    Result := StrCmpLogicalW(PChar(S1), PChar(S2))
+  else
+    Result := lstrcmpi(PChar(S1), PChar(S2));
+end;
+
 { Shortcut-handling }
 
 function ResolveFileShortCut(SourceFile: string; ShowDialog: Boolean = False): string;

+ 21 - 18
source/packages/filemng/CustomDriveView.pas

@@ -38,6 +38,7 @@ type
     FUseSystemContextMenu: Boolean;
     FDimmHiddenDirs: Boolean;
     FShowHiddenDirs: Boolean;
+    FNaturalOrderNumericalSorting: Boolean;
     FContinue: Boolean;
     FImageList: TImageList;
     FScrollOnDragOver: TTreeViewScrollOnDragOver;
@@ -66,6 +67,7 @@ type
     procedure SetTargetPopUpMenu(Value: Boolean);
     procedure SetDimmHiddenDirs(Value: Boolean);
     procedure SetShowHiddenDirs(Value: Boolean);
+    procedure SetNaturalOrderNumericalSorting(Value: Boolean);
 
     function GetDirectory: string; virtual;
     procedure SetDirectory(Value: string); virtual;
@@ -80,6 +82,7 @@ type
     function CustomDrawItem(Node: TTreeNode; State: TCustomDrawState;
       Stage: TCustomDrawStage; var PaintImages: Boolean): Boolean; override;
     procedure NeedImageLists(Recreate: Boolean);
+    procedure DoCompare(Sender: TObject; Node1, Node2: TTreeNode; Data: Integer; var Compare: Integer);
 
     procedure CNNotify(var Msg: TWMNotify); message CN_NOTIFY;
     procedure CMColorChanged(var Msg: TMessage); message CM_COLORCHANGED;
@@ -174,6 +177,7 @@ type
       write SetDimmHiddenDirs default False;
     property ShowHiddenDirs: Boolean read FShowHiddenDirs
       write SetShowHiddenDirs default False;
+    property NaturalOrderNumericalSorting: Boolean read FNaturalOrderNumericalSorting write SetNaturalOrderNumericalSorting;
 
     property DDLinkOnExeDrag: Boolean read FDDLinkOnExeDrag write FDDLinkOnExeDrag default True;
 
@@ -245,6 +249,8 @@ begin
   FCanChange := True;
   FUseSystemContextMenu := True;
   FContinue := True;
+  FNaturalOrderNumericalSorting := True;
+  OnCompare := DoCompare;
 
   FDragDropFilesEx := TCustomizableDragDropFilesEx.Create(Self);
   with FDragDropFilesEx do
@@ -1099,26 +1105,14 @@ begin
   end;
 end; {CenterNode}
 
+procedure TCustomDriveView.DoCompare(Sender: TObject; Node1, Node2: TTreeNode; Data: Integer; var Compare: Integer);
+begin
+  Compare := CompareLogicalTextPas(Node1.Text, Node2.Text, NaturalOrderNumericalSorting);
+end;
+
 function TCustomDriveView.SortChildren(ParentNode: TTreeNode; Recurse: Boolean): Boolean;
-var
-  Node: TTreeNode;
 begin
-  Result := False;
-  if Assigned(ParentNode) and
-     TreeView_SortChildren(Self.Handle, ParentNode.ItemID, LongBool(0)) then
-  begin
-    Result := True;
-    if Recurse then
-    begin
-      Node := ParentNode.GetFirstChild;
-      while Assigned(Node) do
-      begin
-        if Node.HasChildren then
-          SortChildren(Node, Recurse);
-        Node := ParentNode.GetNextChild(Node);
-      end;
-    end;
-  end;
+  Result := Assigned(ParentNode) and ParentNode.AlphaSort(Recurse);
 end; {SortChildren}
 
 function TCustomDriveView.IterateSubTree(var StartNode : TTreeNode;
@@ -1220,6 +1214,15 @@ begin
   end;
 end; {SetDimmHiddenDirs}
 
+procedure TCustomDriveView.SetNaturalOrderNumericalSorting(Value: Boolean);
+begin
+  if NaturalOrderNumericalSorting <> Value then
+  begin
+    FNaturalOrderNumericalSorting := Value;
+    AlphaSort;
+  end;
+end;
+
 function TCustomDriveView.GetTargetPopupMenu: Boolean;
 begin
   if Assigned(FDragDropFilesEx) then Result := FDragDropFilesEx.TargetPopupMenu

+ 3 - 13
source/packages/filemng/DirView.pas

@@ -1946,16 +1946,6 @@ begin
   Result := ExtractFileExt(PFileRec(Item.Data)^.FileName);
 end; {ItemFileExt}
 
-function StrCmpLogicalW(const sz1, sz2: UnicodeString): Integer; stdcall; external 'shlwapi.dll';
-
-function CompareLogicalText(const S1, S2: string; NaturalOrderNumericalSorting: Boolean): Integer;
-begin
-  if NaturalOrderNumericalSorting then
-    Result := StrCmpLogicalW(PChar(S1), PChar(S2))
-  else
-    Result := lstrcmpi(PChar(S1), PChar(S2));
-end;
-
 function CompareFileType(I1, I2: TListItem; P1, P2: PFileRec): Integer;
 var
   Key1, Key2: string;
@@ -1972,7 +1962,7 @@ begin
     Key1 := P1.TypeName + ' ' + P1.FileExt + ' ' + P1.DisplayName;
     Key2 := P2.TypeName + ' ' + P2.FileExt + ' ' + P2.DisplayName;
   end;
-  Result := CompareLogicalText(Key1, Key2, TDirView(I1.ListView).NaturalOrderNumericalSorting);
+  Result := CompareLogicalTextPas(Key1, Key2, TDirView(I1.ListView).NaturalOrderNumericalSorting);
 end;
 
 function CompareFileTime(P1, P2: PFileRec): Integer;
@@ -2057,7 +2047,7 @@ begin
         dvExt:
           if not P1.isDirectory then
           begin
-            Result := CompareLogicalText(
+            Result := CompareLogicalTextPas(
               P1.FileExt + ' ' + P1.DisplayName, P2.FileExt + ' ' + P2.DisplayName,
               AOwner.NaturalOrderNumericalSorting);
           end
@@ -2069,7 +2059,7 @@ begin
 
       if Result = fEqual then
       begin
-        Result := CompareLogicalText(P1.DisplayName, P2.DisplayName, AOwner.NaturalOrderNumericalSorting)
+        Result := CompareLogicalTextPas(P1.DisplayName, P2.DisplayName, AOwner.NaturalOrderNumericalSorting)
       end;
     end;
   end;