Skip to content

Commit

Permalink
wip managerdevicemenu actions
Browse files Browse the repository at this point in the history
  • Loading branch information
infirit committed Dec 20, 2022
1 parent ff5dc17 commit 2a145ba
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 42 deletions.
2 changes: 2 additions & 0 deletions blueman/Functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ def format_bytes(size: float) -> Tuple[float, str]:
def create_menuitem(
text: str,
icon_name: Optional[str] = None,
action_name: Optional[str] = None,
pixbuf: Optional[GdkPixbuf.Pixbuf] = None,
surface: Optional[cairo.Surface] = None,
) -> Gtk.ImageMenuItem:
Expand All @@ -194,6 +195,7 @@ def create_menuitem(
raise ValueError("At least provide one of, icon name, surface or pixbuf")

item = Gtk.ImageMenuItem(label=text, image=image, use_underline=True)
item.set_action_name(action_name)
child = item.get_child()
assert isinstance(child, Gtk.AccelLabel)
child.set_use_markup(True)
Expand Down
98 changes: 56 additions & 42 deletions blueman/gui/manager/ManagerDeviceMenu.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
from enum import Enum, auto
from gettext import gettext as _
from typing import Dict, List, Tuple, Optional, TYPE_CHECKING, Union, Iterable
from typing import Dict, List, Tuple, Optional, TYPE_CHECKING, Union, Iterable, Any

from blueman.Functions import create_menuitem, e_
from blueman.bluez.Network import AnyNetwork
Expand All @@ -25,6 +25,7 @@
gi.require_version("Gdk", "3.0")
from gi.repository import Gdk
from gi.repository import GLib
from gi.repository import Gio

if TYPE_CHECKING:
from blueman.gui.manager.ManagerDeviceList import ManagerDeviceList
Expand Down Expand Up @@ -53,6 +54,8 @@ class ManagerDeviceMenu(Gtk.Menu):
__ops__: Dict[str, str] = {}
__instances__: List["ManagerDeviceMenu"] = []

__registered_actions: List[str] = []

SelectedDevice: Device

def __init__(self, blueman: "Blueman") -> None:
Expand All @@ -62,6 +65,9 @@ def __init__(self, blueman: "Blueman") -> None:

self.is_popup = False

assert isinstance(blueman.window, Gtk.Widget)
self.attach_to_widget(blueman.window, None)

self._device_property_changed_signal = self.Blueman.List.connect("device-property-changed",
self.on_device_property_changed)
ManagerDeviceMenu.__instances__.append(self)
Expand All @@ -78,8 +84,40 @@ def __init__(self, blueman: "Blueman") -> None:
logging.error("** Failed to connect to applet", exc_info=True)
self._appl = None

for name in ("connect", "disconnect", "remove", "rename"):
if name not in self.__registered_actions:
self.Blueman.register_action(name, self._simple_actions)
self.__registered_actions.append(name)

self.generate()

def _simple_actions(self, action: Gio.Action, _val: Optional[Any]) -> None:
name = action.get_name()
logging.debug(f"Executing action {name}")
if name == "connect":
self.connect_service(self.SelectedDevice)
elif name == "disconnect":
self.disconnect_service(self.SelectedDevice)
elif name == "remove":
self.Blueman.remove(self.SelectedDevice)
elif name == "rename":
def on_response(dialog: Gtk.Dialog, response_id: int) -> None:
if response_id == Gtk.ResponseType.ACCEPT:
assert isinstance(alias_entry, Gtk.Entry) # https://github.com/python/mypy/issues/2608
self.SelectedDevice.set('Alias', alias_entry.get_text())
elif response_id == 1:
self.SelectedDevice.set('Alias', '')
dialog.destroy()

builder = Builder("rename-device.ui")
dialog = builder.get_widget("dialog", Gtk.Dialog)
dialog.set_transient_for(self.Blueman.window)
dialog.props.icon_name = "blueman"
alias_entry = builder.get_widget("alias_entry", Gtk.Entry)
alias_entry.set_text(self.SelectedDevice['Alias'])
dialog.connect("response", on_response)
dialog.present()

def __del__(self) -> None:
logging.debug("deleting devicemenu")

Expand All @@ -104,6 +142,7 @@ def set_op(self, device: Device, message: str) -> None:
logging.info(f"op: regenerating instance {inst}")
if inst.SelectedDevice == self.SelectedDevice and not (inst.is_popup and not inst.props.visible):
inst.generate()
self.queue_resize()

def get_op(self, device: Device) -> Optional[str]:
try:
Expand All @@ -119,6 +158,7 @@ def unset_op(self, device: Device) -> None:
logging.info(f"op: regenerating instance {inst}")
if inst.SelectedDevice == self.SelectedDevice and not (inst.is_popup and not inst.props.visible):
inst.generate()
self.queue_resize()

def _on_service_property_changed(self, _service: Union[AnyNetwork, AnyDevice], key: str, _value: object,
_path: str) -> None:
Expand Down Expand Up @@ -246,6 +286,7 @@ def show_generic_connect_calc(self, device_uuids: Iterable[str]) -> bool:
return not device_uuids

def generate(self) -> None:
logging.debug(f"{self.Blueman.list_actions()}")
self.clear()

if not self.is_popup or self.props.visible:
Expand Down Expand Up @@ -281,15 +322,14 @@ def generate(self) -> None:
show_generic_connect = self.show_generic_connect_calc(self.SelectedDevice['UUIDs'])

if not row["connected"] and show_generic_connect:
connect_item = create_menuitem(_("<b>_Connect</b>"), "bluetooth-symbolic")
connect_item.connect("activate", lambda _item: self.connect_service(self.SelectedDevice))
connect_item = create_menuitem(_("<b>_Connect</b>"), "bluetooth-symbolic", action_name="app.connect")
connect_item.props.tooltip_text = _("Connects auto connect profiles A2DP source, A2DP sink, and HID")
connect_item.show()
self.append(connect_item)
elif show_generic_connect:
connect_item = create_menuitem(_("<b>_Disconnect</b>"), "bluetooth-disabled-symbolic")
connect_item = create_menuitem(_("<b>_Disconnect</b>"), "bluetooth-disabled-symbolic",
action_name="app.disconnect")
connect_item.props.tooltip_text = _("Forcefully disconnect the device")
connect_item.connect("activate", lambda _item: self.disconnect_service(self.SelectedDevice))
connect_item.show()
self.append(connect_item)

Expand Down Expand Up @@ -337,81 +377,55 @@ def generate(self) -> None:
for it in sorted(action_items, key=lambda i: i.position):
self.append(it.item)

send_item = create_menuitem(_("Send a _File…"), "blueman-send-symbolic")
send_item = create_menuitem(_("Send a _File…"), "blueman-send-symbolic", action_name="app.sendfile")
send_item.props.sensitive = False
self.append(send_item)
send_item.show()

if row["objpush"]:
send_item.connect("activate", lambda x: self.Blueman.send(self.SelectedDevice))
send_item.props.sensitive = True

item = Gtk.SeparatorMenuItem()
item.show()
self.append(item)

item = create_menuitem(_("_Pair"), "blueman-pair-symbolic")
item = create_menuitem(_("_Pair"), "blueman-pair-symbolic", action_name="app.bond")
item.props.tooltip_text = _("Create pairing with the device")
self.append(item)
item.show()
if not row["paired"]:
item.connect("activate", lambda x: self.Blueman.bond(self.SelectedDevice))
else:
if row["paired"]:
item.props.sensitive = False

if not row["trusted"]:
item = create_menuitem(_("_Trust"), "blueman-trust-symbolic")
item.connect("activate", lambda x: self.Blueman.toggle_trust(self.SelectedDevice))
item = create_menuitem(_("_Trust"), "blueman-trust-symbolic", action_name="app.trust")
# item.connect("activate", lambda x: self.Blueman.toggle_trust(self.SelectedDevice))
self.append(item)
item.show()
else:
item = create_menuitem(_("_Untrust"), "blueman-untrust-symbolic")
item = create_menuitem(_("_Untrust"), "blueman-untrust-symbolic", action_name="app.trust")
self.append(item)
item.connect("activate", lambda x: self.Blueman.toggle_trust(self.SelectedDevice))
item.show()
item.props.tooltip_text = _("Mark/Unmark this device as trusted")

if not row["blocked"]:
item = create_menuitem(_("_Block"), "blueman-block-symbolic")
item.connect("activate", lambda x: self.Blueman.toggle_blocked(self.SelectedDevice))
item = create_menuitem(_("_Block"), "blueman-block-symbolic", action_name="app.block")
self.append(item)
item.show()
else:
item = create_menuitem(_("_Unblock"), "blueman-block-symbolic")
item = create_menuitem(_("_Unblock"), "blueman-block-symbolic", action_name="app.block")
self.append(item)
item.connect("activate", lambda x: self.Blueman.toggle_blocked(self.SelectedDevice))
item.show()
item.props.tooltip_text = _("Block/Unblock this device")

def on_rename(_item: Gtk.MenuItem, device: Device) -> None:
def on_response(dialog: Gtk.Dialog, response_id: int) -> None:
if response_id == Gtk.ResponseType.ACCEPT:
assert isinstance(alias_entry, Gtk.Entry) # https://github.com/python/mypy/issues/2608
device.set('Alias', alias_entry.get_text())
elif response_id == 1:
device.set('Alias', '')
dialog.destroy()

builder = Builder("rename-device.ui")
dialog = builder.get_widget("dialog", Gtk.Dialog)
dialog.set_transient_for(self.Blueman.window)
dialog.props.icon_name = "blueman"
alias_entry = builder.get_widget("alias_entry", Gtk.Entry)
alias_entry.set_text(device['Alias'])
dialog.connect("response", on_response)
dialog.present()

item = Gtk.MenuItem.new_with_mnemonic(_("R_ename device…"))
item.connect('activate', on_rename, self.SelectedDevice)
item = Gtk.MenuItem(label=_("R_ename device…"), use_underline=True)
item.set_action_name("app.rename")
self.append(item)
item.show()

item = Gtk.SeparatorMenuItem()
item.show()
self.append(item)

item = create_menuitem(_("_Remove…"), "list-remove-symbolic")
item.connect("activate", lambda x: self.Blueman.remove(self.SelectedDevice))
item = create_menuitem(_("_Remove…"), "list-remove-symbolic", action_name="app.remove")
self.append(item)
item.show()
item.props.tooltip_text = _("Remove this device from the known devices list")
Expand Down

0 comments on commit 2a145ba

Please sign in to comment.