Skip to content

Commit

Permalink
feat: Add a dynamic dropdown menu containing the list of available up…
Browse files Browse the repository at this point in the history
…dates to the systray applet menu (#272)

Add a dynamic menu entry containing the state of the system and an associated dropdown menu containing the list of available updates. This serves as an alternative to the dynamic tooltip (which may not supported on every panel / systray implementation)

Closes #260
  • Loading branch information
Antiz96 authored Oct 6, 2024
1 parent 64378f1 commit af51378
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
run: find . -name '*.sh' -exec shellcheck --color=always {} +

- name: Run pylint
run: find . -name '*.py' -exec pylint -d E0611,E0401,C0103 --output-format=colorized {} +
run: find . -name '*.py' -exec pylint -d E0611,E0401,C0103,C0301 --output-format=colorized {} +

- name: Run make test
run: make test
31 changes: 22 additions & 9 deletions po/arch-update.pot
Original file line number Diff line number Diff line change
Expand Up @@ -588,42 +588,55 @@ msgstr ""
msgid "No service requiring a post upgrade restart found\\n"
msgstr ""

#: src/lib/tray.py:123
msgid "Arch-Update: 'updates' state file isn't found"
#: src/lib/tray.py:123 src/lib/tray.py:125
msgid "'updates' state file isn't found"
msgstr ""

#: src/lib/tray.py:137
msgid "Arch-Update: System is up to date"
#: src/lib/tray.py:135 src/lib/tray.py:136
msgid "System is up to date"
msgstr ""

#: src/lib/tray.py:140
#, python-brace-format
msgid ""
"Arch-Update: 1 update available\n"
"1 update available\n"
"\n"
"{update_list}"
msgstr ""

#: src/lib/tray.py:141
msgid "1 update available"
msgstr ""

#: src/lib/tray.py:145
#, python-brace-format
msgid ""
"Arch-Update: {updates} updates available\n"
"{updates} updates available\n"
"\n"
"{update_list}"
msgstr ""

#: src/lib/tray.py:182
#: src/lib/tray.py:146
#, python-brace-format
msgid "{updates} updates available"
msgstr ""

#: src/lib/tray.py:186
msgid "Run Arch-Update"
msgstr ""

#: src/lib/tray.py:183
#: src/lib/tray.py:187
msgid "Check for updates"
msgstr ""

#: src/lib/tray.py:184
#: src/lib/tray.py:188
msgid "Exit"
msgstr ""

#: src/lib/tray.py:191
msgid "Checking for updates..."
msgstr ""

#: src/lib/tray.sh:20
#, sh-format
msgid "Arch-Update tray desktop file not found"
Expand Down
39 changes: 26 additions & 13 deletions po/fr.po
Original file line number Diff line number Diff line change
Expand Up @@ -658,48 +658,61 @@ msgstr ""
msgid "No service requiring a post upgrade restart found\\n"
msgstr "Aucun service nécessitant un redémarrage suite à la mise à jour n'a été trouvé\\n"

#: src/lib/tray.py:123
msgid "Arch-Update: 'updates' state file isn't found"
msgstr "Arch-Update : fichier d'état 'updates' non trouvé"
#: src/lib/tray.py:123 src/lib/tray.py:125
msgid "'updates' state file isn't found"
msgstr "fichier d'état 'updates' non trouvé"

#: src/lib/tray.py:137
msgid "Arch-Update: System is up to date"
msgstr "Arch-Update : Le système est à jour"
#: src/lib/tray.py:135 src/lib/tray.py:136
msgid "System is up to date"
msgstr "Le système est à jour"

#: src/lib/tray.py:140
#, python-brace-format
msgid ""
"Arch-Update: 1 update available\n"
"1 update available\n"
"\n"
"{update_list}"
msgstr ""
"Arch-Update : 1 mise à jour disponible\n"
"1 mise à jour disponible\n"
"\n"
"{update_list}"

#: src/lib/tray.py:141
msgid "1 update available"
msgstr "1 mise à jour disponible"

#: src/lib/tray.py:145
#, python-brace-format
msgid ""
"Arch-Update: {updates} updates available\n"
"{updates} updates available\n"
"\n"
"{update_list}"
msgstr ""
"Arch-Update : {updates} mises à jour disponibles\n"
"{updates} mises à jour disponibles\n"
"\n"
"{update_list}"

#: src/lib/tray.py:182
#: src/lib/tray.py:146
#, python-brace-format
msgid "{updates} updates available"
msgstr "{updates} mises à jour disponibles"

#: src/lib/tray.py:186
msgid "Run Arch-Update"
msgstr "Lancer Arch-Update"

#: src/lib/tray.py:183
#: src/lib/tray.py:187
msgid "Check for updates"
msgstr "Vérifier les mises à jour"

#: src/lib/tray.py:184
#: src/lib/tray.py:188
msgid "Exit"
msgstr "Quitter"

#: src/lib/tray.py:191
msgid "Checking for updates..."
msgstr "Vérification des mises à jour..."

#: src/lib/tray.sh:20
#, sh-format
msgid "Arch-Update tray desktop file not found"
Expand Down
49 changes: 31 additions & 18 deletions src/lib/tray.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ class ArchUpdateQt6:
""" System Tray using QT6 library """

def file_changed(self):
""" Update icon and tooltip on state file content changes """
""" Update icon, tooltip and dropdown menu on state file content changes """
self.update_icon()
self.update_tooltip()
self.update_tooltip_and_dropdown_menu()

def update_icon(self):
""" Update the tray icon based on the icon state file content """
Expand All @@ -110,7 +110,7 @@ def update_icon(self):
icon = QIcon.fromTheme(contents)
self.tray.setIcon(icon)

def update_tooltip(self):
def update_tooltip_and_dropdown_menu(self):
""" Update the tooltip with the number / list of pending updates """
if self.watcher and not self.updatesfile in self.watcher.files():
self.watcher.addPath(self.updatesfile)
Expand All @@ -120,33 +120,38 @@ def update_tooltip(self):
updates_list = f.readlines()
except FileNotFoundError:
log.error("State updates file missing")
tooltip = _("Arch-Update: 'updates' state file isn't found")
tooltip = _("'updates' state file isn't found")
self.tray.setToolTip(tooltip)
self.dropdown_menu.setTitle(_("'updates' state file isn't found"))
self.dropdown_menu.setEnabled(False)
return

# Remove empty lines
updates_list = [
update.strip()
for update in updates_list
if update.strip()
]
updates_list = [update.strip() for update in updates_list if update.strip()]

updates_count = len(updates_list)

if updates_count == 0:
tooltip = _("Arch-Update: System is up to date")
tooltip = _("System is up to date")
self.dropdown_menu.setTitle(_("System is up to date"))
self.dropdown_menu.setEnabled(False)
elif updates_count == 1:
update_list = "".join(updates_list)
tooltip = _("Arch-Update: 1 update available\n\n{update_list}").format(
update_list=update_list
)
tooltip = _("1 update available\n\n{update_list}").format(update_list=update_list)
self.dropdown_menu.setTitle(_("1 update available"))
self.dropdown_menu.setEnabled(True)
else:
update_list = "\n".join(updates_list)
tooltip = _("Arch-Update: {updates} updates available\n\n{update_list}").format(
updates=updates_count, update_list=update_list
)
tooltip = _("{updates} updates available\n\n{update_list}").format(updates=updates_count, update_list=update_list)
self.dropdown_menu.setTitle(_("{updates} updates available").format(updates=updates_count))
self.dropdown_menu.setEnabled(True)

# Update tooltip and dropdown menu accordingly
self.tray.setToolTip(tooltip)
self.dropdown_menu.clear()
if updates_list:
for update in updates_list:
self.dropdown_menu.addAction(update)

def run(self):
""" Start arch-update """
Expand All @@ -173,7 +178,6 @@ def __init__(self, iconfile):

# Icon
self.tray = QSystemTrayIcon()
self.file_changed()
self.tray.setVisible(True)
self.tray.activated.connect(self.run)

Expand All @@ -182,6 +186,13 @@ def __init__(self, iconfile):
menu_launch = QAction(_("Run Arch-Update"))
menu_check = QAction(_("Check for updates"))
menu_exit = QAction(_("Exit"))

# Dynamic dropdown menu to show the update list
self.dropdown_menu = QMenu(_("Checking for updates..."))

# Add actions to the menu
menu.addMenu(self.dropdown_menu)
menu.addSeparator()
menu.addAction(menu_launch)
menu.addAction(menu_check)
menu.addAction(menu_exit)
Expand All @@ -196,8 +207,10 @@ def __init__(self, iconfile):
self.watcher = QFileSystemWatcher([self.iconfile, self.updatesfile])
self.watcher.fileChanged.connect(self.file_changed)

app.exec()
# Initial file check to set the right icon, tooltip and dropdown menu text
self.file_changed()

app.exec()

if __name__ == "__main__":
ArchUpdateQt6(ICON_FILE)

0 comments on commit af51378

Please sign in to comment.