2 # -*- coding: utf-8 -*-
4 # gPodder - A media aggregator and podcast client
5 # Copyright (c) 2005-2010 Thomas Perl and the gPodder Team
7 # gPodder is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # gPodder is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 # widgets.py -- Additional widgets for gPodder
24 # Thomas Perl <thp@gpodder.org> 2009-03-31
31 from xml
.sax
import saxutils
33 class SimpleMessageArea(gtk
.HBox
):
34 """A simple, yellow message area. Inspired by gedit.
36 Original C source code:
37 http://svn.gnome.org/viewvc/gedit/trunk/gedit/gedit-message-area.c
39 def __init__(self
, message
, buttons
=()):
40 gtk
.HBox
.__init
__(self
, spacing
=6)
41 self
.set_border_width(6)
42 self
.__in
_style
_set
= False
43 self
.connect('style-set', self
.__style
_set
)
44 self
.connect('expose-event', self
.__expose
_event
)
46 self
.__label
= gtk
.Label()
47 self
.__label
.set_alignment(0.0, 0.5)
48 self
.__label
.set_line_wrap(False)
49 self
.__label
.set_ellipsize(pango
.ELLIPSIZE_END
)
50 self
.__label
.set_markup('<b>%s</b>' % saxutils
.escape(message
))
51 self
.pack_start(self
.__label
, expand
=True, fill
=True)
54 for button
in buttons
:
55 hbox
.pack_start(button
, expand
=True, fill
=False)
56 self
.pack_start(hbox
, expand
=False, fill
=False)
58 def set_markup(self
, markup
, line_wrap
=True):
59 self
.__label
.set_markup(markup
)
60 self
.__label
.set_line_wrap(line_wrap
)
62 def __style_set(self
, widget
, previous_style
):
63 if self
.__in
_style
_set
:
66 w
= gtk
.Window(gtk
.WINDOW_POPUP
)
67 w
.set_name('gtk-tooltip')
71 self
.__in
_style
_set
= True
73 self
.__in
_style
_set
= False
79 def __expose_event(self
, widget
, event
):
80 style
= widget
.get_style()
81 rect
= widget
.get_allocation()
82 style
.paint_flat_box(widget
.window
, gtk
.STATE_NORMAL
,
83 gtk
.SHADOW_OUT
, None, widget
, "tooltip",
84 rect
.x
, rect
.y
, rect
.width
, rect
.height
)
87 class NotificationWindow(gtk
.Window
):
88 """A quick substitution widget for pynotify notifications."""
89 def __init__(self
, message
, title
=None, important
=False, widget
=None):
90 gtk
.Window
.__init
__(self
, gtk
.WINDOW_POPUP
)
91 self
._finished
= False
92 message_area
= SimpleMessageArea('')
93 arrow
= gtk
.image_new_from_stock(gtk
.STOCK_GO_UP
, \
95 arrow
.set_alignment(.5, 0.)
96 arrow
.set_padding(6, 0)
97 message_area
.pack_start(arrow
, False)
98 message_area
.reorder_child(arrow
, 0)
100 message_area
.set_markup('<b>%s</b>\n<small>%s</small>' % (saxutils
.escape(title
), saxutils
.escape(message
)))
102 message_area
.set_markup(saxutils
.escape(message
))
103 self
.add(message_area
)
104 self
.set_gravity(gtk
.gdk
.GRAVITY_NORTH_WEST
)
106 if widget
is not None:
107 _x
, _y
, ww
, hh
, _depth
= self
.window
.get_geometry()
109 while not isinstance(parent
, gtk
.Window
):
110 parent
= parent
.get_parent()
111 x
, y
, _w
, _h
, _depth
= parent
.window
.get_geometry()
112 rect
= widget
.allocation
113 w
, h
= rect
.width
, rect
.height
116 arrow_rect
= arrow
.allocation
118 self
.move(x
+w
/2-arrow_rect
.x
-arrow_rect
.width
/2, y
+h
-5)
120 self
.move(x
+w
/2-ww
/2, y
+h
/2-hh
/2+20)
121 message_area
.remove(arrow
)
123 def show_timeout(self
, timeout
=8000):
124 gobject
.timeout_add(timeout
, self
._hide
_and
_destroy
)
127 def _hide_and_destroy(self
):
128 if not self
._finished
:
130 self
._finished
= True
133 class SpinningProgressIndicator(gtk
.Image
):
134 # Progress indicator loading inspired by glchess from gnome-games-clutter
135 def __init__(self
, size
=32):
136 gtk
.Image
.__init
__(self
)
141 # Load the progress indicator
142 icon_theme
= gtk
.icon_theme_get_default()
146 icon
= icon_theme
.load_icon(ICON('process-working'), size
, 0)
147 width
, height
= icon
.get_width(), icon
.get_height()
148 if width
< size
or height
< size
:
149 size
= min(width
, height
)
150 for row
in range(height
/size
):
151 for column
in range(width
/size
):
152 frame
= icon
.subpixbuf(column
*size
, row
*size
, size
, size
)
153 self
._frames
.append(frame
)
154 # Remove the first frame (the "idle" icon)
157 self
.step_animation()
159 # FIXME: This is not very beautiful :/
160 self
.set_from_stock(gtk
.STOCK_EXECUTE
, gtk
.ICON_SIZE_BUTTON
)
162 def step_animation(self
):
163 if len(self
._frames
) > 1:
165 if self
._frame
_id
>= len(self
._frames
):
167 self
.set_from_pixbuf(self
._frames
[self
._frame
_id
])