diff options
author | Charles Kerr <charles.kerr@canonical.com> | 2013-08-10 04:26:27 +0000 |
---|---|---|
committer | Tarmac <> | 2013-08-10 04:26:27 +0000 |
commit | f28653eb1a4a310987fffc44334b93da3f547d41 (patch) | |
tree | 82a72bfbb7eeca76766d73ae20f1152c5b8392c3 /src/desktop.vala | |
parent | 0391025f72e9e5fed972b40e63087635d50c9234 (diff) | |
parent | a0616908a817d6fad47c29ae703fc8a2ea379af6 (diff) | |
download | ayatana-indicator-bluetooth-f28653eb1a4a310987fffc44334b93da3f547d41.tar.gz ayatana-indicator-bluetooth-f28653eb1a4a310987fffc44334b93da3f547d41.tar.bz2 ayatana-indicator-bluetooth-f28653eb1a4a310987fffc44334b93da3f547d41.zip |
Add phone profile. Export menus & actions using gio. Drops the gtk, dbusmenu, and libindicator build dependencies. Drops runtime dependency on gnome-blueooth in the phone profile.
Approved by Ted Gould, PS Jenkins bot, Mathieu Trudel-Lapierre.
Diffstat (limited to 'src/desktop.vala')
-rw-r--r-- | src/desktop.vala | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/src/desktop.vala b/src/desktop.vala new file mode 100644 index 0000000..4a10db8 --- /dev/null +++ b/src/desktop.vala @@ -0,0 +1,286 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Charles Kerr <charles.kerr@canonical.com> + */ + +class Desktop: Profile +{ + private uint idle_rebuild_id = 0; + private Settings settings; + private SimpleActionGroup action_group; + + private Menu device_section; + private HashTable<uint,SimpleAction> connect_actions; + + protected override void dispose () + { + if (idle_rebuild_id != 0) + { + Source.remove (idle_rebuild_id); + idle_rebuild_id = 0; + } + + base.dispose (); + } + + public Desktop (Bluetooth bluetooth, SimpleActionGroup action_group) + { + const string profile_name = "desktop"; + + base (bluetooth, profile_name); + + this.action_group = action_group; + + connect_actions = new HashTable<uint,SimpleAction>(direct_hash, direct_equal); + + settings = new Settings ("com.canonical.indicator.bluetooth"); + + // build the static actions + Action[] actions = {}; + actions += root_action; + actions += create_enabled_action (bluetooth); + actions += create_discoverable_action (bluetooth); + actions += create_wizard_action (); + actions += create_browse_files_action (); + actions += create_send_file_action (); + actions += create_show_settings_action (); + foreach (var a in actions) + action_group.insert (a); + + build_menu (); + + // know when to show the indicator & when to hide it + settings.changed["visible"].connect (()=> update_visibility()); + bluetooth.notify.connect (() => update_visibility()); + update_visibility (); + + // when devices change, rebuild our device section + bluetooth.devices_changed.connect (()=> { + if (idle_rebuild_id == 0) + idle_rebuild_id = Idle.add (() => { + rebuild_device_section (); + idle_rebuild_id = 0; + return false; + }); + }); + } + + void update_visibility () + { + visible = bluetooth.powered && !bluetooth.blocked && settings.get_boolean("visible"); + } + + /// + /// MenuItems + /// + + MenuItem create_device_connection_menuitem (Device device) + { + var id = device.id; + var action_name = @"desktop-device-$(id)-connected"; + + var item = new MenuItem (_("Connection"), @"indicator.$action_name"); + item.set_attribute ("x-canonical-type", + "s", "com.canonical.indicator.switch"); + + // if this doesn't already have an action, create one + if (!connect_actions.contains (id)) + { + debug (@"creating action for $action_name"); + var a = new SimpleAction.stateful (action_name, + null, + device.is_connected); + + a.activate.connect (() + => a.set_state (!a.get_state().get_boolean())); + + a.notify["state"].connect (() + => bluetooth.set_device_connected (id, a.get_state().get_boolean())); + + connect_actions.insert (device.id, a); + action_group.insert (a); + } + else + { + debug (@"updating action $(device.id) state to $(device.is_connected)"); + var action = connect_actions.lookup (device.id); + action.set_state (device.is_connected); + } + + return item; + } + + void rebuild_device_section () + { + device_section.remove_all (); + + foreach (var device in bluetooth.get_devices()) + { + Menu submenu = new Menu (); + MenuItem item; + + if (device.is_connectable) + submenu.append_item (create_device_connection_menuitem (device)); + + if (device.supports_browsing) + submenu.append (_("Browse files…"), + @"indicator.desktop-browse-files::$(device.address)"); + + if (device.supports_file_transfer) + submenu.append (_("Send files…"), + @"indicator.desktop-send-file::$(device.address)"); + + switch (device.device_type) + { + case Device.Type.KEYBOARD: + submenu.append (_("Keyboard Settings…"), + "indicator.desktop-show-settings::keyboard"); + break; + + case Device.Type.MOUSE: + case Device.Type.TABLET: + submenu.append (_("Mouse and Touchpad Settings…"), + "indicator.desktop-show-settings::mouse"); + break; + + case Device.Type.HEADSET: + case Device.Type.HEADPHONES: + case Device.Type.OTHER_AUDIO: + submenu.append (_("Sound Settings…"), + "indicator.desktop-show-settings::sound"); + break; + } + + // only show the device if it's got actions that we can perform on it + if (submenu.get_n_items () > 0) + { + item = new MenuItem (device.name, null); + item.set_attribute_value ("icon", device.icon.serialize()); + item.set_submenu (submenu); + device_section.append_item (item); + } + } + } + + void build_menu () + { + Menu section; + MenuItem item; + + // quick toggles section + section = new Menu (); + section.append_item (create_enabled_menuitem ()); + item = new MenuItem ("Visible", "indicator.desktop-discoverable"); + item.set_attribute ("x-canonical-type", "s", + "com.canonical.indicator.switch"); + section.append_item (item); + menu.append_section (null, section); + + // devices section + device_section = new Menu (); + rebuild_device_section (); + menu.append_section (null, device_section); + + // settings section + section = new Menu (); + section.append (_("Set Up New Device…"), + "indicator.desktop-wizard"); + section.append (_("Bluetooth Settings…"), + "indicator.desktop-show-settings::bluetooth"); + menu.append_section (null, section); + } + + /// + /// Actions + /// + + void show_settings (string panel) + { + spawn_command_line_async ("gnome-control-center " + panel); + } + + Action create_discoverable_action (Bluetooth bluetooth) + { + var action = new SimpleAction.stateful ("desktop-discoverable", + null, + bluetooth.discoverable); + + action.activate.connect (() + => action.set_state (!action.get_state().get_boolean())); + + action.notify["state"].connect (() + => bluetooth.try_set_discoverable (action.get_state().get_boolean())); + + bluetooth.notify["discoverable"].connect (() + => action.set_state (bluetooth.discoverable)); + + action.set_enabled (bluetooth.powered); + bluetooth.notify["powered"].connect (() + => action.set_enabled (bluetooth.powered)); + + return action; + } + + Action create_wizard_action () + { + var action = new SimpleAction ("desktop-wizard", null); + + action.activate.connect (() + => spawn_command_line_async ("bluetooth-wizard")); + return action; + } + + Action create_browse_files_action () + { + var action = new SimpleAction ("desktop-browse-files", VariantType.STRING); + action.activate.connect ((action, address) => { + var uri = @"obex://[$(address.get_string())]/"; + var file = File.new_for_uri (uri); + file.mount_enclosing_volume.begin (MountMountFlags.NONE, + null, null, (obj, res) => { + try { + AppInfo.launch_default_for_uri (uri, null); + } catch (Error e) { + warning (@"unable to launch '$uri': $(e.message)"); + } + }); + }); + return action; + } + + Action create_send_file_action () + { + var action = new SimpleAction ("desktop-send-file", VariantType.STRING); + + action.activate.connect ((action, address) => { + var cmd = @"bluetooth-sendto --device=$(address.get_string())"; + spawn_command_line_async (cmd); + }); + + return action; + } + + Action create_show_settings_action () + { + var action = new SimpleAction ("desktop-show-settings", VariantType.STRING); + + action.activate.connect ((action, panel) + => show_settings (panel.get_string())); + + return action; + } +} |