mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge pull request #3631 from Flow-Launcher/file_tooltip
Support More Information for Files, Folders and Volumes Tooltips & Add Custom Preview Panel Support for Folder Results
This commit is contained in:
commit
d04f493e57
7 changed files with 330 additions and 50 deletions
|
|
@ -46,6 +46,7 @@
|
|||
<system:String x:Key="plugin_explorer_shell_path">Shell Path</system:String>
|
||||
<system:String x:Key="plugin_explorer_indexsearchexcludedpaths_header">Index Search Excluded Paths</system:String>
|
||||
<system:String x:Key="plugin_explorer_use_location_as_working_dir">Use search result's location as the working directory of the executable</system:String>
|
||||
<system:String x:Key="plugin_explorer_display_more_info_in_tooltip">Display more information like size and age in tooltips</system:String>
|
||||
<system:String x:Key="plugin_explorer_default_open_in_file_manager">Hit Enter to open folder in Default File Manager</system:String>
|
||||
<system:String x:Key="plugin_explorer_usewindowsindexfordirectorysearch">Use Index Search For Path Search</system:String>
|
||||
<system:String x:Key="plugin_explorer_manageindexoptions">Indexing Options</system:String>
|
||||
|
|
@ -82,6 +83,9 @@
|
|||
<!-- Plugin Tooltip -->
|
||||
<system:String x:Key="plugin_explorer_plugin_ToolTipOpenDirectory">Ctrl + Enter to open the directory</system:String>
|
||||
<system:String x:Key="plugin_explorer_plugin_ToolTipOpenContainingFolder">Ctrl + Enter to open the containing folder</system:String>
|
||||
<system:String x:Key="plugin_explorer_plugin_tooltip_more_info">{0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}</system:String>
|
||||
<system:String x:Key="plugin_explorer_plugin_tooltip_more_info_unknown">Unknown</system:String>
|
||||
<system:String x:Key="plugin_explorer_plugin_tooltip_more_info_volume">{0}{3}Space free: {1}{3}Total size: {2}</system:String>
|
||||
|
||||
<!-- Context menu items -->
|
||||
<system:String x:Key="plugin_explorer_copypath">Copy path</system:String>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
{
|
||||
public static class ResultManager
|
||||
{
|
||||
private static readonly string ClassName = nameof(ResultManager);
|
||||
|
||||
private static readonly string[] SizeUnits = { "B", "KB", "MB", "GB", "TB" };
|
||||
private static PluginInitContext Context;
|
||||
private static Settings Settings { get; set; }
|
||||
|
|
@ -99,10 +101,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
AutoCompleteText = GetAutoCompleteText(title, query, path, ResultType.Folder),
|
||||
TitleHighlightData = Context.API.FuzzySearch(query.Search, title).MatchData,
|
||||
CopyText = path,
|
||||
Preview = new Result.PreviewInfo
|
||||
{
|
||||
FilePath = path,
|
||||
},
|
||||
PreviewPanel = new Lazy<UserControl>(() => new PreviewPanel(Settings, path, ResultType.Folder)),
|
||||
Action = c =>
|
||||
{
|
||||
if (c.SpecialKeyState.ToModifierKeys() == ModifierKeys.Alt)
|
||||
|
|
@ -163,7 +162,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
},
|
||||
Score = score,
|
||||
TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenDirectory"),
|
||||
SubTitleToolTip = path,
|
||||
SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetFolderMoreInfoTooltip(path) : path,
|
||||
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path, WindowsIndexed = windowsIndexed }
|
||||
};
|
||||
}
|
||||
|
|
@ -184,6 +183,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
if (progressValue >= 90)
|
||||
progressBarColor = "#da2626";
|
||||
|
||||
var tooltip = Settings.DisplayMoreInformationInToolTip
|
||||
? GetVolumeMoreInfoTooltip(path, freespace, totalspace)
|
||||
: path;
|
||||
|
||||
return new Result
|
||||
{
|
||||
Title = title,
|
||||
|
|
@ -202,8 +205,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
OpenFolder(path);
|
||||
return true;
|
||||
},
|
||||
TitleToolTip = path,
|
||||
SubTitleToolTip = path,
|
||||
TitleToolTip = tooltip,
|
||||
SubTitleToolTip = tooltip,
|
||||
ContextData = new SearchResult { Type = ResultType.Volume, FullPath = path, WindowsIndexed = windowsIndexed }
|
||||
};
|
||||
}
|
||||
|
|
@ -269,7 +272,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
bool isMedia = IsMedia(Path.GetExtension(filePath));
|
||||
var title = Path.GetFileName(filePath);
|
||||
|
||||
|
||||
/* Preview Detail */
|
||||
|
||||
var result = new Result
|
||||
|
|
@ -287,7 +289,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
TitleHighlightData = Context.API.FuzzySearch(query.Search, title).MatchData,
|
||||
Score = score,
|
||||
CopyText = filePath,
|
||||
PreviewPanel = new Lazy<UserControl>(() => new PreviewPanel(Settings, filePath)),
|
||||
PreviewPanel = new Lazy<UserControl>(() => new PreviewPanel(Settings, filePath, ResultType.File)),
|
||||
Action = c =>
|
||||
{
|
||||
if (c.SpecialKeyState.ToModifierKeys() == ModifierKeys.Alt)
|
||||
|
|
@ -318,7 +320,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
return true;
|
||||
},
|
||||
TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenContainingFolder"),
|
||||
SubTitleToolTip = filePath,
|
||||
SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetFileMoreInfoTooltip(filePath) : filePath,
|
||||
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath, WindowsIndexed = windowsIndexed }
|
||||
};
|
||||
return result;
|
||||
|
|
@ -349,6 +351,46 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
_ = Task.Run(() => EverythingApi.IncrementRunCounterAsync(fileOrFolder));
|
||||
}
|
||||
|
||||
private static string GetFileMoreInfoTooltip(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileSize = PreviewPanel.GetFileSize(filePath);
|
||||
var fileCreatedAt = PreviewPanel.GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
|
||||
var fileModifiedAt = PreviewPanel.GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
|
||||
return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
|
||||
filePath, fileSize, fileCreatedAt, fileModifiedAt, Environment.NewLine);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Context.API.LogException(ClassName, $"Failed to load tooltip for {filePath}", e);
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetFolderMoreInfoTooltip(string folderPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var folderSize = PreviewPanel.GetFolderSize(folderPath);
|
||||
var folderCreatedAt = PreviewPanel.GetFolderCreatedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
|
||||
var folderModifiedAt = PreviewPanel.GetFolderLastModifiedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
|
||||
return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
|
||||
folderPath, folderSize, folderCreatedAt, folderModifiedAt, Environment.NewLine);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Context.API.LogException(ClassName, $"Failed to load tooltip for {folderPath}", e);
|
||||
return folderPath;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetVolumeMoreInfoTooltip(string volumePath, string freespace, string totalspace)
|
||||
{
|
||||
return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_volume"),
|
||||
volumePath, freespace, totalspace, Environment.NewLine);
|
||||
}
|
||||
|
||||
private static readonly string[] MediaExtensions = { ".jpg", ".png", ".avi", ".mkv", ".bmp", ".gif", ".wmv", ".mp3", ".flac", ".mp4" };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ namespace Flow.Launcher.Plugin.Explorer
|
|||
|
||||
public bool DefaultOpenFolderInFileManager { get; set; } = false;
|
||||
|
||||
public bool DisplayMoreInformationInToolTip { get; set; } = false;
|
||||
|
||||
public string SearchActionKeyword { get; set; } = Query.GlobalPluginWildcardSign;
|
||||
|
||||
public bool SearchActionKeywordEnabled { get; set; } = true;
|
||||
|
|
|
|||
|
|
@ -244,6 +244,21 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
|
|||
"yyyy-MM-dd",
|
||||
"yyyy-MM-dd ddd",
|
||||
"yyyy-MM-dd, dddd",
|
||||
"dd/MMM/yyyy",
|
||||
"dd/MMM/yyyy ddd",
|
||||
"dd/MMM/yyyy, dddd",
|
||||
"dd-MMM-yyyy",
|
||||
"dd-MMM-yyyy ddd",
|
||||
"dd-MMM-yyyy, dddd",
|
||||
"dd.MMM.yyyy",
|
||||
"dd.MMM.yyyy ddd",
|
||||
"dd.MMM.yyyy, dddd",
|
||||
"MMM/dd/yyyy",
|
||||
"MMM/dd/yyyy ddd",
|
||||
"MMM/dd/yyyy, dddd",
|
||||
"yyyy-MMM-dd",
|
||||
"yyyy-MMM-dd ddd",
|
||||
"yyyy-MMM-dd, dddd",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@
|
|||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
|
|
@ -228,16 +229,25 @@
|
|||
Content="{DynamicResource plugin_explorer_default_open_in_file_manager}"
|
||||
IsChecked="{Binding Settings.DefaultOpenFolderInFileManager}" />
|
||||
|
||||
<TextBlock
|
||||
<CheckBox
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
|
||||
HorizontalAlignment="Left"
|
||||
Content="{DynamicResource plugin_explorer_display_more_info_in_tooltip}"
|
||||
IsChecked="{Binding Settings.DisplayMoreInformationInToolTip}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource Color05B}"
|
||||
Text="{DynamicResource plugin_explorer_file_editor_path}" />
|
||||
<StackPanel
|
||||
Grid.Row="2"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
|
||||
Orientation="Horizontal">
|
||||
|
|
@ -256,7 +266,7 @@
|
|||
</StackPanel>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
|
||||
HorizontalAlignment="Left"
|
||||
|
|
@ -264,7 +274,7 @@
|
|||
Foreground="{DynamicResource Color05B}"
|
||||
Text="{DynamicResource plugin_explorer_folder_editor_path}" />
|
||||
<StackPanel
|
||||
Grid.Row="3"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
|
||||
Orientation="Horizontal">
|
||||
|
|
@ -283,7 +293,7 @@
|
|||
</StackPanel>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
|
||||
HorizontalAlignment="Left"
|
||||
|
|
@ -291,7 +301,7 @@
|
|||
Foreground="{DynamicResource Color05B}"
|
||||
Text="{DynamicResource plugin_explorer_shell_path}" />
|
||||
<StackPanel
|
||||
Grid.Row="4"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
|
||||
Orientation="Horizontal">
|
||||
|
|
@ -310,14 +320,14 @@
|
|||
</StackPanel>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource Color05B}"
|
||||
Text="{DynamicResource plugin_explorer_Index_Search_Engine}" />
|
||||
<ComboBox
|
||||
Grid.Row="5"
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
|
||||
HorizontalAlignment="Left"
|
||||
|
|
@ -327,14 +337,14 @@
|
|||
SelectedItem="{Binding SelectedIndexSearchEngine}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="6"
|
||||
Grid.Row="7"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource Color05B}"
|
||||
Text="{DynamicResource plugin_explorer_Content_Search_Engine}" />
|
||||
<ComboBox
|
||||
Grid.Row="6"
|
||||
Grid.Row="7"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
|
||||
HorizontalAlignment="Left"
|
||||
|
|
@ -344,14 +354,14 @@
|
|||
SelectedItem="{Binding SelectedContentSearchEngine}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="7"
|
||||
Grid.Row="8"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource Color05B}"
|
||||
Text="{DynamicResource plugin_explorer_Directory_Recursive_Search_Engine}" />
|
||||
<ComboBox
|
||||
Grid.Row="7"
|
||||
Grid.Row="8"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
|
||||
HorizontalAlignment="Left"
|
||||
|
|
@ -361,14 +371,14 @@
|
|||
SelectedItem="{Binding SelectedPathEnumerationEngine}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="8"
|
||||
Grid.Row="9"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource Color05B}"
|
||||
Text="{DynamicResource plugin_explorer_Excluded_File_Types}" />
|
||||
<TextBox
|
||||
Grid.Row="8"
|
||||
Grid.Row="9"
|
||||
Grid.Column="1"
|
||||
MinWidth="{StaticResource SettingPanelTextBoxMinWidth}"
|
||||
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
|
||||
|
|
@ -377,14 +387,14 @@
|
|||
ToolTip="{DynamicResource plugin_explorer_Excluded_File_Types_Tooltip}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="9"
|
||||
Grid.Row="10"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource Color05B}"
|
||||
Text="{DynamicResource plugin_explorer_Maximum_Results}" />
|
||||
<TextBox
|
||||
Grid.Row="9"
|
||||
Grid.Row="10"
|
||||
Grid.Column="1"
|
||||
MinWidth="{StaticResource SettingPanelTextBoxMinWidth}"
|
||||
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
|
||||
|
|
@ -396,7 +406,7 @@
|
|||
ToolTip="{DynamicResource plugin_explorer_Maximum_Results_Tooltip}" />
|
||||
|
||||
<Button
|
||||
Grid.Row="10"
|
||||
Grid.Row="11"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@
|
|||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Style="{DynamicResource PreviewItemSubTitleStyle}"
|
||||
Text="{Binding FileSize, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
|
||||
Text="{Binding FileSize, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Mode=OneWay}"
|
||||
TextWrapping="Wrap"
|
||||
Visibility="{Binding FileSizeVisibility, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
|
@ -16,8 +18,10 @@ namespace Flow.Launcher.Plugin.Explorer.Views;
|
|||
|
||||
public partial class PreviewPanel : UserControl, INotifyPropertyChanged
|
||||
{
|
||||
private static readonly string ClassName = nameof(PreviewPanel);
|
||||
|
||||
private string FilePath { get; }
|
||||
public string FileSize { get; } = "";
|
||||
public string FileSize { get; private set; } = Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
public string CreatedAt { get; } = "";
|
||||
public string LastModifiedAt { get; } = "";
|
||||
private ImageSource _previewImage = new BitmapImage();
|
||||
|
|
@ -50,7 +54,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
|
|||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
|
||||
public PreviewPanel(Settings settings, string filePath)
|
||||
public PreviewPanel(Settings settings, string filePath, ResultType type)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
|
|
@ -60,33 +64,32 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
|
|||
|
||||
if (Settings.ShowFileSizeInPreviewPanel)
|
||||
{
|
||||
var fileSize = new FileInfo(filePath).Length;
|
||||
FileSize = ResultManager.ToReadableSize(fileSize, 2);
|
||||
if (type == ResultType.File)
|
||||
{
|
||||
FileSize = GetFileSize(filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
FileSize = GetFolderSize(filePath);
|
||||
OnPropertyChanged(nameof(FileSize));
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.ShowCreatedDateInPreviewPanel)
|
||||
{
|
||||
DateTime createdDate = File.GetCreationTime(filePath);
|
||||
string formattedDate = createdDate.ToString(
|
||||
$"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
|
||||
CultureInfo.CurrentCulture
|
||||
);
|
||||
|
||||
string result = formattedDate;
|
||||
if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
|
||||
CreatedAt = result;
|
||||
CreatedAt = type == ResultType.File ?
|
||||
GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel) :
|
||||
GetFolderCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
|
||||
}
|
||||
|
||||
if (Settings.ShowModifiedDateInPreviewPanel)
|
||||
{
|
||||
DateTime lastModifiedDate = File.GetLastWriteTime(filePath);
|
||||
string formattedDate = lastModifiedDate.ToString(
|
||||
$"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
|
||||
CultureInfo.CurrentCulture
|
||||
);
|
||||
string result = formattedDate;
|
||||
if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
|
||||
LastModifiedAt = result;
|
||||
LastModifiedAt = type == ResultType.File ?
|
||||
GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel) :
|
||||
GetFolderLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
|
||||
}
|
||||
|
||||
_ = LoadImageAsync();
|
||||
|
|
@ -96,7 +99,211 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
|
|||
{
|
||||
PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
public static string GetFileSize(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(filePath);
|
||||
return ResultManager.ToReadableSize(fileInfo.Length, 2);
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"File not found: {filePath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Main.Context.API.LogException(ClassName, $"Failed to get file size for {filePath}", e);
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetFileCreatedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
|
||||
{
|
||||
try
|
||||
{
|
||||
var createdDate = File.GetCreationTime(filePath);
|
||||
var formattedDate = createdDate.ToString(
|
||||
$"{previewPanelDateFormat} {previewPanelTimeFormat}",
|
||||
CultureInfo.CurrentCulture
|
||||
);
|
||||
|
||||
var result = formattedDate;
|
||||
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
|
||||
return result;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"File not found: {filePath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Main.Context.API.LogException(ClassName, $"Failed to get file created date for {filePath}", e);
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetFileLastModifiedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lastModifiedDate = File.GetLastWriteTime(filePath);
|
||||
var formattedDate = lastModifiedDate.ToString(
|
||||
$"{previewPanelDateFormat} {previewPanelTimeFormat}",
|
||||
CultureInfo.CurrentCulture
|
||||
);
|
||||
|
||||
var result = formattedDate;
|
||||
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
|
||||
return result;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"File not found: {filePath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Main.Context.API.LogException(ClassName, $"Failed to get file modified date for {filePath}", e);
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetFolderSize(string folderPath)
|
||||
{
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
|
||||
|
||||
try
|
||||
{
|
||||
// Use parallel enumeration for better performance
|
||||
var directoryInfo = new DirectoryInfo(folderPath);
|
||||
long size = directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories)
|
||||
.AsParallel()
|
||||
.WithCancellation(timeoutCts.Token)
|
||||
.Sum(file => file.Length);
|
||||
|
||||
return ResultManager.ToReadableSize(size, 2);
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
// For parallel operations, AggregateException may be thrown if any of the tasks fail
|
||||
catch (AggregateException ae)
|
||||
{
|
||||
switch (ae.InnerException)
|
||||
{
|
||||
case FileNotFoundException:
|
||||
Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
case UnauthorizedAccessException:
|
||||
Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
case OperationCanceledException:
|
||||
Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
default:
|
||||
Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", ae);
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", e);
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetFolderCreatedAt(string folderPath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
|
||||
{
|
||||
try
|
||||
{
|
||||
var createdDate = Directory.GetCreationTime(folderPath);
|
||||
var formattedDate = createdDate.ToString(
|
||||
$"{previewPanelDateFormat} {previewPanelTimeFormat}",
|
||||
CultureInfo.CurrentCulture
|
||||
);
|
||||
|
||||
var result = formattedDate;
|
||||
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
|
||||
return result;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Main.Context.API.LogException(ClassName, $"Failed to get folder created date for {folderPath}", e);
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetFolderLastModifiedAt(string folderPath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lastModifiedDate = Directory.GetLastWriteTime(folderPath);
|
||||
var formattedDate = lastModifiedDate.ToString(
|
||||
$"{previewPanelDateFormat} {previewPanelTimeFormat}",
|
||||
CultureInfo.CurrentCulture
|
||||
);
|
||||
|
||||
var result = formattedDate;
|
||||
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
|
||||
return result;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Main.Context.API.LogException(ClassName, $"Failed to get folder modified date for {folderPath}", e);
|
||||
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetFileAge(DateTime fileDateTime)
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
|
|
|||
Loading…
Reference in a new issue