Merge lp:~robru/friends/menus into lp:friends

Proposed by Robert Bruce Park
Status: Merged
Merged at revision: 69
Proposed branch: lp:~robru/friends/menus
Merge into: lp:friends
Diff against target: 270 lines (+40/-108)
5 files modified
friends/main.py (+0/-2)
friends/service/dispatcher.py (+18/-6)
friends/tests/test_dispatcher.py (+4/-3)
friends/tests/test_menu.py (+5/-7)
friends/utils/menus.py (+13/-90)
To merge this branch: bzr merge lp:~robru/friends/menus
Reviewer Review Type Date Requested Status
Ken VanDine Approve
Review via email: mp+132824@code.launchpad.net

Description of the change

Connect the menu management code into the dispatcher.

To post a comment you must log in.
Revision history for this message
Ken VanDine (ken-vandine) wrote :

I made a few tweaks and merged, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'friends/main.py'
2--- friends/main.py 2012-11-04 19:30:57 +0000
3+++ friends/main.py 2012-11-04 20:53:18 +0000
4@@ -38,7 +38,6 @@
5 from friends.utils.avatar import Avatar
6 from friends.utils.base import initialize_caches
7 from friends.utils.logging import initialize
8-from friends.utils.menus import MenuManager
9 from friends.utils.model import prune_model
10 from friends.utils.options import Options
11
12@@ -110,7 +109,6 @@
13 class services:
14 connection = ConnectionMonitor()
15 dispatcher = Dispatcher(loop, refresh_interval)
16- menus = MenuManager(dispatcher.Refresh, loop.quit)
17 shorten = URLShorten(gsettings)
18
19 if args.test:
20
21=== modified file 'friends/service/dispatcher.py'
22--- friends/service/dispatcher.py 2012-11-04 19:19:42 +0000
23+++ friends/service/dispatcher.py 2012-11-04 20:53:18 +0000
24@@ -32,7 +32,8 @@
25 from friends.utils.account import AccountManager
26 from friends.utils.manager import protocol_manager
27 from friends.utils.signaler import signaler
28-from friends.utils.model import persist_model
29+from friends.utils.menus import MenuManager
30+from friends.utils.model import persist_model, Model
31
32 log = logging.getLogger(__name__)
33
34@@ -50,6 +51,11 @@
35 self.mainloop = mainloop
36 self._interval = interval
37 self.account_manager = AccountManager()
38+
39+ self._unread_count = 0
40+ self.menu_manager = MenuManager(self.Refresh, self.mainloop.quit)
41+ Model.connect('row-added', self._increment_unread_count)
42+
43 self._timer_id = None
44 signaler.add_signal('ConnectionOnline', self._on_connection_online)
45 signaler.add_signal('ConnectionOffline', self._on_connection_offline)
46@@ -73,8 +79,14 @@
47 def online(self):
48 return self._timer_id is not None
49
50+ def _increment_unread_count(self, model, itr):
51+ self._unread_count += 1
52+ self.menu_manager.update_unread_count(self._unread_count)
53+
54 @dbus.service.method(DBUS_INTERFACE)
55 def Refresh(self):
56+ self._unread_count = 0
57+
58 log.debug('Refresh requested')
59 # Wait for all previous actions to complete before
60 # starting a load of new ones.
61@@ -106,18 +118,18 @@
62 # Always return True, or else GLib mainloop will stop invoking it.
63 return True
64
65- @dbus.service.method(DBUS_INTERFACE, in_signature='s')
66- def UpdateIndicators(self, stream):
67- """Update counts in messaging indicators.
68+ @dbus.service.method(DBUS_INTERFACE)
69+ def ClearIndicators(self):
70+ """Indicate that messages have been read.
71
72 example:
73 import dbus
74 obj = dbus.SessionBus().get_object(DBUS_INTERFACE,
75 '/com/canonical/Friends/Service')
76 service = dbus.Interface(obj, DBUS_INTERFACE)
77- service.UpdateIndicators('stream')
78+ service.ClearIndicators()
79 """
80- pass #TODO
81+ self.menu_manager.update_unread_count(0)
82
83 @dbus.service.method(DBUS_INTERFACE, in_signature='sss')
84 def Do(self, action, account_id='', arg=''):
85
86=== modified file 'friends/tests/test_dispatcher.py'
87--- friends/tests/test_dispatcher.py 2012-11-04 19:19:42 +0000
88+++ friends/tests/test_dispatcher.py 2012-11-04 20:53:18 +0000
89@@ -85,9 +85,10 @@
90
91 self.assertEqual(self.log_mock.empty(), 'Refresh requested\n')
92
93- def test_update_indicators(self):
94- # TODO
95- self.assertIsNone(self.dispatcher.UpdateIndicators('stream'))
96+ def test_clear_indicators(self):
97+ self.dispatcher.menu_manager = mock.Mock()
98+ self.dispatcher.ClearIndicators()
99+ self.dispatcher.menu_manager.update_unread_count.assert_called_once_with(0)
100
101 def test_do(self):
102 account = mock.Mock()
103
104=== modified file 'friends/tests/test_menu.py'
105--- friends/tests/test_menu.py 2012-10-27 00:14:40 +0000
106+++ friends/tests/test_menu.py 2012-11-04 20:53:18 +0000
107@@ -35,20 +35,18 @@
108
109 def setUp(self):
110 self.menu = MenuManager(callback_stub, callback_stub)
111- self.menu.launcher = mock.Mock()
112+ self.menu.messaging = mock.Mock()
113
114 def test_unread_count_visible(self):
115 # Calling update_unread_count() with a non-zero value will make the
116 # count visible.
117- expected = [mock.call('count', 42), mock.call('count_visible', True)]
118 self.menu.update_unread_count(42)
119- self.assertEqual(self.menu.launcher.set_property.call_args_list,
120- expected)
121+ self.menu.messaging.set_source_count.assert_called_once_with(
122+ 'unread', 42)
123
124 def test_unread_count_invisible(self):
125 # Calling update_unread_count() with a zero value will make the count
126 # invisible.
127- expected = [mock.call('count', 0), mock.call('count_visible', False)]
128 self.menu.update_unread_count(0)
129- self.assertEqual(self.menu.launcher.set_property.call_args_list,
130- expected)
131+ self.menu.messaging.set_source_count.assert_called_once_with(
132+ 'unread', 0)
133
134=== modified file 'friends/utils/menus.py'
135--- friends/utils/menus.py 2012-11-04 19:19:42 +0000
136+++ friends/utils/menus.py 2012-11-04 20:53:18 +0000
137@@ -19,13 +19,7 @@
138 import subprocess
139
140 from gettext import gettext as _
141-
142-Unity = None
143-Dbusmenu = None
144-try:
145- from gi.repository import Unity, Dbusmenu
146-except ImportError:
147- pass
148+from gi.repository import Gio
149
150
151 MessagingMenu = None
152@@ -35,7 +29,6 @@
153 pass
154
155
156-DESKTOP_ID = 'friends.desktop'
157 log = logging.getLogger(__name__)
158
159
160@@ -63,9 +56,8 @@
161
162
163 class MenuManager:
164- """Manage the Unity and indicator menus over dbus."""
165+ """Manage the indicator menus over dbus."""
166 messaging = None
167- launcher = None
168
169 def __init__(self, refresh_callback, shutdown_callback):
170 self._refresh = refresh_callback
171@@ -73,88 +65,19 @@
172 # Only do the menu initializations if they are available.
173 if MessagingMenu:
174 self.init_messaging_menu()
175- if Unity and Dbusmenu:
176- self.init_dbus_menu()
177
178 def init_messaging_menu(self):
179- self.messaging = MessagingMenu.App(desktop_id=DESKTOP_ID)
180+ self.messaging = MessagingMenu.App(desktop_id='gwibber.desktop')
181+ self.messaging.append_source(
182+ 'unread',
183+ Gio.Icon.new_for_string(''),
184+ 'Unread')
185 self.messaging.register()
186-
187- def init_dbus_menu(self):
188- self.launcher = Unity.LauncherEntry.get_for_desktop_id(DESKTOP_ID)
189- quicklist = Dbusmenu.Menuitem.new()
190- # The update status menu item.
191- post_menu = Dbusmenu.Menuitem.new()
192- post_menu.property_set(Dbusmenu.MENUITEM_PROP_LABEL,
193- _('Update Status'))
194- post_menu.connect('item-activated', helper('friends-poster'))
195- # The refresh menu item.
196- refresh_menu = Dbusmenu.Menuitem.new()
197- refresh_menu.property_set(Dbusmenu.MENUITEM_PROP_LABEL, _('Refresh'))
198- refresh_menu.connect('item-activated', self._refresh)
199- # The preferences menu item.
200- preferences_menu = Dbusmenu.Menuitem.new()
201- preferences_menu.property_set(Dbusmenu.MENUITEM_PROP_LABEL,
202- _('Preferences'))
203- preferences_menu.connect('item-activated',
204- helper('friends-preferences'))
205- # The quit menu item.
206- quit_menu = Dbusmenu.Menuitem.new()
207- quit_menu.property_set(Dbusmenu.MENUITEM_PROP_LABEL, _('Quit'))
208- quit_menu.connect('item-activated', self._shutdown)
209- # Make all the menu items visible.
210- for menu in (post_menu, refresh_menu, preferences_menu, quit_menu):
211- menu.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
212- quicklist.child_append(menu)
213- # Initialize the unread count to zero.
214- self.launcher.set_property('quicklist', quicklist)
215- self.update_unread_count(0)
216+ # TODO add shortcuts for refresh and quit into this menu?
217
218 def update_unread_count(self, count):
219- """Update the unread count. If zoer, make it invisible."""
220- if self.launcher:
221- self.launcher.set_property('count', count)
222- self.launcher.set_property('count_visible', bool(count))
223-
224-
225-# XXX This bit allows you to test this file by running it. This doesn't fit
226-# very well into the larger testsuite architecture so we could probably
227-# improve this somehow, but I'm not sure how.
228-#
229-# In the meantime, run this like so (from the directory containing the
230-# setup.py file):
231-#
232-# $ python3 -m friends.utils.menus
233-#
234-# You should see the Friends icon in the launcher and switcher get the value
235-# '20'. If Friends is not running, pass in a second positional argument which
236-# is the name of a desktop file for an application that is running, e.g.:
237-#
238-# $ python3 -m friends.utils.menus gnome-terminal.desktop
239-#
240-# Pass in another argument to set some number other than 20. If you pass in
241-# 0, the count will not be visible.
242-#
243-# Hit C-c to quit.
244-
245-if __name__ == '__main__':
246- import sys
247- from gi.repository import GObject
248-
249- if len(sys.argv) > 1:
250- DESKTOP_ID = sys.argv[1]
251- if len(sys.argv) > 2:
252- count = int(sys.argv[2])
253- else:
254- count = 20
255-
256- def stub(*ignore):
257- pass
258-
259- menu = MenuManager(stub, stub)
260- menu.update_unread_count(count)
261-
262- try:
263- GObject.MainLoop().run()
264- except KeyboardInterrupt:
265- pass
266+ """Update the unread count. If zero, make it invisible."""
267+ if not self.messaging:
268+ return
269+
270+ self.messaging.set_source_count('unread', count)

Subscribers

People subscribed via source and target branches