Merge lp:~facundo/magicicada-gui/icon-ftw into lp:magicicada-gui

Proposed by Facundo Batista
Status: Merged
Approved by: Natalia Bidart
Approved revision: 138
Merged at revision: 138
Proposed branch: lp:~facundo/magicicada-gui/icon-ftw
Merge into: lp:magicicada-gui
Diff against target: 221 lines (+86/-32)
4 files modified
AUTHORS (+2/-2)
data/ui/main.ui (+3/-9)
magicicada/gui/gtk/main.py (+71/-11)
magicicada/gui/gtk/tests/test_main.py (+10/-10)
To merge this branch: bzr merge lp:~facundo/magicicada-gui/icon-ftw
Reviewer Review Type Date Requested Status
Natalia Bidart Approve
Review via email: mp+200476@code.launchpad.net

Commit message

Put an icon in the systray.

Description of the change

Put an icon in the systray.

This icon shows the options to show/hide, about, and exit the application.

Tests adjusted.

To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'AUTHORS'
2--- AUTHORS 2011-09-30 15:58:24 +0000
3+++ AUTHORS 2014-01-05 05:47:45 +0000
4@@ -1,2 +1,2 @@
5-Copyright (C) 2010 Natalia Bidart <nataliabidart@gmail.com>
6-Copyright (C) 2010 Facundo Batista <facundo@taniquetil.com.ar>
7+Copyright (C) 2010-2014 Natalia Bidart <nataliabidart@gmail.com>
8+Copyright (C) 2010-2014 Facundo Batista <facundo@taniquetil.com.ar>
9
10=== modified file 'data/ui/main.ui'
11--- data/ui/main.ui 2012-08-21 20:10:09 +0000
12+++ data/ui/main.ui 2014-01-05 05:47:45 +0000
13@@ -6,9 +6,9 @@
14 <property name="border_width">5</property>
15 <property name="type_hint">normal</property>
16 <property name="program_name">Magicicada</property>
17- <property name="copyright" translatable="yes">Copyright 2010 Chicharreros
18-Copyright 2010 Natalia Bidart &lt;nataliabidart@gmail.com&gt;
19-Copyright 2010 Facundo Batista &lt;facundo@taniquetil.com.ar&gt;</property>
20+ <property name="copyright" translatable="yes">Copyright 2010-2014 Chicharreros
21+Copyright 2010-2014 Natalia Bidart &lt;nataliabidart@gmail.com&gt;
22+Copyright 2010-2014 Facundo Batista &lt;facundo@taniquetil.com.ar&gt;</property>
23 <property name="website">http://launchpad.net/magicicada</property>
24 <property name="license" translatable="yes">GNU General Public License
25
26@@ -127,10 +127,4 @@
27 </object>
28 </child>
29 </object>
30- <object class="GtkStatusIcon" id="status_icon">
31- <property name="has_tooltip">True</property>
32- <property name="tooltip_text">Magicicada</property>
33- <property name="title">Magicicada</property>
34- <signal name="activate" handler="on_status_icon_activate" swapped="no"/>
35- </object>
36 </interface>
37
38=== modified file 'magicicada/gui/gtk/main.py'
39--- magicicada/gui/gtk/main.py 2012-11-29 17:49:29 +0000
40+++ magicicada/gui/gtk/main.py 2014-01-05 05:47:45 +0000
41@@ -1,6 +1,6 @@
42 # -*- coding: utf-8 -*-
43 #
44-# Copyright 2010-2012 Chicharreros
45+# Copyright 2010-2014 Chicharreros
46 #
47 # This program is free software: you can redistribute it and/or modify it
48 # under the terms of the GNU General Public License version 3, as published
49@@ -16,12 +16,13 @@
50
51 """Magicicada GTK UI."""
52
53-import sys
54 import gettext
55 import logging
56+import os
57+import sys
58
59 # pylint: disable=E0611
60-from gi.repository import GdkPixbuf
61+from gi.repository import GdkPixbuf, AppIndicator3, Gtk
62 # pylint: enable=E0611
63
64 # optional Launchpad integration, pylint: disable=F0401
65@@ -60,6 +61,67 @@
66 # pylint: disable=W0613
67
68
69+class Indicator(object):
70+ """The indicator."""
71+ def __init__(self, main_ui):
72+ self.main_ui = main_ui
73+
74+ category = AppIndicator3.IndicatorCategory.APPLICATION_STATUS
75+ icon_name = "icon-idle-16"
76+ logos_path = os.path.join(get_data_file(), 'media')
77+ ind = AppIndicator3.Indicator.new("magicicada", icon_name, category)
78+ ind.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
79+ ind.set_title("Magicicada")
80+ ind.set_icon_theme_path(logos_path)
81+ ind.set_icon(icon_name)
82+ self.indicator = ind
83+ self.menu = None
84+ self.set_menu()
85+
86+ def set_icon(self, name):
87+ """Put a proper icon in the systray."""
88+ full_name = "icon-%s-16" % (name,)
89+ self.indicator.set_icon(full_name)
90+
91+ def set_menu(self):
92+ """Set the menu in the indicator."""
93+ menu = self._build_menu()
94+ self.indicator.set_menu(menu)
95+
96+ def _build_menu(self):
97+ """Build the menu according to the config."""
98+ menu = Gtk.Menu()
99+ accgroup = Gtk.AccelGroup()
100+
101+ # show / hide
102+ item = Gtk.ImageMenuItem.new_from_stock("Show / Hide", accgroup)
103+ menu.append(item)
104+ item.connect("activate", self._show_hide)
105+ item.show()
106+
107+ # about
108+ item = Gtk.ImageMenuItem.new_from_stock("gtk-about", accgroup)
109+ menu.append(item)
110+ item.connect("activate", self._run_about_dialog)
111+ item.show()
112+
113+ # quit!
114+ item = Gtk.ImageMenuItem.new_from_stock("gtk-quit", accgroup)
115+ menu.append(item)
116+ item.connect("activate", self.main_ui.on_destroy)
117+ item.show()
118+
119+ return menu
120+
121+ def _run_about_dialog(self, _):
122+ """Run the About dialog."""
123+ self.main_ui.on_about_activate(None)
124+
125+ def _show_hide(self, _):
126+ """Show or hide the main window.."""
127+ self.main_ui.show_hide()
128+
129+
130 class MagicicadaUI(Buildable):
131 """Magicicada GUI main class."""
132
133@@ -96,9 +158,7 @@
134 self.main_window.set_default_icon_list(self._icons.values())
135 self.main_window.set_icon_list(self._icons.values())
136
137- self._status_icons = build_icon_dict(16)
138- self.status_icon = self.builder.get_object('status_icon')
139- self.status_icon.set_from_pixbuf(self._status_icons['idle'])
140+ self.indicator = Indicator(self)
141
142 about_fname = get_data_file('media', 'logo-128.png')
143 self.about_dialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(about_fname))
144@@ -132,8 +192,8 @@
145 self.about_dialog.run()
146 self.about_dialog.hide()
147
148- def on_status_icon_activate(self, widget, data=None):
149- """Systray icon was clicked."""
150+ def show_hide(self):
151+ """Show or hide the main window.."""
152 if self.main_window.get_visible():
153 self.main_window.hide()
154 else:
155@@ -147,11 +207,11 @@
156 # change status icon
157 state = kwargs.get('state')
158 if state == syncdaemon.STATE_IDLE:
159- self.status_icon.set_from_pixbuf(self._status_icons['idle'])
160+ self.indicator.set_icon('idle')
161 elif state == syncdaemon.STATE_WORKING:
162- self.status_icon.set_from_pixbuf(self._status_icons['working'])
163+ self.indicator.set_icon('working')
164 else:
165- self.status_icon.set_from_pixbuf(self._status_icons['alert'])
166+ self.indicator.set_icon('alert')
167
168 @log(logger, level=logging.INFO)
169 def on_initial_data_ready(self):
170
171=== modified file 'magicicada/gui/gtk/tests/test_main.py'
172--- magicicada/gui/gtk/tests/test_main.py 2012-08-21 22:38:50 +0000
173+++ magicicada/gui/gtk/tests/test_main.py 2014-01-05 05:47:45 +0000
174@@ -1,6 +1,6 @@
175 # -*- coding: utf-8 -*-
176 #
177-# Copyright 2010-2012 Chicharreros
178+# Copyright 2010-2014 Chicharreros
179 #
180 # This program is free software: you can redistribute it and/or modify it
181 # under the terms of the GNU General Public License version 3, as published
182@@ -132,31 +132,31 @@
183 def test_update_statusicon_idle(self):
184 """Status icon is updated to idle."""
185 self.ui.on_status_changed(state=syncdaemon.STATE_IDLE)
186- pixbuf_set = self.ui.status_icon.get_pixbuf()
187- self.assertEqual(pixbuf_set, self.ui._status_icons['idle'])
188+ icon_name = self.ui.indicator.indicator.get_icon()
189+ self.assertEqual(icon_name, "icon-idle-16")
190
191 def test_update_statusicon_working(self):
192 """Status icon is updated to working."""
193 self.ui.on_status_changed(state=syncdaemon.STATE_WORKING)
194- pixbuf_set = self.ui.status_icon.get_pixbuf()
195- self.assertEqual(pixbuf_set, self.ui._status_icons['working'])
196+ icon_name = self.ui.indicator.indicator.get_icon()
197+ self.assertEqual(icon_name, "icon-working-16")
198
199 def test_update_statusicon_alert(self):
200 """Status icon is updated to alert."""
201 self.ui.on_status_changed(state=syncdaemon.STATE_STOPPED)
202- pixbuf_set = self.ui.status_icon.get_pixbuf()
203- self.assertEqual(pixbuf_set, self.ui._status_icons['alert'])
204+ icon_name = self.ui.indicator.indicator.get_icon()
205+ self.assertEqual(icon_name, "icon-alert-16")
206
207 def test_main_window_is_hid_when_icon_clicked(self):
208 """Main window is hid when the systray icon is clicked."""
209- self.ui.on_status_icon_activate(self.ui.status_icon)
210+ self.ui.show_hide()
211 self.assertFalse(self.ui.main_window.get_visible(),
212 'main_window should be invisible when icon clicked.')
213
214 def test_main_window_is_shown_when_clicked_after_hidden(self):
215 """Main window is shown when the icon is clicked after hidden."""
216- self.ui.on_status_icon_activate(self.ui.status_icon) # hide
217- self.ui.on_status_icon_activate(self.ui.status_icon) # show
218+ self.ui.show_hide() # hide
219+ self.ui.show_hide() # show
220 msg = 'main_window should be visible when icon clicked after hidden.'
221 self.assertTrue(self.ui.main_window.get_visible(), msg)
222

Subscribers

People subscribed via source and target branches