366dc90d00611e1cac3bfb4539b51f56faa30ce6
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 class UIFactory(object):
42 ("refresh", gtk
.STOCK_REFRESH
, _("_Refresh"), None, _("Update this feed"), None),
43 ("add_child", gtk
.STOCK_ADD
, _("Add child"), None, _("Update this feed"), None),
44 ("mark_as_read", gtk
.STOCK_CLEAR
, _("_Mark As Read"),
45 None, _("Mark all items in this feed as read"), None),
46 ("stop_refresh", None, _("_Stop Refresh"), None, _("Stop updating this feed"), None),
47 ("remove", gtk
.STOCK_REMOVE
, _("Remo_ve"), None, _("Remove"), None),
48 ("properties", gtk
.STOCK_INFO
, _("_Information"), None, _("Feed-specific properties"), None),
49 ("text_copy", gtk
.STOCK_COPY
, "_Copy", None, None, None),
50 ("link_copy", None, "_Copy Link Location", None, None, None),
51 ("link_open", None, "_Open Link", None, None, None),
52 ("subscribe", None, "_Subscribe", None, None, None),
53 ("zoom_in", gtk
.STOCK_ZOOM_IN
, "Zoom _In", None, None, None),
54 ("zoom_out", gtk
.STOCK_ZOOM_OUT
, "Zoom _Out", None, None, None),
55 ("zoom_100", gtk
.STOCK_ZOOM_100
, "_Normal Size", None, None, None),
56 ("mark_as_unread", gtk
.STOCK_CONVERT
, "Mark as _Unread", None, "Mark this item as unread", None)
59 def __new__(cls
, *a
, **k
):
60 obj
= object.__new
__(cls
, *a
, **k
)
61 obj
.__dict
__ = cls
._shared
_state
64 def __init__(self
, name
):
66 print 'initializing ui manager'
67 self
.action_groups
= {}
68 self
.manager
= gtk
.UIManager()
69 action_group
= gtk
.ActionGroup(name
)
70 action_group
.add_actions(UIFactory
.actions
)
71 num_action_groups
= len(self
.manager
.get_action_groups())
72 self
.action_groups
[name
] = num_action_groups
73 self
.manager
.insert_action_group(action_group
, num_action_groups
)
74 ui
= os
.path
.join(straw
.defs
.STRAW_DATA_DIR
, 'ui.xml')
75 self
.manager
.add_ui_from_file(ui
)
77 def get_popup(self
, path
):
78 return self
.manager
.get_widget(path
)
80 def get_action(self
, path
):
81 return self
.manager
.get_action(path
)
83 def ensure_update(self
):
84 self
.manager
.ensure_update()
87 def report_error(primary
, secondary
, parent
=None):
88 dialog
= gtk
.MessageDialog(parent
,
89 type=gtk
.MESSAGE_ERROR
,
90 buttons
=gtk
.BUTTONS_OK
,
91 message_format
=primary
)
92 dialog
.format_secondary_text(secondary
)
93 response
= dialog
.run()
97 def report_offline_status(parent
=None):
98 dialog
= gtk
.MessageDialog(parent
,
99 type=gtk
.MESSAGE_WARNING
,
100 buttons
=gtk
.BUTTONS_OK_CANCEL
,
101 message_format
="You Are Offline!")
102 dialog
.format_secondary_markup(_("You are currently reading offline. Would you like to go online now?"))
103 response
= dialog
.run()
109 Juri Pakaste <juri@iki.fi>
112 Jan Alonzo <jmalonzo@unpluggable.com>
113 Ryan P. Skadberg <skadz@stigmata.org>
114 Leandro Lameiro <lameiro@gmail.com>
115 Tuukka Hastrup <tuukka@iki.fi>
118 Iain McCoy <iain@mccoy.id.au>
119 Lucas Nussbaum <lucas@lucas-nussbaum.net>
120 Olivier Crete <tester@tester.ca>
121 Scott Douglas-Watson <sdouglaswatson@yahoo.co.uk>
122 Terje R\xf8sten (distutils)
125 Mark Pilgrim (feedparser and feedfinder)
126 Joe Gregorio (httplib2)
128 iconfile
= os
.path
.join(straw
.defs
.STRAW_DATA_DIR
,"straw.png")
129 logo
= gtk
.gdk
.pixbuf_new_from_file(iconfile
)
130 description
= _("A Desktop Feed Reader")
131 straw_copyright
= u
"""
132 Copyright \xa9 2005-2007 Straw Contributors
133 Copyright \xa9 2002-2004 Juri Pakaste"""
135 u
'Jakub \'jimmac\' Steiner',
140 u
"GNOME i18n Project and Translators<http://developer.gnome.org/projects/gtp/>",
141 u
"Juri Pakaste <juri@iki.fi>",
142 u
"Martin Steldinger <tribble@hanfplantage.de>",
143 u
"David Rousseau <boiteaflood@wanadoo.fr>",
144 u
"Sergei Vavinov <svv@cmc.msu.ru>",
145 u
"Terje R\xf8sten <terjeros@phys.ntnu.no>",
146 u
"Francisco J. Fernandez <franciscojavier.fernandez.serrador@hispalinux.es>",
147 u
"Elros Cyriatan (Dutch Translation)"
150 translator_credits
= 'translator_credits'
151 about
= gtk
.AboutDialog()
152 about
.set_name(straw
.defs
.PACKAGE
)
153 about
.set_version(straw
.defs
.VERSION
)
154 about
.set_copyright(straw_copyright
)
155 about
.set_comments(description
)
156 about
.set_authors(people
.splitlines())
157 about
.set_artists(artists
)
159 about
.set_translator_credits(translator_credits
)
160 about
.set_license(__license__
)
161 gtk
.about_dialog_set_url_hook(lambda about
, url
: url_show(url
))
162 about
.set_website(straw
.defs
.STRAW_HOME
)
163 about
.set_website_label(straw
.defs
.STRAW_HOME
)
164 about
.connect('response', lambda widget
, response
: widget
.destroy())
167 def listdiff(l1
, l2
, test
=None):
169 return _listdifftest(l1
, l2
, test
)
184 return (common
, inl1
, inl2
)
187 browser_type
= Config
.get(OPTION_WEB_BROWSER_TYPE
)
189 if browser_type
== "gnome":
190 return gnomevfs
.url_show(url
)
193 browser_cmd
= Config
.get(OPTION_WEB_BROWSER_CMD
)
194 cmdbin
, args
= string
.splitfields(browser_cmd
, maxsplit
=1)
197 pid
= subprocess
.Popen([cmdbin
, link
]).pid
199 except ValueError, ve
:
200 raise UrlOpenException("Problem opening link %s" % ve
)
203 def set_clipboard_text(text
):
204 clipboard
= gtk
.clipboard_get(selection
="CLIPBOARD")
205 clipboard
.set_text(text
)
208 class UrlOpenException(Exception):
211 entity
= re
.compile(r
'\&.\w*?\;')
212 def convert_entities(text
):
214 entities
= htmlentitydefs
.entitydefs
216 ent_code
= entities
.get(ents
[1:-1], None)
217 if ent_code
is not None:
219 ents
= unicode(ent_code
, get_locale_encoding())
220 except UnicodeDecodeError:
221 ents
= unicode(ent_code
, 'latin-1')
222 except Exception, ex
:
223 error
.log("error occurred while converting entity %s: %s" % (ents
, ex
))
225 # check if it still needs conversion
226 if entity
.search(ents
) is None:
235 return unichr(int(code
, base
))
239 in_entity
= entity
.search(text
)
240 if in_entity
is None:
243 ctext
= in_entity
.re
.sub(conv
, text
)
246 def complete_url(url
, feed_location
):
247 #print "---- COMPLETING %s WITH %s" % (url, feed_location)
248 url
= urllib
.quote(url
, safe
=string
.punctuation
)
249 if urlparse
.urlparse(url
)[0] == '':
250 return urlparse
.urljoin(feed_location
, url
)
254 def get_url_location(url
):
255 url
= urllib
.quote(url
, safe
=string
.punctuation
)
256 parsed_url
= urlparse
.urlsplit(url
)
257 return urlparse
.urlunsplit((parsed_url
[0], parsed_url
[1], '','',''))
259 def get_locale_encoding():
261 encoding
= locale
.getpreferredencoding()
263 encoding
= sys
.getdefaultencoding()
266 def format_date(date
, format
=None, encoding
=None):
269 format
= get_date_format()
271 encoding
= get_locale_encoding()
272 timestr
= time
.strftime(format
, time
.localtime(calendar
.timegm(date
)))
273 return unicode(timestr
, encoding
)
275 def get_date_format():
276 # this is here just to make xgettext happy: it should be defined in
277 # only one place, and a good one would be MainWindow.py module level.
278 # however, we can't access _ there.
279 # The format: %A is the full weekday name
280 # %B is the full month name
281 # %e is the day of the month as a decimal number,
282 # without leading zero
283 # This should be translated to be suitable for the locale in
284 # question, feel free to alter the order and the parameters (they
285 # are strftime(3) parameters, the whole string is passed to the
286 # function, Straw does no additional interpretation) if you feel
287 # it's necessary in the translation file.
288 return _('%A %B %e %H:%M')
290 def pango_escape(text
):
292 return xml
.sax
.saxutils
.escape(text
)
296 def html_replace(exc
):
297 """ Python Cookbook 2ed, Section 1.23
299 if isinstance(exc
, (UnicodeDecodeError, UnicodeTranslateError)):
300 s
= [ u
'&%s;' % codepoint2name
[ord(c
)] for c
in exc
.object[exc
.start
:exc
.end
]]
301 return ''.join(s
), exc
.end
303 raise TypeError("can't handle %s" % exc
.__name
__)
305 codecs
.register_error('html_replace', html_replace
)