~jconti/recent-notifications/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
"""
MessageWindow.py
by Jason Conti
February 19, 2010

Popup window for viewing notifications.
"""

import gnomeapplet
import gtk
import pango

class MessageWindow(gtk.Window):
  """Shows the log of notification messages."""
  def __init__(self, parent, limit_messages = 5):
    gtk.Window.__init__(self)

    self._parent = parent
    self._limit_messages = limit_messages

    self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK)
    self.set_decorated(False)
    self.set_resizable(False)
    self.stick()
    self.set_title("Message Window")
    self.set_border_width(5)
    self.set_size_request(400, -1)

    self._vbox = gtk.VBox(True, 5)
    self.add(self._vbox)

    self._empty_label = gtk.Label("No messages")
    self._vbox.pack_start(self._empty_label)

    self._messages = []

  def add_message(self, message):
    """Adds a message to the message window."""
    widget = MessageWidget(message)
    self._messages.append(widget)
    self._vbox.pack_start(widget)

    if self._empty_label != None:
      self._vbox.remove(self._empty_label)
      self._empty_label.destroy()
      self._empty_label = None

    if len(self._messages) > self._limit_messages:
      message = self._messages.pop(0)
      self._vbox.remove(message)
      message.destroy()

  def align_with_parent(self):
    """Adapted from position_calendar_popup in the GNOME clock applet."""
    # Get the size of the applet button and the size of this window
    x, y = self._parent.get_origin()
    w, h = self.size_request()
    button_w, button_h = self._parent.get_size()

    screen = self.get_screen()
    monitor = None

    # Figure out which monitor we are on
    for i in range(screen.get_n_monitors()):
      m = screen.get_monitor_geometry(i)

      if x >= m.x and x <= m.x + m.width and y >= m.y and y <= m.y + m.height:
        monitor = m
        break

    # Probably xinerama
    if monitor == None:
      monitor = gtk.gdk.Rectangle(0, 0, screen.get_width(), screen.get_height())

    orient = self._parent.get_orient()

    # Figure out the x, y coordinates of the window and the gravity depending
    # on the orientation of the panel
    if orient == gnomeapplet.ORIENT_RIGHT:  # Panel on left
      x += button_w
      if (y + h) > monitor.y + monitor.height:
        y -= (y + h) - (monitor.y + monitor.height)

      if (y + h) > (monitor.height / 2):
        gravity = gtk.gdk.GRAVITY_SOUTH_WEST
      else:
        gravity = gtk.gdk.GRAVITY_NORTH_WEST

    elif orient == gnomeapplet.ORIENT_LEFT: # Panel on right
      x -= w
      if (y + h) > monitor.y + monitor.height:
        y -= (y + h) - (monitor.y + monitor.height)

      if (y + h) > (monitor.height / 2):
        gravity = gtk.gdk.GRAVITY_SOUTH_EAST
      else:
        gravity = gtk.gdk.GRAVITY_NORTH_EAST

    elif orient == gnomeapplet.ORIENT_DOWN: # Panel on top
      y += button_h
      if (x + w) > monitor.x + monitor.width:
        x -= (x + w) - (monitor.x + monitor.width)

      gravity = gtk.gdk.GRAVITY_NORTH_WEST

    else: # Panel on bottom
      y -= h
      if (x + w) > monitor.x + monitor.width:
        x -= (x + w) - (monitor.x + monitor.width)

      gravity = gtk.gdk.GRAVITY_SOUTH_WEST

    self.move(x, y)
    self.set_gravity(gravity)

class MessageWidget(gtk.Frame):
  """Widget to display a Notifications.Message."""
  def __init__(self, message):
    gtk.Frame.__init__(self)

    self._message = message

    self._vbox = gtk.VBox(False, 5)
    self._vbox.set_border_width(5)
    self.add(self._vbox)

    self._title_label = gtk.Label(message.summary)
    attr = pango.AttrList()
    attr.insert(pango.AttrWeight(pango.WEIGHT_BOLD, 0, -1))
    self._title_label.set_attributes(attr)
    self._vbox.pack_start(self._title_label)

    self._body_label = gtk.Label(message.body)
    self._body_label.set_line_wrap(True)
    self._vbox.pack_start(self._body_label)

    self._timestamp_label = gtk.Label(message.formatted_time() + " from " + message.app_name)
    attr = pango.AttrList()
    attr.insert(pango.AttrScale(pango.SCALE_SMALL, 0, -1))
    self._timestamp_label.set_attributes(attr)
    self._vbox.pack_start(self._timestamp_label)