/// <summary> /// Load the list of available skins into <see cref="Global.User.SkinList"/>. /// </summary> public void LoadSkinList() { string path = About.SkinsPath; FileSystemInfo[] fInfos = null; try { DirectoryInfo dInfo; dInfo = new DirectoryInfo(path); fInfos = dInfo.GetFileSystemInfos(); if (fInfos == null) { LimeMsg.Error("UnableOpenDir", path); } } catch { LimeMsg.Error("UnableOpenDir", path); } if (fInfos != null) { Array.Sort(fInfos, (x, y) => StringComparer.InvariantCultureIgnoreCase.Compare(x.Name, y.Name)); var dirs = new List <string>(fInfos.Length); foreach (var info in fInfos) { if ((info.Attributes & FileAttributes.Directory) != 0) { dirs.Add(info.Name); } } Global.User.SkinList = dirs.ToArray(); // Parameter cleanup if (Global.User.SkinParams != null) { string[] keys = Global.User.SkinParams.Keys.ToArray(); foreach (string key in keys) { if (!dirs.Contains(key)) { LimeMsg.Debug("Skin: Parameter cleanup: {0}", key); Global.User.SkinParams.Remove(key); } } } } }
// -------------------------------------------------------------------------------------------------- #region ctors /// <summary> /// Constructor /// </summary> /// <param name="skinName">Name of the skin</param> /// <param name="loadParam">Load the parameters from user-config</param> public Skin(string skinName, bool loadParam = true) { LimeMsg.Debug("Skin: constructor"); LimeLib.LifeTrace(this); // Invalidate this skin Name = null; // Prepare to populate new set of Skin-parameters SkinParam.Clear(); // Load Skin list LoadSkinList(); // Load resource ResourceDictionary resources = null; if (!string.IsNullOrEmpty(skinName)) { // Load Xaml here string dir = About.SkinsPath; #if DEBUG // Debug Only: bypass local skins to use the one in the project directly if (!string.IsNullOrEmpty(Global.DebugProjectDir)) { dir = Path.Combine(Global.DebugProjectDir, "Skins"); } #endif dir = Path.Combine(dir, skinName); dir = LimeLib.ResolvePath(dir); string path = Path.Combine(dir, skinName + ".xaml"); path = LimeLib.ResolvePath(path); // Parse theXaml. This may fail if there is a file/Xaml error using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { // Get the root element, which must be a ResourceDictionary resources = (ResourceDictionary)XamlReader.Load(fs); } // File change monitoring if (Global.User.SkinAutoRefresh && Global.User.DevMode) { LimeMsg.Debug("Skin: constructor: Watch changes on {0}", dir); _Watch = new FileSystemWatcher { Path = dir, IncludeSubdirectories = false, Filter = "" }; _Watch.Changed += new FileSystemEventHandler(OnXamlFileChanged); _Watch.EnableRaisingEvents = true; } else { _Watch = null; } } // Freeze the Parameters SkinParam.Lock(); // Retrieve/check Required resources double version = 0.0; try { MetaAuthor = (string)resources["MetaAuthor"]; MetaContact = (string)resources["MetaContact"]; MetaWebsite = (string)resources["MetaWebsite"]; MetaDescription = (string)resources["MetaDescription"]; version = (double)resources["MetaLimeVersion"]; } catch (ResourceReferenceKeyNotFoundException e) { LimeMsg.Error("ErrSkinParMiss", e.Key); } catch { LimeMsg.Error("ErrSkinFormat"); } if (version > 0.5) { // Successfull if (version > About.versionNum) { LimeMsg.Error("ErrSkinVersion", skinName, About.name, version); } } // Process the Skin parameters var parList = SkinParam.List.ToArray(); SkinParam.Clear(); // Assign the key of the resource-dictonary to the SkinParam Ident. foreach (var key in resources.Keys) { if (key is string skey && resources[key] is SkinParam res) { res.Ident = skey; // Exclude Empty elements if (res.Content == null && res.Name == null) { res.Visible = false; } } } // Retrieve special parameters IconBigSize = Array.Find(parList, x => x.Ident == "ParamIconBigSize"); IconSmallSize = Array.Find(parList, x => x.Ident == "ParamIconSmallSize"); if (IconBigSize == null) { LimeMsg.Error("ErrSkinParMiss", nameof(IconBigSize)); return; } if (IconSmallSize == null) { LimeMsg.Error("ErrSkinParMiss", nameof(IconSmallSize)); return; } // Remove the non-visible parameters from the list of parameters parList = parList.Where(x => x.Visible).ToArray(); // Retrieve (if exists) parameters from the Configuration (settings) SkinParam[] configParam = null; if (Global.User.SkinParams != null) { Global.User.SkinParams.TryGetValue(skinName, out configParam); } // Process every paramters foreach (var param in parList) { // Create, reference and retrieve the property from the config (settings) LimeMsg.Debug("Skin: Parameter: {0} ({1})", param.Ident, param.Type); if (param.Content != null) { // If no explicit name, assign the type to the Name property if (param.Name == null) { string name = param.Type.ToString(); if (name != null) { while (name.Contains(".")) { name = name.Substring(name.IndexOf(".") + 1); } param.Name = name; } } // Default description if (param.Desc == null) { param.Desc = "Skin Parameter: " + param.Name; } // Load Setting if (configParam != null && loadParam) { SkinParam match = Array.Find(configParam, x => x.Ident == param.Ident); if (match != null) { string val = match.Serialize; LimeMsg.Debug("Skin: Parameter: Load {0} = {1}", param.Ident, val); try { param.Serialize = val; } catch { if (Global.User.DevMode) { LimeMsg.Error("ErrSkinParValue", param.Ident, val); } } } } // Monitor this property for modification param.PropertyChangedWeak += SkinParamPropertyChanged; } } // Monitor the user-properties Scaled and EnableTypeScaled Global.User.PropertyChangedWeak += IconSizePropertyChanged; Global.Local.PropertyChangedWeak += IconSizePropertyChanged; // Apply the skin Application.Current.Resources = resources; Commands.MainWindow.Style = (Style)Commands.MainWindow.FindResource(typeof(Window)); // Validate the skin Name = skinName; // Make the parameters visible (binding) Parameters = parList; // Parameter are considered as modified when reset to default if (!loadParam && configParam != null) { Global.User.Modified = true; } }
/// <summary> /// Handle the Command Line Interface parsing of the application. /// </summary> /// <param name="firstInstance">true if this is the first instance, false if the application is re-opened</param> /// <param name="args">list of arguments of the command</param> /// <returns>true if handled.</returns> public bool CommandLineInterface(bool firstInstance, IList <string> args) { LimeMsg.Debug("CommandLineInterface: {0}", firstInstance); Global.Local.CtrlMode = CtrlMode.CLI; for (int i = firstInstance ? 0 : 1; i < args.Count; i++) { LimeMsg.Debug("CommandLineInterface: {0}: arg: {1}", firstInstance, args[i]); string arg = args[i]; if (arg.Length > 0) { // Options LimeProperty prop = null; bool isToggle = false; // Parse argument (detect = and !) string value = null; int idx = arg.IndexOf('='); if (idx >= 0) { value = arg.Substring(idx + 1); arg = arg.Substring(0, idx).Trim(); } else if (arg.EndsWith("!")) { isToggle = true; arg = arg.Substring(0, arg.Length - 1).Trim(); } if ((prop = Global.Properties.Get(arg)) != null) { // Property if (value != null) { if (prop.ReadOnly) { LimeMsg.Error("ErrReadOnlyProp", args[i]); } else { try { prop.Serialize = value; } catch { LimeMsg.Error("ErrInvProp", args[i], prop.Type.ToString()); } } } else if (isToggle) { prop.Toggle(); } else if (prop.Content is LimeCommand cmd) { cmd.Execute(); } } else { // Other options bool handled = true; switch (arg.ToLower()) { case "?": case "h": case "help": { // TODO: do something usefull here Console.WriteLine("hello"); break; } default: handled = false; break; } // Try Skin-parameters if (!handled && Global.Local.Skin != null) { var param = Global.Local.Skin.Get(arg); if (param != null) { if (param.Visible && param.Content != null) { handled = true; if (value != null) { try { param.Serialize = value; } catch { LimeMsg.Error("ErrInvSkinProp", args[i], param.Type.ToString()); } } break; } } } // No match found if (!handled) { LimeMsg.Error("ErrInvArg", args[i]); } } } } return(true); }