~jconti/recent-notifications/trunk

« back to all changes in this revision

Viewing changes to recent_notifications/MessageWindow.py

  • Committer: Jason Conti
  • Date: 2010-02-18 20:17:33 UTC
  • Revision ID: jason.conti@gmail.com-20100218201733-i671lnpp0g78nyco
Adding template for empty icon.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
"""
2
 
MessageWindow.py
3
 
by Jason Conti
4
 
February 19, 2010
5
 
 
6
 
Popup window for viewing notifications.
7
 
"""
8
 
 
9
 
import gnomeapplet
10
 
import gobject
11
 
import gtk
12
 
import logging
13
 
 
14
 
from string import Template
15
 
 
16
 
from MessageList import MessageList
17
 
from Translations import _
18
 
 
19
 
logger = logging.getLogger("MessageWindow")
20
 
 
21
 
class Column(object):
22
 
  """Maps column names to column numbers."""
23
 
  APP_NAME  = 0
24
 
  SEPARATOR = 1
25
 
  COUNT     = 2
26
 
 
27
 
class MessageWindow(gtk.Window):
28
 
  """Shows the log of notification messages."""
29
 
  def __init__(self, parent):
30
 
    gtk.Window.__init__(self)
31
 
 
32
 
    self._parent = parent
33
 
 
34
 
    self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK)
35
 
    self.set_decorated(False)
36
 
    self.set_resizable(False)
37
 
    self.set_property("skip-taskbar-hint", True)
38
 
    self.stick()
39
 
    self.set_title(_("Message Window"))
40
 
    self.set_border_width(0)
41
 
    self.set_size_request(400, 400)
42
 
 
43
 
    self._frame = gtk.Frame()
44
 
    self._frame.set_border_width(0)
45
 
    self._frame.set_shadow_type(gtk.SHADOW_OUT)
46
 
    self.add(self._frame)
47
 
 
48
 
    self._vadjust = gtk.Adjustment()
49
 
    self._vadjust.connect("changed", self.on_vadjust_changed)
50
 
 
51
 
    self._vbox = gtk.VBox()
52
 
    self._frame.add(self._vbox)
53
 
 
54
 
    self._scroll = gtk.ScrolledWindow(vadjustment=self._vadjust)
55
 
    self._scroll.set_border_width(5)
56
 
    self._scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
57
 
    self._scroll.connect("size-allocate", self.on_scroll_resize)
58
 
    self._vbox.pack_start(self._scroll, True)
59
 
 
60
 
    self._message_list = MessageList(self)
61
 
    self._scroll.add(self._message_list)
62
 
 
63
 
    # app_name, is_separator, count
64
 
    self._combolist = gtk.ListStore(str, bool, int)
65
 
    self._combobox = gtk.ComboBox(self._combolist)
66
 
    self._combo_app_cell = gtk.CellRendererText()
67
 
    self._combobox.pack_start(self._combo_app_cell, True)
68
 
    self._combobox.add_attribute(self._combo_app_cell, "text", Column.APP_NAME)
69
 
    self._combo_count_cell = gtk.CellRendererText()
70
 
    self._combobox.pack_start(self._combo_count_cell, False)
71
 
    self._combobox.add_attribute(self._combo_count_cell, "text", Column.COUNT)
72
 
    self._combobox.set_row_separator_func(lambda m, i: m.get_value(i, Column.SEPARATOR))
73
 
    self._combobox.connect("changed", self.on_combobox_changed)
74
 
    self._vbox.pack_start(self._combobox, False)
75
 
 
76
 
    self.initialize_combobox()
77
 
 
78
 
  def on_combobox_changed(self, combobox, *args):
79
 
    """Set the tree filters to the selected app."""
80
 
    active = self._combobox.get_active()
81
 
    self._message_list.unselect_all()
82
 
    if active == 0:
83
 
      self._message_list.set_filter_app(None)
84
 
    else:
85
 
      iter = self._combobox.get_active_iter()
86
 
      app_name = self._combolist.get_value(iter, Column.APP_NAME)
87
 
      self._message_list.set_filter_app(app_name)
88
 
 
89
 
  def on_scroll_resize(self, scroll, allocation, *args):
90
 
    """Updates the message list wrap width when the scrolled window resizes."""
91
 
    self._message_list.set_wrap_width(allocation.width)
92
 
 
93
 
  def on_vadjust_changed(self, adjustment, *args):
94
 
    """Reset the adjustment position when the adjustment is changed (resized), but
95
 
    not moved, so the user can scroll around freely."""
96
 
    self._vadjust.set_value(0)
97
 
 
98
 
  def add_message(self, message):
99
 
    """Adds a message to the message window."""
100
 
    self._message_list.add_message(message)
101
 
 
102
 
  def clear_messages(self):
103
 
    """Clears all messages from the message window."""
104
 
    self._message_list.clear()
105
 
    self.initialize_combobox()
106
 
 
107
 
  def clear_selections(self):
108
 
    """Unselects every row in the treeview and marks the messages as read."""
109
 
    self._message_list.mark_as_read()
110
 
    self._message_list.unselect_all()
111
 
 
112
 
  def show_dropdown(self):
113
 
    """Shows the dropdown window"""
114
 
    self.show_all()
115
 
    self.align_with_parent()
116
 
 
117
 
  def hide_dropdown(self):
118
 
    """Hides the dropdown window"""
119
 
    self.hide_all()
120
 
    self.clear_selections()
121
 
 
122
 
  def increment_count(self, iter):
123
 
    """Increments the message count at the given row."""
124
 
    count = self._combolist.get_value(iter, Column.COUNT)
125
 
    self._combolist.set_value(iter, Column.COUNT, count + 1)
126
 
 
127
 
  def decrement_count(self, iter):
128
 
    """Decrements the message count at the given row."""
129
 
    count = self._combolist.get_value(iter, Column.COUNT)
130
 
    self._combolist.set_value(iter, Column.COUNT, count - 1)
131
 
 
132
 
  def initialize_combobox(self):
133
 
    """Clear the combobox and set the initial entry."""
134
 
    self._combolist.clear()
135
 
    self._combolist.append([_("All Applications"), False, 0])
136
 
    self._comboapps = {}
137
 
    self._combobox.set_active(0)
138
 
 
139
 
  def set_message_limit(self, n):
140
 
    """Sets the message limit of the MessageList."""
141
 
    self._message_list.set_message_limit(n)
142
 
 
143
 
  def increment_combobox(self, app_name):
144
 
    """Updates the combobox app names and message counts."""
145
 
    # Add a separator if there isn't one yet
146
 
    if len(self._combolist) == 1:
147
 
      self._combolist.append(["Separator", True, 0])
148
 
 
149
 
    self.increment_count(self._combolist.get_iter_first())
150
 
 
151
 
    if app_name not in self._comboapps:
152
 
      iter = self._combolist.append([app_name, False, 1])
153
 
      self._comboapps[app_name] = iter
154
 
    else:
155
 
      self.increment_count(self._comboapps[app_name])
156
 
 
157
 
  def decrement_combobox(self, app_name):
158
 
    """Updates the combobox app names and message counts."""
159
 
    self.decrement_count(self._combolist.get_iter_first())
160
 
 
161
 
    if app_name in self._comboapps:
162
 
      self.decrement_count(self._comboapps[app_name])
163
 
 
164
 
  def align_with_parent(self):
165
 
    """Adapted from position_calendar_popup in the GNOME clock applet."""
166
 
    # Get the size of the applet button and the size of this window
167
 
    applet_x, applet_y = x, y = self._parent.get_origin()
168
 
    w, h = self.get_size()
169
 
    button_w, button_h = self._parent.get_size()
170
 
 
171
 
    screen = self.get_screen()
172
 
    monitor = None
173
 
    monitor_index = -1
174
 
 
175
 
    # Figure out which monitor we are on
176
 
    for i in range(screen.get_n_monitors()):
177
 
      m = screen.get_monitor_geometry(i)
178
 
 
179
 
      if x >= m.x and x <= m.x + m.width and y >= m.y and y <= m.y + m.height:
180
 
        monitor = m
181
 
        monitor_index = i
182
 
        break
183
 
 
184
 
    # Probably xinerama
185
 
    if monitor == None:
186
 
      monitor = gtk.gdk.Rectangle(0, 0, screen.get_width(), screen.get_height())
187
 
 
188
 
    orient = self._parent.get_orient()
189
 
 
190
 
    # Figure out the x, y coordinates of the window and the gravity depending
191
 
    # on the orientation of the panel
192
 
    if orient == gnomeapplet.ORIENT_RIGHT:  # Panel on left
193
 
      x += button_w
194
 
      if (y + h) > monitor.y + monitor.height:
195
 
        y -= (y + h) - (monitor.y + monitor.height)
196
 
 
197
 
    elif orient == gnomeapplet.ORIENT_LEFT: # Panel on right
198
 
      x -= w
199
 
      if (y + h) > monitor.y + monitor.height:
200
 
        y -= (y + h) - (monitor.y + monitor.height)
201
 
 
202
 
    elif orient == gnomeapplet.ORIENT_DOWN: # Panel on top
203
 
      y += button_h
204
 
      if (x + w) > monitor.x + monitor.width:
205
 
        x -= (x + w) - (monitor.x + monitor.width)
206
 
 
207
 
    else: # Panel on bottom
208
 
      y -= h
209
 
      if (x + w) > monitor.x + monitor.width:
210
 
        x -= (x + w) - (monitor.x + monitor.width)
211
 
 
212
 
    gravity = gtk.gdk.GRAVITY_NORTH_WEST
213
 
 
214
 
    self.set_gravity(gravity)
215
 
    self.move(x, y)
216
 
 
217
 
    logger.debug("""
218
 
--------------------------------------------------
219
 
align_with_parent:
220
 
  applet:
221
 
    x: {0}
222
 
    y: {1}
223
 
    w: {2}
224
 
    h: {3}
225
 
    orient: {4}
226
 
  window:
227
 
    x: {5}
228
 
    y: {6}
229
 
    w: {7}
230
 
    h: {8}
231
 
    gravity: {9}
232
 
  monitor:
233
 
    x: {10}
234
 
    y: {11}
235
 
    w: {12}
236
 
    h: {13}
237
 
    index: {14}
238
 
--------------------------------------------------
239
 
    """.format(applet_x, applet_y, button_w, button_h, orient,
240
 
      x, y, w, h, gravity,
241
 
      monitor.x, monitor.y, monitor.width, monitor.height, monitor_index))
242