/* * Copyright 2013 Canonical Ltd. * Copyright 2022-2023 Robert Tari * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authors: * Charles Kerr * Robert Tari */ class Profile: Object { protected Bluetooth bluetooth; protected string profile_name; protected Menu root; protected Menu menu; private uint menu_export_id; protected SimpleAction root_action; protected bool visible { get; set; default = true; } public Profile (Bluetooth bluetooth, string profile_name) { this.bluetooth = bluetooth; this.profile_name = profile_name; root_action = new SimpleAction.stateful (@"root-$profile_name", null, action_state_for_root()); notify["visible"].connect (() => update_root_action_state()); bluetooth.notify["enabled"].connect (() => update_root_action_state()); bluetooth.notify["connected"].connect (() => update_root_action_state()); menu = new Menu (); var item = create_root_menuitem (); item.set_submenu (menu); root = new Menu (); root.append_item (item); } public void export_menu (DBusConnection connection, string object_path) { try { debug (@"exporting menu '$profile_name'"); menu_export_id = connection.export_menu_model (object_path, root); } catch (Error e) { critical (@"Unable to export menu on $object_path: $(e.message)"); } } public void unexport_menu (DBusConnection connection) { if (menu_export_id != 0) { debug (@"unexporting menu '$profile_name'"); connection.unexport_menu_model (menu_export_id); menu_export_id = 0; } } protected void spawn_command_line_async (string command) { try { Process.spawn_command_line_async (command); } catch (Error e) { warning (@"Unable to launch '$command': $(e.message)"); } } /// /// Menu Items /// protected MenuItem create_enabled_menuitem () { var item = new MenuItem (_("Bluetooth"), "indicator.bluetooth-enabled(true)"); item.set_attribute ("x-ayatana-type", "s", "org.ayatana.indicator.switch"); return item; } private MenuItem create_root_menuitem () { var item = new MenuItem (null, @"indicator.root-$profile_name"); item.set_attribute ("x-ayatana-type", "s", "org.ayatana.indicator.root"); return item; } /// /// Actions /// protected Action create_supported_action (Bluetooth bluetooth) { var action = new SimpleAction.stateful ("bluetooth-supported", null, new Variant.boolean (bluetooth.supported)); bluetooth.notify["supported"].connect (() => action.set_state (new Variant.boolean (bluetooth.supported))); return action; } protected Action create_enabled_action (Bluetooth bluetooth) { var action = new SimpleAction.stateful ("bluetooth-enabled", VariantType.BOOLEAN, new Variant.boolean (bluetooth.enabled)); action.activate.connect ((action, param) => action.change_state (param)); action.change_state.connect ((action, requestedValue) => bluetooth.try_set_enabled (requestedValue.get_boolean())); bluetooth.notify["enabled"].connect (() => action.set_state (new Variant.boolean (bluetooth.enabled))); return action; } protected void update_root_action_state () { root_action.set_state (action_state_for_root ()); } protected Variant action_state_for_root () { string a11y; string icon_name; if (bluetooth.connected) { a11y = "Bluetooth (connections)"; icon_name = "bluetooth-paired"; } else if (bluetooth.enabled) { a11y = "Bluetooth (on)"; icon_name = "bluetooth-active"; } else { a11y = "Bluetooth (off)"; icon_name = "bluetooth-disabled"; } var icon = new ThemedIcon.with_default_fallbacks (icon_name); var builder = new VariantBuilder (new VariantType ("a{sv}")); builder.add ("{sv}", "visible", new Variant.boolean (visible)); builder.add ("{sv}", "accessible-desc", new Variant.string (a11y)); if (AyatanaCommon.utils_is_lomiri () || (bluetooth.supported && visible)) { builder.add ("{sv}", "icon", icon.serialize()); } builder.add ("{sv}", "title", new Variant.string (_("Bluetooth"))); builder.add ("{sv}", "tooltip", new Variant.string (_("Bluetooth status & device connections"))); return builder.end (); } }