181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
1 |
"""
|
2 |
MessageItem.py
|
|
3 |
March 28, 2011
|
|
4 |
||
5 |
A widget to represent a notification.
|
|
6 |
"""
|
|
7 |
||
8 |
import logging |
|
9 |
||
182
by Jason Conti
MessageItem labels now wrap, increased the icon size, and made links clickable. |
10 |
from gi.repository import GLib, GObject, Gtk, Pango |
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
11 |
|
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
12 |
import Icon |
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
13 |
import Timestamp |
14 |
||
201
by Jason Conti
Using a bit of cairo to display icons with rounded edges and message items with rounded backgrounds. Still need to get the proper colors from the gtk theme and possibly add options for custom colors. |
15 |
from RoundedWidgets import RoundedBox, RoundedIcon |
205
by Jason Conti
Added theme support. User themes are stored in ~/.config/recent-notifications/themes/, see themes/default for the proper format. The desired theme is set with the theme property in ~/.config/recent-notifications/preferences. Still need to add support for acquiring the colors from the system gtk theme. |
16 |
from Theme import Color |
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
17 |
from Translations import _ |
18 |
||
19 |
logger = logging.getLogger("MessageItem") |
|
20 |
||
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
21 |
def create_label(): |
22 |
label = Gtk.Label() |
|
23 |
label.set_use_markup(True) |
|
196
by Jason Conti
Updated the number of translatable strings and fixed the labels so they properly rewrap when the window is resized in the experimental unity version. |
24 |
label.set_selectable(True) |
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
25 |
label.set_line_wrap(True) |
26 |
label.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR) |
|
27 |
label.set_alignment(0, 0) |
|
28 |
label.set_size_request(300, -1) |
|
29 |
return label |
|
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
30 |
|
31 |
def escape_text(text): |
|
32 |
return GLib.markup_escape_text(text, len(text)) |
|
33 |
||
201
by Jason Conti
Using a bit of cairo to display icons with rounded edges and message items with rounded backgrounds. Still need to get the proper colors from the gtk theme and possibly add options for custom colors. |
34 |
class MessageItem(RoundedBox): |
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
35 |
"""A widget to represent a notification"""
|
36 |
def __init__(self, message): |
|
201
by Jason Conti
Using a bit of cairo to display icons with rounded edges and message items with rounded backgrounds. Still need to get the proper colors from the gtk theme and possibly add options for custom colors. |
37 |
RoundedBox.__init__(self) |
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
38 |
|
182
by Jason Conti
MessageItem labels now wrap, increased the icon size, and made links clickable. |
39 |
self.set_border_width(2) |
207
by Jason Conti
Setting most of the colors with a gtk rc style now, except RoundedBox, because I can't figure out how to get the background style color. Seems like it should be widget.style.bg[state] however that list is always empty. |
40 |
self.set_name("message_item") |
182
by Jason Conti
MessageItem labels now wrap, increased the icon size, and made links clickable. |
41 |
|
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
42 |
self._unread = True |
43 |
||
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
44 |
self._message = message |
182
by Jason Conti
MessageItem labels now wrap, increased the icon size, and made links clickable. |
45 |
self._message_icon_size = 48 |
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
46 |
|
47 |
self._hbox = Gtk.HBox() |
|
201
by Jason Conti
Using a bit of cairo to display icons with rounded edges and message items with rounded backgrounds. Still need to get the proper colors from the gtk theme and possibly add options for custom colors. |
48 |
self._hbox.set_border_width(10) |
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
49 |
self.add(self._hbox) |
50 |
||
202
by Jason Conti
Ported Config.py to the unity app, promoting it to a proper GObject in the process, so value changes are handled by signals instead of calling functions. Adding a basic set of tests for the new Config class. Adding __init__.py to unity to make it a proper module for testing (will need renaming later). Changed the edge radius to 5px for the message icon. |
51 |
self._image = RoundedIcon(radius = 5) |
182
by Jason Conti
MessageItem labels now wrap, increased the icon size, and made links clickable. |
52 |
self._hbox.pack_start(self._image, False, False, 10) |
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
53 |
self.update_image() |
54 |
||
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
55 |
self._vbox = Gtk.VBox() |
56 |
self._hbox.pack_start(self._vbox, True, True, 0) |
|
57 |
||
58 |
self._summary_hbox = Gtk.HBox() |
|
59 |
self._vbox.pack_start(self._summary_hbox, False, False, 1) |
|
60 |
||
61 |
self._image_unread = Gtk.Image() |
|
62 |
self._summary_hbox.pack_start(self._image_unread, False, False, 5) |
|
63 |
||
64 |
try: |
|
65 |
pixbuf = Icon.load("notification-new", 16) |
|
66 |
except: |
|
67 |
logger.exception("Failed to load notification-new icon.") |
|
68 |
else: |
|
69 |
self._image_unread.set_from_pixbuf(pixbuf) |
|
70 |
||
71 |
self._label_summary = create_label() |
|
207
by Jason Conti
Setting most of the colors with a gtk rc style now, except RoundedBox, because I can't figure out how to get the background style color. Seems like it should be widget.style.bg[state] however that list is always empty. |
72 |
self._label_summary.set_name("message_label") |
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
73 |
self._summary_hbox.pack_start(self._label_summary, True, True, 0) |
74 |
||
75 |
self._label_body = create_label() |
|
207
by Jason Conti
Setting most of the colors with a gtk rc style now, except RoundedBox, because I can't figure out how to get the background style color. Seems like it should be widget.style.bg[state] however that list is always empty. |
76 |
self._label_body.set_name("message_label") |
77 |
logger.debug("FG: {0}".format(self._label_body.style.fg)) |
|
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
78 |
self._vbox.pack_start(self._label_body, True, True, 1) |
79 |
||
80 |
self._label_info = create_label() |
|
207
by Jason Conti
Setting most of the colors with a gtk rc style now, except RoundedBox, because I can't figure out how to get the background style color. Seems like it should be widget.style.bg[state] however that list is always empty. |
81 |
self._label_info.set_name("message_label") |
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
82 |
self._vbox.pack_start(self._label_info, False, False, 0) |
83 |
self.update_labels() |
|
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
84 |
|
189
by Jason Conti
Mostly implemented filtering. No decrement on the combobox yet. Reverted the icon by app_name, was throwing a seemingly uncatchable GError. |
85 |
def get_app_name(self): |
86 |
"""Returns the app_name of this item"""
|
|
87 |
return self._message.app_name |
|
88 |
||
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
89 |
def escape_body(self, text): |
90 |
"""Text needs to be escaped in case it contains characters that will cause errors
|
|
91 |
parsing the markup, but some clients send text that is already escaped. This causes
|
|
92 |
messages to have &, <, and > strings instead of the appropriate characters.
|
|
93 |
This method replaces those with the appropriate characters and then escapes the text.
|
|
94 |
TODO: Create a better HTML/entity parser.
|
|
95 |
"""
|
|
96 |
result = text.replace("&", "&") |
|
97 |
result = result.replace("'", "'") |
|
98 |
result = result.replace(">", ">") |
|
99 |
result = result.replace("<", "<") |
|
100 |
result = result.replace(""", '"') |
|
182
by Jason Conti
MessageItem labels now wrap, increased the icon size, and made links clickable. |
101 |
return self.markup_links(escape_text(result)) |
102 |
||
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
103 |
def is_unread(self): |
104 |
"""Get the unread status of this message"""
|
|
105 |
return self._unread |
|
106 |
||
107 |
def set_unread(self, unread): |
|
108 |
"""Sets the unread status of this messages and the visibility of the icon"""
|
|
109 |
if unread and not self._unread: |
|
110 |
self._unread = True |
|
111 |
self._image_unread.show() |
|
112 |
self._summary_hbox.pack_start(self._image_unread, False, False, 5) |
|
113 |
self._summary_hbox.reorder_child(self._image_unread, 0) |
|
114 |
||
115 |
elif not unread and self._unread: |
|
116 |
self._unread = False |
|
117 |
self._image_unread.hide() |
|
118 |
self._summary_hbox.remove(self._image_unread) |
|
119 |
||
196
by Jason Conti
Updated the number of translatable strings and fixed the labels so they properly rewrap when the window is resized in the experimental unity version. |
120 |
def set_width(self, width): |
121 |
"""Updates the wrap width of the labels in this message item, minus the icon
|
|
122 |
size and various padding."""
|
|
201
by Jason Conti
Using a bit of cairo to display icons with rounded edges and message items with rounded backgrounds. Still need to get the proper colors from the gtk theme and possibly add options for custom colors. |
123 |
new_width = width - self._message_icon_size - 60 |
196
by Jason Conti
Updated the number of translatable strings and fixed the labels so they properly rewrap when the window is resized in the experimental unity version. |
124 |
self._label_summary.set_size_request(new_width, -1) |
125 |
self._label_body.set_size_request(new_width, -1) |
|
126 |
self._label_info.set_size_request(new_width, -1) |
|
127 |
||
182
by Jason Conti
MessageItem labels now wrap, increased the icon size, and made links clickable. |
128 |
def markup_links(self, text): |
129 |
"""Filters escaped text for web links and makes them clickable"""
|
|
130 |
result = [] |
|
131 |
for s in text.split(): |
|
132 |
if s.startswith("http://"): |
|
133 |
name = s |
|
134 |
url = s |
|
135 |
result.append('<a href="{0}">{1}</a>'.format(url, name)) |
|
136 |
elif s.startswith("www."): |
|
137 |
name = s |
|
138 |
url = "http://" + s |
|
139 |
result.append('<a href="{0}">{1}</a>'.format(url, name)) |
|
140 |
else: |
|
141 |
result.append(s) |
|
142 |
||
143 |
return " ".join(result) |
|
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
144 |
|
145 |
def update_image(self): |
|
146 |
"""Updates the image"""
|
|
147 |
try: |
|
148 |
pixbuf = self._message.get_icon(self._message_icon_size) |
|
149 |
except: |
|
150 |
logger.exception("Failed to get icon: {0}".format(self._message.app_icon)) |
|
151 |
else: |
|
152 |
self._image.set_from_pixbuf(pixbuf) |
|
153 |
||
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
154 |
def update_labels(self): |
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
155 |
"""Updates the label markup"""
|
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
156 |
summary = escape_text(self._message.summary.encode("utf8")) |
157 |
body = self.escape_body(self._message.body.encode("utf8")) |
|
158 |
timestamp = escape_text(Timestamp.locale_datetime(self._message.timestamp)) |
|
159 |
app_name = escape_text(self._message.app_name) |
|
196
by Jason Conti
Updated the number of translatable strings and fixed the labels so they properly rewrap when the window is resized in the experimental unity version. |
160 |
|
185
by Jason Conti
Adding an icon to MessageItem to show its unread status. Removed MessageList.py since it is no longer used. |
161 |
self._label_summary.set_markup("<b>{0}</b>".format(summary)) |
162 |
self._label_body.set_markup(body) |
|
163 |
self._label_info.set_markup("<small><i>{0} {1} <b>{2}</b></i></small>".format(timestamp, |
|
164 |
_("from"), app_name)) |
|
181
by Jason Conti
Adding MessageItem.py to test using regular widgets to display notifications. |
165 |