FIX: Notification when changing file source, fixes bug [3136397] and changing file source in a locked tab.

This commit is contained in:
cobines 2010-12-19 03:31:12 +00:00
commit bf4e5da56b
3 changed files with 198 additions and 188 deletions

View file

@ -459,11 +459,10 @@ type
procedure seLogWindowSpecialLineColors(Sender: TObject; Line: integer;
var Special: boolean; var FG, BG: TColor);
function FileViewBeforeChangeDirectory(Sender: TFileView; const NewDir : String): Boolean;
procedure FileViewAfterChangeDirectory(Sender: TFileView; const NewDir : String);
procedure FileViewChangeFileSource(Sender: TFileView);
procedure FileViewActivate(Sender: TFileView);
procedure FileViewReload(Sender: TFileView);
function FileViewBeforeChangePath(FileView: TFileView; NewFileSource: IFileSource; const NewPath : String): Boolean;
procedure FileViewAfterChangePath(FileView: TFileView);
procedure FileViewActivate(FileView: TFileView);
procedure FileViewReload(FileView: TFileView);
procedure edtCommandKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure edtCommandEnter(Sender: TObject);
@ -2733,15 +2732,15 @@ begin
end;
end;
function TfrmMain.FileViewBeforeChangeDirectory(Sender: TFileView; const NewDir: String): Boolean;
function TfrmMain.FileViewBeforeChangePath(FileView: TFileView; NewFileSource: IFileSource; const NewPath: String): Boolean;
var
ANoteBook: TFileViewNotebook;
Page, NewPage: TFileViewPage;
begin
Result:= True;
if Sender.NotebookPage is TFileViewPage then
if FileView.NotebookPage is TFileViewPage then
begin
Page := Sender.NotebookPage as TFileViewPage;
Page := FileView.NotebookPage as TFileViewPage;
case Page.LockState of
tlsPathLocked:
@ -2751,93 +2750,73 @@ begin
begin
Result := False; // do not change directory in this tab
ANoteBook := Page.Notebook;
if Assigned(NewFileSource) then
begin
ANoteBook := Page.Notebook;
// Create same type
NewPage := ANoteBook.AddPage;
Page.FileView.Clone(NewPage);
NewPage.FileView.CurrentPath := NewDir;
NewPage.MakeActive;
// Create same type
NewPage := ANoteBook.AddPage;
Page.FileView.Clone(NewPage);
NewPage.FileView.AddFileSource(NewFileSource, NewPath);
NewPage.MakeActive;
end;
end;
end;
end;
end;
procedure TfrmMain.FileViewAfterChangeDirectory(Sender: TFileView; const NewDir: String);
procedure TfrmMain.FileViewAfterChangePath(FileView: TFileView);
var
ANoteBook : TFileViewNotebook;
Page: TFileViewPage;
sCaption : String;
begin
if Sender.NotebookPage is TFileViewPage then
if FileView.NotebookPage is TFileViewPage then
begin
Page := Sender.NotebookPage as TFileViewPage;
ANoteBook := Page.Notebook;
if Page.LockState = tlsNormal then // if not locked tab
begin
sCaption := GetLastDir(NewDir);
Page.UpdateCaption(sCaption);
end;
// update file system watcher directory
if (Page.FileView.FileSource.IsClass(TFileSystemFileSource)) then
begin
if (ANoteBook = nbLeft) and Assigned(LeftFrameWatcher) then
LeftFrameWatcher.WatchPath:= NewDir
else if (ANoteBook = nbRight) and Assigned(RightFrameWatcher) then
RightFrameWatcher.WatchPath:= NewDir;
if glsDirHistory.IndexOf(NewDir) = -1 then
glsDirHistory.Insert(0, NewDir);
end;
UpdateSelectedDrive(ANoteBook);
UpdateFreeSpace(ANoteBook.Side);
UpdatePrompt;
{if (fspDirectAccess in Page.FileView.FileSource.GetProperties) then
begin
if gTermWindow and Assigned(Cons) then
Cons.Terminal.SetCurrentDir(NewDir);
end;}
end;
end;
procedure TfrmMain.FileViewChangeFileSource(Sender: TFileView);
var
ANoteBook : TFileViewNotebook;
Page: TFileViewPage;
sCaption : String;
begin
if Sender.NotebookPage is TFileViewPage then
begin
Page := Sender.NotebookPage as TFileViewPage;
Page := FileView.NotebookPage as TFileViewPage;
ANoteBook := Page.Notebook;
if Page.LockState = tlsNormal then // if not locked tab
begin
sCaption := GetLastDir(Page.FileView.CurrentPath);
Page.UpdateCaption(sCaption);
end;
Page.UpdateCaption(GetLastDir(FileView.CurrentPath));
if Page.IsActive then
begin
ToggleFileSystemWatcher;
UpdateSelectedDrive(ANoteBook);
UpdateFreeSpace(ANoteBook.Side);
UpdatePrompt;
if Assigned(FileView.FileSource) then
begin
// update file system watcher directory
if FileView.FileSource.IsClass(TFileSystemFileSource) then
begin
if (ANoteBook = nbLeft) and Assigned(LeftFrameWatcher) then
LeftFrameWatcher.WatchPath:= FileView.CurrentPath
else if (ANoteBook = nbRight) and Assigned(RightFrameWatcher) then
RightFrameWatcher.WatchPath:= FileView.CurrentPath;
if glsDirHistory.IndexOf(FileView.CurrentPath) = -1 then
glsDirHistory.Insert(0, FileView.CurrentPath);
end;
UpdateSelectedDrive(ANoteBook);
UpdateFreeSpace(ANoteBook.Side);
UpdatePrompt;
end;
end;
{if (fspDirectAccess in FileView.FileSource.GetProperties) then
begin
if gTermWindow and Assigned(Cons) then
Cons.Terminal.SetCurrentDir(FileView.CurrentPath);
end;}
end;
end;
procedure TfrmMain.FileViewActivate(Sender: TFileView);
procedure TfrmMain.FileViewActivate(FileView: TFileView);
var
Page: TFileViewPage;
begin
if Sender.NotebookPage is TFileViewPage then
if FileView.NotebookPage is TFileViewPage then
begin
Page := Sender.NotebookPage as TFileViewPage;
Page := FileView.NotebookPage as TFileViewPage;
PanelSelected := Page.Notebook.Side;
UpdateSelectedDrive(Page.Notebook);
UpdatePrompt;
@ -2845,13 +2824,13 @@ begin
end;
end;
procedure TfrmMain.FileViewReload(Sender: TFileView);
procedure TfrmMain.FileViewReload(FileView: TFileView);
var
Page: TFileViewPage;
begin
if Sender.NotebookPage is TFileViewPage then
if FileView.NotebookPage is TFileViewPage then
begin
Page := Sender.NotebookPage as TFileViewPage;
Page := FileView.NotebookPage as TFileViewPage;
if Page.IsActive then
begin
@ -2972,9 +2951,8 @@ procedure TfrmMain.AssignEvents(AFileView: TFileView);
begin
with AFileView do
begin
OnBeforeChangeDirectory := @FileViewBeforeChangeDirectory;
OnAfterChangeDirectory := @FileViewAfterChangeDirectory;
OnChangeFileSource := @FileViewChangeFileSource;
OnBeforeChangePath := @FileViewBeforeChangePath;
OnAfterChangePath := @FileViewAfterChangePath;
OnActivate := @FileViewActivate;
OnReload := @FileViewReload;
end;
@ -3351,6 +3329,26 @@ end;
procedure TfrmMain.ToggleFileSystemWatcher;
var
WatchFilter: TWatchFilter;
procedure ToggleWatcher(FileView: TFileView; var Watcher: TFileSystemWatcher; AnOwner: TComponent);
begin
if (WatchFilter <> []) and Assigned(FileView.FileSource) and
(FileView.FileSource.IsClass(TFileSystemFileSource)) then
begin
if not Assigned(Watcher) then
begin
Watcher:= TFileSystemWatcher.Create(AnOwner, FileView.CurrentPath, WatchFilter);
Watcher.OnWatcherNotifyEvent:= @FramePanelOnWatcherNotifyEvent;
Watcher.Active:= True;
end;
end
else
begin
if Assigned(Watcher) then
FreeAndNil(Watcher);
end;
end;
begin
WatchFilter:= [];
if (watch_file_name_change in gWatchDirs) then
@ -3358,35 +3356,8 @@ begin
if (watch_attributes_change in gWatchDirs) then
Include(WatchFilter, wfAttributesChange);
if (WatchFilter <> []) and (FrameLeft.FileSource.IsClass(TFileSystemFileSource)) then
begin
if not Assigned(LeftFrameWatcher) then
begin
LeftFrameWatcher:= TFileSystemWatcher.Create(nbLeft, FrameLeft.CurrentPath, WatchFilter);
LeftFrameWatcher.OnWatcherNotifyEvent:= @FramePanelOnWatcherNotifyEvent;
LeftFrameWatcher.Active:= True;
end;
end
else
begin
if Assigned(LeftFrameWatcher) then
FreeAndNil(LeftFrameWatcher);
end;
if (WatchFilter <> []) and (FrameRight.FileSource.IsClass(TFileSystemFileSource)) then
begin
if not Assigned(RightFrameWatcher) then
begin
RightFrameWatcher:= TFileSystemWatcher.Create(nbRight, FrameRight.CurrentPath, WatchFilter);
RightFrameWatcher.OnWatcherNotifyEvent:= @FramePanelOnWatcherNotifyEvent;
RightFrameWatcher.Active:= True;
end;
end
else
begin
if Assigned(RightFrameWatcher) then
FreeAndNil(RightFrameWatcher);
end;
ToggleWatcher(FrameLeft, LeftFrameWatcher, nbLeft);
ToggleWatcher(FrameRight, RightFrameWatcher, nbRight);
end;
procedure TfrmMain.UpdateWindowView;
@ -4347,7 +4318,7 @@ begin
Break;
end
else
RemoveLastFileSource;
RemoveCurrentFileSource;
end;
if FileSourcesCount = 0 then

View file

@ -398,7 +398,7 @@ type
function GetSelectedFiles: TFiles; override;
procedure SetSorting(NewSortings: TFileSortings); override;
procedure AfterChangePath(NewPath: String); override;
procedure AfterChangePath; override;
public
ActiveColm: String;
@ -417,7 +417,7 @@ type
procedure CloneTo(FileView: TFileView); override;
procedure AddFileSource(aFileSource: IFileSource; aPath: String); override;
procedure RemoveLastFileSource; override;
procedure RemoveCurrentFileSource; override;
procedure Reload(const PathsToReload: TPathsArray = nil); override;
procedure StopBackgroundWork; override;
@ -1397,9 +1397,9 @@ begin
end;
end;
procedure TColumnsFileView.AfterChangePath(NewPath: String);
procedure TColumnsFileView.AfterChangePath;
begin
inherited AfterChangePath(NewPath);
inherited;
FUpdatingGrid := True;
dgPanel.Row := 0;
@ -3054,14 +3054,8 @@ end;
procedure TColumnsFileView.AddFileSource(aFileSource: IFileSource; aPath: String);
begin
LastActiveFile := '';
RequestedActiveFile := '';
inherited AddFileSource(aFileSource, aPath);
if Assigned(OnChangeFileSource) then
OnChangeFileSource(Self);
FUpdatingGrid := True;
dgPanel.Row := 0;
FUpdatingGrid := False;
@ -3069,17 +3063,14 @@ begin
UpdateAddressLabel;
end;
procedure TColumnsFileView.RemoveLastFileSource;
procedure TColumnsFileView.RemoveCurrentFileSource;
var
FocusedFile: String;
begin
// Temporary. Do this by remembering the file name in a list?
FocusedFile := ExtractFileName(FileSource.CurrentAddress);
inherited RemoveLastFileSource;
if Assigned(OnChangeFileSource) then
OnChangeFileSource(Self);
inherited;
SetActiveFile(FocusedFile);
@ -5060,4 +5051,4 @@ begin
end;
end.

View file

@ -13,10 +13,17 @@ type
TFileView = class;
TOnBeforeChangeDirectory = function (FileView: TFileView; const NewDir : String): Boolean of object;
TOnAfterChangeDirectory = procedure (FileView: TFileView; const NewDir : String) of object;
{en
Called before path is changed. If it returns @true the paths is changed
(and if successful, OnAfterChangePath is called). If it returns @false,
the path is not changed.
NewFileSource is @nil the last file source is to be removed.
}
TOnBeforeChangePath = function (FileView: TFileView;
NewFileSource: IFileSource;
const NewPath : String): Boolean of object;
TOnAfterChangePath = procedure (FileView: TFileView) of object;
TOnChangeActiveFile = procedure (FileView: TFileView; const aFile : TFile) of object;
TOnChangeFileSource = procedure (FileView: TFileView) of object;
TOnActivate = procedure (aFileView: TFileView) of object;
TOnReload = procedure (aFileView: TFileView) of object;
@ -61,10 +68,9 @@ type
FMethods: TMethodsList;
FOnBeforeChangeDirectory : TOnBeforeChangeDirectory;
FOnAfterChangeDirectory : TOnAfterChangeDirectory;
FOnBeforeChangePath : TOnBeforeChangePath;
FOnAfterChangePath : TOnAfterChangePath;
FOnChangeActiveFile: TOnChangeActiveFile;
FOnChangeFileSource : TOnChangeFileSource;
FOnActivate : TOnActivate;
FOnReload : TOnReload;
@ -105,12 +111,13 @@ type
{en
Called before changing path. If returns @false the path is not changed.
NewFileSource is @nil if the last file source is to be removed.
}
function BeforeChangePath(NewPath: String): Boolean; virtual;
function BeforeChangePath(NewFileSource: IFileSource; NewPath: String): Boolean; virtual;
{en
Called after path is changed.
}
procedure AfterChangePath(NewPath: String); virtual;
procedure AfterChangePath; virtual;
property FilePropertiesNeeded: TFilePropertiesTypes read FFilePropertiesNeeded write FFilePropertiesNeeded;
property LastActiveFile: String read FLastActiveFile write FLastActiveFile;
@ -136,7 +143,7 @@ type
procedure CloneTo(AFileView: TFileView); virtual;
procedure AddFileSource(aFileSource: IFileSource; aPath: String); virtual;
procedure RemoveLastFileSource; virtual;
procedure RemoveCurrentFileSource; virtual;
procedure RemoveAllFileSources; virtual;
{en
Assigns the list of file sources and paths into those file sources
@ -234,10 +241,9 @@ type
property Sorting: TFileSortings read FSortings write SetSorting;
property NotebookPage: TCustomPage read GetNotebookPage;
property OnBeforeChangeDirectory : TOnBeforeChangeDirectory read FOnBeforeChangeDirectory write FOnBeforeChangeDirectory;
property OnAfterChangeDirectory : TOnAfterChangeDirectory read FOnAfterChangeDirectory write FOnAfterChangeDirectory;
property OnBeforeChangePath : TOnBeforeChangePath read FOnBeforeChangePath write FOnBeforeChangePath;
property OnAfterChangePath : TOnAfterChangePath read FOnAfterChangePath write FOnAfterChangePath;
property OnChangeActiveFile : TOnChangeActiveFile read FOnChangeActiveFile write FOnChangeActiveFile;
property OnChangeFileSource : TOnChangeFileSource read FOnChangeFileSource write FOnChangeFileSource;
property OnActivate : TOnActivate read FOnActivate write FOnActivate;
property OnReload : TOnReload read FOnReload write FOnReload;
end;
@ -319,10 +325,9 @@ end;
procedure TFileView.CreateDefault(AOwner: TWinControl);
begin
FOnBeforeChangeDirectory := nil;
FOnAfterChangeDirectory := nil;
FOnBeforeChangePath := nil;
FOnAfterChangePath := nil;
FOnChangeActiveFile := nil;
FOnChangeFileSource := nil;
FOnActivate := nil;
FOnReload := nil;
FSortings := nil;
@ -363,9 +368,8 @@ begin
begin
// FFileSource should have been passed to FileView constructor already.
// FMethods are created in FileView constructor.
AFileView.OnBeforeChangeDirectory := Self.OnBeforeChangeDirectory;
AFileView.OnAfterChangeDirectory := Self.OnAfterChangeDirectory;
AFileView.OnChangeFileSource := Self.OnChangeFileSource;
AFileView.OnBeforeChangePath := Self.OnBeforeChangePath;
AFileView.OnAfterChangePath := Self.OnAfterChangePath;
AFileView.OnActivate := Self.OnActivate;
AFileView.OnReload := Self.OnReload;
@ -399,10 +403,10 @@ end;
procedure TFileView.SetCurrentPath(NewPath: String);
begin
if BeforeChangePath(NewPath) then
if BeforeChangePath(FileSource, NewPath) then
begin
FHistory.AddPath(NewPath); // Sets CurrentPath.
AfterChangePath(NewPath);
AfterChangePath;
{$IFDEF DEBUG_HISTORY}
FHistory.DebugShow;
{$ENDIF}
@ -590,15 +594,15 @@ begin
end;
end;
function TFileView.BeforeChangePath(NewPath: String): Boolean;
function TFileView.BeforeChangePath(NewFileSource: IFileSource; NewPath: String): Boolean;
begin
if NewPath <> '' then
begin
if Assigned(OnBeforeChangeDirectory) then
if not OnBeforeChangeDirectory(Self, NewPath) then
if Assigned(OnBeforeChangePath) then
if not OnBeforeChangePath(Self, NewFileSource, NewPath) then
Exit(False);
if not FileSource.SetCurrentWorkingDirectory(NewPath) then
if Assigned(NewFileSource) and not NewFileSource.SetCurrentWorkingDirectory(NewPath) then
begin
msgError(Format(rsMsgChDirFailed, [NewPath]));
Exit(False);
@ -610,13 +614,13 @@ begin
Result := False;
end;
procedure TFileView.AfterChangePath(NewPath: String);
procedure TFileView.AfterChangePath;
begin
LastActiveFile := '';
RequestedActiveFile := '';
if Assigned(OnAfterChangeDirectory) then
OnAfterChangeDirectory(Self, NewPath);
if Assigned(OnAfterChangePath) then
OnAfterChangePath(Self);
end;
procedure TFileView.ChangePathToParent(AllowChangingFileSource: Boolean);
@ -630,7 +634,7 @@ begin
// If there is a higher level file source then change to it.
if (FileSourcesCount > 1) and AllowChangingFileSource then
begin
RemoveLastFileSource;
RemoveCurrentFileSource;
Reload;
UpdateView;
end;
@ -670,39 +674,88 @@ begin
end;
procedure TFileView.AddFileSource(aFileSource: IFileSource; aPath: String);
var
IsNewFileSource: Boolean;
begin
if Assigned(FileSource) then
FileSource.RemoveReloadEventListener(@ReloadEvent);
FHistory.Add(aFileSource, aPath);
Reload;
UpdateView;
FileSource.AddReloadEventListener(@ReloadEvent);
{$IFDEF DEBUG_HISTORY}
FHistory.DebugShow;
{$ENDIF}
end;
IsNewFileSource := aFileSource <> FileSource;
procedure TFileView.RemoveLastFileSource;
begin
if FileSourcesCount > 0 then
if BeforeChangePath(aFileSource, aPath) then
begin
FileSource.RemoveReloadEventListener(@ReloadEvent);
FHistory.DeleteFromCurrentFileSource;
Reload;
UpdateView;
FileSource.AddReloadEventListener(@ReloadEvent);
if Assigned(FileSource) and IsNewFileSource then
FileSource.RemoveReloadEventListener(@ReloadEvent);
FHistory.Add(aFileSource, aPath);
if Assigned(FileSource) and IsNewFileSource then
begin
Reload;
UpdateView;
FileSource.AddReloadEventListener(@ReloadEvent);
end;
AfterChangePath;
{$IFDEF DEBUG_HISTORY}
FHistory.DebugShow;
{$ENDIF}
end;
end;
procedure TFileView.RemoveCurrentFileSource;
var
NewFileSource: IFileSource = nil;
NewPath: String = '';
IsNewFileSource: Boolean;
PrevIndex: Integer;
begin
if FileSourcesCount > 0 then
begin
PrevIndex := FHistory.CurrentFileSourceIndex - 1;
if PrevIndex >= 0 then
begin
NewFileSource := FHistory.FileSource[PrevIndex];
NewPath := FHistory.Path[PrevIndex, FHistory.PathsCount[PrevIndex] - 1];
end;
IsNewFileSource := NewFileSource <> FileSource;
if BeforeChangePath(NewFileSource, NewPath) then
begin
if IsNewFileSource then
FileSource.RemoveReloadEventListener(@ReloadEvent);
FHistory.DeleteFromCurrentFileSource;
if Assigned(FileSource) and IsNewFileSource then
begin
Reload;
UpdateView;
FileSource.AddReloadEventListener(@ReloadEvent);
end;
AfterChangePath;
{$IFDEF DEBUG_HISTORY}
FHistory.DebugShow;
{$ENDIF}
end;
end;
end;
procedure TFileView.RemoveAllFileSources;
begin
if FileSourcesCount > 0 then
begin
FileSource.RemoveReloadEventListener(@ReloadEvent);
FHistory.Clear;
if BeforeChangePath(nil, '') then
begin
FileSource.RemoveReloadEventListener(@ReloadEvent);
FHistory.Clear;
AfterChangePath;
{$IFDEF DEBUG_HISTORY}
FHistory.DebugShow;
{$ENDIF}
end;
end;
end;
@ -789,36 +842,31 @@ end;
procedure TFileView.GoToHistoryIndex(aFileSourceIndex, aPathIndex: Integer);
var
OldFileSourceIndex, OldPathIndex: Integer;
IsNewFileSource: Boolean;
begin
if aFileSourceIndex <> FHistory.CurrentFileSourceIndex then
begin
OldFileSourceIndex := FHistory.CurrentFileSourceIndex;
OldPathIndex := FHistory.CurrentPathIndex;
IsNewFileSource := FHistory.FileSource[aFileSourceIndex] <> FHistory.CurrentFileSource;
if BeforeChangePath(FHistory.FileSource[aFileSourceIndex],
FHistory.Path[aFileSourceIndex, aPathIndex]) then
begin
if Assigned(FileSource) and IsNewFileSource then
FileSource.RemoveReloadEventListener(@ReloadEvent);
FileSource.RemoveReloadEventListener(@ReloadEvent);
FHistory.SetIndexes(aFileSourceIndex, aPathIndex);
if BeforeChangePath(FHistory.CurrentPath) then
if Assigned(FileSource) and IsNewFileSource then
begin
Reload;
UpdateView;
end
else
FHistory.SetIndexes(OldFileSourceIndex, OldPathIndex);
FileSource.AddReloadEventListener(@ReloadEvent);
end
else if aPathIndex <> FHistory.CurrentPathIndex then
begin
if BeforeChangePath(FHistory.Path[aFileSourceIndex, aPathIndex]) then
begin
FHistory.SetIndexes(aFileSourceIndex, aPathIndex);
AfterChangePath(FHistory.Path[aFileSourceIndex, aPathIndex]);
FileSource.AddReloadEventListener(@ReloadEvent);
end;
end;
{$IFDEF DEBUG_HISTORY}
FHistory.DebugShow;
{$ENDIF}
AfterChangePath;
{$IFDEF DEBUG_HISTORY}
FHistory.DebugShow;
{$ENDIF}
end;
end;
procedure TFileView.GoToPrevHistory;