mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
Enforced update to file format v2.2
This commit is contained in:
parent
29b592a6d1
commit
f860b91a72
@ -291,24 +291,55 @@ namespace DisplayMagician {
|
||||
//Application.SetHighDpiMode(HighDpiMode.SystemAware);
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
||||
|
||||
// Check if it's an upgrade from DisplayMagician v2.x to v2.2
|
||||
// and if it is then copy the old configs to the new filenames and
|
||||
// explain to the user what they need to do.
|
||||
string dp22 = Path.Combine(AppProfilePath, "DisplayProfiles_2.2.json");
|
||||
string dp21 = Path.Combine(AppProfilePath, "DisplayProfiles_2.1.json");
|
||||
string dp20 = Path.Combine(AppProfilePath, "DisplayProfiles_2.0.json");
|
||||
string dp10 = Path.Combine(AppProfilePath, "DisplayProfiles_1.0.json");
|
||||
|
||||
if ((File.Exists(dp21) || File.Exists(dp20)) && !File.Exists(Path.Combine(AppProfilePath, "DisplayProfiles_2.2.json")))
|
||||
{
|
||||
logger.Info($"Program/Main: This is an upgrade from an earlier DisplayMagician version to DisplayMagician v2.2, so performing some upgrade steps.");
|
||||
|
||||
// Copy the older files across to the new names, then the migrate JSON function
|
||||
// within the ProfileRepository will take care of the rest
|
||||
if (File.Exists(dp20))
|
||||
{
|
||||
File.Copy(dp20, dp22);
|
||||
}
|
||||
else if (File.Exists(dp21))
|
||||
{
|
||||
File.Copy(dp21, dp22);
|
||||
}
|
||||
|
||||
// Warn the user about the fact we need them to recreate their Display Profiles again!
|
||||
StartMessageForm myMessageWindow = new StartMessageForm();
|
||||
myMessageWindow.MessageMode = "rtf";
|
||||
myMessageWindow.URL = "https://displaymagician.littlebitbig.com/messages/DisplayMagician21to22.rtf";
|
||||
myMessageWindow.HeadingText = "DisplayMagician v2.2 Upgrade Warning";
|
||||
myMessageWindow.ButtonText = "&Close";
|
||||
myMessageWindow.ShowDialog();
|
||||
}
|
||||
// Check if it's an upgrade from DisplayMagician v1 to v2
|
||||
// and if it is then copy the old configs to the new filenames and
|
||||
// explain to the user what they need to do.
|
||||
// e.g. DisplayProfiles_1.0.json exists, but DisplayProfiles_2.1.json doesn't
|
||||
if (File.Exists(Path.Combine(AppProfilePath, "DisplayProfiles_1.0.json")) && !File.Exists(Path.Combine(AppProfilePath, "DisplayProfiles_2.1.json")))
|
||||
// e.g. DisplayProfiles_1.0.json exists, but DisplayProfiles_2.2.json doesn't
|
||||
else if (File.Exists(Path.Combine(AppProfilePath, "DisplayProfiles_1.0.json")) && !File.Exists(Path.Combine(AppProfilePath, "DisplayProfiles_2.2.json")))
|
||||
{
|
||||
logger.Info($"Program/Main: This is an upgrade from DisplayMagician v1.0 to DisplayMagician v2.1, so performing some upgrade steps.");
|
||||
logger.Info($"Program/Main: This is an upgrade from DisplayMagician v1.0 to DisplayMagician v2.2, so performing some upgrade steps.");
|
||||
// Note whether we copied the old Settings file to the new v2 name earlier (before the logging was enabled)
|
||||
if (upgradedSettingsFile)
|
||||
{
|
||||
logger.Info($"Program/Main: Upgraded v1.0 settings file {oldSettingsFile} to v2.0 settings file {newSettingsFile} earlier in loading process (before logging service was available).");
|
||||
logger.Info($"Program/Main: Upgraded v1.0 settings file {oldSettingsFile} to v2.2 settings file {newSettingsFile} earlier in loading process (before logging service was available).");
|
||||
}
|
||||
|
||||
// Copy the old Game Shortcuts file to the new v2 name
|
||||
string oldShortcutsFile = Path.Combine(AppShortcutPath, "Shortcuts_1.0.json");
|
||||
string newShortcutsFile = Path.Combine(AppShortcutPath, "Shortcuts_2.0.json");
|
||||
string newShortcutsFile = Path.Combine(AppShortcutPath, "Shortcuts_2.2.json");
|
||||
try
|
||||
{
|
||||
if (File.Exists(oldShortcutsFile) && !File.Exists(newShortcutsFile))
|
||||
@ -325,26 +356,12 @@ namespace DisplayMagician {
|
||||
// Warn the user about the fact we need a new DisplayProfiles_2.0.json
|
||||
StartMessageForm myMessageWindow = new StartMessageForm();
|
||||
myMessageWindow.MessageMode = "rtf";
|
||||
myMessageWindow.URL = "https://displaymagician.littlebitbig.com/messages/DisplayMagician1to2.rtf";
|
||||
myMessageWindow.HeadingText = "DisplayMagician v2.1.0 Upgrade Warning";
|
||||
myMessageWindow.URL = "https://displaymagician.littlebitbig.com/messages/DisplayMagicianRecreateProfiles.rtf";
|
||||
myMessageWindow.HeadingText = "You need to recreate your Display Profiles";
|
||||
myMessageWindow.ButtonText = "&Close";
|
||||
myMessageWindow.ShowDialog();
|
||||
}
|
||||
// Check if it's an upgrade from DisplayMagician v2.0 to v2.1
|
||||
// and if it is then copy the old configs to the new filenames and
|
||||
// explain to the user what they need to do.
|
||||
// e.g. DisplayProfiles_2.1.json exists, but DisplayProfiles_2.0.json doesn't
|
||||
else if (File.Exists(Path.Combine(AppProfilePath, "DisplayProfiles_2.0.json")) && !File.Exists(Path.Combine(AppProfilePath, "DisplayProfiles_2.1.json")))
|
||||
{
|
||||
logger.Info($"Program/Main: This is an upgrade from DisplayMagician v2.0 to DisplayMagician v2.1, so performing some upgrade steps.");
|
||||
// Warn the user about the fact we need a new DisplayProfiles_2.0.json
|
||||
StartMessageForm myMessageWindow = new StartMessageForm();
|
||||
myMessageWindow.MessageMode = "rtf";
|
||||
myMessageWindow.URL = "https://displaymagician.littlebitbig.com/messages/DisplayMagician20to21.rtf";
|
||||
myMessageWindow.HeadingText = "DisplayMagician v2.1.0 Upgrade Warning";
|
||||
myMessageWindow.ButtonText = "&Close";
|
||||
myMessageWindow.ShowDialog();
|
||||
}
|
||||
|
||||
|
||||
logger.Debug($"Setting up commandline processing configuration");
|
||||
var app = new CommandLineApplication
|
||||
|
@ -26,8 +26,8 @@ using System.Resources;
|
||||
[assembly: Guid("e4ceaf5e-ad01-4695-b179-31168eb74c48")]
|
||||
|
||||
// Version information
|
||||
[assembly: AssemblyVersion("2.2.0.55")]
|
||||
[assembly: AssemblyFileVersion("2.2.0.55")]
|
||||
[assembly: AssemblyVersion("2.2.0.72")]
|
||||
[assembly: AssemblyFileVersion("2.2.0.72")]
|
||||
[assembly: NeutralResourcesLanguageAttribute( "en" )]
|
||||
[assembly: CLSCompliant(true)]
|
||||
|
||||
|
@ -472,6 +472,20 @@ namespace DisplayMagician
|
||||
|
||||
_allShortcuts = JsonConvert.DeserializeObject<List<ShortcutItem>>(json, mySerializerSettings);
|
||||
|
||||
}
|
||||
catch (JsonReaderException ex)
|
||||
{
|
||||
// If there is a error in the JSON format
|
||||
if (ex.HResult == -2146233088)
|
||||
{
|
||||
MessageBox.Show($"The Game Shortcuts file {_shortcutStorageJsonFileName} contains a syntax error. Please check the file for correctness with a JSON validator.", "Error loading the Game Shortcuts", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
SharedLogger.logger.Error(ex, $"ShortcutRepository/LoadShortcuts: JSONReaderException - The Shortcuts file {_shortcutStorageJsonFileName} contains a syntax error. Please check the file for correctness with a JSON validator.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"ShortcutRepository/LoadShortcuts: JSONReaderException while trying to process the Shortcuts json data file {_shortcutStorageJsonFileName} but JsonConvert threw an exception.");
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -540,6 +540,7 @@ namespace DisplayMagician.UIForms
|
||||
Path.Combine(Program.AppLogPath,"DisplayMagician2.log"),
|
||||
Path.Combine(Program.AppLogPath,"DisplayMagician3.log"),
|
||||
Path.Combine(Program.AppLogPath,"DisplayMagician4.log"),
|
||||
Path.Combine(Program.AppProfilePath,"DisplayProfiles_2.2.json"),
|
||||
Path.Combine(Program.AppProfilePath,"DisplayProfiles_2.1.json"),
|
||||
Path.Combine(Program.AppProfilePath,"DisplayProfiles_2.0.json"),
|
||||
Path.Combine(Program.AppShortcutPath,"Shortcuts_2.0.json"),
|
||||
|
@ -65,7 +65,7 @@ namespace DisplayMagicianShared
|
||||
public static string AppIconPath = System.IO.Path.Combine(AppDataPath, $"Icons");
|
||||
public static string AppDisplayMagicianIconFilename = System.IO.Path.Combine(AppIconPath, @"DisplayMagician.ico");
|
||||
private static readonly string AppProfileStoragePath = System.IO.Path.Combine(AppDataPath, $"Profiles");
|
||||
private static readonly string _profileStorageJsonFileName = System.IO.Path.Combine(AppProfileStoragePath, $"DisplayProfiles_2.1.json");
|
||||
private static readonly string _profileStorageJsonFileName = System.IO.Path.Combine(AppProfileStoragePath, $"DisplayProfiles_2.2.json");
|
||||
|
||||
|
||||
|
||||
@ -696,7 +696,6 @@ namespace DisplayMagicianShared
|
||||
// Migrate any previous entries to the latest version of the file format to the latest one
|
||||
json = MigrateJsonToLatestVersion(json);
|
||||
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(json))
|
||||
{
|
||||
List<string> jsonErrors = new List<string>();
|
||||
@ -705,7 +704,7 @@ namespace DisplayMagicianShared
|
||||
{
|
||||
JsonSerializerSettings mySerializerSettings = new JsonSerializerSettings
|
||||
{
|
||||
MissingMemberHandling = MissingMemberHandling.Error,
|
||||
MissingMemberHandling = MissingMemberHandling.Ignore,
|
||||
NullValueHandling = NullValueHandling.Include,
|
||||
//NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Include,
|
||||
@ -721,6 +720,20 @@ namespace DisplayMagicianShared
|
||||
};
|
||||
_allProfiles = JsonConvert.DeserializeObject<List<ProfileItem>>(json, mySerializerSettings);
|
||||
|
||||
}
|
||||
catch (JsonReaderException ex)
|
||||
{
|
||||
// If there is a error in the JSON format
|
||||
if (ex.HResult == -2146233088)
|
||||
{
|
||||
MessageBox.Show($"The Display Profiles file {_profileStorageJsonFileName} contains a syntax error. Please check the file for correctness with a JSON validator.", "Error loading the Display Profiles", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
SharedLogger.logger.Error(ex, $"ProfileRepository/LoadProfiles: JSONReaderException - The Display Profiles file {_profileStorageJsonFileName} contains a syntax error. Please check the file for correctness with a JSON validator.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"ProfileRepository/LoadProfiles: JSONReaderException while trying to process the Profiles json data file {_profileStorageJsonFileName} but JsonConvert threw an exception.");
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -789,89 +802,44 @@ namespace DisplayMagicianShared
|
||||
}
|
||||
catch(JsonReaderException ex)
|
||||
{
|
||||
SharedLogger.logger.Error($"ProfileRepository/MigrateJsonToLatestVersion: JSONReaderException while trying to process the Profiles json data to migrate any older feature to the latest version.");
|
||||
// If there is a error in the JSON format
|
||||
if (ex.HResult == -2146233088)
|
||||
{
|
||||
MessageBox.Show("The Display Profiles file contains a syntax error. Please check the file for correctness with a JSON validator.", "Error loading the Display Profiles", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
SharedLogger.logger.Error(ex, $"ProfileRepository/MigrateJsonToLatestVersion: JSONReaderException - The Display Profiles file contains a syntax error. Please check the file for correctness with a JSON validator.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"ProfileRepository/MigrateJsonToLatestVersion: JSONReaderException while trying to process the Profiles json data to migrate any older feature to the latest version.");
|
||||
}
|
||||
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Error($"ProfileRepository/MigrateJsonToLatestVersion: Exception while trying to process the Profiles json data to migrate any older feature to the latest version.");
|
||||
SharedLogger.logger.Error(ex,$"ProfileRepository/MigrateJsonToLatestVersion: Exception while trying to process the Profiles json data to migrate any older feature to the latest version.");
|
||||
}
|
||||
|
||||
// We do the change we wre trying to do
|
||||
// We do the actual change we were trying to do
|
||||
try
|
||||
{
|
||||
/*// Now we try and add a default NVIDIA Color Settings if there isn't one
|
||||
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Looking for missing NVIDIA Color Config.");
|
||||
// Create a default object
|
||||
NVIDIA_DISPLAY_CONFIG myDefaultConfig = new NVIDIA_DISPLAY_CONFIG();
|
||||
myDefaultConfig.ColorConfig.ColorData = new Dictionary<uint, NV_COLOR_DATA_V5>();
|
||||
JObject defaultColorConfig = (JObject)JToken.FromObject(myDefaultConfig.ColorConfig);
|
||||
|
||||
for (int i=0; i < root.Count; i++)
|
||||
{
|
||||
JObject profile = (JObject)root[i];
|
||||
JObject result = (JObject)profile.SelectToken("NVIDIADisplayConfig.ColorConfig.ColorData");
|
||||
if (result == null)
|
||||
{
|
||||
|
||||
JObject NVIDIADisplayConfig = (JObject)profile.SelectToken("NVIDIADisplayConfig");
|
||||
NVIDIADisplayConfig.Add("ColorConfig",defaultColorConfig);
|
||||
changedJson = true;
|
||||
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Patched missing NVIDIA Color Config in profile {profile.SelectToken("Name")} (index {i}).");
|
||||
}
|
||||
}
|
||||
|
||||
// Now we try to patch in a Windows GDI device context into the json if there isnt one
|
||||
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Looking for missing Windows GDI Device Context.");
|
||||
// Now we try to patch in a Windows Taskbar Stuck Rects list into the json if there isnt one
|
||||
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Looking for missing Windows Taskbar settings.");
|
||||
// Create a default object
|
||||
Dictionary<string, GDI_DISPLAY_SETTING> GdiDisplaySettings = new Dictionary<string, GDI_DISPLAY_SETTING>();
|
||||
JObject defaultGdiDisplaySettings = (JObject)JToken.FromObject(GdiDisplaySettings);
|
||||
List<TaskBarStuckRectangle> taskBarStuckRectangles = new List<TaskBarStuckRectangle>();
|
||||
for (int i = 0; i < root.Count; i++)
|
||||
{
|
||||
JObject profile = (JObject)root[i];
|
||||
JObject result = (JObject)profile.SelectToken("WindowsDisplayConfig.GdiDisplaySettings");
|
||||
if (result == null)
|
||||
JArray WindowsTaskBarLayout = (JArray)profile.SelectToken("WindowsDisplayConfig.TaskBarLayout");
|
||||
if (WindowsTaskBarLayout == null)
|
||||
{
|
||||
|
||||
JObject WindowsDisplayConfig = (JObject)profile.SelectToken("WindowsDisplayConfig");
|
||||
WindowsDisplayConfig.Add("GdiDisplaySettings", defaultGdiDisplaySettings);
|
||||
JObject WindowsDisplayConfig = (JObject)profile.SelectToken("WindowsDisplayConfig");
|
||||
JArray newTaskBarLayout = JArray.FromObject(taskBarStuckRectangles);
|
||||
WindowsDisplayConfig.Add("TaskBarLayout",newTaskBarLayout);
|
||||
changedJson = true;
|
||||
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Patched missing Windows GDI Device Context in profile {profile.SelectToken("Name")} (index {i}).");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Patched missing Windows TaskBarLayout in profile {profile.SelectToken("Name")} (index {i}).");
|
||||
}
|
||||
}
|
||||
|
||||
// Now we try to convert the individual sourceids into a list of source ids to cope with cloned devices
|
||||
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Looking for missing Windows GDI Device Context.");
|
||||
// Create a default object
|
||||
List<uint> WinDisplaySourcesList = new List<uint>();
|
||||
//JObject WinDisplaySources = (JObject)JToken.FromObject(WinDisplaySourcesList);
|
||||
for (int i = 0; i < root.Count; i++)
|
||||
{
|
||||
JObject profile = (JObject)root[i];
|
||||
try
|
||||
{
|
||||
JObject WindowsDisplaySources = (JObject)profile.SelectToken("WindowsDisplayConfig.DisplaySources");
|
||||
Dictionary<string, List<uint>> existingDisplaySources = WindowsDisplaySources.ToObject<Dictionary<string, List<uint>>>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
JObject WindowsDisplaySources = (JObject)profile.SelectToken("WindowsDisplayConfig.DisplaySources");
|
||||
//foreach (var displaySource in WindowsDisplaySources.ToObject<Dictionary<string,uint>>())
|
||||
Dictionary<string, uint> existingDisplaySources = WindowsDisplaySources.ToObject<Dictionary<string, uint>>();
|
||||
Dictionary<string, List<uint>> newDisplaySources = new Dictionary<string, List<uint>>();
|
||||
foreach (var sourceName in existingDisplaySources.Keys)
|
||||
{
|
||||
List<uint> newList = new List<uint>();
|
||||
newList.Add((uint)existingDisplaySources[sourceName]);
|
||||
newDisplaySources[sourceName] = newList;
|
||||
}
|
||||
JObject newSourcesDict = JObject.FromObject(newDisplaySources);
|
||||
JToken WindowsDisplayConfig = (JToken)profile.SelectToken("WindowsDisplayConfig.DisplaySources");
|
||||
WindowsDisplayConfig.Replace(newSourcesDict);
|
||||
changedJson = true;
|
||||
SharedLogger.logger.Trace($"ProfileRepository/MigrateJsonToLatestVersion: Patched missing Windows GDI Device Context in profile {profile.SelectToken("Name")} (index {i}).");
|
||||
}
|
||||
|
||||
} */
|
||||
}
|
||||
|
||||
}
|
||||
catch (JsonReaderException ex)
|
||||
|
@ -16,6 +16,19 @@ namespace DisplayMagicianShared
|
||||
|
||||
public TaskBarStuckRectangle SingleMonitorStuckRectangle { get; set; }
|
||||
|
||||
public override bool Equals(object obj) => obj is TaskBarSettings other && this.Equals(other);
|
||||
public bool Equals(TaskBarSettings other)
|
||||
=> Options == other.Options &&
|
||||
SingleMonitorStuckRectangle.Equals(other.SingleMonitorStuckRectangle);
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (Options, SingleMonitorStuckRectangle).GetHashCode();
|
||||
}
|
||||
public static bool operator ==(TaskBarSettings lhs, TaskBarSettings rhs) => lhs.Equals(rhs);
|
||||
|
||||
public static bool operator !=(TaskBarSettings lhs, TaskBarSettings rhs) => !(lhs == rhs);
|
||||
|
||||
public static TaskBarSettings GetCurrent()
|
||||
{
|
||||
var taskBarOptions = new List<Tuple<string, int>>();
|
||||
|
@ -252,6 +252,22 @@ namespace DisplayMagicianShared
|
||||
|
||||
public int Version { get; set; }
|
||||
|
||||
public override bool Equals(object obj) => obj is TaskBarStuckRectangle other && this.Equals(other);
|
||||
public bool Equals(TaskBarStuckRectangle other)
|
||||
=> Version == other.Version &&
|
||||
DevicePath == other.DevicePath &&
|
||||
Binary.Equals(other.Binary);
|
||||
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
//return (DisplayConfigPaths, DisplayConfigModes, DisplayHDRStates, GdiDisplaySettings.Values, IsCloned, DisplayIdentifiers).GetHashCode();
|
||||
return (Version, DevicePath, Binary).GetHashCode();
|
||||
}
|
||||
public static bool operator ==(TaskBarStuckRectangle lhs, TaskBarStuckRectangle rhs) => lhs.Equals(rhs);
|
||||
|
||||
public static bool operator !=(TaskBarStuckRectangle lhs, TaskBarStuckRectangle rhs) => !(lhs == rhs);
|
||||
|
||||
public static TaskBarStuckRectangle GetCurrent()
|
||||
{
|
||||
return GetCurrent((string)null);
|
||||
|
@ -58,7 +58,8 @@ namespace DisplayMagicianShared.Windows
|
||||
// Additionally, we had to disable the DEviceKey from the equality testing within the GDI library itself as that waould also change after changing back from NVIDIA surround
|
||||
// This still allows us to detect when refresh rates change, which will allow DisplayMagician to detect profile differences.
|
||||
GdiDisplaySettings.Values.SequenceEqual(other.GdiDisplaySettings.Values) &&
|
||||
DisplayIdentifiers.SequenceEqual(other.DisplayIdentifiers);
|
||||
DisplayIdentifiers.SequenceEqual(other.DisplayIdentifiers) &&
|
||||
TaskBarLayout.SequenceEqual(other.TaskBarLayout);
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
@ -163,9 +164,10 @@ namespace DisplayMagicianShared.Windows
|
||||
myDefaultConfig.DisplayConfigPaths = new DISPLAYCONFIG_PATH_INFO[0];
|
||||
myDefaultConfig.DisplayHDRStates = new List<ADVANCED_HDR_INFO_PER_PATH>();
|
||||
myDefaultConfig.DisplayIdentifiers = new List<string>();
|
||||
myDefaultConfig.DisplaySources = new Dictionary<string, List<uint>>();
|
||||
myDefaultConfig.IsCloned = false;
|
||||
myDefaultConfig.DisplaySources = new Dictionary<string, List<uint>>();
|
||||
myDefaultConfig.GdiDisplaySettings = new Dictionary<string, GDI_DISPLAY_SETTING>();
|
||||
myDefaultConfig.TaskBarLayout = new List<TaskBarStuckRectangle>();
|
||||
myDefaultConfig.IsCloned = false;
|
||||
|
||||
return myDefaultConfig;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user