901 lines
36 KiB
C#
901 lines
36 KiB
C#
using System.IO;
|
|||
|
|
using System.Windows;
|
||
|
|
using System.Windows.Controls;
|
||
|
|
using System.Windows.Controls.Primitives;
|
||
|
|
using System.Windows.Input;
|
||
|
|
using PCL.Core.App;
|
||
|
|
using PCL.Core.App.Localization;
|
||
|
|
using PCL.Core.Logging;
|
||
|
|
using PCL.Core.UI;
|
||
|
|
using PCL.Core.Utils.Validate;
|
||
|
|
using PCL.Network;
|
||
|
|
|
||
|
|
namespace PCL;
|
||
|
|
|
||
|
|
public partial class PageSelectLeft : IRefreshable
|
||
|
|
{
|
||
|
|
private bool isFirstLoad = true;
|
||
|
|
private List<ModFolder.McFolder> mcFolderListLast;
|
||
|
|
|
||
|
|
public PageSelectLeft()
|
||
|
|
{
|
||
|
|
Initialized += PageSelectLeft_Initialized;
|
||
|
|
Loaded += PageSelectLeft_Loaded;
|
||
|
|
InitializeComponent();
|
||
|
|
}
|
||
|
|
|
||
|
|
void IRefreshable.Refresh()
|
||
|
|
{
|
||
|
|
RefreshCurrent();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void PageSelectLeft_Initialized(object sender, EventArgs e)
|
||
|
|
{
|
||
|
|
ModFolder.mcFolderListLoader.PreviewFinish += _ =>
|
||
|
|
{
|
||
|
|
if (ModMain.frmSelectLeft is not null) ModBase.RunInUiWait(McFolderListUI);
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
private void PageSelectLeft_Loaded(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
if (isFirstLoad)
|
||
|
|
McFolderListUI(); // 若已经执行完成,触发首次加载
|
||
|
|
isFirstLoad = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void McFolderListUI()
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
// 确认数据有变化
|
||
|
|
if (mcFolderListLast is not null && mcFolderListLast.SequenceEqual(ModFolder.mcFolderList))
|
||
|
|
return;
|
||
|
|
|
||
|
|
mcFolderListLast = new List<ModFolder.McFolder>(ModFolder.mcFolderList);
|
||
|
|
|
||
|
|
// 创建 UI
|
||
|
|
ModMain.frmSelectLeft.PanList.Children.Clear();
|
||
|
|
|
||
|
|
// 文件夹列表标题
|
||
|
|
ModMain.frmSelectLeft.PanList.Children.Add(new TextBlock
|
||
|
|
{
|
||
|
|
Text = Lang.Text("Select.Folder.ListTitle"),
|
||
|
|
Margin = new Thickness(13, 18, 5, 4),
|
||
|
|
Opacity = 0.6,
|
||
|
|
FontSize = 12
|
||
|
|
});
|
||
|
|
|
||
|
|
for (var i = 0; i < ModFolder.mcFolderList.Count; i++)
|
||
|
|
{
|
||
|
|
var folder = ModFolder.mcFolderList[i];
|
||
|
|
|
||
|
|
// 创建 ContextMenu
|
||
|
|
var contMenu = new ContextMenu();
|
||
|
|
|
||
|
|
// 添加菜单项
|
||
|
|
void AddMenuItem(string name, string header, string svgIcon = null, Thickness? padding = null,
|
||
|
|
RoutedEventHandler clickHandler = null)
|
||
|
|
{
|
||
|
|
var item = new MyMenuItem
|
||
|
|
{
|
||
|
|
Name = name,
|
||
|
|
Header = header,
|
||
|
|
SvgIcon = svgIcon,
|
||
|
|
Padding = padding ?? new Thickness(0)
|
||
|
|
};
|
||
|
|
if (clickHandler is not null)
|
||
|
|
item.Click += clickHandler;
|
||
|
|
contMenu.Items.Add(item);
|
||
|
|
}
|
||
|
|
|
||
|
|
const string iconRestore = "lucide/rotate-ccw";
|
||
|
|
const string iconRename = "lucide/pencil";
|
||
|
|
const string iconMoveup = "lucide/move-up";
|
||
|
|
const string iconMovedown = "lucide/move-down";
|
||
|
|
const string iconOpen = "lucide/folder-open";
|
||
|
|
const string iconRefresh = "lucide/refresh-cw";
|
||
|
|
const string iconDelete = "lucide/trash-2";
|
||
|
|
const string iconRemove = "lucide/list-x";
|
||
|
|
|
||
|
|
switch (folder.type)
|
||
|
|
{
|
||
|
|
case ModFolder.McFolder.Types.Original:
|
||
|
|
AddMenuItem("Rename", Lang.Text("Select.Folder.Rename"), iconRename, new Thickness(0, 2, 0, 0),
|
||
|
|
ModMain.frmSelectLeft.Rename_Click);
|
||
|
|
AddMenuItem("MoveUp", Lang.Text("Select.Folder.MoveUp"), iconMoveup, null,
|
||
|
|
ModMain.frmSelectLeft.MoveUp_Click);
|
||
|
|
AddMenuItem("MoveDown", Lang.Text("Select.Folder.MoveDown"), iconMovedown, null,
|
||
|
|
ModMain.frmSelectLeft.MoveDown_Click);
|
||
|
|
AddMenuItem("Open", Lang.Text("Common.Action.Open"), iconOpen, null,
|
||
|
|
ModMain.frmSelectLeft.Open_Click);
|
||
|
|
AddMenuItem("Refresh", Lang.Text("Common.Action.Refresh"), iconRefresh, null,
|
||
|
|
ModMain.frmSelectLeft.Refresh_Click);
|
||
|
|
AddMenuItem("Delete",
|
||
|
|
ModFolder.mcFolderList.Count == 1 &&
|
||
|
|
folder.Location == Path.Combine(ModBase.exePath, ".minecraft") + @"\"
|
||
|
|
? Lang.Text("Select.Folder.Clear")
|
||
|
|
: Lang.Text("Common.Action.Delete"), iconDelete, new Thickness(0, 0, 0, 2),
|
||
|
|
ModMain.frmSelectLeft.Delete_Click);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case ModFolder.McFolder.Types.RenamedOriginal:
|
||
|
|
AddMenuItem("Restore", Lang.Text("Select.Folder.RestoreName"), iconRestore,
|
||
|
|
new Thickness(0, 2, 0, 0),
|
||
|
|
ModMain.frmSelectLeft.Restore_Click);
|
||
|
|
AddMenuItem("Rename", Lang.Text("Select.Folder.Rename"), iconRename, null,
|
||
|
|
ModMain.frmSelectLeft.Rename_Click);
|
||
|
|
AddMenuItem("MoveUp", Lang.Text("Select.Folder.MoveUp"), iconMoveup, null,
|
||
|
|
ModMain.frmSelectLeft.MoveUp_Click);
|
||
|
|
AddMenuItem("MoveDown", Lang.Text("Select.Folder.MoveDown"), iconMovedown, null,
|
||
|
|
ModMain.frmSelectLeft.MoveDown_Click);
|
||
|
|
AddMenuItem("Open", Lang.Text("Common.Action.Open"), iconOpen, null,
|
||
|
|
ModMain.frmSelectLeft.Open_Click);
|
||
|
|
AddMenuItem("Refresh", Lang.Text("Common.Action.Refresh"), iconRefresh, null,
|
||
|
|
ModMain.frmSelectLeft.Refresh_Click);
|
||
|
|
AddMenuItem("Delete", Lang.Text("Common.Action.Delete"), iconDelete, new Thickness(0, 0, 0, 2),
|
||
|
|
ModMain.frmSelectLeft.Delete_Click);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case ModFolder.McFolder.Types.Custom:
|
||
|
|
AddMenuItem("Rename", Lang.Text("Select.Folder.Rename"), iconRename, new Thickness(0, 2, 0, 0),
|
||
|
|
ModMain.frmSelectLeft.Rename_Click);
|
||
|
|
AddMenuItem("MoveUp", Lang.Text("Select.Folder.MoveUp"), iconMoveup, null,
|
||
|
|
ModMain.frmSelectLeft.MoveUp_Click);
|
||
|
|
AddMenuItem("MoveDown", Lang.Text("Select.Folder.MoveDown"), iconMovedown, null,
|
||
|
|
ModMain.frmSelectLeft.MoveDown_Click);
|
||
|
|
AddMenuItem("Open", Lang.Text("Common.Action.Open"), iconOpen, null,
|
||
|
|
ModMain.frmSelectLeft.Open_Click);
|
||
|
|
AddMenuItem("Refresh", Lang.Text("Common.Action.Refresh"), iconRefresh, null,
|
||
|
|
ModMain.frmSelectLeft.Refresh_Click);
|
||
|
|
AddMenuItem("Remove", Lang.Text("Select.Folder.RemoveFromList"), iconRemove,
|
||
|
|
null, ModMain.frmSelectLeft.Remove_Click);
|
||
|
|
AddMenuItem("Delete", Lang.Text("Common.Action.Delete"), iconDelete, new Thickness(0, 0, 0, 2),
|
||
|
|
ModMain.frmSelectLeft.Delete_Click);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 控制上移下移显示
|
||
|
|
var moveUpItem = contMenu.Items.OfType<MyMenuItem>().FirstOrDefault(x => x.Name == "MoveUp");
|
||
|
|
var moveDownItem = contMenu.Items.OfType<MyMenuItem>().FirstOrDefault(x => x.Name == "MoveDown");
|
||
|
|
|
||
|
|
// 如果是第一个项目,隐藏上移按钮
|
||
|
|
if (i == 0) moveUpItem.Visibility = Visibility.Collapsed;
|
||
|
|
|
||
|
|
// 如果是最后一个项目,隐藏下移按钮
|
||
|
|
if (i == ModFolder.mcFolderList.Count - 1) moveDownItem.Visibility = Visibility.Collapsed;
|
||
|
|
|
||
|
|
// 构建列表项
|
||
|
|
var newItem = new MyListItem
|
||
|
|
{
|
||
|
|
IsScaleAnimationEnabled = false,
|
||
|
|
Type = MyListItem.CheckType.RadioBox,
|
||
|
|
MinPaddingRight = 30,
|
||
|
|
Title = folder.Name,
|
||
|
|
Info = folder.Location,
|
||
|
|
Height = 40,
|
||
|
|
ContextMenu = contMenu,
|
||
|
|
Tag = folder
|
||
|
|
};
|
||
|
|
|
||
|
|
newItem.Changed += (a, b) => ModMain.frmSelectLeft.Folder_Change((MyListItem)a, b);
|
||
|
|
|
||
|
|
// 拖拽
|
||
|
|
newItem.AllowDrop = true;
|
||
|
|
newItem.MouseMove += ModMain.frmSelectLeft.Item_MouseMove;
|
||
|
|
newItem.DragEnter += ModMain.frmSelectLeft.Item_DragEnter;
|
||
|
|
newItem.DragOver += ModMain.frmSelectLeft.Item_DragOver;
|
||
|
|
newItem.DragLeave += ModMain.frmSelectLeft.Item_DragLeave;
|
||
|
|
newItem.Drop += ModMain.frmSelectLeft.Item_Drop;
|
||
|
|
|
||
|
|
// 图标按钮
|
||
|
|
var newIconButton = new MyIconButton
|
||
|
|
{
|
||
|
|
SvgIcon = "lucide/settings",
|
||
|
|
LogoScale = 1.1
|
||
|
|
};
|
||
|
|
newIconButton.Click += (_, _) =>
|
||
|
|
{
|
||
|
|
contMenu.PlacementTarget = newItem;
|
||
|
|
contMenu.IsOpen = true;
|
||
|
|
};
|
||
|
|
newItem.Buttons = [newIconButton];
|
||
|
|
|
||
|
|
ModMain.frmSelectLeft.PanList.Children.Add(newItem);
|
||
|
|
|
||
|
|
LogWrapper.Info($"[Minecraft] 有效的 Minecraft 文件夹:{folder.Name} > {folder.Location}");
|
||
|
|
}
|
||
|
|
|
||
|
|
// 标题文本
|
||
|
|
ModMain.frmSelectLeft.PanList.Children.Add(new TextBlock
|
||
|
|
{
|
||
|
|
Text = Lang.Text("Select.Folder.AddOrImport"),
|
||
|
|
Margin = new Thickness(13, 18, 5, 4),
|
||
|
|
Opacity = 0.6,
|
||
|
|
FontSize = 12
|
||
|
|
});
|
||
|
|
|
||
|
|
// 创建新文件夹按钮
|
||
|
|
if (!Directory.Exists(Path.Combine(ModBase.exePath, ".minecraft")))
|
||
|
|
{
|
||
|
|
var itemCreate = new MyListItem
|
||
|
|
{
|
||
|
|
IsScaleAnimationEnabled = false,
|
||
|
|
Type = MyListItem.CheckType.Clickable,
|
||
|
|
Title = Lang.Text("Select.Folder.CreateNew.Title"),
|
||
|
|
Height = 34,
|
||
|
|
ToolTip = Lang.Text("Select.Folder.CreateNew.ToolTip"),
|
||
|
|
LogoScale = 0.9,
|
||
|
|
SvgIcon = "lucide/folder-plus"
|
||
|
|
};
|
||
|
|
ToolTipService.SetPlacement(itemCreate, PlacementMode.Right);
|
||
|
|
itemCreate.Click += (_, _) => ModMain.frmSelectLeft.Create_Click();
|
||
|
|
ModMain.frmSelectLeft.PanList.Children.Add(itemCreate);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 添加按钮
|
||
|
|
var itemAdd = new MyListItem
|
||
|
|
{
|
||
|
|
IsScaleAnimationEnabled = false,
|
||
|
|
Type = MyListItem.CheckType.Clickable,
|
||
|
|
Title = Lang.Text("Select.Folder.AddExisting.Title"),
|
||
|
|
Height = 34,
|
||
|
|
ToolTip = Lang.Text("Select.Folder.AddExisting.ToolTip"),
|
||
|
|
SvgIcon = "lucide/folder-input"
|
||
|
|
};
|
||
|
|
ToolTipService.SetPlacement(itemAdd, PlacementMode.Right);
|
||
|
|
itemAdd.Click += (_, _) => ModMain.frmSelectLeft.Add_Click();
|
||
|
|
ModMain.frmSelectLeft.PanList.Children.Add(itemAdd);
|
||
|
|
|
||
|
|
// 导入整合包
|
||
|
|
var itemInstall = new MyListItem
|
||
|
|
{
|
||
|
|
IsScaleAnimationEnabled = false,
|
||
|
|
Type = MyListItem.CheckType.Clickable,
|
||
|
|
Title = Lang.Text("Select.Folder.ImportModpack.Title"),
|
||
|
|
Height = 34,
|
||
|
|
ToolTip = Lang.Text("Select.Folder.ImportModpack.ToolTip"),
|
||
|
|
SvgIcon = "lucide/package-plus"
|
||
|
|
};
|
||
|
|
ToolTipService.SetPlacement(itemInstall, PlacementMode.Right);
|
||
|
|
itemInstall.Click += (_, _) => ModModpack.ModpackInstall();
|
||
|
|
ModMain.frmSelectLeft.PanList.Children.Add(itemInstall);
|
||
|
|
|
||
|
|
// 边距
|
||
|
|
ModMain.frmSelectLeft.PanList.Children.Add(new FrameworkElement { Height = 10, IsHitTestVisible = false });
|
||
|
|
|
||
|
|
// 确认勾选状态
|
||
|
|
for (var i = 0; i < ModFolder.mcFolderList.Count; i++)
|
||
|
|
if (ModFolder.mcFolderList[i].Location == ModFolder.mcFolderSelected)
|
||
|
|
{
|
||
|
|
((MyListItem)ModMain.frmSelectLeft.PanList.Children[i + 1]).Checked = true; //去掉第一个标题
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ModFolder.mcFolderList.Count == 0)
|
||
|
|
throw new ArgumentNullException("没有可用的 Minecraft 文件夹");
|
||
|
|
States.Game.SelectedFolder = ModFolder.mcFolderList[0].Location.Replace(ModBase.exePath, "$");
|
||
|
|
((MyListItem)ModMain.frmSelectLeft.PanList.Children[1]).Checked = true;
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
LogWrapper.Error(ex, "构建 Minecraft 文件夹列表 UI 出错");
|
||
|
|
}
|
||
|
|
finally
|
||
|
|
{
|
||
|
|
ModLoader.LoaderFolderRun(ModInstanceList.mcInstanceListLoader,
|
||
|
|
ModFolder.mcFolderSelected,
|
||
|
|
ModLoader.LoaderFolderRunType.RunOnUpdated,
|
||
|
|
1,
|
||
|
|
"versions\\");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void MoveUp_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
var folder =
|
||
|
|
(ModFolder.McFolder)((MyListItem)((Popup)((ContextMenu)((MyMenuItem)sender).Parent).Parent)
|
||
|
|
.PlacementTarget)
|
||
|
|
.Tag;
|
||
|
|
var index = ModFolder.mcFolderList.IndexOf(folder);
|
||
|
|
if (index <= 0) return;
|
||
|
|
ModFolder.mcFolderList.RemoveAt(index);
|
||
|
|
ModFolder.mcFolderList.Insert(index - 1, folder);
|
||
|
|
UpdateFolderOrder();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void MoveDown_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
var folder =
|
||
|
|
(ModFolder.McFolder)((MyListItem)((Popup)((ContextMenu)((MyMenuItem)sender).Parent).Parent)
|
||
|
|
.PlacementTarget)
|
||
|
|
.Tag;
|
||
|
|
var index = ModFolder.mcFolderList.IndexOf(folder);
|
||
|
|
if (index >= ModFolder.mcFolderList.Count - 1) return;
|
||
|
|
ModFolder.mcFolderList.RemoveAt(index);
|
||
|
|
ModFolder.mcFolderList.Insert(index + 1, folder);
|
||
|
|
UpdateFolderOrder();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void UpdateFolderOrder()
|
||
|
|
{
|
||
|
|
States.Game.Folders = ModFolder.mcFolderList
|
||
|
|
.Select(folder => $"{folder.Name}>{folder.Location}")
|
||
|
|
.ToArray()
|
||
|
|
.Join("|");
|
||
|
|
McFolderListUI();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void Restore_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
var folder =
|
||
|
|
(ModFolder.McFolder)((MyListItem)((Popup)((ContextMenu)((MyMenuItem)sender).Parent).Parent)
|
||
|
|
.PlacementTarget)
|
||
|
|
.Tag;
|
||
|
|
var index = ModFolder.mcFolderList.IndexOf(folder);
|
||
|
|
ModFolder.mcFolderList[index].type = ModFolder.McFolder.Types.Original;
|
||
|
|
ModFolder.mcFolderList[index].Name = Lang.Text("Select.Folder.OfficialLauncherFolder");
|
||
|
|
UpdateFolderOrder();
|
||
|
|
}
|
||
|
|
|
||
|
|
// 添加文件夹
|
||
|
|
private void Add_Click()
|
||
|
|
{
|
||
|
|
var newFolder = "";
|
||
|
|
// 检查是否有下载任务
|
||
|
|
if (ModNet.HasDownloadingTask())
|
||
|
|
{
|
||
|
|
HintService.Hint(Lang.Text("Select.Folder.CannotAddWhileDownloading"), HintType.Error);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
// 获取输入
|
||
|
|
newFolder = SystemDialogs.SelectFolder();
|
||
|
|
if (string.IsNullOrEmpty(newFolder))
|
||
|
|
return;
|
||
|
|
if (newFolder.Contains('!') || newFolder.Contains(';'))
|
||
|
|
{
|
||
|
|
HintService.Hint(Lang.Text("Select.Folder.InvalidPathChars"), HintType.Error);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 要求输入显示名称
|
||
|
|
var splitedNames = newFolder.TrimEnd('\\').Split(@"\");
|
||
|
|
var defaultName = splitedNames.Last() == ".minecraft"
|
||
|
|
? splitedNames.Length >= 3 ? splitedNames[^2] : ""
|
||
|
|
: splitedNames.Last();
|
||
|
|
if (defaultName.Length > 40)
|
||
|
|
defaultName = defaultName[..39];
|
||
|
|
var newName = ModMain.MyMsgBoxInput(Lang.Text("Select.Folder.InputDisplayName.Title"),
|
||
|
|
Lang.Text("Select.Folder.InputDisplayName.Message"), defaultName,
|
||
|
|
[new NullOrWhiteSpaceValidator(), new StringLengthValidator(), new BlacklistValidator([">", "|"])]);
|
||
|
|
if (string.IsNullOrWhiteSpace(newName))
|
||
|
|
return;
|
||
|
|
// 添加文件夹
|
||
|
|
AddFolder(newFolder, newName, true);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
ModBase.Log(
|
||
|
|
ex,
|
||
|
|
Lang.Text("Select.Folder.Error.Add", newFolder),
|
||
|
|
ModBase.LogLevel.Feedback,
|
||
|
|
userSummary: Lang.Text("Select.Folder.Error.Add", newFolder));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 将指定文件夹添加到 Minecraft 文件夹列表,并选中它。
|
||
|
|
/// </summary>
|
||
|
|
public static void AddFolder(string folderPath, string displayName, bool showHint)
|
||
|
|
{
|
||
|
|
// 检查文件夹权限
|
||
|
|
// 检查实际的 Minecraft 文件夹位置(没有问题,或是在子文件夹中)
|
||
|
|
// 判断是否已经添加过,若添加过则直接修改自定义名
|
||
|
|
// 如果没有添加过,则添加进去
|
||
|
|
// 保存
|
||
|
|
// 切换选择并更新列表
|
||
|
|
// 提示
|
||
|
|
// 检查是否为根目录整合包,自动关闭版本隔离
|
||
|
|
// 1. 根目录中存在数个 Mod
|
||
|
|
// 2. 实例数较少,可能为整合包
|
||
|
|
// 3. 能够找到可安装 Mod 的实例
|
||
|
|
// 4. 该实例的隔离文件夹下不存在 mods
|
||
|
|
// 满足以上全部条件则视为根目录整合包
|
||
|
|
ModBase.RunInThread(() =>
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
if (!folderPath.EndsWith(@"\")) folderPath += @"\";
|
||
|
|
if (!ModBase.CheckPermission(folderPath))
|
||
|
|
{
|
||
|
|
if (!showHint) throw new Exception("PCL 没有访问文件夹的权限:" + folderPath);
|
||
|
|
HintService.Hint(Lang.Text("Select.Folder.AccessDenied"), HintType.Error);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!ModBase.CheckPermission(folderPath + @"versions\"))
|
||
|
|
foreach (var Folder in new DirectoryInfo(folderPath).GetDirectories())
|
||
|
|
if (ModBase.CheckPermission(Path.Combine(Folder.FullName, "versions")))
|
||
|
|
{
|
||
|
|
folderPath = Folder.FullName + @"\";
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
var folders = new List<string>(States.Game.Folders.Split("|"));
|
||
|
|
var isAdded = false;
|
||
|
|
var isReplace = false;
|
||
|
|
for (int i = 0, loopTo = folders.Count - 1; i <= loopTo; i++)
|
||
|
|
{
|
||
|
|
var folder = folders[i];
|
||
|
|
if (string.IsNullOrEmpty(folder)) continue;
|
||
|
|
if (folder.Split(">")[1] != (folderPath ?? "")) continue;
|
||
|
|
isAdded = true;
|
||
|
|
if (folder.Split(">")[0] == displayName)
|
||
|
|
{
|
||
|
|
if (showHint) HintService.Hint(Lang.Text("Select.Folder.AlreadyInList"));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
folders[i] = $"{displayName}>{folderPath}";
|
||
|
|
isReplace = true;
|
||
|
|
if (showHint)
|
||
|
|
HintService.Hint(Lang.Text("Select.Folder.NameUpdated", displayName), HintType.Success);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!isAdded) folders.Add($"{displayName}>{folderPath}");
|
||
|
|
States.Game.Folders = folders.ToArray().Join("|");
|
||
|
|
States.Game.SelectedFolder = folderPath.Replace(ModBase.exePath, "$");
|
||
|
|
ModFolder.mcFolderListLoader.Start(isForceRestart: true);
|
||
|
|
if (isReplace) return;
|
||
|
|
if (showHint) HintService.Hint(Lang.Text("Select.Folder.Added", displayName), HintType.Success);
|
||
|
|
var modFolder = new DirectoryInfo(folderPath + @"mods\");
|
||
|
|
if (!(modFolder.Exists && modFolder.EnumerateFiles().Count() >= 3)) return;
|
||
|
|
var versionFolder = new DirectoryInfo(folderPath + @"versions\");
|
||
|
|
if (!(versionFolder.Exists && versionFolder.EnumerateDirectories().Count() <= 3)) return;
|
||
|
|
foreach (var VersionPath in versionFolder.EnumerateDirectories())
|
||
|
|
{
|
||
|
|
var version = new McInstance(VersionPath.FullName);
|
||
|
|
version.Load();
|
||
|
|
if (!version.Modable) continue;
|
||
|
|
var modIndieFolder = new DirectoryInfo(version.PathInstance + @"mods\");
|
||
|
|
if (modIndieFolder.Exists && modIndieFolder.EnumerateFiles().Any()) return;
|
||
|
|
Config.Instance.IndieV1[version.PathInstance] = 2;
|
||
|
|
Config.Instance.IndieV2[version.PathInstance] = false;
|
||
|
|
ModBase.Log("[Setup] 已自动关闭单版本隔离:" + version.Name, ModBase.LogLevel.Debug);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
ModBase.Log(
|
||
|
|
ex,
|
||
|
|
Lang.Text("Select.Folder.Error.AddNew"),
|
||
|
|
ModBase.LogLevel.Feedback,
|
||
|
|
userSummary: Lang.Text("Select.Folder.Error.AddNew"));
|
||
|
|
}
|
||
|
|
}); // 加上斜杠……
|
||
|
|
}
|
||
|
|
|
||
|
|
// 创建文件夹
|
||
|
|
public void Create_Click()
|
||
|
|
{
|
||
|
|
// 检查是否有下载任务
|
||
|
|
if (ModNet.HasDownloadingTask())
|
||
|
|
{
|
||
|
|
HintService.Hint(Lang.Text("Select.Folder.CannotCreateWhileDownloading"), HintType.Error);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!Directory.Exists(ModBase.exePath + @".minecraft\"))
|
||
|
|
{
|
||
|
|
Directory.CreateDirectory(ModBase.exePath + @".minecraft\");
|
||
|
|
Directory.CreateDirectory(ModBase.exePath + @".minecraft\versions\");
|
||
|
|
States.Game.SelectedFolder = @"$.minecraft\";
|
||
|
|
ModFolder.McFolderLauncherProfilesJsonCreate(ModBase.exePath + @".minecraft\");
|
||
|
|
HintService.Hint(Lang.Text("Select.Folder.CreateSuccess"), HintType.Success);
|
||
|
|
}
|
||
|
|
|
||
|
|
ModFolder.mcFolderListLoader.Start(isForceRestart: true);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 右键菜单
|
||
|
|
public void Remove_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var folder =
|
||
|
|
(ModFolder.McFolder)((MyListItem)((Popup)((ContextMenu)((MyMenuItem)sender).Parent).Parent)
|
||
|
|
.PlacementTarget).Tag;
|
||
|
|
switch (ModMain.MyMsgBox(
|
||
|
|
Lang.Text("Select.Folder.Cleanup.Message"),
|
||
|
|
Lang.Text("Select.Folder.Cleanup.Title"), Lang.Text("Common.Action.Delete"),
|
||
|
|
Lang.Text("Select.Folder.Cleanup.Keep"), Lang.Text("Common.Action.Cancel")))
|
||
|
|
{
|
||
|
|
case 1:
|
||
|
|
{
|
||
|
|
// 删除配置文件
|
||
|
|
if (File.Exists(folder.Location + "PCL.ini"))
|
||
|
|
File.Delete(folder.Location + "PCL.ini");
|
||
|
|
if (Directory.Exists(folder.Location + @"versions\"))
|
||
|
|
foreach (var Version in new DirectoryInfo(folder.Location + @"versions\")
|
||
|
|
.EnumerateDirectories())
|
||
|
|
if (Directory.Exists(Path.Combine(Version.FullName, "PCL")))
|
||
|
|
Directory.Delete(Path.Combine(Version.FullName, "PCL"), true);
|
||
|
|
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case 2:
|
||
|
|
{
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
// 不删除
|
||
|
|
case 3:
|
||
|
|
{
|
||
|
|
// 取消
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 若修改了本部分代码,应对应修改 Delete_Click 中的代码
|
||
|
|
// 获取并删除列表项
|
||
|
|
var folders = new List<string>(States.Game.Folders.Split("|"));
|
||
|
|
var name = "";
|
||
|
|
for (int i = 0, loopTo = folders.Count - 1; i <= loopTo; i++)
|
||
|
|
{
|
||
|
|
if (string.IsNullOrEmpty(folders[i]))
|
||
|
|
break;
|
||
|
|
if (!folders[i].EndsWith(folder.Location)) continue;
|
||
|
|
name = folders[i].BeforeFirst(">");
|
||
|
|
folders.RemoveAt(i);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 保存
|
||
|
|
States.Game.Folders = folders.Count == 0 ? "" : folders.ToArray().Join("|");
|
||
|
|
HintService.Hint(
|
||
|
|
folder.type == ModFolder.McFolder.Types.Custom
|
||
|
|
? Lang.Text("Select.Folder.RemoveSuccess", name)
|
||
|
|
: Lang.Text("Select.Folder.RestoreSuccess"),
|
||
|
|
HintType.Success);
|
||
|
|
ModFolder.mcFolderListLoader.Start(isForceRestart: true);
|
||
|
|
}
|
||
|
|
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
ModBase.Log(
|
||
|
|
ex,
|
||
|
|
Lang.Text("Select.Folder.Error.Remove"),
|
||
|
|
ModBase.LogLevel.Feedback,
|
||
|
|
userSummary: Lang.Text("Select.Folder.Error.Remove"));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void Delete_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
var menuItem = (MyMenuItem)sender;
|
||
|
|
var contextMenu = (ContextMenu)menuItem.Parent;
|
||
|
|
var popup = (Popup)contextMenu.Parent;
|
||
|
|
var listItem = (MyListItem)popup.PlacementTarget;
|
||
|
|
var folder = (ModFolder.McFolder)listItem.Tag;
|
||
|
|
|
||
|
|
var isClearing =
|
||
|
|
folder.type is ModFolder.McFolder.Types.Original or ModFolder.McFolder.Types.RenamedOriginal
|
||
|
|
&& folder.Location == ModBase.exePath + @".minecraft\"
|
||
|
|
&& ModFolder.mcFolderList.Count == 1;
|
||
|
|
|
||
|
|
var deleteText = Lang.Text(isClearing ? "Select.Folder.Clear" : "Common.Action.Delete");
|
||
|
|
var firstWarning =
|
||
|
|
Lang.Text(isClearing ? "Select.Folder.Clear.FirstWarning" : "Select.Folder.Delete.FirstWarning",
|
||
|
|
folder.Location);
|
||
|
|
var finalWarning =
|
||
|
|
Lang.Text(isClearing ? "Select.Folder.Clear.FinalWarning" : "Select.Folder.Delete.FinalWarning",
|
||
|
|
folder.Location);
|
||
|
|
var confirmTitle = Lang.Text(isClearing ? "Select.Folder.Clear.Confirm" : "Select.Folder.Delete.Confirm");
|
||
|
|
var inProgress = Lang.Text(isClearing ? "Select.Folder.Clear.InProgress" : "Select.Folder.Delete.InProgress",
|
||
|
|
folder.Name);
|
||
|
|
var success = Lang.Text(isClearing ? "Select.Folder.Clear.Success" : "Select.Folder.Delete.Success",
|
||
|
|
folder.Name);
|
||
|
|
|
||
|
|
if (ModMain.MyMsgBox(firstWarning, Lang.Text("Select.Folder.Delete.WarningTitle"),
|
||
|
|
Lang.Text("Common.Action.Cancel"), Lang.Text("Common.Action.Confirm"),
|
||
|
|
Lang.Text("Common.Action.Cancel")) != 2)
|
||
|
|
return;
|
||
|
|
|
||
|
|
if (ModMain.MyMsgBox(finalWarning, Lang.Text("Select.Folder.Delete.WarningTitle"),
|
||
|
|
confirmTitle, Lang.Text("Common.Action.Cancel"),
|
||
|
|
isWarn: true) != 1)
|
||
|
|
return;
|
||
|
|
|
||
|
|
var folders = States.Game.Folders.Split('|', StringSplitOptions.RemoveEmptyEntries).ToList();
|
||
|
|
var index = folders.FindIndex(f => f.EndsWith(folder.Location));
|
||
|
|
if (index >= 0)
|
||
|
|
folders.RemoveAt(index);
|
||
|
|
States.Game.Folders = string.Join("|", folders);
|
||
|
|
|
||
|
|
ModBase.RunInNewThread(() =>
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
HintService.Hint(inProgress);
|
||
|
|
ModBase.DeleteDirectory(folder.Location);
|
||
|
|
if (isClearing)
|
||
|
|
Directory.CreateDirectory(folder.Location);
|
||
|
|
HintService.Hint(success, HintType.Success);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
ModBase.Log(
|
||
|
|
ex,
|
||
|
|
Lang.Text("Select.Folder.Error.Operate", deleteText, folder.Name),
|
||
|
|
ModBase.LogLevel.Hint,
|
||
|
|
userSummary: Lang.Text("Select.Folder.Error.Operate", deleteText, folder.Name));
|
||
|
|
}
|
||
|
|
finally
|
||
|
|
{
|
||
|
|
ModFolder.mcFolderListLoader.Start(isForceRestart: true);
|
||
|
|
}
|
||
|
|
}, "Folder Delete " + ModBase.GetUuid(), ThreadPriority.BelowNormal);
|
||
|
|
}
|
||
|
|
|
||
|
|
public void Open_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
ModBase.OpenExplorer(((MyListItem)((Popup)((ContextMenu)((MyMenuItem)sender).Parent).Parent).PlacementTarget)
|
||
|
|
.Info);
|
||
|
|
}
|
||
|
|
|
||
|
|
public void Refresh_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
var data = (ModFolder.McFolder)((MyListItem)((Popup)((ContextMenu)((MyMenuItem)sender).Parent).Parent)
|
||
|
|
.PlacementTarget).Tag;
|
||
|
|
RefreshCurrent(data.Location);
|
||
|
|
}
|
||
|
|
|
||
|
|
public void RefreshCurrent()
|
||
|
|
{
|
||
|
|
RefreshCurrent(ModFolder.mcFolderSelected);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void RefreshCurrent(string folder)
|
||
|
|
{
|
||
|
|
ModBase.WriteIni(Path.Combine(folder, "PCL.ini"), "InstanceCache", "");
|
||
|
|
if (folder == ModFolder.mcFolderSelected)
|
||
|
|
ModLoader.LoaderFolderRun(ModInstanceList.mcInstanceListLoader, ModFolder.mcFolderSelected,
|
||
|
|
ModLoader.LoaderFolderRunType.ForceRun, 1, @"versions\");
|
||
|
|
}
|
||
|
|
|
||
|
|
public void Rename_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
var folder =
|
||
|
|
(ModFolder.McFolder)((MyListItem)((Popup)((ContextMenu)((MyMenuItem)sender).Parent).Parent)
|
||
|
|
.PlacementTarget)
|
||
|
|
.Tag;
|
||
|
|
try
|
||
|
|
{
|
||
|
|
// 获取输入
|
||
|
|
var newName = ModMain.MyMsgBoxInput(Lang.Text("Select.Folder.Rename.Title"), "", folder.Name,
|
||
|
|
[
|
||
|
|
new NullOrWhiteSpaceValidator(), new StringLengthValidator(1, 30),
|
||
|
|
new BlacklistValidator([">", "|"])
|
||
|
|
]);
|
||
|
|
if (string.IsNullOrWhiteSpace(newName))
|
||
|
|
return;
|
||
|
|
// 修改自定义名
|
||
|
|
var folders = new List<string>(States.Game.Folders.Split("|"));
|
||
|
|
var isAdded = false;
|
||
|
|
for (int i = 0, loopTo = folders.Count - 1; i <= loopTo; i++)
|
||
|
|
{
|
||
|
|
var folderCurrent = folders[i];
|
||
|
|
if (string.IsNullOrEmpty(folderCurrent))
|
||
|
|
continue;
|
||
|
|
if (folderCurrent.Split(">")[1] != (folder.Location ?? "")) continue;
|
||
|
|
isAdded = true;
|
||
|
|
if (folderCurrent.Split(">")[0] == newName)
|
||
|
|
// 名称未修改
|
||
|
|
return;
|
||
|
|
|
||
|
|
folders[i] = $"{newName}>{folder.Location}";
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 如果没有添加过,则添加进去(因为修改了默认项的名称)
|
||
|
|
if (!isAdded)
|
||
|
|
folders.Add($"{newName}>{folder.Location}");
|
||
|
|
HintService.Hint(Lang.Text("Select.Folder.NameUpdated", newName), HintType.Success);
|
||
|
|
// 保存
|
||
|
|
States.Game.Folders = folders.ToArray().Join("|");
|
||
|
|
ModFolder.mcFolderListLoader.Start(isForceRestart: true);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
ModBase.Log(
|
||
|
|
ex,
|
||
|
|
Lang.Text("Select.Folder.Error.Rename"),
|
||
|
|
ModBase.LogLevel.Feedback,
|
||
|
|
userSummary: Lang.Text("Select.Folder.Error.Rename"));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 点击选项
|
||
|
|
public void Folder_Change(MyListItem sender, ModBase.RouteEventArgs e)
|
||
|
|
{
|
||
|
|
if (!e.raiseByMouse || !sender.Checked)
|
||
|
|
return;
|
||
|
|
// 检查是否有下载任务
|
||
|
|
if (ModNet.HasDownloadingTask(true))
|
||
|
|
{
|
||
|
|
HintService.Hint(Lang.Text("Select.Folder.SwitchBlockedByDownload"), HintType.Error);
|
||
|
|
e.handled = true;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 更换
|
||
|
|
States.Game.SelectedFolder = ((ModFolder.McFolder)sender.Tag).Location.Replace(ModBase.exePath, "$");
|
||
|
|
ModFolder.mcFolderListLoader.Start(isForceRestart: true);
|
||
|
|
ModLoader.LoaderFolderRun(ModInstanceList.mcInstanceListLoader, ModFolder.mcFolderSelected,
|
||
|
|
ModLoader.LoaderFolderRunType.RunOnUpdated, 1, @"versions\"); // 刷新实例列表
|
||
|
|
}
|
||
|
|
|
||
|
|
#region 拖拽排序功能
|
||
|
|
|
||
|
|
// 拖拽开始时的鼠标移动处理
|
||
|
|
private void Item_MouseMove(object sender, MouseEventArgs e)
|
||
|
|
{
|
||
|
|
var item = (MyListItem)sender;
|
||
|
|
// 当按住鼠标左键时开始拖拽操作
|
||
|
|
if (e.LeftButton != MouseButtonState.Pressed) return;
|
||
|
|
try
|
||
|
|
{
|
||
|
|
DragDrop.DoDragDrop(item, item.Tag, DragDropEffects.Move);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
ModBase.Log(ex, "开始拖拽操作失败");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 拖拽进入时的处理
|
||
|
|
private void Item_DragEnter(object sender, DragEventArgs e)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
if (e.Data.GetDataPresent(typeof(ModFolder.McFolder)))
|
||
|
|
{
|
||
|
|
e.Effects = DragDropEffects.Move;
|
||
|
|
// 添加视觉反馈
|
||
|
|
var item = (MyListItem)sender;
|
||
|
|
item.Opacity = 0.7d;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
e.Effects = DragDropEffects.None;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (Exception)
|
||
|
|
{
|
||
|
|
e.Effects = DragDropEffects.None;
|
||
|
|
}
|
||
|
|
|
||
|
|
e.Handled = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 拖拽悬停时的处理
|
||
|
|
private void Item_DragOver(object sender, DragEventArgs e)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
e.Effects = e.Data.GetDataPresent(typeof(ModFolder.McFolder))
|
||
|
|
? DragDropEffects.Move
|
||
|
|
: DragDropEffects.None;
|
||
|
|
}
|
||
|
|
catch (Exception)
|
||
|
|
{
|
||
|
|
e.Effects = DragDropEffects.None;
|
||
|
|
}
|
||
|
|
|
||
|
|
e.Handled = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 拖拽离开时的处理
|
||
|
|
private void Item_DragLeave(object sender, DragEventArgs e)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
// 恢复视觉状态
|
||
|
|
var item = (MyListItem)sender;
|
||
|
|
item.Opacity = 1.0d;
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
ModBase.Log(ex, "拖拽离开处理失败");
|
||
|
|
}
|
||
|
|
|
||
|
|
e.Handled = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 拖拽放下时的处理
|
||
|
|
private void Item_Drop(object sender, DragEventArgs e)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var targetItem = (MyListItem)sender;
|
||
|
|
var targetFolder = (ModFolder.McFolder)targetItem.Tag;
|
||
|
|
|
||
|
|
// 恢复视觉状态
|
||
|
|
targetItem.Opacity = 1.0d;
|
||
|
|
|
||
|
|
// 检查数据有效性
|
||
|
|
if (!e.Data.GetDataPresent(typeof(ModFolder.McFolder)))
|
||
|
|
{
|
||
|
|
e.Handled = true;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var sourceFolder = (ModFolder.McFolder)e.Data.GetData(typeof(ModFolder.McFolder));
|
||
|
|
|
||
|
|
// 检查是否为有效的拖拽操作
|
||
|
|
if (ReferenceEquals(sourceFolder, targetFolder))
|
||
|
|
{
|
||
|
|
e.Handled = true;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 检查文件夹是否在列表中
|
||
|
|
if (!ModFolder.mcFolderList.Contains(sourceFolder) || !ModFolder.mcFolderList.Contains(targetFolder))
|
||
|
|
{
|
||
|
|
e.Handled = true;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 获取源文件夹和目标文件夹的索引
|
||
|
|
var sourceIndex = ModFolder.mcFolderList.IndexOf(sourceFolder);
|
||
|
|
var targetIndex = ModFolder.mcFolderList.IndexOf(targetFolder);
|
||
|
|
|
||
|
|
// 执行移动操作
|
||
|
|
if (sourceIndex == targetIndex) return;
|
||
|
|
// 先移除源文件夹
|
||
|
|
ModFolder.mcFolderList.RemoveAt(sourceIndex);
|
||
|
|
|
||
|
|
// 计算新的插入位置
|
||
|
|
int newTargetIndex;
|
||
|
|
|
||
|
|
// 向下拖拽:插入到目标项目的后面
|
||
|
|
// 由于移除了源项目,目标索引已经自动减1,所以直接使用TargetIndex就是插入到目标后面
|
||
|
|
// 向上拖拽:插入到目标项目的前面
|
||
|
|
newTargetIndex = targetIndex;
|
||
|
|
|
||
|
|
// 确保插入位置不超出列表范围
|
||
|
|
if (newTargetIndex > ModFolder.mcFolderList.Count)
|
||
|
|
newTargetIndex = ModFolder.mcFolderList.Count;
|
||
|
|
else if (newTargetIndex < 0) newTargetIndex = 0;
|
||
|
|
|
||
|
|
// 插入到新位置
|
||
|
|
ModFolder.mcFolderList.Insert(newTargetIndex, sourceFolder);
|
||
|
|
|
||
|
|
// 更新文件夹顺序并刷新UI
|
||
|
|
UpdateFolderOrder();
|
||
|
|
|
||
|
|
var direction = sourceIndex < targetIndex ? "后面" : "前面";
|
||
|
|
ModBase.Log(
|
||
|
|
$"[Control] 文件夹拖拽排序:{sourceFolder.Name} -> 位置 {newTargetIndex} (在 {targetFolder.Name} {direction})",
|
||
|
|
ModBase.LogLevel.Debug);
|
||
|
|
}
|
||
|
|
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
ModBase.Log(
|
||
|
|
ex,
|
||
|
|
Lang.Text("Select.Folder.Error.DragDrop"),
|
||
|
|
ModBase.LogLevel.Feedback,
|
||
|
|
userSummary: Lang.Text("Select.Folder.Error.DragDrop"));
|
||
|
|
}
|
||
|
|
finally
|
||
|
|
{
|
||
|
|
e.Handled = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#endregion
|
||
|
|
}
|