Skip to content

Commit

Permalink
Merge #4168 Work around OpenFileDialog always showing all shortcuts d…
Browse files Browse the repository at this point in the history
…espite filters
  • Loading branch information
HebaruSan committed Aug 21, 2024
2 parents 9007b20 + 82e5c35 commit 2fc36b4
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 52 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ All notable changes to this project will be documented in this file.
- [Multiple] Stop checking multiple hashes (#4135 by: HebaruSan)
- [Core] Fix max version column for wildcard compat (#4142 by: HebaruSan)
- [Multiple] Refactor ZIP importing (#4153 by: HebaruSan)
- [GUI] Work around OpenFileDialog always showing all shortcuts despite filters (#4168 by: HebaruSan)

### Internal

Expand Down
2 changes: 1 addition & 1 deletion Core/CkanTransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static TransactionScope CreateTransactionScope()
}

// System.ArgumentOutOfRangeException : Time-out interval must be less than 2^32-2. (Parameter 'dueTime')
private const double timeoutMs = Int32.MaxValue;
private const double timeoutMs = int.MaxValue;
private static readonly TimeSpan maxCoretimeout = TimeSpan.FromMilliseconds(timeoutMs);

private static readonly TransactionOptions transOpts = new TransactionOptions()
Expand Down
2 changes: 1 addition & 1 deletion Core/Configuration/JsonConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public JsonConfiguration(string newConfig = null)
// If you have multiple instances of CKAN running at the same time, each will
// believe that their copy of the config file in memory is authoritative, so
// changes made by one copy will not be respected by the other.
private string configFile = defaultConfigFile;
private readonly string configFile = defaultConfigFile;
private Config config = null;

public string DownloadCacheDir
Expand Down
115 changes: 71 additions & 44 deletions GUI/Dialogs/ManageGameInstancesDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,24 @@ namespace CKAN.GUI
#endif
public partial class ManageGameInstancesDialog : Form
{
private static GameInstanceManager manager => Main.Instance.Manager;
private readonly IUser _user;
private RenameInstanceDialog _renameInstanceDialog;
private readonly OpenFileDialog _instanceDialog = new OpenFileDialog()
{
AddExtension = false,
CheckFileExists = false,
CheckPathExists = false,
InitialDirectory = Environment.CurrentDirectory,
Filter = GameFolderFilter(manager),
Multiselect = false
};

/// <summary>
/// Generate filter string for OpenFileDialog
/// </summary>
/// <param name="mgr">Game instance manager that can tell us about the build ID files</param>
/// <returns>
/// "Build metadata files (buildID.txt;buildID64.txt)|buildID.txt;buildID64.txt"
/// </returns>
public static string GameFolderFilter(GameInstanceManager mgr)
=> Properties.Resources.GameProgramFileDescription
+ "|" + string.Join(";", mgr.AllInstanceAnchorFiles);

public bool HasSelections => GameInstancesListView.SelectedItems.Count > 0;

/// <summary>
/// Initialize the game instance selection window
/// </summary>
/// <param name="mgr">Game instance manager object to provide our game instances</param>
/// <param name="centerScreen">true to center the window on the screen, false to center it on the parent</param>
public ManageGameInstancesDialog(bool centerScreen, IUser user)
/// <param name="user">IUser object reference for raising dialogs</param>
public ManageGameInstancesDialog(GameInstanceManager mgr,
bool centerScreen,
IUser user)
{
_user = user;
manager = mgr;
this.user = user;
InitializeComponent();
DialogResult = DialogResult.Cancel;

instanceDialog.Filter = GameFolderFilter(manager);
instanceDialog.FileOk += InstanceFileOK;

if (centerScreen)
{
StartPosition = FormStartPosition.CenterScreen;
Expand Down Expand Up @@ -101,6 +83,19 @@ public void UpdateInstancesList()
GameInstancesListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
}

/// <summary>
/// Generate filter string for OpenFileDialog
/// </summary>
/// <param name="mgr">Game instance manager that can tell us about the build ID files</param>
/// <returns>
/// "Build metadata files (buildID.txt;buildID64.txt)|buildID.txt;buildID64.txt"
/// </returns>
public static string GameFolderFilter(GameInstanceManager mgr)
=> Properties.Resources.GameProgramFileDescription
+ "|" + string.Join(";", mgr.AllInstanceAnchorFiles);

public bool HasSelections => GameInstancesListView.SelectedItems.Count > 0;

private void AddOrRemoveColumn(ListView listView, ColumnHeader column, bool condition, int index)
{
if (condition && !listView.Columns.Contains(column))
Expand Down Expand Up @@ -157,22 +152,20 @@ protected override void OnHelpButtonClicked(CancelEventArgs evt)
}

private static string FormatVersion(GameVersion v)
{
return v == null
=> v == null
? Properties.Resources.CompatibleGameVersionsDialogNone
// The BUILD component is not useful visually
: new GameVersion(v.Major, v.Minor, v.Patch).ToString();
}

private void AddToCKANMenuItem_Click(object sender, EventArgs e)
{
if (_instanceDialog.ShowDialog(this) != DialogResult.OK
|| !File.Exists(_instanceDialog.FileName))
if (instanceDialog.ShowDialog(this) != DialogResult.OK
|| !File.Exists(instanceDialog.FileName))
{
return;
}

var path = Path.GetDirectoryName(_instanceDialog.FileName);
var path = Path.GetDirectoryName(instanceDialog.FileName);
try
{
var instanceName = Path.GetFileName(path);
Expand All @@ -181,17 +174,17 @@ private void AddToCKANMenuItem_Click(object sender, EventArgs e)
instanceName = path;
}
instanceName = manager.GetNextValidInstanceName(instanceName);
manager.AddInstance(path, instanceName, _user);
manager.AddInstance(path, instanceName, user);
UpdateInstancesList();
}
catch (NotKSPDirKraken k)
{
_user.RaiseError(Properties.Resources.ManageGameInstancesNotValid,
user.RaiseError(Properties.Resources.ManageGameInstancesNotValid,
new object[] { k.path });
}
catch (Exception exc)
{
_user.RaiseError(exc.Message);
user.RaiseError(exc.Message);
}
}

Expand All @@ -213,7 +206,7 @@ private void CloneGameInstanceMenuItem_Click(object sender, EventArgs e)
{
var old_instance = manager.CurrentInstance;

var result = new CloneGameInstanceDialog(manager, _user, (string)GameInstancesListView.SelectedItems[0].Tag).ShowDialog(this);
var result = new CloneGameInstanceDialog(manager, user, (string)GameInstancesListView.SelectedItems[0].Tag).ShowDialog(this);
if (result == DialogResult.OK && !Equals(old_instance, manager.CurrentInstance))
{
DialogResult = DialogResult.OK;
Expand Down Expand Up @@ -246,7 +239,7 @@ private void UseSelectedInstance()
}
catch (NotKSPDirKraken k)
{
_user.RaiseError(Properties.Resources.ManageGameInstancesNotValid, k.path);
user.RaiseError(Properties.Resources.ManageGameInstancesNotValid, k.path);
}
}
}
Expand All @@ -270,7 +263,7 @@ private void SetAsDefaultCheckbox_Click(object sender, EventArgs e)
}
catch (NotKSPDirKraken k)
{
_user.RaiseError(Properties.Resources.ManageGameInstancesNotValid, k.path);
user.RaiseError(Properties.Resources.ManageGameInstancesNotValid, k.path);
}
}
}
Expand Down Expand Up @@ -321,7 +314,7 @@ private void OpenDirectoryMenuItem_Click(object sender, EventArgs e)

if (!Directory.Exists(path))
{
_user.RaiseError(Properties.Resources.ManageGameInstancesDirectoryDeleted, path);
user.RaiseError(Properties.Resources.ManageGameInstancesDirectoryDeleted, path);
return;
}

Expand All @@ -333,14 +326,14 @@ private void RenameButton_Click(object sender, EventArgs e)
var instance = (string)GameInstancesListView.SelectedItems[0].Tag;

// show the dialog, and only continue if the user selected "OK"
_renameInstanceDialog = new RenameInstanceDialog();
if (_renameInstanceDialog.ShowRenameInstanceDialog(instance) != DialogResult.OK)
var renameInstanceDialog = new RenameInstanceDialog();
if (renameInstanceDialog.ShowRenameInstanceDialog(instance) != DialogResult.OK)
{
return;
}

// proceed with instance rename
manager.RenameInstance(instance, _renameInstanceDialog.GetResult());
manager.RenameInstance(instance, renameInstanceDialog.GetResult());
UpdateInstancesList();
}

Expand All @@ -359,5 +352,39 @@ private void UpdateButtonState()
ForgetButton.Enabled = HasSelections && (string)GameInstancesListView.SelectedItems[0].Tag != manager.CurrentInstance?.Name;
ImportFromSteamMenuItem.Enabled = manager.SteamLibrary.Games.Length > 0;
}

private readonly GameInstanceManager manager;

private readonly IUser user;

private readonly OpenFileDialog instanceDialog = new OpenFileDialog()
{
AddExtension = false,
CheckFileExists = false,
CheckPathExists = false,
DereferenceLinks = false,
InitialDirectory = Environment.CurrentDirectory,
Multiselect = false,
};

private void InstanceFileOK(object sender, CancelEventArgs e)
{
if (sender is OpenFileDialog dlg)
{
// OpenFileDialog always shows shortcuts (!!!!!),
// so we have to re-enforce the filter ourselves
var chosen = Path.GetFileName(dlg.FileName);
var allowed = manager.AllInstanceAnchorFiles;
if (!allowed.Contains(chosen))
{
e.Cancel = true;
user.RaiseError(Properties.Resources.ManageGameInstancesInvalidFileSelected,
chosen,
string.Join(Environment.NewLine,
allowed.OrderBy(f => f)
.Select(f => $" - {f}")));
}
}
}
}
}
4 changes: 2 additions & 2 deletions GUI/Main/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ private bool InstancePromptAtStart()
bool gotInstance = false;
Util.Invoke(this, () =>
{
var result = new ManageGameInstancesDialog(!actuallyVisible, currentUser).ShowDialog(this);
var result = new ManageGameInstancesDialog(Manager, !actuallyVisible, currentUser).ShowDialog(this);
gotInstance = result == DialogResult.OK;
});
return gotInstance;
Expand All @@ -335,7 +335,7 @@ private bool InstancePromptAtStart()
private void manageGameInstancesMenuItem_Click(object sender, EventArgs e)
{
var old_instance = CurrentInstance;
var result = new ManageGameInstancesDialog(!actuallyVisible, currentUser).ShowDialog(this);
var result = new ManageGameInstancesDialog(Manager, !actuallyVisible, currentUser).ShowDialog(this);
if (result == DialogResult.OK && !Equals(old_instance, CurrentInstance))
{
for (bool done = false; !done;)
Expand Down
4 changes: 2 additions & 2 deletions GUI/Model/ModList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public Tuple<IEnumerable<ModChange>, Dictionary<CkanModule, string>, List<string
}

foreach (var im in registry.FindRemovableAutoInstalled(
InstalledAfterChanges(registry, changeSet, version).ToList(), version))
InstalledAfterChanges(registry, changeSet).ToList(), version))
{
changeSet.Add(new ModChange(im.Module, GUIModChangeType.Remove, new SelectionReason.NoLongerUsed()));
modules_to_remove.Add(im.Module);
Expand Down Expand Up @@ -228,7 +228,7 @@ public Tuple<IEnumerable<ModChange>, Dictionary<CkanModule, string>, List<string
/// <param name="crit">Compatible versions of current instance</param>
/// <returns>Sequence of InstalledModules after the changes are applied, not including dependencies</returns>
private IEnumerable<InstalledModule> InstalledAfterChanges(
IRegistryQuerier registry, HashSet<ModChange> changeSet, GameVersionCriteria crit)
IRegistryQuerier registry, HashSet<ModChange> changeSet)
{
var removingIdents = changeSet
.Where(ch => ch.ChangeType != GUIModChangeType.Install)
Expand Down
7 changes: 7 additions & 0 deletions GUI/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,13 @@ You can refresh the mod list manually with the Refresh button at the top, and yo
<data name="ManageGameInstancesDirectoryDeleted" xml:space="preserve"><value>Directory "{0}" doesn't exist.</value></data>
<data name="ManageGameInstancesNameColumnInvalid" xml:space="preserve"><value>{0} (INVALID)</value></data>
<data name="ManageGameInstancesNameColumnLocked" xml:space="preserve"><value>{0} (LOCKED)</value></data>
<data name="ManageGameInstancesInvalidFileSelected" xml:space="preserve"><value>Not a valid game instance file: "{0}"

If you selected a shortcut, don't do that; Windows won't let us hide them from this dialog even though they're invalid.

Find the folder where your game is installed and choose one of these files:

{1}</value></data>
<data name="NewRepoDialogFailed" xml:space="preserve"><value>Failed to fetch master list.</value></data>
<data name="PluginsDialogFilter" xml:space="preserve"><value>CKAN Plugins (*.dll)|*.dll</value></data>
<data name="SettingsDialogSummmary" xml:space="preserve"><value>{0} files, {1}, {2} free</value></data>
Expand Down
1 change: 0 additions & 1 deletion Netkan/Transformers/InternalCkanTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using log4net;

using CKAN.Versioning;
using CKAN.NetKAN.Extensions;
using CKAN.NetKAN.Model;
using CKAN.NetKAN.Services;
Expand Down
1 change: 0 additions & 1 deletion Netkan/Transformers/MetaNetkanTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using log4net;
using Newtonsoft.Json.Linq;

using CKAN.Versioning;
using CKAN.NetKAN.Extensions;
using CKAN.NetKAN.Model;
using CKAN.NetKAN.Services;
Expand Down

0 comments on commit 2fc36b4

Please sign in to comment.