6
The main recent-notifications-unity application.
12
from gi.repository import GObject, Gtk
15
from gi.repository import Unity
21
from About import show_about
22
from Config import Config
23
from MessageList import MessageList
24
from Notification import Notification
25
from Theme import Theme
26
from Translations import _
28
# Setup the application logging to file and stdout for errors
30
log_format = "%(asctime)s %(name)s %(levelname)s: %(message)s"
32
logging.basicConfig(level=logging.DEBUG,
33
filename=os.path.expanduser("~/.cache/recent-notifications.log"),
37
console = logging.StreamHandler()
38
console.setLevel(logging.ERROR)
39
console.setFormatter(logging.Formatter(log_format))
41
logging.getLogger("").addHandler(console)
44
logger = logging.getLogger("Main")
46
SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__))
48
PREFERENCES_PATH = "~/.config/recent-notifications/preferences"
51
"""Maps column names to column numbers."""
56
class MainWindow(Gtk.Window):
58
GObject.GObject.__init__(self)
60
self._default_size = 400
62
self.set_title(_("Recent Notifications"))
63
self.set_default_size(self._default_size, self._default_size)
64
self.connect("destroy", self.on_destroy)
65
self.connect("focus-in-event", self.on_focus_in)
66
self.connect("focus-out-event", self.on_focus_out)
67
self.connect("size-allocate", self.on_size_allocate)
69
self._message_count = 0
71
self._uimanager = Gtk.UIManager()
72
self.add_accel_group(self._uimanager.get_accel_group())
74
self._actiongroup = Gtk.ActionGroup("MenuBar")
75
self._actiongroup.add_actions([
76
("Messages", None, _("_Messages"), None, None, None),
77
("Clear", Gtk.STOCK_CLEAR, None, None, None, self.on_clear),
78
("Quit", Gtk.STOCK_QUIT, None, None, None, self.on_destroy),
79
("Help", None, _("_Help"), None, None, None),
80
("About", Gtk.STOCK_ABOUT, None, None, None, self.on_show_about)
82
self._uimanager.insert_action_group(self._actiongroup)
84
self._uimanager.add_ui_from_string("""
86
<menubar name="MenuBar">
87
<menu action="Messages">
88
<menuitem action="Clear"/>
89
<menuitem action="Quit"/>
92
<menuitem action="About"/>
98
self._vbox = Gtk.VBox()
101
self._menubar = self._uimanager.get_widget("/MenuBar")
102
self._vbox.pack_start(self._menubar, False, False, 0)
104
self._message_list = MessageList()
105
self._vbox.pack_start(self._message_list, True, True, 2)
107
# app_name, is_separator, count
108
self._combolist = Gtk.ListStore(str, bool, int)
109
self._combobox = Gtk.ComboBox()
110
self._combobox.set_model(self._combolist)
111
self._combo_app_cell = Gtk.CellRendererText()
112
self._combobox.pack_start(self._combo_app_cell, True)
113
self._combobox.add_attribute(self._combo_app_cell, "text", Column.APP_NAME)
114
self._combo_count_cell = Gtk.CellRendererText()
115
self._combobox.pack_start(self._combo_count_cell, False)
116
self._combobox.add_attribute(self._combo_count_cell, "text", Column.COUNT)
117
self._combobox.set_row_separator_func(lambda m, i, *args: m.get_value(i, Column.SEPARATOR), None)
118
self._combobox.connect("changed", self.on_combobox_changed)
119
self._vbox.pack_start(self._combobox, False, False, 0)
121
self.initialize_combobox()
124
self._launcher = Unity.LauncherEntry.get_for_desktop_id("recent-notifications.desktop")
126
self._launcher = None
128
self._notify = Notification()
129
self._notify.connect("message-received", self.on_message_received)
131
self._preferences = Config(PREFERENCES_PATH)
132
self._preferences.set_if_unset("theme", "default")
135
theme_name = self._preferences.get("theme", "default")
136
theme = Theme(theme_name)
137
theme.apply_gtk_styles()
139
def zero_count(self):
140
"""Zero the message count"""
141
self._message_count = 0
144
def increment_count(self):
145
"""Increments the message count"""
146
self._message_count += 1
149
def update_count(self):
150
"""Updates the message count display"""
152
self._launcher.set_property("count", self._message_count)
153
if self._message_count > 0:
154
self._launcher.set_property("count_visible", True)
156
self._launcher.set_property("count_visible", False)
158
def increment_count_column(self, iter):
159
"""Increments the count column of the given iter"""
160
count = self._combolist.get_value(iter, Column.COUNT)
161
self._combolist.set_value(iter, Column.COUNT, count + 1)
163
def increment_combobox(self, app_name):
164
"""Updates the combobox app names and message counts."""
165
# Add a separator if there isn't one yet
166
if len(self._combolist) == 1:
167
self._combolist.append(["Separator", True, 0])
169
iter = self._combolist.get_iter_first()
170
self.increment_count_column(iter)
172
updated_count = False
173
iter = self._combolist.iter_next(iter)
175
name = self._combolist.get_value(iter, Column.APP_NAME)
177
self.increment_count_column(iter)
180
iter = self._combolist.iter_next(iter)
181
if not updated_count:
182
iter = self._combolist.append([app_name, False, 1])
184
def initialize_combobox(self):
185
"""Clear the combobox and set the initial entry."""
186
self._combolist.clear()
187
self._combolist.append([_("All Applications"), False, 0])
189
self._combobox.set_active(0)
191
def on_clear(self, *args):
192
"""Clear the messages"""
193
self._message_list.clear_messages()
195
def on_combobox_changed(self, combobox, *args):
196
"""Filter based on app_name"""
197
active = self._combobox.get_active()
199
self._message_list.filter_by(None)
201
iter = self._combobox.get_active_iter()
202
app_name = self._combolist.get_value(iter, Column.APP_NAME)
203
self._message_list.filter_by(app_name)
205
def on_destroy(self, *args):
206
"""Quit the application"""
209
def on_focus_in(self, widget, event):
210
"""Window receives focus"""
213
def on_focus_out(self, widget, event):
214
"""Window receives focus"""
216
self._message_list.mark_as_read()
218
def on_message_received(self, monitor, message):
219
"""Received a notification"""
220
self.increment_count()
221
self.increment_combobox(message.app_name)
222
self._message_list.add_message(message)
224
def on_size_allocate(self, widget, size):
226
self._message_list.set_width(size.width)
228
def on_show_about(self, *args):
229
"""Show the about dialog"""
233
icon_path = os.path.join(SCRIPT_PATH, "..", "icons")
234
theme = Gtk.IconTheme.get_default()
235
theme.append_search_path(icon_path)
237
window = MainWindow()
241
if __name__ == "__main__":