Disabling history items when they're unavailable
4 files changed, 35 insertions(+), 11 deletions(-)

M winrustler/ui/__main__.py
M winrustler/ui/app.py
M winrustler/ui/history.py
M winrustler/ui/state.py
M winrustler/ui/__main__.py +3 -3
@@ 35,7 35,7 @@ def main():
     app = WinRustlerApp(qt_args, quitOnLastWindowClosed=False)
     app.startTimer(100)  # So the interpreter can handle SIGINT
 
-    history_menu = QMenu(parent=None)
+    history_menu = QMenu(parent=None, toolTipsVisible=True)
     history_feature = HistoryFeature(app.winset, history_menu)
     history_feature.load()
     history_feature.rustle.connect(app.attempt_rustle)

          
@@ 52,12 52,12 @@ def main():
     if args.show:
         tray.show_window()
 
-    print("Lets go!")
+    logger.info("Lets go!")
     try:
         app.exec_()
     finally:
         tray.hide()
-    print("hey, we exited cleanly!")
+    logger.info("hey, we exited cleanly!")
 
 
 if __name__ == "__main__":

          
M winrustler/ui/app.py +11 -5
@@ 8,9 8,9 @@ from PyQt5.QtCore import (
         pyqtSlot,
         QTimer,
 )
-from PyQt5.QtWidgets import QApplication
+from PyQt5.QtWidgets import QApplication, QMessageBox
 
-from winrustler.winapi import WindowDiscovery, query_one
+from winrustler.winapi import WindowDiscovery, query_one, NoResults, TooManyResults
 from winrustler.ui.winapi import WinHooker
 from winrustler.ui.debug import show_exceptions
 

          
@@ 68,6 68,12 @@ class WinRustlerApp(QApplication):
     @pyqtSlot(object, object)
     @show_exceptions
     def attempt_rustle(self, window_title, rustle):
-        hwnd = query_one(self.winset.hwnds, window_title)
-        rustle = attr.evolve(rustle, hwnd=hwnd)
-        self.do_rustling(rustle)
+        try:
+            hwnd = query_one(self.winset.hwnds, window_title)
+        except NoResults as e:
+            QMessageBox.critical("No windows found named \"%s\"." % window_title)
+        except TooManyResult as es:
+            QMessageBox.critical("Multiple windows named \"%s\". Couldn't decide which to use." % window_title)
+        else:
+            rustle = attr.evolve(rustle, hwnd=hwnd)
+            self.do_rustling(rustle)

          
M winrustler/ui/history.py +15 -3
@@ 7,6 7,7 @@ from PyQt5.QtCore import QObject, pyqtSl
 from PyQt5.QtWidgets import QMenu, QAction
 
 from winrustler.winapi import get_window_title
+from winrustler.winapi import query_one, NoResults, TooManyResults
 from winrustler.ui.debug import show_exceptions
 from winrustler.ui.state import program_settings, Serialization
 from winrustler.ui.winapi import get_window_icon

          
@@ 59,13 60,24 @@ class HistoryFeature(QObject):
         self.menu.addAction("&Clear")
         self.data = []
         self.actions = {}  # Maps data to actions?
-        self.winset.tell_and_connect(self._update_engagement)
+        self.winset.tell_and_connect(self._refresh_engagement)
 
     @pyqtSlot(object, object)
     @show_exceptions
-    def _update_engagement(self, new, lost):
+    def _refresh_engagement(self, new, old):
         for past in self.data:
-            pass
+            act = self.actions[past]
+            try:
+                hwnd = query_one(self.winset.hwnds, past.window_title)
+            except NoResults as e:
+                act.setToolTip("No matching windows found.")
+                act.setEnabled(False)
+            except TooManyResult as es:
+                act.setToolTip("Multiple matching windows found.")
+                act.setEnabled(False)
+            else:
+                #act.setIcon(get_window_icon(hwnd)) # hrm...
+                act.setEnabled(True)
 
     def save(self):
         settings = program_settings()

          
M winrustler/ui/state.py +6 -0
@@ 18,6 18,12 @@ IDENT_KEY = "__typename__"
 
 @attr.s()
 class Serialization():
+    """
+    Some crap for transforming attr classes into data types that can be
+    stored and restored into QSettings without PyQt5 being a dick and trying to
+    use pickling...
+    """
+
     _cls_idents = attr.ib(default=attr.Factory(dict))
     _ident_clss = attr.ib(default=attr.Factory(dict))