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:
Jack Ye 2025-06-09 13:00:16 +08:00 committed by GitHub
commit d04f493e57
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 330 additions and 50 deletions

View file

@ -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>

View file

@ -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" };
}

View file

@ -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;

View file

@ -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

View file

@ -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}"

View file

@ -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}}" />

View file

@ -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;