1
1
import logging
2
2
import asyncio
3
3
import shlex
4
+ from functools import partial
4
5
5
6
from quamash import QtCore , QtGui , QtWidgets
6
7
from pyqtgraph import dockarea
@@ -19,16 +20,19 @@ def __init__(self, token, name, command):
19
20
self .applet_name = name
20
21
self .command = command
21
22
23
+ def rename (self , name ):
24
+ self .applet_name = name
25
+ self .label .setText ("Applet: " + name )
26
+
22
27
async def start (self ):
23
28
command = self .command .format (embed_token = self .token )
24
29
logger .debug ("starting command %s for %s" , command , self .applet_name )
25
30
try :
26
31
self .process = await asyncio .create_subprocess_exec (
27
32
* shlex .split (command ))
28
- except FileNotFoundError :
29
- logger .warning ("Applet %s failed to start" , self .applet_name )
30
- else :
31
- logger .warning ("Applet %s exited" , self .applet_name )
33
+ except :
34
+ logger .warning ("Applet %s failed to start" , self .applet_name ,
35
+ exc_info = True )
32
36
33
37
def capture (self , win_id ):
34
38
logger .debug ("capturing window 0x%x for %s" , win_id , self .applet_name )
@@ -54,11 +58,17 @@ async def terminate(self):
54
58
except ProcessLookupError :
55
59
pass
56
60
await self .process .wait ()
61
+ del self .process
62
+
63
+ async def restart (self ):
64
+ await self .terminate ()
65
+ await self .start ()
57
66
58
67
59
68
class AppletsDock (dockarea .Dock ):
60
69
def __init__ (self , manager ):
61
70
self .manager = manager
71
+ self .token_to_checkbox = dict ()
62
72
63
73
dockarea .Dock .__init__ (self , "Applets" )
64
74
self .setMinimumSize (QtCore .QSize (850 , 450 ))
@@ -81,6 +91,7 @@ def __init__(self, manager):
81
91
new_action .triggered .connect (self .new )
82
92
self .table .addAction (new_action )
83
93
restart_action = QtGui .QAction ("Restart selected applet" , self .table )
94
+ restart_action .triggered .connect (self .restart )
84
95
self .table .addAction (restart_action )
85
96
delete_action = QtGui .QAction ("Delete selected applet" , self .table )
86
97
delete_action .triggered .connect (self .delete )
@@ -102,12 +113,26 @@ def cell_changed(self, row, column):
102
113
name = name .text ()
103
114
token = self .manager .create (name , command )
104
115
item .applet_token = token
116
+ self .token_to_checkbox [token ] = item
105
117
else :
106
118
token = getattr (item , "applet_token" , None )
107
119
if token is not None :
108
120
# cell_changed is emitted at row creation
109
121
self .manager .delete (token )
110
- item .applet_token = None
122
+ elif column == 1 or column == 2 :
123
+ new_value = self .table .item (row , column ).text ()
124
+ token = getattr (self .table .item (row , 0 ), "applet_token" , None )
125
+ if token is not None :
126
+ if column == 1 :
127
+ self .manager .rename (token , new_value )
128
+ else :
129
+ self .manager .set_command (token , new_value )
130
+
131
+ def disable_token (self , token ):
132
+ checkbox_item = self .token_to_checkbox [token ]
133
+ checkbox_item .applet_token = None
134
+ del self .token_to_checkbox [token ]
135
+ checkbox_item .setCheckState (QtCore .Qt .Unchecked )
111
136
112
137
def new (self ):
113
138
row = self .table .rowCount ()
@@ -119,10 +144,22 @@ def new(self):
119
144
checkbox .setCheckState (QtCore .Qt .Unchecked )
120
145
self .table .setItem (row , 0 , checkbox )
121
146
147
+ def restart (self ):
148
+ selection = self .table .selectedRanges ()
149
+ if selection :
150
+ row = selection [0 ].topRow ()
151
+ token = getattr (self .table .item (row , 0 ), "applet_token" , None )
152
+ if token is not None :
153
+ asyncio .ensure_future (self .manager .restart (token ))
154
+
122
155
def delete (self ):
123
156
selection = self .table .selectedRanges ()
124
157
if selection :
125
- self .table .deleteRow (selection [0 ].topRow ())
158
+ row = selection [0 ].topRow ()
159
+ token = getattr (self .table .item (row , 0 ), "applet_token" , None )
160
+ if token is not None :
161
+ self .manager .delete (token )
162
+ self .table .deleteRow (row )
126
163
127
164
128
165
class AppletManagerRPC :
@@ -154,11 +191,27 @@ def create(self, name, command):
154
191
self .applet_docks [token ] = dock
155
192
self .dock_area .floatDock (dock )
156
193
asyncio .ensure_future (dock .start ())
194
+ dock .sigClosed .connect (partial (self .on_dock_closed , token ))
157
195
return token
158
196
159
- def delete (self , token ):
197
+ def on_dock_closed (self , token ):
198
+ asyncio .ensure_future (self .applet_docks [token ].terminate ())
199
+ self .main_dock .disable_token (token )
160
200
del self .applet_docks [token ]
161
201
202
+ def delete (self , token ):
203
+ # This in turns calls on_dock_closed and main_dock.disable_token
204
+ self .applet_docks [token ].close ()
205
+
206
+ def rename (self , token , name ):
207
+ self .applet_docks [token ].rename (name )
208
+
209
+ def set_command (self , token , command ):
210
+ self .applet_docks [token ].command = command
211
+
212
+ async def restart (self , token ):
213
+ await self .applet_docks [token ].restart ()
214
+
162
215
async def stop (self ):
163
216
for dock in self .applet_docks .values ():
164
217
await dock .terminate ()
0 commit comments