aboutsummaryrefslogtreecommitdiff
path: root/src/desktop.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/desktop.vala')
-rw-r--r--src/desktop.vala192
1 files changed, 176 insertions, 16 deletions
diff --git a/src/desktop.vala b/src/desktop.vala
index a7b8995..31fe9ac 100644
--- a/src/desktop.vala
+++ b/src/desktop.vala
@@ -19,11 +19,14 @@
class Desktop: Profile
{
+ private uint idle_rebuild_id = 0;
private Settings settings;
private Bluetooth bluetooth;
private SimpleAction root_action;
private Action[] all_actions;
+ private Menu device_section;
+ private HashTable<uint,SimpleAction> connect_actions;
public override void add_actions_to_group (SimpleActionGroup group)
{
@@ -31,29 +34,136 @@ class Desktop: Profile
group.insert (all_actions[i]);
}
+ protected override void dispose ()
+ {
+ if (idle_rebuild_id != 0)
+ {
+ Source.remove (idle_rebuild_id);
+ idle_rebuild_id = 0;
+ }
+
+ base.dispose ();
+ }
+
public Desktop (Bluetooth bluetooth)
{
base ("desktop");
this.bluetooth = bluetooth;
+ connect_actions = new HashTable<uint,SimpleAction>(direct_hash, direct_equal);
+
settings = new Settings ("com.canonical.indicator.bluetooth");
- root_action = new SimpleAction.stateful ("root-desktop", null, action_state_for_root());
+ root_action = create_root_action ();
all_actions = {};
all_actions += root_action;
all_actions += create_enabled_action (bluetooth);
all_actions += create_discoverable_action (bluetooth);
- all_actions += create_settings_action ();
all_actions += create_wizard_action ();
+ all_actions += create_browse_files_action ();
+ all_actions += create_send_file_action ();
+ all_actions += create_show_settings_action ();
+
+ build_menu ();
- bluetooth.notify.connect (() => update_root_action_state());
settings.changed["visible"].connect (()=> update_root_action_state());
+ bluetooth.notify.connect (() => update_root_action_state());
+ bluetooth.devices_changed.connect (()=> {
+ if (idle_rebuild_id == 0)
+ idle_rebuild_id = Idle.add (() => {
+ rebuild_device_section();
+ idle_rebuild_id = 0;
+ return false;
+ });
+ });
+ }
+
+ ///
+ /// MenuItems
+ ///
+
+ MenuItem create_device_connection_menuitem (Device device)
+ {
+ var action_name = @"desktop-device-$(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 (device.id))
+ {
+ debug (@"creating action for $action_name");
+ var action = new SimpleAction.stateful (action_name, null, device.is_connected);
+ action.activate.connect (() => action.set_state (!action.get_state().get_boolean()));
+ action.notify["state"].connect (() => bluetooth.set_device_connected (device.id, action.get_state().get_boolean()));
+ connect_actions.insert (device.id, action);
+ all_actions += action;
+ }
+ 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 ();
item = new MenuItem ("Bluetooth", "indicator.desktop-enabled");
item.set_attribute ("x-canonical-type", "s", "com.canonical.indicator.switch");
@@ -63,12 +173,40 @@ class Desktop: Profile
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-settings");
+ section.append (_("Bluetooth Settings…"), "indicator.desktop-show-settings::bluetooth");
menu.append_section (null, section);
}
+ ///
+ /// Action Helpers
+ ///
+
+ void spawn_command_line_async (string command)
+ {
+ try {
+ Process.spawn_command_line_async (command);
+ } catch (Error e) {
+ warning ("unable to launch '$command': $(e.message)");
+ }
+ }
+
+ void show_control_center (string panel)
+ {
+ spawn_command_line_async ("gnome-control-center " + panel);
+ }
+
+ ///
+ /// Actions
+ ///
+
Action create_enabled_action (Bluetooth bluetooth)
{
var action = new SimpleAction.stateful ("desktop-enabled", null, !bluetooth.blocked);
@@ -89,15 +227,6 @@ class Desktop: Profile
return action;
}
- void spawn_command_line_async (string command)
- {
- try {
- Process.spawn_command_line_async (command);
- } catch (Error e) {
- warning ("unable to launch '%s': %s", command, e.message);
- }
- }
-
Action create_wizard_action ()
{
var action = new SimpleAction ("desktop-wizard", null);
@@ -105,10 +234,36 @@ class Desktop: Profile
return action;
}
- Action create_settings_action ()
+ Action create_browse_files_action ()
{
- var action = new SimpleAction ("desktop-settings", null);
- action.activate.connect (() => spawn_command_line_async ("gnome-control-center bluetooth"));
+ 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) => {
+ spawn_command_line_async ("bluetooth-sendto --device=$(address.get_string())");
+ });
+ return action;
+ }
+
+ Action create_show_settings_action ()
+ {
+ var action = new SimpleAction ("desktop-show-settings", VariantType.STRING);
+ action.activate.connect ((action, panel) => show_control_center (panel.get_string()));
return action;
}
@@ -143,6 +298,11 @@ class Desktop: Profile
return builder.end ();
}
+ SimpleAction create_root_action ()
+ {
+ return new SimpleAction.stateful ("root-desktop", null, action_state_for_root());
+ }
+
void update_root_action_state ()
{
root_action.set_state (action_state_for_root ());