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
=== modified file 'AUTHORS'
--- AUTHORS 2011-09-30 15:58:24 +0000
+++ AUTHORS 2014-01-05 05:47:45 +0000
@@ -1,2 +1,2 @@
1Copyright (C) 2010 Natalia Bidart <nataliabidart@gmail.com>1Copyright (C) 2010-2014 Natalia Bidart <nataliabidart@gmail.com>
2Copyright (C) 2010 Facundo Batista <facundo@taniquetil.com.ar>2Copyright (C) 2010-2014 Facundo Batista <facundo@taniquetil.com.ar>
33
=== modified file 'data/ui/main.ui'
--- data/ui/main.ui 2012-08-21 20:10:09 +0000
+++ data/ui/main.ui 2014-01-05 05:47:45 +0000
@@ -6,9 +6,9 @@
6 <property name="border_width">5</property>6 <property name="border_width">5</property>
7 <property name="type_hint">normal</property>7 <property name="type_hint">normal</property>
8 <property name="program_name">Magicicada</property>8 <property name="program_name">Magicicada</property>
9 <property name="copyright" translatable="yes">Copyright 2010 Chicharreros9 <property name="copyright" translatable="yes">Copyright 2010-2014 Chicharreros
10Copyright 2010 Natalia Bidart &lt;nataliabidart@gmail.com&gt;10Copyright 2010-2014 Natalia Bidart &lt;nataliabidart@gmail.com&gt;
11Copyright 2010 Facundo Batista &lt;facundo@taniquetil.com.ar&gt;</property>11Copyright 2010-2014 Facundo Batista &lt;facundo@taniquetil.com.ar&gt;</property>
12 <property name="website">http://launchpad.net/magicicada</property>12 <property name="website">http://launchpad.net/magicicada</property>
13 <property name="license" translatable="yes">GNU General Public License13 <property name="license" translatable="yes">GNU General Public License
1414
@@ -127,10 +127,4 @@
127 </object>127 </object>
128 </child>128 </child>
129 </object>129 </object>
130 <object class="GtkStatusIcon" id="status_icon">
131 <property name="has_tooltip">True</property>
132 <property name="tooltip_text">Magicicada</property>
133 <property name="title">Magicicada</property>
134 <signal name="activate" handler="on_status_icon_activate" swapped="no"/>
135 </object>
136</interface>130</interface>
137131
=== modified file 'magicicada/gui/gtk/main.py'
--- magicicada/gui/gtk/main.py 2012-11-29 17:49:29 +0000
+++ magicicada/gui/gtk/main.py 2014-01-05 05:47:45 +0000
@@ -1,6 +1,6 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2#2#
3# Copyright 2010-2012 Chicharreros3# Copyright 2010-2014 Chicharreros
4#4#
5# This program is free software: you can redistribute it and/or modify it5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published6# under the terms of the GNU General Public License version 3, as published
@@ -16,12 +16,13 @@
1616
17"""Magicicada GTK UI."""17"""Magicicada GTK UI."""
1818
19import sys
20import gettext19import gettext
21import logging20import logging
21import os
22import sys
2223
23# pylint: disable=E061124# pylint: disable=E0611
24from gi.repository import GdkPixbuf25from gi.repository import GdkPixbuf, AppIndicator3, Gtk
25# pylint: enable=E061126# pylint: enable=E0611
2627
27# optional Launchpad integration, pylint: disable=F040128# optional Launchpad integration, pylint: disable=F0401
@@ -60,6 +61,67 @@
60# pylint: disable=W061361# pylint: disable=W0613
6162
6263
64class Indicator(object):
65 """The indicator."""
66 def __init__(self, main_ui):
67 self.main_ui = main_ui
68
69 category = AppIndicator3.IndicatorCategory.APPLICATION_STATUS
70 icon_name = "icon-idle-16"
71 logos_path = os.path.join(get_data_file(), 'media')
72 ind = AppIndicator3.Indicator.new("magicicada", icon_name, category)
73 ind.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
74 ind.set_title("Magicicada")
75 ind.set_icon_theme_path(logos_path)
76 ind.set_icon(icon_name)
77 self.indicator = ind
78 self.menu = None
79 self.set_menu()
80
81 def set_icon(self, name):
82 """Put a proper icon in the systray."""
83 full_name = "icon-%s-16" % (name,)
84 self.indicator.set_icon(full_name)
85
86 def set_menu(self):
87 """Set the menu in the indicator."""
88 menu = self._build_menu()
89 self.indicator.set_menu(menu)
90
91 def _build_menu(self):
92 """Build the menu according to the config."""
93 menu = Gtk.Menu()
94 accgroup = Gtk.AccelGroup()
95
96 # show / hide
97 item = Gtk.ImageMenuItem.new_from_stock("Show / Hide", accgroup)
98 menu.append(item)
99 item.connect("activate", self._show_hide)
100 item.show()
101
102 # about
103 item = Gtk.ImageMenuItem.new_from_stock("gtk-about", accgroup)
104 menu.append(item)
105 item.connect("activate", self._run_about_dialog)
106 item.show()
107
108 # quit!
109 item = Gtk.ImageMenuItem.new_from_stock("gtk-quit", accgroup)
110 menu.append(item)
111 item.connect("activate", self.main_ui.on_destroy)
112 item.show()
113
114 return menu
115
116 def _run_about_dialog(self, _):
117 """Run the About dialog."""
118 self.main_ui.on_about_activate(None)
119
120 def _show_hide(self, _):
121 """Show or hide the main window.."""
122 self.main_ui.show_hide()
123
124
63class MagicicadaUI(Buildable):125class MagicicadaUI(Buildable):
64 """Magicicada GUI main class."""126 """Magicicada GUI main class."""
65127
@@ -96,9 +158,7 @@
96 self.main_window.set_default_icon_list(self._icons.values())158 self.main_window.set_default_icon_list(self._icons.values())
97 self.main_window.set_icon_list(self._icons.values())159 self.main_window.set_icon_list(self._icons.values())
98160
99 self._status_icons = build_icon_dict(16)161 self.indicator = Indicator(self)
100 self.status_icon = self.builder.get_object('status_icon')
101 self.status_icon.set_from_pixbuf(self._status_icons['idle'])
102162
103 about_fname = get_data_file('media', 'logo-128.png')163 about_fname = get_data_file('media', 'logo-128.png')
104 self.about_dialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(about_fname))164 self.about_dialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(about_fname))
@@ -132,8 +192,8 @@
132 self.about_dialog.run()192 self.about_dialog.run()
133 self.about_dialog.hide()193 self.about_dialog.hide()
134194
135 def on_status_icon_activate(self, widget, data=None):195 def show_hide(self):
136 """Systray icon was clicked."""196 """Show or hide the main window.."""
137 if self.main_window.get_visible():197 if self.main_window.get_visible():
138 self.main_window.hide()198 self.main_window.hide()
139 else:199 else:
@@ -147,11 +207,11 @@
147 # change status icon207 # change status icon
148 state = kwargs.get('state')208 state = kwargs.get('state')
149 if state == syncdaemon.STATE_IDLE:209 if state == syncdaemon.STATE_IDLE:
150 self.status_icon.set_from_pixbuf(self._status_icons['idle'])210 self.indicator.set_icon('idle')
151 elif state == syncdaemon.STATE_WORKING:211 elif state == syncdaemon.STATE_WORKING:
152 self.status_icon.set_from_pixbuf(self._status_icons['working'])212 self.indicator.set_icon('working')
153 else:213 else:
154 self.status_icon.set_from_pixbuf(self._status_icons['alert'])214 self.indicator.set_icon('alert')
155215
156 @log(logger, level=logging.INFO)216 @log(logger, level=logging.INFO)
157 def on_initial_data_ready(self):217 def on_initial_data_ready(self):
158218
=== modified file 'magicicada/gui/gtk/tests/test_main.py'
--- magicicada/gui/gtk/tests/test_main.py 2012-08-21 22:38:50 +0000
+++ magicicada/gui/gtk/tests/test_main.py 2014-01-05 05:47:45 +0000
@@ -1,6 +1,6 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2#2#
3# Copyright 2010-2012 Chicharreros3# Copyright 2010-2014 Chicharreros
4#4#
5# This program is free software: you can redistribute it and/or modify it5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published6# under the terms of the GNU General Public License version 3, as published
@@ -132,31 +132,31 @@
132 def test_update_statusicon_idle(self):132 def test_update_statusicon_idle(self):
133 """Status icon is updated to idle."""133 """Status icon is updated to idle."""
134 self.ui.on_status_changed(state=syncdaemon.STATE_IDLE)134 self.ui.on_status_changed(state=syncdaemon.STATE_IDLE)
135 pixbuf_set = self.ui.status_icon.get_pixbuf()135 icon_name = self.ui.indicator.indicator.get_icon()
136 self.assertEqual(pixbuf_set, self.ui._status_icons['idle'])136 self.assertEqual(icon_name, "icon-idle-16")
137137
138 def test_update_statusicon_working(self):138 def test_update_statusicon_working(self):
139 """Status icon is updated to working."""139 """Status icon is updated to working."""
140 self.ui.on_status_changed(state=syncdaemon.STATE_WORKING)140 self.ui.on_status_changed(state=syncdaemon.STATE_WORKING)
141 pixbuf_set = self.ui.status_icon.get_pixbuf()141 icon_name = self.ui.indicator.indicator.get_icon()
142 self.assertEqual(pixbuf_set, self.ui._status_icons['working'])142 self.assertEqual(icon_name, "icon-working-16")
143143
144 def test_update_statusicon_alert(self):144 def test_update_statusicon_alert(self):
145 """Status icon is updated to alert."""145 """Status icon is updated to alert."""
146 self.ui.on_status_changed(state=syncdaemon.STATE_STOPPED)146 self.ui.on_status_changed(state=syncdaemon.STATE_STOPPED)
147 pixbuf_set = self.ui.status_icon.get_pixbuf()147 icon_name = self.ui.indicator.indicator.get_icon()
148 self.assertEqual(pixbuf_set, self.ui._status_icons['alert'])148 self.assertEqual(icon_name, "icon-alert-16")
149149
150 def test_main_window_is_hid_when_icon_clicked(self):150 def test_main_window_is_hid_when_icon_clicked(self):
151 """Main window is hid when the systray icon is clicked."""151 """Main window is hid when the systray icon is clicked."""
152 self.ui.on_status_icon_activate(self.ui.status_icon)152 self.ui.show_hide()
153 self.assertFalse(self.ui.main_window.get_visible(),153 self.assertFalse(self.ui.main_window.get_visible(),
154 'main_window should be invisible when icon clicked.')154 'main_window should be invisible when icon clicked.')
155155
156 def test_main_window_is_shown_when_clicked_after_hidden(self):156 def test_main_window_is_shown_when_clicked_after_hidden(self):
157 """Main window is shown when the icon is clicked after hidden."""157 """Main window is shown when the icon is clicked after hidden."""
158 self.ui.on_status_icon_activate(self.ui.status_icon) # hide158 self.ui.show_hide() # hide
159 self.ui.on_status_icon_activate(self.ui.status_icon) # show159 self.ui.show_hide() # show
160 msg = 'main_window should be visible when icon clicked after hidden.'160 msg = 'main_window should be visible when icon clicked after hidden.'
161 self.assertTrue(self.ui.main_window.get_visible(), msg)161 self.assertTrue(self.ui.main_window.get_visible(), msg)
162162

Subscribers

People subscribed via source and target branches