///////////////////////////////////////////////////////////////////////// // Copyright 2011-2018 Simon Schneegans // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ///////////////////////////////////////////////////////////////////////// namespace GnomePie { ///////////////////////////////////////////////////////////////////////// /// A singleton class for storing global settings. These settings can /// be loaded from and saved to an XML file. ///////////////////////////////////////////////////////////////////////// public class Config : GLib.Object { ///////////////////////////////////////////////////////////////////// /// The singleton instance of this class. ///////////////////////////////////////////////////////////////////// private static Config _instance = null; ///////////////////////////////////////////////////////////////////// /// Returns the singleton instance. ///////////////////////////////////////////////////////////////////// public static Config global { get { if (_instance == null) { _instance = new Config(); _instance.load(); } return _instance; } private set { _instance = value; } } ///////////////////////////////////////////////////////////////////// /// All settings variables. ///////////////////////////////////////////////////////////////////// public Theme theme { get; set; } public double refresh_rate { get; set; default = 60.0; } public double global_scale { get; set; default = 1.0; } public int activation_range { get; set; default = 200; } public int max_visible_slices { get; set; default = 24; } public bool show_indicator { get; set; default = true; } public bool show_captions { get; set; default = false; } public bool search_by_string { get; set; default = true; } public bool auto_start { get; set; default = false; } public int showed_news { get; set; default = 0; } public Gee.ArrayList themes { get; private set; } ///////////////////////////////////////////////////////////////////// /// Saves all above variables to a file. ///////////////////////////////////////////////////////////////////// public void save() { var writer = new Xml.TextWriter.filename(Paths.settings); writer.start_document("1.0"); writer.start_element("settings"); writer.write_attribute("theme", theme.name); writer.write_attribute("refresh_rate", refresh_rate.to_string()); writer.write_attribute("global_scale", global_scale.to_string()); writer.write_attribute("activation_range", activation_range.to_string()); writer.write_attribute("max_visible_slices", max_visible_slices.to_string()); writer.write_attribute("show_indicator", show_indicator ? "true" : "false"); writer.write_attribute("show_captions", show_captions ? "true" : "false"); writer.write_attribute("search_by_string", search_by_string ? "true" : "false"); writer.write_attribute("showed_news", showed_news.to_string()); writer.end_element(); writer.end_document(); } ///////////////////////////////////////////////////////////////////// /// Loads all settings variables from a file. ///////////////////////////////////////////////////////////////////// private void load() { // check for auto_start filename this.auto_start = FileUtils.test(Paths.autostart, FileTest.EXISTS); // parse the settings file Xml.Parser.init(); Xml.Doc* settingsXML = Xml.Parser.parse_file(Paths.settings); bool error_occrured = false; string theme_name = ""; if (settingsXML != null) { Xml.Node* root = settingsXML->get_root_element(); if (root != null) { for (Xml.Attr* attribute = root->properties; attribute != null; attribute = attribute->next) { string attr_name = attribute->name.down(); string attr_content = attribute->children->content; switch (attr_name) { case "theme": theme_name = attr_content; break; case "refresh_rate": refresh_rate = double.parse(attr_content); break; case "global_scale": global_scale = double.parse(attr_content); global_scale.clamp(0.5, 2.0); break; case "activation_range": activation_range = int.parse(attr_content); activation_range.clamp(0, 2000); break; case "max_visible_slices": max_visible_slices = int.parse(attr_content); max_visible_slices.clamp(10, 2000); break; case "show_indicator": show_indicator = bool.parse(attr_content); break; case "show_captions": show_captions = bool.parse(attr_content); break; case "search_by_string": search_by_string = bool.parse(attr_content); break; case "showed_news": showed_news = int.parse(attr_content); break; default: warning("Invalid setting \"" + attr_name + "\" in gnome-pie.conf!"); break; } } Xml.Parser.cleanup(); } else { warning("Error loading settings: gnome-pie.conf is empty! Using defaults..."); error_occrured = true; } delete settingsXML; } else { warning("Error loading settings: gnome-pie.conf not found! Using defaults..."); error_occrured = true; } load_themes(theme_name); if (error_occrured) { save(); } } ///////////////////////////////////////////////////////////////////// /// Registers all themes in the user's and in the global /// theme directory. ///////////////////////////////////////////////////////////////////// public void load_themes(string current) { themes = new Gee.ArrayList(); try { string name; // load global themes var d = Dir.open(Paths.global_themes); while ((name = d.read_name()) != null) { var new_theme = new Theme(Paths.global_themes + "/" + name); if (new_theme.load()) { themes.add(new_theme); } } // load local themes d = Dir.open(Paths.local_themes); while ((name = d.read_name()) != null) { var new_theme = new Theme(Paths.local_themes + "/" + name); if (new_theme.load()) themes.add(new_theme); } } catch (Error e) { warning (e.message); } if (themes.size > 0) { if (current == "") { current = "Adwaita"; warning("No theme specified! Using default..."); } foreach (var t in themes) { if (t.name == current) { theme = t; break; } } if (theme == null) { theme = themes[0]; warning("Theme \"" + current + "\" not found! Using fallback..."); } theme.load_images(); } else { error("No theme found!"); } } ///////////////////////////////////////////////////////////////////// /// Returns true if a loaded theme has the given name or is in a /// directory with the given name. ///////////////////////////////////////////////////////////////////// public bool has_theme(string name) { foreach (var theme in themes) { if (theme.name == name || theme.directory.has_suffix(name)) { return true; } } return false; } } }