Procházet zdrojové kódy

* Improve file selection dialog, patch by unxed. Fixes issue #41404

Michaël Van Canneyt před 17 hodinami
rodič
revize
51fe99c752
2 změnil soubory, kde provedl 118 přidání a 40 odebrání
  1. 90 21
      packages/fv/src/stddlg.inc
  2. 28 19
      packages/fv/src/views.inc

+ 90 - 21
packages/fv/src/stddlg.inc

@@ -186,6 +186,7 @@ type
     procedure GetData(var Rec); virtual;
     function GetText(Item,MaxLen: Sw_Integer): Sw_String; virtual;
     function GetKey(var S: Sw_String): Pointer; virtual;
+    function GetItemColor(Item: Sw_Integer; IsFocused, IsSelectedInner: Boolean): Word; virtual;
     procedure HandleEvent(var Event: TEvent); virtual;
     procedure ReadDirectory(AWildCard: PathStr);
     procedure SetData(var Rec); virtual;
@@ -860,12 +861,12 @@ end;
 function TFileCollection.Compare(Key1, Key2: Pointer): Sw_Integer;
 begin
   if PSearchRec(Key1)^.Name = PSearchRec(Key2)^.Name then Compare := 0
-  else if PSearchRec(Key1)^.Name = '..' then Compare := 1
-  else if PSearchRec(Key2)^.Name = '..' then Compare := -1
+  else if PSearchRec(Key1)^.Name = '..' then Compare := -1
+  else if PSearchRec(Key2)^.Name = '..' then Compare := 1
   else if (PSearchRec(Key1)^.Attr and Directory <> 0) and
-     (PSearchRec(Key2)^.Attr and Directory = 0) then Compare := 1
+     (PSearchRec(Key2)^.Attr and Directory = 0) then Compare := -1
   else if (PSearchRec(Key2)^.Attr and Directory <> 0) and
-     (PSearchRec(Key1)^.Attr and Directory = 0) then Compare := -1
+     (PSearchRec(Key1)^.Attr and Directory = 0) then Compare := 1
   else if UpperName(PSearchRec(Key1)^.Name) > UpperName(PSearchRec(Key2)^.Name) then
     Compare := 1
 {$ifdef unix}
@@ -1070,8 +1071,8 @@ begin
   S := SR^.Name;
   if SR^.Attr and Directory <> 0 then
   begin
-    S[Length(S)+1] := DirSeparator;
-    Inc(S[0]);
+    //S[Length(S)+1] := DirSeparator;
+    //Inc(S[0]);
   end;
   GetText := S;
 end;
@@ -1226,6 +1227,25 @@ begin
     Self.ReadDirectory(Directory Sw_PString_DeRef + WildCard);
 end;
 
+function TFileList.GetItemColor(Item: Sw_Integer; IsFocused, IsSelectedInner: Boolean): Word;
+var
+  SR: PSearchRec;
+begin
+  if (List <> nil) and (Item < List^.Count) then
+  begin
+    SR := PSearchRec(List^.At(Item));
+    if (SR^.Attr and Directory <> 0) then
+    begin
+      if IsSelectedInner then
+        Result := GetColor(3)
+      else 
+        Result := GetColor(6);
+      Exit;
+    end;
+  end;
+  Result := inherited GetItemColor(Item, IsFocused, IsSelectedInner);
+end;
+
 {****************************************************************************}
 { TFileInfoPane Object                        }
 {****************************************************************************}
@@ -1594,30 +1614,31 @@ begin
   Options := Options or ofCentered;
   WildCard := AWildCard;
 
-  R.Assign(3,3,31,4);
+  R.Assign(4,11,34,12);
+  Control := New(PScrollBar, Init(R));
+  Insert(Control);
+  R.Assign(4,3,34,11);
+  FileList := New(PFileList, Init(R, PScrollBar(Control)));
+  FileList^.GrowMode:=gfGrowHiX or gfGrowHiY;
+  Insert(FileList);
+  R.Assign(3,2,8,3);
+  Control := New(PLabel, Init(R, slFiles, FileList));
+  Insert(Control);
+
+  R.Assign(3,23,31,24);
   FileName := New(PFileInputLine, Init(R, 79));
   FileName^.GrowMode:=gfGrowHiX;
   FileName^.Data Sw_PString_DeRef := WildCard;
   Insert(FileName);
-  R.Assign(2,2,3+CStrLen(InputName),3);
+
+  R.Assign(2,22,3+CStrLen(InputName),23);
   Control := New(PLabel, Init(R, InputName, FileName));
   Insert(Control);
-  R.Assign(31,3,34,4);
+  R.Assign(31,23,34,24);
   FileHistory := New(PFileHistory, Init(R, FileName, HistoryId));
   FileHistory^.GrowMode:=gfGrowHiX or gfGrowLoX;
   Insert(FileHistory);
 
-  R.Assign(3,14,34,15);
-  Control := New(PScrollBar, Init(R));
-  Insert(Control);
-  R.Assign(3,6,34,14);
-  FileList := New(PFileList, Init(R, PScrollBar(Control)));
-  FileList^.GrowMode:=gfGrowHiX or gfGrowHiY;
-  Insert(FileList);
-  R.Assign(2,5,8,6);
-  Control := New(PLabel, Init(R, slFiles, FileList));
-  Insert(Control);
-
   R.Assign(35,3,46,5);
   Opt := bfDefault;
   if AOptions and fdOpenButton <> 0 then
@@ -1802,7 +1823,7 @@ begin
   if (Sw_String(Rec) <> '') and (IsWild(TWildStr(Sw_String(Rec)))) then
   begin
     Valid(cmFileInit);
-    FileName^.Select;
+    FileList^.Select;
   end;
 end;
 
@@ -1834,6 +1855,10 @@ var
   Dir: DirStr;
   Name: NameStr;
   Ext: ExtStr;
+  OldDirName: NameStr;
+  OldDir, OldName, OldExt: DirStr;
+  i: Integer;
+  P: PSearchRec;
 
   function CheckDirectory(var S: PathStr): Boolean;
   begin
@@ -1899,6 +1924,14 @@ begin
         if CheckDirectory(Dir) then
         begin
           FileHistory^.AdaptHistoryToDir(Dir);
+
+          OldDirName := '';
+          if (Directory <> Sw_PString_Empty) then
+          begin
+            FSplit(Copy(Directory Sw_PString_DeRef, 1, Length(Directory Sw_PString_DeRef) - 1), OldDir, OldName, OldExt);
+            OldDirName := OldName + OldExt;
+          end;
+
 {$ifdef FV_UNICODE}
           Directory:=Sw_PString_Empty;
           Directory:=Dir;
@@ -1913,6 +1946,19 @@ begin
           if Command <> cmFileInit then
             FileList^.Select;
           FileList^.ReadDirectory(Directory Sw_PString_DeRef+WildCard);
+
+          if OldDirName <> '' then
+          begin
+            for i := 0 to FileList^.List^.Count - 1 do
+            begin
+              P := PSearchRec(FileList^.List^.At(i));
+              if P^.Name = OldDirName then
+              begin
+                FileList^.FocusItem(i);
+                break;
+              end;
+            end;
+          end;
         end;
       end
     else
@@ -1921,6 +1967,14 @@ begin
         it's just there, 'coz I don't want to rearrange the following "if"s... }
       if IsDir(FName) then
         begin
+
+          OldDirName := '';
+          if (Directory <> Sw_PString_Empty) then
+          begin
+            FSplit(Copy(Directory Sw_PString_DeRef, 1, Length(Directory Sw_PString_DeRef) - 1), OldDir, OldName, OldExt);
+            OldDirName := OldName + OldExt;
+          end;
+
           if CheckDirectory(FName) then
           begin
             FileHistory^.AdaptHistoryToDir(CompleteDir(FName));
@@ -1932,8 +1986,23 @@ begin
             DisposeStr(Directory);
             Directory := NewSTr(CompleteDir(FName));
 {$endif}
+
             if Command <> cmFileInit then FileList^.Select;
             FileList^.ReadDirectory(Directory Sw_PString_DeRef+WildCard);
+
+            if OldDirName <> '' then
+            begin
+              for i := 0 to FileList^.List^.Count - 1 do
+              begin
+                P := PSearchRec(FileList^.List^.At(i));
+                if P^.Name = OldDirName then
+                begin
+                  FileList^.FocusItem(i);
+                  break;
+                end;
+              end;
+            end;
+
           end
         end
       else

+ 28 - 19
packages/fv/src/views.inc

@@ -210,7 +210,7 @@ CONST
    CFrame      = #1#1#2#2#3;                          { Frame palette }
    CScrollBar  = #4#5#5;                              { Scrollbar palette }
    CScroller   = #6#7;                                { Scroller palette }
-   CListViewer = #26#26#27#28#29;                     { Listviewer palette }
+   CListViewer = #26#26#27#28#29#31;                  { Listviewer palette }
 
    CBlueWindow = #8#9#10#11#12#13#14#15;              { Blue window palette }
    CCyanWindow = #16#17#18#19#20#21#22#23;            { Cyan window palette }
@@ -647,6 +647,7 @@ TYPE
       FUNCTION GetPalette: PPalette; Virtual;
       FUNCTION IsSelected (Item: Sw_Integer): Boolean; Virtual;
       FUNCTION GetText (Item: Sw_Integer; MaxLen: Sw_Integer): Sw_String; Virtual;
+      FUNCTION GetItemColor(Item: Sw_Integer; IsFocused, IsSelectedInner: Boolean): Word; virtual;
       PROCEDURE Draw; Virtual;
       PROCEDURE FocusItem (Item: Sw_Integer); Virtual;
       PROCEDURE SetTopItem (Item: Sw_Integer);
@@ -3621,6 +3622,16 @@ BEGIN
    S.Read(w, SizeOf(w)); Range:=w;                    { Read listview range }
 END;
 
+FUNCTION TListViewer.GetItemColor(Item: Sw_Integer; IsFocused, IsSelectedInner: Boolean): Word;
+begin
+  if (State AND (sfSelected + sfActive) = (sfSelected + sfActive)) AND IsFocused AND (Range > 0) then
+    Result := GetColor(3)
+  else if (Item < Range) AND IsSelectedInner then
+    Result := GetColor(4)
+  else
+    Result := GetColor(2); // Normal
+end;
+
 {--TListViewer--------------------------------------------------------------}
 {  GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB        }
 {---------------------------------------------------------------------------}
@@ -3663,20 +3674,18 @@ BEGIN
      For J := 0 To NumCols-1 Do Begin                 { For each column }
        Item := J*Size.Y + I + TopItem;                { Process this item }
        CurCol := J*ColWidth;                          { Current column }
-       If (State AND (sfSelected + sfActive) =
-       (sfSelected + sfActive)) AND (Focused = Item)  { Focused item }
-       AND (Range > 0) Then Begin
-         Color := GetColor(3);                        { Focused colour }
-         SetCursor(CurCol+1,I);                       { Set the cursor }
-         SCOff := 0;                                  { Zero colour offset }
-       End Else If (Item < Range) AND IsSelected(Item){ Selected item }
-       Then Begin
-         Color := GetColor(4);                        { Selected color }
-         SCOff := 2;                                  { Colour offset=2 }
-       End Else Begin
-         Color := GetColor(2);                        { Normal Color }
-         SCOff := 4;                                  { Colour offset=4 }
-       End;
+
+       Color := GetItemColor(Item, (Focused = Item), IsSelected(Item));
+       If (State AND (sfSelected + sfActive) = (sfSelected + sfActive)) AND (Focused = Item) AND (Range > 0) Then
+       begin
+         SetCursor(CurCol+1,I);
+         SCOff := 0;
+       end
+       else if (Item < Range) AND IsSelected(Item) then
+         SCOff := 2
+       else
+         SCOff := 4;
+
       MoveChar(B[CurCol], ' ', Color, ColWidth);      { Clear buffer }
        If (Item < Range) Then Begin                   { Within text range }
          Text := GetText(Item, ColWidth + Indent);    { Fetch text }
@@ -3867,10 +3876,10 @@ BEGIN
            Ni := Focused - Size.Y Else Exit;          { One column left }
          kbPgDn: Ni := Focused + Size.Y * NumCols;    { One page down }
          kbPgUp: Ni := Focused - Size.Y * NumCols;    { One page up }
-         kbHome: Ni := TopItem;                       { Move to top }
-         kbEnd: Ni := TopItem + (Size.Y*NumCols)-1;   { Move to bottom }
-         kbCtrlPgDn: Ni := Range - 1;                 { Move to last item }
-         kbCtrlPgUp: Ni := 0;                         { Move to first item }
+         kbHome: Ni := 0;                             { Move to first item }
+         kbEnd: Ni := Range - 1;                      { Move to last item }
+         kbCtrlPgDn: Ni := TopItem + (Size.Y*NumCols)-1;{ Move to bottom }
+         kbCtrlPgUp: Ni := TopItem;                   { Move to top }
          Else Exit;
        End;
        MoveFocus(Ni);                                 { Move the focus }