44import webbrowser
55import os
66import subprocess
7+ from collections import defaultdict
78
89from PyQt5 import QtCore
910from PyQt5 .QtWidgets import QApplication , QSystemTrayIcon , QMessageBox , QMenu , QWidget , QPushButton
@@ -93,12 +94,18 @@ def show_module_failed_dialog(module):
9394 box .show ()
9495
9596 def rebuild_modules_menu ():
96- for module in modulesMenu .actions ():
97- name = module .text ()
98- alive = self .manager .modules [name ].is_alive ()
99- module .setChecked (alive )
100- # print(module.text(), alive)
97+ for action in modulesMenu .actions ():
98+ if action .isEnabled ():
99+ name = action .module .name
100+ alive = self .manager .modules [name ].is_alive ()
101+ action .setChecked (alive )
102+ # print(module.text(), alive)
101103
104+ # TODO: Do it in a better way, singleShot isn't pretty...
105+ QtCore .QTimer .singleShot (2000 , rebuild_modules_menu )
106+ QtCore .QTimer .singleShot (2000 , rebuild_modules_menu )
107+
108+ def check_module_status ():
102109 unexpected_exits = self .manager .get_unexpected_stops ()
103110 if unexpected_exits :
104111 for module in unexpected_exits :
@@ -107,22 +114,34 @@ def rebuild_modules_menu():
107114
108115 # TODO: Do it in a better way, singleShot isn't pretty...
109116 QtCore .QTimer .singleShot (2000 , rebuild_modules_menu )
110-
111- QtCore .QTimer .singleShot (2000 , rebuild_modules_menu )
117+ QtCore .QTimer .singleShot (2000 , check_module_status )
112118
113119 def _build_modulemenu (self , moduleMenu ):
114120 moduleMenu .clear ()
115121
116122 def add_module_menuitem (module ):
117- ac = moduleMenu .addAction (module .name , lambda : module .toggle ())
123+ title = module .name
124+ ac = moduleMenu .addAction (title , lambda : module .toggle ())
125+ # Kind of nasty, but a quick way to affiliate the module to the menu action for when it needs updating
126+ ac .module = module
118127 ac .setCheckable (True )
119128 ac .setChecked (module .is_alive ())
120129
121- add_module_menuitem (self .manager .modules ["aw-server" ])
130+ modules_by_location = defaultdict (lambda : list ())
131+ for module in sorted (self .manager .modules .values (), key = lambda m : m .name ):
132+ modules_by_location [module .location ].append (module )
133+
134+ for location , modules in sorted (modules_by_location .items (), key = lambda kv : kv [0 ]):
135+ header = moduleMenu .addAction (location )
136+ header .setEnabled (False )
137+
138+ # Always show aw-server first
139+ if "aw-server" in (m .name for m in modules ):
140+ add_module_menuitem (self .manager .modules ["aw-server" ])
122141
123- for module_name in sorted (self . manager . modules . keys () ):
124- if module_name != "aw-server" :
125- add_module_menuitem (self .manager .modules [module_name ])
142+ for module in sorted (modules , key = lambda m : m . name ):
143+ if module . name != "aw-server" :
144+ add_module_menuitem (self .manager .modules [module . name ])
126145
127146
128147def exit_dialog ():
0 commit comments