2020-07-07 07:15:45 +12:00
|
|
|
|
// <copyright file="RowData.cs" company="PlaceholderCompany">
|
|
|
|
|
// Copyright (c) PlaceholderCompany. All rights reserved.
|
|
|
|
|
// </copyright>
|
2020-03-28 08:43:16 +13:00
|
|
|
|
|
|
|
|
|
namespace SystemTrayMenu.DataClasses
|
|
|
|
|
{
|
2020-07-07 07:15:45 +12:00
|
|
|
|
using System;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using SystemTrayMenu.Utilities;
|
2022-06-18 00:38:09 +12:00
|
|
|
|
using static SystemTrayMenu.Utilities.IconReader;
|
2021-06-27 21:35:07 +12:00
|
|
|
|
using Menu = SystemTrayMenu.UserInterface.Menu;
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2021-10-14 04:13:11 +13:00
|
|
|
|
internal class RowData
|
2020-03-28 08:43:16 +13:00
|
|
|
|
{
|
2020-07-07 09:37:55 +12:00
|
|
|
|
private static DateTime contextMenuClosed;
|
2021-04-17 12:39:48 +12:00
|
|
|
|
private Icon icon;
|
2020-03-28 08:43:16 +13:00
|
|
|
|
|
2022-06-18 00:38:09 +12:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="RowData"/> class.
|
|
|
|
|
/// empty dummy.
|
|
|
|
|
/// </summary>
|
2020-03-30 06:26:45 +13:00
|
|
|
|
internal RowData()
|
2020-03-28 08:43:16 +13:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-18 00:38:09 +12:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="RowData"/> class.
|
|
|
|
|
/// (Related replace "\x00" see #171.)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="isFolder">Flag if file or folder.</param>
|
|
|
|
|
/// <param name="isAddionalItem">Flag if addional item, from other folder than root folder.</param>
|
|
|
|
|
/// <param name="isNetworkRoot">Flag if resolved from network root folder.</param>
|
|
|
|
|
/// <param name="level">The number of the menu level.</param>
|
|
|
|
|
/// <param name="path">Path to item.</param>
|
|
|
|
|
internal RowData(bool isFolder, bool isAddionalItem, bool isNetworkRoot, int level, string path)
|
|
|
|
|
{
|
|
|
|
|
IsFolder = isFolder;
|
|
|
|
|
IsAddionalItem = isAddionalItem;
|
|
|
|
|
IsNetworkRoot = isNetworkRoot;
|
|
|
|
|
Level = level;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
FileInfo = new FileInfo(path.Replace("\x00", string.Empty));
|
|
|
|
|
Path = FileInfo.FullName;
|
|
|
|
|
FileExtension = System.IO.Path.GetExtension(Path);
|
|
|
|
|
IsLink = FileExtension.Equals(".lnk", StringComparison.InvariantCultureIgnoreCase);
|
|
|
|
|
if (IsLink)
|
|
|
|
|
{
|
|
|
|
|
ResolvedPath = FileLnk.GetResolvedFileName(Path, out bool isLinkToFolder);
|
|
|
|
|
IsLinkToFolder = isLinkToFolder || FileLnk.IsNetworkRoot(ResolvedPath);
|
|
|
|
|
ShowOverlay = Properties.Settings.Default.ShowLinkOverlay;
|
|
|
|
|
Text = System.IO.Path.GetFileNameWithoutExtension(Path);
|
|
|
|
|
if (string.IsNullOrEmpty(ResolvedPath))
|
|
|
|
|
{
|
|
|
|
|
Log.Info($"Resolved path is empty: '{Path}'");
|
|
|
|
|
ResolvedPath = Path;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ResolvedPath = Path;
|
|
|
|
|
if (string.IsNullOrEmpty(FileInfo.Name))
|
|
|
|
|
{
|
|
|
|
|
int nameBegin = FileInfo.FullName.LastIndexOf(@"\", StringComparison.InvariantCulture) + 1;
|
|
|
|
|
Text = FileInfo.FullName[nameBegin..];
|
|
|
|
|
}
|
|
|
|
|
else if (FileExtension.Equals(".url", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
FileExtension.Equals(".appref-ms", StringComparison.InvariantCultureIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
ShowOverlay = Properties.Settings.Default.ShowLinkOverlay;
|
|
|
|
|
Text = System.IO.Path.GetFileNameWithoutExtension(FileInfo.Name);
|
|
|
|
|
}
|
|
|
|
|
else if (!IsFolder && Config.IsHideFileExtension())
|
|
|
|
|
{
|
|
|
|
|
Text = System.IO.Path.GetFileNameWithoutExtension(FileInfo.Name);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Text = FileInfo.Name;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ContainsMenu = IsFolder || IsLinkToFolder;
|
|
|
|
|
IsMainMenu = Level == 0;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Log.Warn($"path:'{path}'", ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal FileInfo FileInfo { get; }
|
|
|
|
|
|
|
|
|
|
internal string Path { get; }
|
|
|
|
|
|
|
|
|
|
internal bool IsFolder { get; }
|
|
|
|
|
|
|
|
|
|
internal bool IsAddionalItem { get; }
|
|
|
|
|
|
|
|
|
|
internal bool IsNetworkRoot { get; }
|
|
|
|
|
|
|
|
|
|
internal int Level { get; set; }
|
|
|
|
|
|
|
|
|
|
internal string FileExtension { get; }
|
|
|
|
|
|
|
|
|
|
internal bool IsLink { get; }
|
|
|
|
|
|
|
|
|
|
internal string ResolvedPath { get; }
|
|
|
|
|
|
|
|
|
|
internal bool IsLinkToFolder { get; }
|
2022-06-13 11:32:36 +12:00
|
|
|
|
|
2022-06-18 00:38:09 +12:00
|
|
|
|
internal bool ShowOverlay { get; }
|
|
|
|
|
|
|
|
|
|
internal string Text { get; }
|
|
|
|
|
|
|
|
|
|
internal bool ContainsMenu { get; }
|
|
|
|
|
|
|
|
|
|
internal bool IsMainMenu { get; }
|
2020-07-08 03:05:19 +12:00
|
|
|
|
|
|
|
|
|
internal Menu SubMenu { get; set; }
|
|
|
|
|
|
|
|
|
|
internal bool IsMenuOpen { get; set; }
|
|
|
|
|
|
2022-02-05 22:32:28 +13:00
|
|
|
|
internal bool IsClicking { get; set; }
|
|
|
|
|
|
2020-07-08 03:05:19 +12:00
|
|
|
|
internal bool IsSelected { get; set; }
|
|
|
|
|
|
|
|
|
|
internal bool IsContextMenuOpen { get; set; }
|
|
|
|
|
|
|
|
|
|
internal bool HiddenEntry { get; set; }
|
|
|
|
|
|
|
|
|
|
internal int RowIndex { get; set; }
|
|
|
|
|
|
2021-09-24 08:53:46 +12:00
|
|
|
|
internal bool IconLoading { get; set; }
|
|
|
|
|
|
2021-10-26 08:45:49 +13:00
|
|
|
|
internal bool ProcessStarted { get; set; }
|
|
|
|
|
|
2020-05-14 05:14:51 +12:00
|
|
|
|
internal void SetData(RowData data, DataTable dataTable)
|
2020-03-30 06:26:45 +13:00
|
|
|
|
{
|
2020-05-14 05:14:51 +12:00
|
|
|
|
DataRow row = dataTable.Rows.Add();
|
|
|
|
|
data.RowIndex = dataTable.Rows.IndexOf(row);
|
2020-03-30 06:26:45 +13:00
|
|
|
|
|
|
|
|
|
if (HiddenEntry)
|
|
|
|
|
{
|
2022-06-18 00:38:09 +12:00
|
|
|
|
row[0] = AddIconOverlay(data.icon, Properties.Resources.White50Percentage);
|
2020-03-30 06:26:45 +13:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-07-07 09:37:55 +12:00
|
|
|
|
row[0] = data.icon;
|
2020-03-30 06:26:45 +13:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 11:32:36 +12:00
|
|
|
|
row[1] = data.Text;
|
2020-05-14 05:14:51 +12:00
|
|
|
|
row[2] = data;
|
2020-03-30 06:26:45 +13:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-18 00:38:09 +12:00
|
|
|
|
internal Icon ReadIcon(bool updateIconInBackground)
|
2020-03-30 06:26:45 +13:00
|
|
|
|
{
|
2022-06-18 00:38:09 +12:00
|
|
|
|
if (IsFolder || IsLinkToFolder)
|
2020-03-30 06:26:45 +13:00
|
|
|
|
{
|
2022-06-18 00:38:09 +12:00
|
|
|
|
icon = GetFolderIconWithCache(Path, ShowOverlay, updateIconInBackground, IsMainMenu, out bool loading);
|
2021-10-14 04:13:11 +13:00
|
|
|
|
IconLoading = loading;
|
2020-03-30 06:26:45 +13:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-06-18 00:38:09 +12:00
|
|
|
|
icon = GetFileIconWithCache(Path, ResolvedPath, ShowOverlay, updateIconInBackground, IsMainMenu, out bool loading);
|
|
|
|
|
IconLoading = loading;
|
|
|
|
|
}
|
2020-03-30 06:26:45 +13:00
|
|
|
|
|
2022-06-18 00:38:09 +12:00
|
|
|
|
if (!IconLoading)
|
|
|
|
|
{
|
|
|
|
|
if (icon == null)
|
2020-03-30 06:26:45 +13:00
|
|
|
|
{
|
2022-06-18 00:38:09 +12:00
|
|
|
|
icon = Properties.Resources.NotFound;
|
2020-03-30 06:26:45 +13:00
|
|
|
|
}
|
2022-06-18 00:38:09 +12:00
|
|
|
|
else if (HiddenEntry)
|
2021-10-14 04:13:11 +13:00
|
|
|
|
{
|
2022-06-18 00:38:09 +12:00
|
|
|
|
icon = AddIconOverlay(icon, Properties.Resources.White50Percentage);
|
2021-10-14 04:13:11 +13:00
|
|
|
|
}
|
2021-09-25 01:37:58 +12:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-18 00:38:09 +12:00
|
|
|
|
return icon;
|
2020-03-30 06:26:45 +13:00
|
|
|
|
}
|
|
|
|
|
|
2021-11-24 12:22:38 +13:00
|
|
|
|
internal void MouseDown(DataGridView dgv, MouseEventArgs e)
|
2020-07-07 07:15:45 +12:00
|
|
|
|
{
|
2022-02-05 22:32:28 +13:00
|
|
|
|
if (e.Button == MouseButtons.Left)
|
|
|
|
|
{
|
|
|
|
|
IsClicking = true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-07 07:15:45 +12:00
|
|
|
|
if (e != null &&
|
|
|
|
|
e.Button == MouseButtons.Right &&
|
|
|
|
|
FileInfo != null &&
|
|
|
|
|
dgv != null &&
|
|
|
|
|
dgv.Rows.Count > RowIndex &&
|
2020-07-07 09:37:55 +12:00
|
|
|
|
(DateTime.Now - contextMenuClosed).TotalMilliseconds > 200)
|
2020-07-07 07:15:45 +12:00
|
|
|
|
{
|
|
|
|
|
IsContextMenuOpen = true;
|
|
|
|
|
|
2021-11-17 12:13:46 +13:00
|
|
|
|
ShellContextMenu ctxMnu = new();
|
2020-07-07 07:15:45 +12:00
|
|
|
|
Point location = dgv.FindForm().Location;
|
2021-11-17 12:13:46 +13:00
|
|
|
|
Point point = new(
|
2020-07-07 07:15:45 +12:00
|
|
|
|
e.X + location.X + dgv.Location.X,
|
|
|
|
|
e.Y + location.Y + dgv.Location.Y);
|
|
|
|
|
if (ContainsMenu)
|
|
|
|
|
{
|
|
|
|
|
DirectoryInfo[] dir = new DirectoryInfo[1];
|
2022-06-18 00:38:09 +12:00
|
|
|
|
dir[0] = new DirectoryInfo(Path);
|
2020-07-07 07:15:45 +12:00
|
|
|
|
ctxMnu.ShowContextMenu(dir, point);
|
2022-06-19 09:43:30 +12:00
|
|
|
|
TriggerFileWatcherChangeWorkaround();
|
2020-07-07 07:15:45 +12:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
FileInfo[] arrFI = new FileInfo[1];
|
2022-06-18 00:38:09 +12:00
|
|
|
|
arrFI[0] = FileInfo;
|
2020-07-07 07:15:45 +12:00
|
|
|
|
ctxMnu.ShowContextMenu(arrFI, point);
|
2022-06-19 09:43:30 +12:00
|
|
|
|
TriggerFileWatcherChangeWorkaround();
|
2020-07-07 07:15:45 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IsContextMenuOpen = false;
|
2020-07-07 09:37:55 +12:00
|
|
|
|
contextMenuClosed = DateTime.Now;
|
2020-07-07 07:15:45 +12:00
|
|
|
|
}
|
2022-06-19 09:43:30 +12:00
|
|
|
|
|
|
|
|
|
void TriggerFileWatcherChangeWorkaround()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string parentFolder = System.IO.Path.GetDirectoryName(Path);
|
|
|
|
|
Directory.GetFiles(parentFolder);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Log.Warn($"{nameof(TriggerFileWatcherChangeWorkaround)} '{Path}'", ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-24 12:22:38 +13:00
|
|
|
|
}
|
2020-08-06 20:42:27 +12:00
|
|
|
|
|
2021-11-24 12:22:38 +13:00
|
|
|
|
internal void MouseClick(MouseEventArgs e, out bool toCloseByDoubleClick)
|
|
|
|
|
{
|
2022-02-05 22:32:28 +13:00
|
|
|
|
IsClicking = false;
|
2021-11-24 12:22:38 +13:00
|
|
|
|
toCloseByDoubleClick = false;
|
2020-08-06 20:42:27 +12:00
|
|
|
|
if (Properties.Settings.Default.OpenItemWithOneClick)
|
|
|
|
|
{
|
2021-05-02 23:12:18 +12:00
|
|
|
|
OpenItem(e, ref toCloseByDoubleClick);
|
2020-08-06 20:42:27 +12:00
|
|
|
|
}
|
2022-01-16 00:07:02 +13:00
|
|
|
|
|
|
|
|
|
if (Properties.Settings.Default.OpenDirectoryWithOneClick &&
|
|
|
|
|
ContainsMenu && (e == null || e.Button == MouseButtons.Left))
|
|
|
|
|
{
|
2022-06-18 00:38:09 +12:00
|
|
|
|
Log.ProcessStart(Path);
|
2022-01-16 00:07:02 +13:00
|
|
|
|
if (!Properties.Settings.Default.StaysOpenWhenItemClicked)
|
|
|
|
|
{
|
|
|
|
|
toCloseByDoubleClick = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-07 07:15:45 +12:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-02 23:12:18 +12:00
|
|
|
|
internal void DoubleClick(MouseEventArgs e, out bool toCloseByDoubleClick)
|
2020-08-06 20:42:27 +12:00
|
|
|
|
{
|
2022-02-05 22:32:28 +13:00
|
|
|
|
IsClicking = false;
|
2021-05-02 23:12:18 +12:00
|
|
|
|
toCloseByDoubleClick = false;
|
2020-08-06 20:42:27 +12:00
|
|
|
|
if (!Properties.Settings.Default.OpenItemWithOneClick)
|
|
|
|
|
{
|
2021-05-02 23:12:18 +12:00
|
|
|
|
OpenItem(e, ref toCloseByDoubleClick);
|
2020-08-06 20:42:27 +12:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-16 00:07:02 +13:00
|
|
|
|
if (!Properties.Settings.Default.OpenDirectoryWithOneClick &&
|
|
|
|
|
ContainsMenu && (e == null || e.Button == MouseButtons.Left))
|
2020-08-06 20:42:27 +12:00
|
|
|
|
{
|
2022-06-18 00:38:09 +12:00
|
|
|
|
Log.ProcessStart(Path);
|
2021-05-02 23:12:18 +12:00
|
|
|
|
if (!Properties.Settings.Default.StaysOpenWhenItemClicked)
|
|
|
|
|
{
|
|
|
|
|
toCloseByDoubleClick = true;
|
|
|
|
|
}
|
2020-08-06 20:42:27 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-02 23:12:18 +12:00
|
|
|
|
private void OpenItem(MouseEventArgs e, ref bool toCloseByOpenItem)
|
2020-07-07 07:15:45 +12:00
|
|
|
|
{
|
2020-07-07 09:37:55 +12:00
|
|
|
|
if (!ContainsMenu &&
|
|
|
|
|
(e == null || e.Button == MouseButtons.Left))
|
2020-07-07 07:15:45 +12:00
|
|
|
|
{
|
2021-10-26 08:45:49 +13:00
|
|
|
|
ProcessStarted = true;
|
2022-06-18 00:38:09 +12:00
|
|
|
|
string workingDirectory = System.IO.Path.GetDirectoryName(ResolvedPath);
|
2022-06-26 20:56:47 +12:00
|
|
|
|
Log.ProcessStart(Path, string.Empty, false, workingDirectory, true, ResolvedPath);
|
2021-05-03 01:01:31 +12:00
|
|
|
|
if (!Properties.Settings.Default.StaysOpenWhenItemClicked)
|
2020-07-07 07:15:45 +12:00
|
|
|
|
{
|
2021-05-03 01:01:31 +12:00
|
|
|
|
toCloseByOpenItem = true;
|
2020-07-07 07:15:45 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-28 08:43:16 +13:00
|
|
|
|
}
|
|
|
|
|
}
|