3a8f10c4fecb67acd0b6a2db6e1b78ea6b0a1547
3 Module for displaying dialogs related to errors, warnings, notifications,
7 __copyright__
= "Copyright (c) 2002-2005 Free Software Foundation, Inc."
9 Straw is free software; you can redistribute it and/or modify it under the
10 terms of the GNU General Public License as published by the Free Software
11 Foundation; either version 2 of the License, or (at your option) any later
14 Straw is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along with
19 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20 Place - Suite 330, Boston, MA 02111-1307, USA. """
22 from Constants
import *
23 from gettext
import gettext
as _
32 import os
.path
, re
, locale
, time
, calendar
34 import urllib
, string
, urlparse
37 log
= error
.get_logger()
39 class UIFactory(object):
44 ("refresh", gtk
.STOCK_REFRESH
, _("_Refresh"), None, _("Update this feed"), None),
45 ("add_child", gtk
.STOCK_ADD
, _("Add child"), None, _("Update this feed"), None),
46 ("mark_as_read", gtk
.STOCK_CLEAR
, _("_Mark As Read"),
47 None, _("Mark all items in this feed as read"), None),
48 ("stop_refresh", None, _("_Stop Refresh"), None, _("Stop updating this feed"), None),
49 ("remove", gtk
.STOCK_REMOVE
, _("Remo_ve"), None, _("Remove"), None),
50 ("properties", gtk
.STOCK_INFO
, _("_Information"), None, _("Feed-specific properties"), None),
51 ("text_copy", gtk
.STOCK_COPY
, "_Copy", None, None, None),
52 ("link_copy", None, "_Copy Link Location", None, None, None),
53 ("link_open", None, "_Open Link", None, None, None),
54 ("subscribe", None, "_Subscribe", None, None, None),
55 ("zoom_in", gtk
.STOCK_ZOOM_IN
, "Zoom _In", None, None, None),
56 ("zoom_out", gtk
.STOCK_ZOOM_OUT
, "Zoom _Out", None, None, None),
57 ("zoom_100", gtk
.STOCK_ZOOM_100
, "_Normal Size", None, None, None),
58 ("mark_as_unread", gtk
.STOCK_CONVERT
, "Mark as _Unread", None, "Mark this item as unread", None)
61 def __new__(cls
, *a
, **k
):
62 obj
= object.__new
__(cls
, *a
, **k
)
63 obj
.__dict
__ = cls
._shared
_state
66 def __init__(self
, name
):
68 log
.info("Initializing UI manager")
69 self
.action_groups
= {}
70 self
.manager
= gtk
.UIManager()
71 action_group
= gtk
.ActionGroup(name
)
72 action_group
.add_actions(UIFactory
.actions
)
73 num_action_groups
= len(self
.manager
.get_action_groups())
74 self
.action_groups
[name
] = num_action_groups
75 self
.manager
.insert_action_group(action_group
, num_action_groups
)
76 ui
= os
.path
.join(straw
.defs
.STRAW_DATA_DIR
, 'ui.xml')
77 self
.manager
.add_ui_from_file(ui
)
79 def get_popup(self
, path
):
80 return self
.manager
.get_widget(path
)
82 def get_action(self
, path
):
83 return self
.manager
.get_action(path
)
85 def ensure_update(self
):
86 self
.manager
.ensure_update()
89 def report_error(primary
, secondary
, parent
=None):
90 dialog
= gtk
.MessageDialog(parent
,
91 type=gtk
.MESSAGE_ERROR
,
92 buttons
=gtk
.BUTTONS_OK
,
93 message_format
=primary
)
94 dialog
.format_secondary_text(secondary
)
95 response
= dialog
.run()
99 def report_offline_status(parent
=None):
100 dialog
= gtk
.MessageDialog(parent
,
101 type=gtk
.MESSAGE_WARNING
,
102 buttons
=gtk
.BUTTONS_OK_CANCEL
,
103 message_format
="You Are Offline!")
104 dialog
.format_secondary_markup(_("You are currently reading offline. Would you like to go online now?"))
105 response
= dialog
.run()
111 Juri Pakaste <juri@iki.fi>
114 Jan Alonzo <jmalonzo@unpluggable.com>
115 Ryan P. Skadberg <skadz@stigmata.org>
116 Leandro Lameiro <lameiro@gmail.com>
117 Tuukka Hastrup <tuukka@iki.fi>
120 Iain McCoy <iain@mccoy.id.au>
121 Lucas Nussbaum <lucas@lucas-nussbaum.net>
122 Olivier Crete <tester@tester.ca>
123 Scott Douglas-Watson <sdouglaswatson@yahoo.co.uk>
124 Terje R\xf8sten (distutils)
127 Mark Pilgrim (feedparser and feedfinder)
128 Joe Gregorio (httplib2)
130 iconfile
= os
.path
.join(straw
.defs
.STRAW_DATA_DIR
,"straw.png")
131 logo
= gtk
.gdk
.pixbuf_new_from_file(iconfile
)
132 description
= _("A Desktop Feed Reader")
133 straw_copyright
= u
"""
134 Copyright \xa9 2005-2007 Straw Contributors
135 Copyright \xa9 2002-2004 Juri Pakaste"""
137 u
'Jakub \'jimmac\' Steiner',
142 u
"GNOME i18n Project and Translators<http://developer.gnome.org/projects/gtp/>",
143 u
"Juri Pakaste <juri@iki.fi>",
144 u
"Martin Steldinger <tribble@hanfplantage.de>",
145 u
"David Rousseau <boiteaflood@wanadoo.fr>",
146 u
"Sergei Vavinov <svv@cmc.msu.ru>",
147 u
"Terje R\xf8sten <terjeros@phys.ntnu.no>",
148 u
"Francisco J. Fernandez <franciscojavier.fernandez.serrador@hispalinux.es>",
149 u
"Elros Cyriatan (Dutch Translation)"
152 translator_credits
= 'translator_credits'
153 about
= gtk
.AboutDialog()
154 about
.set_name(straw
.defs
.PACKAGE
)
155 about
.set_version(straw
.defs
.VERSION
)
156 about
.set_copyright(straw_copyright
)
157 about
.set_comments(description
)
158 about
.set_authors(people
.splitlines())
159 about
.set_artists(artists
)
161 about
.set_translator_credits(translator_credits
)
162 about
.set_license(__license__
)
163 gtk
.about_dialog_set_url_hook(lambda about
, url
: url_show(url
))
164 about
.set_website(straw
.defs
.STRAW_HOME
)
165 about
.set_website_label(straw
.defs
.STRAW_HOME
)
166 about
.connect('response', lambda widget
, response
: widget
.destroy())
169 def listdiff(l1
, l2
, test
=None):
171 return _listdifftest(l1
, l2
, test
)
186 return (common
, inl1
, inl2
)
189 browser_type
= Config
.get(OPTION_WEB_BROWSER_TYPE
)
191 if browser_type
== "gnome":
192 return gnomevfs
.url_show(url
)
195 browser_cmd
= Config
.get(OPTION_WEB_BROWSER_CMD
)
196 cmdbin
, args
= string
.splitfields(browser_cmd
, maxsplit
=1)
199 pid
= subprocess
.Popen([cmdbin
, link
]).pid
201 except ValueError, ve
:
202 raise UrlOpenException("Problem opening link %s" % ve
)
205 def set_clipboard_text(text
):
206 clipboard
= gtk
.clipboard_get(selection
="CLIPBOARD")
207 clipboard
.set_text(text
)
210 class UrlOpenException(Exception):
213 entity
= re
.compile(r
'\&.\w*?\;')
214 def convert_entities(text
):
216 entities
= htmlentitydefs
.entitydefs
218 ent_code
= entities
.get(ents
[1:-1], None)
219 if ent_code
is not None:
221 ents
= unicode(ent_code
, get_locale_encoding())
222 except UnicodeDecodeError:
223 ents
= unicode(ent_code
, 'latin-1')
224 except Exception, ex
:
225 error
.log("error occurred while converting entity %s: %s" % (ents
, ex
))
227 # check if it still needs conversion
228 if entity
.search(ents
) is None:
237 return unichr(int(code
, base
))
241 in_entity
= entity
.search(text
)
242 if in_entity
is None:
245 ctext
= in_entity
.re
.sub(conv
, text
)
248 def complete_url(url
, feed_location
):
249 #print "---- COMPLETING %s WITH %s" % (url, feed_location)
250 url
= urllib
.quote(url
, safe
=string
.punctuation
)
252 if urlparse
.urlparse(url
)[0] == '':
253 return urlparse
.urljoin(feed_location
, url
)
257 def get_url_location(url
):
258 url
= urllib
.quote(url
, safe
=string
.punctuation
)
259 parsed_url
= urlparse
.urlsplit(url
)
260 return urlparse
.urlunsplit((parsed_url
[0], parsed_url
[1], '','',''))
262 def get_locale_encoding():
264 encoding
= locale
.getpreferredencoding()
266 encoding
= sys
.getdefaultencoding()
269 def format_date(date
, format
=None, encoding
=None):
272 format
= get_date_format()
274 encoding
= get_locale_encoding()
275 timestr
= time
.strftime(format
, time
.localtime(calendar
.timegm(date
)))
276 return unicode(timestr
, encoding
)
278 def get_date_format():
279 # this is here just to make xgettext happy: it should be defined in
280 # only one place, and a good one would be MainWindow.py module level.
281 # however, we can't access _ there.
282 # The format: %A is the full weekday name
283 # %B is the full month name
284 # %e is the day of the month as a decimal number,
285 # without leading zero
286 # This should be translated to be suitable for the locale in
287 # question, feel free to alter the order and the parameters (they
288 # are strftime(3) parameters, the whole string is passed to the
289 # function, Straw does no additional interpretation) if you feel
290 # it's necessary in the translation file.
291 return _('%A %B %e %H:%M')
293 def pango_escape(text
):
295 return gobject
.markup_escape_text(text
)#xml.sax.saxutils.escape(text)
299 def html_replace(exc
):
300 """ Python Cookbook 2ed, Section 1.23
302 if isinstance(exc
, (UnicodeDecodeError, UnicodeTranslateError)):
303 s
= [ u
'&%s;' % codepoint2name
[ord(c
)] for c
in exc
.object[exc
.start
:exc
.end
]]
304 return ''.join(s
), exc
.end
306 raise TypeError("can't handle %s" % exc
.__name
__)
308 codecs
.register_error('html_replace', html_replace
)