Merge lp:~dobey/gwibber/gtk3-pybits into lp:gwibber

Proposed by dobey
Status: Merged
Merged at revision: 1267
Proposed branch: lp:~dobey/gwibber/gtk3-pybits
Merge into: lp:gwibber
Diff against target: 5428 lines (+573/-3225)
35 files modified
.bzrignore (+3/-0)
bin/gwibber (+0/-99)
bin/gwibber-accounts (+7/-5)
bin/gwibber-error (+0/-97)
bin/gwibber-preferences (+0/-65)
bin/gwibber-service (+3/-3)
gwibber/accounts.py (+66/-82)
gwibber/actions.py (+0/-266)
gwibber/client.py (+0/-735)
gwibber/error.py (+6/-6)
gwibber/gwui.py (+117/-118)
gwibber/lib/gtk/widgets.py (+30/-30)
gwibber/microblog/dispatcher.py (+20/-18)
gwibber/microblog/plugins/buzz/gtk/buzz/__init__.py (+10/-11)
gwibber/microblog/plugins/digg/gtk/digg/__init__.py (+5/-6)
gwibber/microblog/plugins/facebook/gtk/facebook/__init__.py (+60/-32)
gwibber/microblog/plugins/flickr/gtk/flickr/__init__.py (+5/-6)
gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py (+38/-33)
gwibber/microblog/plugins/friendfeed/gtk/friendfeed/__init__.py (+5/-6)
gwibber/microblog/plugins/identica/gtk/identica/__init__.py (+25/-27)
gwibber/microblog/plugins/pingfm/gtk/pingfm/__init__.py (+5/-6)
gwibber/microblog/plugins/qaiku/gtk/qaiku/__init__.py (+5/-6)
gwibber/microblog/plugins/statusnet/gtk/statusnet/__init__.py (+27/-26)
gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py (+50/-34)
gwibber/microblog/storage.py (+1/-1)
gwibber/microblog/uploader/ubuntuone_uploader/__init__.py (+8/-11)
gwibber/microblog/util/__init__.py (+7/-8)
gwibber/microblog/util/keyring.py (+50/-7)
gwibber/microblog/util/resources.py (+5/-1)
gwibber/preferences.py (+0/-123)
gwibber/util.py (+13/-12)
po/Makefile.in.in (+0/-222)
po/gwibber.pot (+0/-1043)
tests/Makefile.am (+2/-7)
tests/plugins/test/__init__.py (+0/-73)
To merge this branch: bzr merge lp:~dobey/gwibber/gtk3-pybits
Reviewer Review Type Date Requested Status
Ken VanDine Approve
Review via email: mp+93008@code.launchpad.net

Commit message

Convert gwibber-accounts and gwibber-service over to gtk3 and gobject-introspection

To post a comment you must log in.
lp:~dobey/gwibber/gtk3-pybits updated
1252. By dobey

Merge a few more fixes from Ken

1253. By dobey

Fix selection handling when changing accounts in tree

1254. By dobey

Fix color parsing

Revision history for this message
Ken VanDine (ken-vandine) wrote :

Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2011-07-13 19:29:18 +0000
3+++ .bzrignore 2012-02-14 21:35:21 +0000
4@@ -2,6 +2,8 @@
5 .bzrignore
6 gwibber/semantic.cache
7 semantic.cache
8+*.gmo
9+*.lo
10 *.mo
11 ABOUT-NLS
12 INSTALL
13@@ -22,6 +24,7 @@
14 gnome-doc-utils.make
15 gtk-doc.make
16 install-sh
17+intltool-*
18 libtool
19 ltmain.sh
20 m4/
21
22=== removed file 'bin/gwibber'
23--- bin/gwibber 2011-04-23 04:19:26 +0000
24+++ bin/gwibber 1970-01-01 00:00:00 +0000
25@@ -1,99 +0,0 @@
26-#!/usr/bin/python
27-
28-"""
29-
30-Gwibber Client
31-SegPhault (Ryan Paul) - 05/29/2007
32-
33-"""
34-
35-import sys, gtk, optparse, dbus, wnck, time
36-from os.path import join, dirname, exists, realpath, abspath
37-from dbus.mainloop.glib import DBusGMainLoop
38-from dbus import DBusException
39-import subprocess
40-import gettext
41-from gettext import lgettext as _
42-if hasattr(gettext, 'bind_textdomain_codeset'):
43- gettext.bind_textdomain_codeset('gwibber','UTF-8')
44-gettext.textdomain('gwibber')
45-
46-
47-######################################################################
48-# Setup path
49-
50-LAUNCH_DIR = abspath(sys.path[0])
51-SOURCE_DIR = join(LAUNCH_DIR, "..", "gwibber")
52-
53-DBusGMainLoop(set_as_default=True)
54-
55-# If we were invoked from a Gwibber source directory add that as the
56-# preferred module path ...
57-if exists(join(SOURCE_DIR, "client.py")):
58- sys.path.insert(0, realpath(dirname(SOURCE_DIR)))
59- try:
60- from gwibber.microblog.util import log
61- log.logger.name = "Gwibber GNOME Client"
62- log.logger.info("Running from the source tree")
63- from gwibber import client
64- finally:
65- del sys.path[0]
66-else:
67- from gwibber.microblog.util import log
68- log.logger.name = "Gwibber GNOME Client"
69- log.logger.info("Running from the system path")
70- from gwibber import client
71-
72-######################################################################
73-# Options
74-from optparse import OptionParser
75-parser = OptionParser()
76-parser.add_option("-d", "--debug", action="store_true",
77- dest="debug", default=False,
78- help=_("Log debug messages"))
79-parser.add_option("-o", action="store_true",
80- dest="stdout", default=False,
81- help="Log to stdout")
82-(options, args) = parser.parse_args()
83-
84-if len(args) > 0:
85- import gwibber.lib
86- gw = gwibber.lib.GwibberPublic()
87- uploader = gw.getbus("Uploader")
88- img = uploader.Upload(args[0])
89- subprocess.call(["/usr/bin/gwibber-poster", "-w", "-m", img])
90- quit()
91-
92-
93-######################################################################
94-# Don't run again if we are already running
95-progname = "gwibber"
96-screen = wnck.screen_get_default()
97-while gtk.events_pending():
98- gtk.main_iteration()
99-for w in screen.get_windows():
100- if w.get_application().get_name() == progname:
101- w.activate(int(time.time()))
102- w.move_to_workspace(screen.get_active_workspace())
103- quit()
104-
105-
106-######################################################################
107-if options.debug:
108- log.logger.setLevel(log.logging.DEBUG)
109-else:
110- log.logger.setLevel(log.logging.INFO)
111-if options.stdout:
112- # define a Handler which writes INFO messages or higher to the sys.stderr
113- console = log.logging.StreamHandler()
114- if options.debug:
115- console.setLevel(log.logging.DEBUG)
116- else:
117- console.setLevel(log.logging.INFO)
118- # set a format which is simpler for console use
119- formatter = log.logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
120- console.setFormatter(formatter)
121- log.logger.addHandler(console)
122-
123-client.Client()
124-gtk.main()
125
126=== modified file 'bin/gwibber-accounts'
127--- bin/gwibber-accounts 2012-02-11 05:17:00 +0000
128+++ bin/gwibber-accounts 2012-02-14 21:35:21 +0000
129@@ -21,7 +21,6 @@
130
131 import sys
132 from os.path import join, dirname, exists, realpath, abspath
133-import gtk, gobject, wnck
134 from dbus.mainloop.glib import DBusGMainLoop
135 import gettext
136 from gettext import lgettext as _
137@@ -29,12 +28,15 @@
138 gettext.bind_textdomain_codeset('gwibber','UTF-8')
139 gettext.textdomain('gwibber')
140
141+from gi.repository import Gtk, Wnck
142+
143+
144 ######################################################################
145 # Don't run again if we are already running
146 progname = "gwibber-accounts"
147-screen = wnck.screen_get_default()
148-while gtk.events_pending():
149- gtk.main_iteration()
150+screen = Wnck.Screen.get_default()
151+while Gtk.events_pending():
152+ Gtk.main_iteration()
153 for w in screen.get_windows():
154 if w.get_application().get_name() == progname:
155 import time
156@@ -112,4 +114,4 @@
157
158 DBusGMainLoop(set_as_default=True)
159 accounts.GwibberAccountManager(selected_account=selected_account, condition=condition, message=message)
160-gtk.main()
161+Gtk.main()
162
163=== removed file 'bin/gwibber-error'
164--- bin/gwibber-error 2012-02-11 05:17:00 +0000
165+++ bin/gwibber-error 1970-01-01 00:00:00 +0000
166@@ -1,97 +0,0 @@
167-#!/usr/bin/env python
168-#
169-# Copyright (C) 2010 Canonical Ltd
170-#
171-# This program is free software: you can redistribute it and/or modify
172-# it under the terms of the GNU General Public License version 2 as
173-# published by the Free Software Foundation.
174-#
175-# This program is distributed in the hope that it will be useful,
176-# but WITHOUT ANY WARRANTY; without even the implied warranty of
177-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
178-# GNU General Public License for more details.
179-#
180-# You should have received a copy of the GNU General Public License
181-# along with this program. If not, see <http://www.gnu.org/licenses/>.
182-#
183-# Copyright (C) 2010 Ken VanDine <ken.vandine@canonical.com>
184-#
185-# Launch script for Gwibber Error
186-#
187-
188-import sys
189-from os.path import join, dirname, exists, realpath, abspath
190-import optparse
191-import gtk, wnck
192-
193-######################################################################
194-# Don't run again if we are already running
195-progname = "gwibber-error"
196-screen = wnck.screen_get_default()
197-while gtk.events_pending():
198- gtk.main_iteration()
199-for w in screen.get_windows():
200- if w.get_application().get_name() == progname:
201- import time
202- w.move_to_workspace(screen.get_active_workspace())
203- w.activate(int(time.time()))
204- print int(time.time())
205- quit()
206-
207-
208-######################################################################
209-# Setup path
210-LAUNCH_DIR = abspath(sys.path[0])
211-SOURCE_DIR = join(LAUNCH_DIR, "..", "gwibber")
212-
213-
214-######################################################################
215-# Options
216-from optparse import OptionParser
217-parser = OptionParser()
218-parser.add_option("-m", action="store",
219- dest="message", default=None,
220- help="Error message")
221-parser.add_option("-t", action="store",
222- dest="title", default=None,
223- help="Error title")
224-parser.add_option("-c", action="store",
225- dest="condition", default=None,
226- help="Error condition")
227-parser.add_option("-s", action="store",
228- dest="service", default=None,
229- help="Error service")
230-parser.add_option("-u", action="store",
231- dest="username", default=None,
232- help="Error username")
233-parser.add_option("-e", action="store",
234- dest="type", default=None,
235- help="Error message")
236-(options, args) = parser.parse_args()
237-
238-######################################################################
239-
240-# If we were invoked from a Gwibber source directory add that as the
241-# preferred module path ...
242-if exists(join(SOURCE_DIR, "error.py")):
243- sys.path.insert(0, realpath(dirname(SOURCE_DIR)))
244- try:
245- from gwibber.microblog.util.log import setup_logging
246- setup_logging(False, False)
247- import logging
248- logger = logging.getLogger("Error")
249- logger.info("Running from the source tree")
250- from gwibber import error
251- finally:
252- del sys.path[0]
253-else:
254- from gwibber.microblog.util.log import setup_logging
255- setup_logging(False, False)
256- import logging
257- logger = logging.getLogger("Error")
258- logger.info("Running from the system path")
259- from gwibber import error
260-
261-
262-dlg = error.GwibberErrorService()
263-dlg.ShowDialog(options.message, options.title, options.condition, options.service, options.username, options.type)
264
265=== removed file 'bin/gwibber-preferences'
266--- bin/gwibber-preferences 2010-03-12 16:41:56 +0000
267+++ bin/gwibber-preferences 1970-01-01 00:00:00 +0000
268@@ -1,65 +0,0 @@
269-#!/usr/bin/env python
270-#
271-# Copyright (C) 2010 Canonical Ltd
272-#
273-# This program is free software: you can redistribute it and/or modify
274-# it under the terms of the GNU General Public License version 2 as
275-# published by the Free Software Foundation.
276-#
277-# This program is distributed in the hope that it will be useful,
278-# but WITHOUT ANY WARRANTY; without even the implied warranty of
279-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
280-# GNU General Public License for more details.
281-#
282-# You should have received a copy of the GNU General Public License
283-# along with this program. If not, see <http://www.gnu.org/licenses/>.
284-#
285-# Copyright (C) 2010 Ken VanDine <ken.vandine@canonical.com>
286-#
287-# Launch script for Gwibber Preferences
288-#
289-
290-
291-import sys
292-from os.path import join, dirname, exists, realpath, abspath
293-import gtk, gobject, wnck
294-
295-
296-######################################################################
297-# Don't run again if we are already running
298-progname = "gwibber-preferences"
299-screen = wnck.screen_get_default()
300-while gtk.events_pending():
301- gtk.main_iteration()
302-for w in screen.get_windows():
303- if w.get_application().get_name() == progname:
304- import time
305- w.activate(int(time.time()))
306- w.move_to_workspace(screen.get_active_workspace())
307- quit()
308-
309-######################################################################
310-# Setup path
311-
312-LAUNCH_DIR = abspath(sys.path[0])
313-source_tree_gwibber = join(LAUNCH_DIR, "..", "gwibber")
314-
315-# If we were invoked from a Gwibber source directory add that as the
316-# preferred module path ...
317-if exists(join(source_tree_gwibber, "client.py")):
318- sys.path.insert(0, realpath(dirname(source_tree_gwibber)))
319- try:
320- from gwibber.microblog.util import log
321- log.logger.name = "Gwibber Preferences"
322- log.logger.info("Running from the source tree")
323- from gwibber import preferences
324- finally:
325- del sys.path[0]
326-else:
327- from gwibber.microblog.util import log
328- log.logger.name = "Gwibber Preferences"
329- log.logger.info("Running from the system path")
330- from gwibber import preferences
331-
332-preferences.GwibberPreferences()
333-gtk.main()
334
335=== modified file 'bin/gwibber-service'
336--- bin/gwibber-service 2012-02-10 10:06:59 +0000
337+++ bin/gwibber-service 2012-02-14 21:35:21 +0000
338@@ -1,12 +1,12 @@
339 #!/usr/bin/python
340
341-from gi.repository import Gio
342-import sys, gobject, dbus
343+from gi.repository import Gio, GLib
344+import sys, optparse, dbus
345 from os.path import join, dirname, exists, realpath, abspath
346 from dbus.mainloop.glib import DBusGMainLoop
347
348 DBusGMainLoop(set_as_default=True)
349-loop = gobject.MainLoop()
350+loop = GLib.MainLoop()
351
352 LAUNCH_DIR = abspath(sys.path[0])
353 SOURCE_DIR = join(LAUNCH_DIR, "..", "gwibber")
354
355=== modified file 'gwibber/accounts.py'
356--- gwibber/accounts.py 2012-01-13 11:26:51 +0000
357+++ gwibber/accounts.py 2012-02-14 21:35:21 +0000
358@@ -18,10 +18,7 @@
359 # Accounts interface for Gwibber
360 #
361
362-try:
363- import gnomekeyring
364-except:
365- gnomekeyring = None
366+from gi.repository import Gdk, GdkPixbuf, Gtk, Pango
367
368 import gettext
369 from gettext import lgettext as _
370@@ -29,14 +26,15 @@
371 gettext.bind_textdomain_codeset('gwibber','UTF-8')
372 gettext.textdomain('gwibber')
373
374-import gtk, pango, os, json, uuid
375+import os, json, uuid
376 from gwibber.lib import GwibberPublic
377-import util
378-from microblog.util import resources
379+from gwibber.util import get_service_icon
380+from gwibber.microblog.util import keyring, resources
381
382 for p in resources.get_plugin_dirs()[0]:
383 print "Loading plugin for %s" % p
384- globals()[p] = __import__("%s.gtk.%s" % (p,p), fromlist='*')
385+ globals()[p] = __import__("gwibber.microblog.plugins.%s.gtk.%s" % (p,p),
386+ globals, locals, [""])
387
388 from dbus.mainloop.glib import DBusGMainLoop
389 DBusGMainLoop(set_as_default=True)
390@@ -53,19 +51,19 @@
391 self.message = message
392 self.gwibber = GwibberPublic()
393 self.services = json.loads(self.gwibber.GetServices())
394- self.ui = gtk.Builder()
395+ self.ui = Gtk.Builder()
396 self.ui.set_translation_domain("gwibber")
397 self.ui.add_from_file(resources.get_ui_asset("gwibber-accounts-dialog.ui"))
398 self.ui.connect_signals(self)
399
400- dialog = self.ui.get_object("accounts_dialog")
401- dialog.resize(640,400)
402- dialog.set_icon_name("gwibber")
403- dialog.set_wmclass("gwibber", "Gwibber")
404- dialog.show_all()
405- if hasattr(gtk, "InfoBar"):
406+ self.dialog = self.ui.get_object("accounts_dialog")
407+ self.dialog.resize(640,400)
408+ self.dialog.set_icon_name("gwibber")
409+ self.dialog.set_wmclass("gwibber", "Gwibber")
410+ self.dialog.show_all()
411+ if hasattr(Gtk, "InfoBar"):
412 self.alignment_infobar = self.ui.get_object("alignment_infobar")
413- self.infobar = gtk.InfoBar()
414+ self.infobar = Gtk.InfoBar()
415 self.alignment_infobar.add(self.infobar)
416 self.infobar.hide()
417
418@@ -80,11 +78,10 @@
419
420 self.setup_account_tree()
421 self.populate_account_tree()
422- self.select_account()
423
424 def setup_account_tree(self):
425 # Protocol title, Icon, Protocol Properties
426- self.service_store = gtk.ListStore(str, gtk.gdk.Pixbuf, str)
427+ self.service_store = Gtk.ListStore(str, GdkPixbuf.Pixbuf, str)
428 for name, props in self.services.items():
429 icon = self.get_icon(name)
430 if icon:
431@@ -93,8 +90,8 @@
432 service_combo = self.ui.get_object("protocol_combobox")
433 service_combo.set_model(self.service_store)
434
435- celltxt = gtk.CellRendererText()
436- cellimg = gtk.CellRendererPixbuf()
437+ celltxt = Gtk.CellRendererText()
438+ cellimg = Gtk.CellRendererPixbuf()
439
440 service_combo.pack_start(cellimg, False)
441 service_combo.pack_start(celltxt, False)
442@@ -103,13 +100,13 @@
443 service_combo.set_active(0)
444
445 # Store: Account name, Icon, Protocol properties, Color
446- self.account_store = gtk.TreeStore(str, gtk.gdk.Pixbuf, object, str)
447-
448- icon_column = gtk.TreeViewColumn('Icon')
449- name_column = gtk.TreeViewColumn('Account')
450-
451- celltxt = gtk.CellRendererText()
452- cellimg = gtk.CellRendererPixbuf()
453+ self.account_store = Gtk.TreeStore(str, GdkPixbuf.Pixbuf, object, str)
454+
455+ icon_column = Gtk.TreeViewColumn('Icon')
456+ name_column = Gtk.TreeViewColumn('Account')
457+
458+ celltxt = Gtk.CellRendererText()
459+ cellimg = Gtk.CellRendererPixbuf()
460
461 icon_column.pack_start(cellimg, False)
462 icon_column.add_attribute(cellimg, 'pixbuf', 1)
463@@ -125,40 +122,27 @@
464 self.account_tree.set_model(self.account_store)
465
466 def select_account(self):
467+ column = self.account_tree.get_column(0)
468 if not self.selected_account:
469 if len(self.account_store):
470- self.account_tree.set_cursor(0)
471+ self.account_tree.set_cursor(Gtk.TreePath.new_from_string('0'),
472+ column, False)
473 else: self.add_account()
474 else:
475 for i in self.account_store:
476 if i[2]["id"] == self.selected_account:
477- self.account_tree.set_cursor(i.path)
478- #self.selected_account = None
479+ self.account_tree.set_cursor(i.path, column, False)
480+ self.selected_account = None
481
482
483 def get_icon(self, name):
484- icf = util.get_service_icon(name)
485+ icf = get_service_icon(name)
486 if icf:
487 if os.path.exists(icf):
488- return gtk.gdk.pixbuf_new_from_file(icf)
489+ return GdkPixbuf.Pixbuf.new_from_file(icf)
490 #return gtk.gdk.pixbuf_new_from_file(resources.get_ui_asset("gwibber.png"))
491 return None
492
493- def get_from_keyring(self, acctid, name):
494- item = {"id": str("%s/%s" % (acctid, name))}
495- try:
496- return gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET, item)[0].secret
497- except gnomekeyring.NoMatchError:
498- return None
499-
500- def put_in_keyring(self, acctid, name, value):
501- id = "%s/%s" % (acctid, name)
502- return gnomekeyring.item_create_sync(
503- gnomekeyring.get_default_keyring_sync(),
504- gnomekeyring.ITEM_GENERIC_SECRET,
505- "Gwibber preference: %s" % id,
506- {"id": str(id)}, str(value), True)
507-
508 def populate_account_tree(self):
509 self.account_store.clear()
510 accounts = json.loads(self.gwibber.GetAccounts())
511@@ -174,12 +158,13 @@
512 for f in private_fields:
513 if not account.has_key(f): account[f] = ":KEYRING:MISSING"
514 if account[f].startswith(":KEYRING:"):
515- value = self.get_from_keyring(account["id"], f)
516+ value = keyring.get_from_keyring(account["id"], f)
517 if value is None:
518 color = "pink"
519 self.account_store.append(None, [name, icon, account, color])
520 except:
521 pass
522+ self.select_account()
523
524 def verify_account(self, account):
525 for field in self.services[account["service"]]["config"]:
526@@ -205,24 +190,22 @@
527 pass
528 else:
529 if "id" in self.account:
530+ print self.account['id']
531 try:
532 private_fields = [f.split(":")[-1] for f in self.services[self.account["service"]]["config"] if ":" in f]
533 for f in private_fields:
534 if self.account[f].startswith(":KEYRING:"):
535 keyring_id = int(self.account[f].split(":")[-1])
536- gnomekeyring.item_delete_sync(gnomekeyring.get_default_keyring_sync(), keyring_id)
537+ keyring.del_from_keyring(keyring_id)
538 except:
539 pass
540 self.gwibber.accounts.Delete(self.account["id"])
541 self.populate_account_tree()
542- self.select_account()
543
544 def on_edit_account_save(self, widget=None):
545- print "Saving..."
546-
547 service = self.services[self.account["service"]]
548 is_new = "id" not in self.account
549-
550+
551 if is_new: self.account["id"] = uuid.uuid1().hex
552
553 for config in service["config"]:
554@@ -230,7 +213,6 @@
555 config = config.replace("private:", "")
556 widget = self.account_widget.ui.get_object(config)
557
558-
559 value = None
560
561 for p in ["text", "active"]:
562@@ -238,20 +220,18 @@
563 value = getattr(widget.props, p)
564 self.account[config] = value
565
566- if widget and isinstance(widget, gtk.ColorButton):
567- value = widget.get_color ()
568- self.account[config] = value
569+ if widget and isinstance(widget, Gtk.ColorButton):
570+ value = widget.get_color()
571+ self.account[config] = value.to_string()
572
573 if is_private and self.account.has_key(config):
574 if not self.account[config].startswith(":KEYRING:"):
575- self.account[config] = ":KEYRING:%s" % self.put_in_keyring(
576+ self.account[config] = ":KEYRING:%s" % keyring.put_in_keyring(
577 self.account["id"], config, self.account[config])
578
579 if value:
580- if isinstance(value, gtk.gdk.Color):
581- value = gtk.color_selection_palette_to_string(
582- gtk.color_selection_palette_from_string(value.to_string()))
583- self.account[config] = value
584+ if isinstance(value, Gdk.Color):
585+ self.account[config] = value.to_string()
586
587 if not self.verify_account(self.account): return False
588
589@@ -263,7 +243,7 @@
590
591 # if we just fixed a failure case, hide the infobar
592 if self.account["id"] == self.selected_account:
593- if hasattr(gtk, "InfoBar"):
594+ if hasattr(Gtk, "InfoBar"):
595 self.infobar.hide()
596 self.selected_account = None
597
598@@ -299,18 +279,18 @@
599 self.account_show(service, icon)
600
601 def account_show(self, service_id, icon=None, account=None, condition=None, message=None):
602- if hasattr(gtk, "InfoBar"):
603+ if hasattr(Gtk, "InfoBar"):
604 if condition == "error":
605- self.infobar.set_message_type(gtk.MESSAGE_ERROR)
606+ self.infobar.set_message_type(Gtk.MessageType.ERROR)
607 if condition == "info":
608- self.infobar.set_message_type(gtk.MESSAGE_INFO)
609+ self.infobar.set_message_type(Gtk.MessageType.INFO)
610 if message and condition:
611 if hasattr(self, "infobar_content_area"):
612 for child in self.infobar_content_area.get_children(): child.destroy()
613 self.infobar_content_area = self.infobar.get_content_area()
614- message_label = gtk.Label(message)
615+ message_label = Gtk.Label(message)
616 message_label.set_use_markup(True)
617- message_label.set_ellipsize(pango.ELLIPSIZE_END)
618+ message_label.set_ellipsize(Pango.EllipsizeMode.END)
619 self.infobar_content_area.add(message_label)
620 self.infobar.show_all()
621 else:
622@@ -338,7 +318,7 @@
623
624 aw = globals()[service_id].AccountWidget(account, self)
625
626- vbox_account.pack_start(aw, False, False)
627+ vbox_account.pack_start(aw, False, False, 0)
628 vbox_account.show()
629
630 if "color" not in account:
631@@ -352,21 +332,22 @@
632 value = account[config]
633 widget = aw.ui.get_object(config)
634
635- if isinstance(widget, gtk.Entry):
636+ if isinstance(widget, Gtk.Entry):
637 if is_private and account[config].startswith(":KEYRING:"):
638- value = self.get_from_keyring(account["id"], config)
639+ value = keyring.get_from_keyring(account["id"], config)
640 if not value:
641- widget.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("pink"))
642+ widget.modify_base(Gtk.StateType.NORMAL, Gdk.Color.parse("pink")[1])
643 if value:
644 widget.set_text(value)
645 widget.connect("changed", self.on_edit_account)
646
647- elif isinstance(widget, gtk.CheckButton):
648+ elif isinstance(widget, Gtk.CheckButton):
649 widget.set_active(value)
650 widget.connect("toggled", self.on_edit_account)
651
652- elif isinstance(widget, gtk.ColorButton):
653- widget.set_color(gtk.color_selection_palette_from_string(value)[0])
654+ elif isinstance(widget, Gtk.ColorButton):
655+ parsed, color = Gdk.Color.parse(value)
656+ widget.set_color(color)
657 widget.connect("color-set", self.on_edit_account)
658
659 self.account = account
660@@ -375,16 +356,19 @@
661 self.ui.get_object('vbox_create').hide()
662
663 def on_accounts_dialog_destroy(self, widget, data=None):
664- gtk.main_quit()
665+ Gtk.main_quit()
666
667 def on_accounts_tree_row_activated(self, widget, data=None):
668 self.ui.get_object('vbox_save').hide()
669 self.ui.get_object('vbox_create').hide()
670-
671- model, rows = widget.get_selection().get_selected_rows()
672-
673- if rows:
674- iter = model.get_iter(rows[0][0])
675+
676+ selection = widget.get_selection()
677+ rows, model = (None, None)
678+ if selection:
679+ model, rows = selection.get_selected_rows()
680+
681+ if rows and model:
682+ iter = model.get_iter(rows[0])
683 icon = model.get_value(iter, 1)
684 acct = model.get_value(iter, 2)
685 if self.selected_account == acct["id"] and self.condition:
686@@ -393,4 +377,4 @@
687 self.account_show(acct["service"], icon, acct)
688
689 def on_button_close_clicked(self, widget, data=None):
690- gtk.main_quit()
691+ Gtk.main_quit()
692
693=== removed file 'gwibber/actions.py'
694--- gwibber/actions.py 2011-04-13 18:34:14 +0000
695+++ gwibber/actions.py 1970-01-01 00:00:00 +0000
696@@ -1,266 +0,0 @@
697-import gtk, gwui, microblog, util, json
698-from microblog.util.const import *
699-# Try to import * from custom, install custom.py to include packaging
700-# customizations like distro API keys, etc
701-try:
702- from microblog.util.custom import *
703-except:
704- pass
705-
706-import gwibber.microblog.util
707-from gwibber.microblog.util import resources
708-import mx.DateTime
709-import re
710-
711-from gettext import lgettext as _
712-
713-class MessageAction:
714- icon = None
715- label = None
716-
717- @classmethod
718- def get_icon_path(self, size=16, use_theme=True):
719- return util.icon(self.icon, size, use_theme)
720-
721- @classmethod
722- def include(self, client, msg):
723- if not client.model.services.has_key(msg["service"]):
724- return False
725- return self.__name__ in client.model.services[msg["service"]]["features"]
726-
727- @classmethod
728- def action(self, w, client, msg):
729- pass
730-
731-class reply(MessageAction):
732- icon = "mail-reply-sender"
733- label = _("_Reply")
734-
735- @classmethod
736- def action(self, w, client, msg):
737- if msg.get("private", 0):
738- client.private(msg)
739- else:
740- client.reply(msg)
741-
742- @classmethod
743- def include(self, client, msg):
744- if not client.model.services.has_key(msg["service"]):
745- return False
746- if "reply" in client.model.services[msg["service"]]["features"]:
747- if not msg.get("sender", {}).get("is_me", 0):
748- return True
749-
750-class thread(MessageAction):
751- icon = "mail-reply-all"
752- label = _("View reply t_hread")
753-
754- @classmethod
755- def action(self, w, client, msg):
756- tab_label = msg["original_title"] if msg.has_key("original_title") else msg["text"]
757- client.add_transient_stream(msg.account, "thread",
758- "message:/" + msg.gwibber_path, "Thread")
759-
760-class retweet(MessageAction):
761- icon = "mail-forward"
762- label = _("R_etweet")
763- PARSE_GROUP = re.compile("\B!([A-Za-z0-9_\-]+|@[A-Za-z0-9_\-]$)")
764-
765- @classmethod
766- def action(self, w, client, msg):
767- if "retweet" in client.model.services[msg["service"]]["features"]:
768- text = RETWEET_FORMATS[client.model.settings["retweet_style"]]
769- symbol = "RD" if msg["service"] == "identica" else "RT"
770- text = text.format(text=msg["text"], nick=msg["sender"]["nick"], R=symbol)
771- #replace ! with # if identica service
772- if msg["service"] == "identica" and client.model.settings["global_retweet"]:
773- text = self.PARSE_GROUP.sub('#\\1', text)
774-
775- if not client.model.settings["global_retweet"]:
776- client.message_target.set_target(msg, "repost")
777-
778- client.input.set_text(text)
779- client.input.textview.grab_focus()
780- buf = client.input.textview.get_buffer()
781- buf.place_cursor(buf.get_end_iter())
782-
783- @classmethod
784- def include(self, client, msg):
785- if not client.model.services.has_key(msg["service"]):
786- return False
787-
788- if "retweet" in client.model.services[msg["service"]]["features"]:
789- if not msg.get("sender", {}).get("is_me", 0) and not msg.get("private", 0):
790- return True
791-
792-class private(MessageAction):
793- icon = "mail-reply-sender"
794- label = _("_Direct Message")
795-
796- @classmethod
797- def action(self, w, client, msg):
798- client.private(msg)
799-
800- @classmethod
801- def include(self, client, msg):
802- if not client.model.services.has_key(msg["service"]):
803- return False
804- if "private" in client.model.services[msg["service"]]["features"]:
805- if not msg.get("sender", {}).get("is_me", 0) and not msg.get("private", 0):
806- return True
807-
808-class like(MessageAction):
809- icon = "bookmark_add"
810- label = _("_Like this message")
811-
812- @classmethod
813- def action(self, w, client, msg):
814- client.service.PerformOp(json.dumps({
815- "account": msg["account"],
816- "operation": "like",
817- "args": {"message": msg},
818- "transient": False,
819- }))
820-
821- image = resources.get_ui_asset("gwibber.svg")
822- expire_timeout = 5000
823- n = gwibber.microblog.util.notify(_("Liked"), _("You have marked this message as liked."), image, expire_timeout)
824-
825- @classmethod
826- def include(self, client, msg):
827- if not client.model.services.has_key(msg["service"]):
828- return False
829- if "like" in client.model.services[msg["service"]]["features"]:
830- if not msg.get("sender", {}).get("is_me", 0) and not msg.get("private", 0):
831- return True
832-
833-class delete(MessageAction):
834- icon = "gtk-delete"
835- label = _("_Delete this message")
836-
837- @classmethod
838- def action(self, w, client, msg):
839- client.service.PerformOp(json.dumps({
840- "account": msg["account"],
841- "operation": "delete",
842- "args": {"message": msg},
843- "transient": False,
844- }))
845-
846- image = resources.get_ui_asset("gwibber.svg")
847- expire_timeout = 5000
848- n = gwibber.microblog.util.notify(_("Deleted"), _("The message has been deleted."), image, expire_timeout)
849-
850- @classmethod
851- def include(self, client, msg):
852- if not client.model.services.has_key(msg["service"]):
853- return False
854- if "delete" in client.model.services[msg["service"]]["features"]:
855- if msg.get("sender", {}).get("is_me", 0):
856- return True
857-
858-class search(MessageAction):
859- icon = "gtk-find"
860- label = _("_Search for a query")
861-
862- @classmethod
863- def action(self, w, client, query=None):
864- pass
865-
866-class read(MessageAction):
867- icon = "mail-read"
868- label = _("View _Message")
869-
870- @classmethod
871- def action(self, w, client, msg):
872- if msg.has_key("url"):
873- util.load_url(msg["url"])
874- elif msg.has_key("images"):
875- util.load_url(msg["images"][0]["url"])
876-
877- @classmethod
878- def include(self, client, msg):
879- if not msg.get("private", 0):
880- return "url" in msg
881-
882-class list(MessageAction):
883- @classmethod
884- def action(self, w, client, acct=None, user=None, id=None, name=None):
885- if acct and user and id and name:
886- client.add_stream({
887- "name": name,
888- "account": acct,
889- "operation": "list",
890- "parameters": {"user": user, "id": id},
891- })
892-
893-class user(MessageAction):
894- icon = "face-monkey"
895- label = _("View user _Profile")
896-
897- @classmethod
898- def action(self, w, client, acct=None, name=None):
899- client.add_stream({
900- "name": name,
901- "account": acct,
902- "operation": "user_messages",
903- "parameters": {"id": name, "count": 50},
904- })
905-
906-class menu(MessageAction):
907- @classmethod
908- def action(self, w, client, msg):
909- client.on_message_action_menu(msg, w)
910-
911-class tag(MessageAction):
912- @classmethod
913- def action(self, w, client, acct, query):
914- client.add_stream({
915- "name": "#%s" % query,
916- "query": "#%s" % query,
917- })
918-
919-class translate(MessageAction):
920- icon = "config-language"
921- label = _("Tra_nslate")
922-
923- @classmethod
924- def action(self, w, client, msg):
925- ## Need to figure out the user's language instead of default to EN
926- script = """document.getElementById("text-%s").innerHTML = %s"""
927- text = gwibber.microblog.util.getbus("Translate").Translate(msg["text"], "", "en")
928- if isinstance(w.messages.message_view, gwui.WebUi):
929- w.messages.message_view.execute_script(script % (msg["id"], json.dumps(text)))
930-
931- @classmethod
932- def include(self, client, msg):
933- return True
934-
935-class group(MessageAction):
936- icon = "face-monkey"
937-
938- @classmethod
939- def action(self, w, client, acct, query):
940- client.add_transient_stream(acct, "group", query)
941- print "Searching for group", query
942-
943-class tomboy(MessageAction):
944- icon = "tomboy"
945- label = _("Save to _Tomboy")
946-
947- @classmethod
948- def action(self, w, client, msg):
949- util.create_tomboy_note(
950- _("%(service_name)s message from %(sender)s at %(time)s\n\n%(message)s\n\nSource: %(url)s") % {
951- "service_name": client.model.services[msg["service"]]["name"],
952- "sender": msg["sender"]["name"],
953- "time": mx.DateTime.DateTimeFromTicks(msg["time"]).localtime().strftime(),
954- "message": msg["text"],
955- "url": msg["url"]
956- })
957-
958- @classmethod
959- def include(self, client, msg):
960- return gwibber.microblog.util.service_is_running("org.gnome.Tomboy")
961-
962-MENU_ITEMS = [reply, retweet, private, read, user, like, delete, tomboy, translate]
963
964=== removed file 'gwibber/client.py'
965--- gwibber/client.py 2012-02-10 10:06:59 +0000
966+++ gwibber/client.py 1970-01-01 00:00:00 +0000
967@@ -1,735 +0,0 @@
968-#!/usr/bin/env python
969-
970-import gtk, gobject, gwui, util, actions, json, gconf
971-import subprocess, os, time, datetime
972-from microblog import config
973-import microblog.util
974-from microblog.util import resources
975-
976-import logging
977-logger = logging.getLogger("Client")
978-
979-import gettext
980-from gettext import lgettext as _
981-if hasattr(gettext, 'bind_textdomain_codeset'):
982- gettext.bind_textdomain_codeset('gwibber','UTF-8')
983-gettext.textdomain('gwibber')
984-
985-from microblog.util.const import *
986-# Try to import * from custom, install custom.py to include packaging
987-# customizations like distro API keys, etc
988-try:
989- from microblog.util.custom import *
990-except:
991- pass
992-
993-try:
994- import appindicator
995-except:
996- appindicator = None
997-
998-from dbus.mainloop.glib import DBusGMainLoop
999-import dbus, dbus.service
1000-
1001-DBusGMainLoop(set_as_default=True)
1002-
1003-class GwibberClient(gtk.Window):
1004- def __init__(self):
1005- gtk.Window.__init__(self)
1006- self.ui = gtk.Builder()
1007- self.ui.set_translation_domain ("gwibber")
1008-
1009- self.connection = microblog.util.getbus("Connection")
1010- self.connection.connect_to_signal("ConnectionOnline", self.on_connection_online)
1011- self.connection.connect_to_signal("ConnectionOffline", self.on_connection_offline)
1012-
1013- self.model = gwui.Model()
1014-
1015- self.service = self.model.daemon
1016- self.messages = self.model.messages
1017- self.service.connect_to_signal("LoadingStarted", self.on_loading_started)
1018- self.service.connect_to_signal("LoadingComplete", self.on_loading_complete)
1019- self.service.connect_to_signal("IndicatorInterestAdded", self.on_indicator_interest_added)
1020- self.service.connect_to_signal("IndicatorInterestRemoved", self.on_indicator_interest_removed)
1021-
1022- self.messages.connect_to_signal("Message", self.on_new_message)
1023-
1024- self.shortener = microblog.util.getbus("URLShorten")
1025- self.uploader = microblog.util.getbus("Uploader")
1026-
1027- self.accounts = microblog.util.getbus("Accounts")
1028- self.quicklist_messages = {}
1029-
1030- first_run = False
1031- # check for existing accounts
1032- if len(json.loads(self.accounts.List())) == 0:
1033- # if there are no accounts configured, prompt the user to add some
1034- first_run = True
1035- if os.path.exists(os.path.join("bin", "gwibber-accounts")):
1036- cmd = os.path.join("bin", "gwibber-accounts")
1037- else:
1038- cmd = "gwibber-accounts"
1039- ret = 1
1040- while ret != 0:
1041- ret = subprocess.call([cmd])
1042-
1043- self.setup_ui()
1044-
1045- if first_run:
1046- # Since we didn't have accounts configured when gwibber-service started
1047- # force it to refresh now that accounts have been added
1048- self.service.Refresh()
1049-
1050- # Migrate the autostart gconf key to the new location
1051- if config.GCONF.get("/apps/gwibber/autostart"):
1052- config.GCONF.set_bool("/apps/gwibber/preferences/autostart", True)
1053- config.GCONF.unset('/apps/gwibber/autostart')
1054-
1055- config.GCONF.add_dir("/desktop/gnome/interface/document_font_name", gconf.CLIENT_PRELOAD_NONE)
1056- config.GCONF.notify_add("/desktop/gnome/interface/document_font_name", self.on_font_changed)
1057- config.GCONF.add_dir("/desktop/gnome/font_rendering", gconf.CLIENT_PRELOAD_NONE)
1058- config.GCONF.notify_add("/desktop/gnome/font_rendering", self.on_font_changed)
1059- config.GCONF.add_dir("/apps/gwibber/preferences", gconf.CLIENT_PRELOAD_NONE)
1060-
1061- for x in ["hide_taskbar_entry", "show_tray_icon"]:
1062- self.model.settings.notify(x, self.on_setting_changed)
1063-
1064- # Only use the notification area icon if there is no interest from the
1065- # messaging menu indicator
1066- if self.service.IndicatorInterestCheck():
1067- self.tray_icon.set_visible(False)
1068- else:
1069- self.tray_icon.set_visible(self.model.settings["show_tray_icon"])
1070-
1071- self.set_property("skip-taskbar-hint", self.model.settings["hide_taskbar_entry"])
1072-
1073-
1074- # set state online/offline
1075- if not self.connection.isConnected():
1076- logger.info("Setting to Offline")
1077- self.actions.get_action("refresh").set_sensitive(False)
1078-
1079- # Delay resizing input area or else it doesn't work
1080- gobject.idle_add(lambda: self.input_splitter.set_position(int(self.model.settings["window_splitter"])))
1081-
1082- # Delay resizing the sidebar area or else it doesn't work
1083- gobject.idle_add(lambda: hasattr(self.stream_view, "splitter") and self.stream_view.splitter.set_position(self.model.settings["sidebar_splitter"]))
1084-
1085- # Apply the user's settings
1086- gobject.idle_add(lambda: self.resize(*self.model.settings["window_size"]))
1087- gobject.idle_add(lambda: self.move(*self.model.settings["window_position"]))
1088-
1089- self.connect("configure-event", self.on_configure_event)
1090-
1091- def on_configure_event(self, *args):
1092- self.save_window_settings()
1093-
1094- def on_new_message(self, change, message):
1095- message = json.loads(message)
1096- if appindicator:
1097- if message["stream"] == "messages":
1098- if not message["sender"]["is_me"]:
1099- if not message["sender"].has_key("name"): return
1100- if self.quicklist_messages.has_key(message["sender"]["name"]):
1101- count = self.quicklist_messages[message["sender"]["name"]]["count"] + 1
1102- msg = "%s (%s)" % (message["sender"]["name"], count)
1103- self.quicklist_messages[message["sender"]["name"]]["count"] = count
1104- self.quicklist_messages[message["sender"]["name"]]["menu"].set_label(msg)
1105- self.quicklist_messages[message["sender"]["name"]]["menu"].show()
1106- else:
1107- msg = "%s" % message["sender"]["name"]
1108- ai_entry = gtk.MenuItem(msg)
1109- ai_entry.connect("activate", lambda *a: self.present_with_time(int(time.mktime(datetime.datetime.now().timetuple()))))
1110- self.quicklist_messages[message["sender"]["name"]] = {"count": 1, "menu": ai_entry}
1111- self.ai_menu.prepend(ai_entry)
1112- ai_entry.show()
1113- while len(self.quicklist_messages) >= 7:
1114- self.quicklist_messages.values()[-1]["menu"].destroy()
1115- self.quicklist_messages.pop(self.quicklist_messages.keys()[-1])
1116-
1117- def on_indicator_interest_added(self):
1118- # Hide the notification area icon if there is interest from the
1119- # messaging menu indicator
1120- self.tray_icon.set_visible(False)
1121-
1122- def on_indicator_interest_removed(self):
1123- # Show the notification area icon if there is no interest from the
1124- # messaging menu indicator
1125- self.tray_icon.set_visible(True)
1126-
1127- def on_setting_changed(self, gc, x, pref, y):
1128- if "show_tray_icon" in pref.key:
1129- self.tray_icon.set_visible(pref.value.get_bool())
1130-
1131- if "hide_taskbar_entry" in pref.key:
1132- self.set_property("skip-taskbar-hint", pref.value.get_bool())
1133-
1134- def on_font_changed(self, *args):
1135- self.update_view()
1136-
1137- def setup_ui(self):
1138- self.set_title(_("Social broadcast messages"))
1139- self.set_icon_from_file(resources.get_ui_asset("gwibber.svg"))
1140- self.connect("delete-event", self.on_window_close)
1141-
1142- # Load the application menu
1143- menu_ui = self.setup_menu()
1144- self.add_accel_group(menu_ui.get_accel_group())
1145-
1146- def on_tray_menu_popup(i, b, a):
1147- menu_ui.get_widget("/menu_tray").popup(None, None,
1148- gtk.status_icon_position_menu, b, a, self.tray_icon)
1149-
1150- self.tray_icon = gtk.status_icon_new_from_file(resources.get_ui_asset("gwibber.svg"))
1151- self.tray_icon.connect("activate", self.on_toggle_window_visibility)
1152- self.tray_icon.connect("popup-menu", on_tray_menu_popup)
1153-
1154- # Create animated loading spinner
1155- self.loading_spinner = gtk.Image()
1156- menu_spin = gtk.ImageMenuItem("")
1157- menu_spin.set_right_justified(True)
1158- menu_spin.set_sensitive(False)
1159- menu_spin.set_image(self.loading_spinner)
1160-
1161- # Force the spinner to show in newer versions of Gtk
1162- if hasattr(menu_spin, "set_always_show_image"):
1163- menu_spin.set_always_show_image(True)
1164-
1165- menubar = menu_ui.get_widget("/menubar_main")
1166- menubar.append(menu_spin)
1167-
1168- # Load the user's saved streams
1169- streams = json.loads(self.model.settings["streams"])
1170- streams = [dict((str(k), v) for k, v in s.items()) for s in streams]
1171-
1172- # Use the multicolumn mode if there are multiple saved streams
1173- view_class = getattr(gwui, "MultiStreamUi" if len(streams) > 1 else "SingleStreamUi")
1174-
1175- self.stream_view = view_class(self.model)
1176- self.stream_view.connect("action", self.on_action)
1177- self.stream_view.connect("search", self.on_perform_search)
1178- self.stream_view.connect("stream-changed", self.on_stream_changed)
1179- self.stream_view.connect("stream-closed", self.on_stream_closed)
1180- if isinstance(self.stream_view, gwui.MultiStreamUi):
1181- self.stream_view.connect("pane-closed", self.on_pane_closed)
1182-
1183- self.input = gwui.Input()
1184- self.input.connect("submit", self.on_input_activate)
1185- self.input.connect("changed", self.on_input_changed)
1186- self.input.connect("clear", self.on_input_cleared)
1187-
1188- self.input_splitter = gtk.VPaned()
1189- self.input_splitter.pack1(self.stream_view, resize=True)
1190- self.input_splitter.pack2(self.input, resize=False)
1191-
1192- self.input_splitter.set_focus_child(self.input)
1193-
1194- self.attach_image = gtk.Image()
1195- self.attach_image.set_from_stock(gtk.STOCK_ADD, gtk.ICON_SIZE_BUTTON)
1196-
1197- self.button_attach = gtk.Button()
1198- self.button_attach.set_image(self.attach_image)
1199- self.button_attach.set_tooltip_text(_("Upload image"))
1200- self.button_attach.connect("clicked", self.on_button_attach_clicked)
1201-
1202- self.button_send = gtk.Button(_("Send"))
1203- self.button_send.set_tooltip_text(_("Post to all enabled services"))
1204- self.button_send.connect("clicked", self.on_button_send_clicked)
1205-
1206- self.message_target = gwui.AccountTargetBar(self.model)
1207- self.message_target.pack_end(self.button_send, False)
1208- self.message_target.pack_end(self.button_attach, False)
1209- self.message_target.connect("canceled", self.on_reply_cancel)
1210-
1211- content = gtk.VBox(spacing=5)
1212- content.pack_start(self.input_splitter, True)
1213- content.pack_start(self.message_target, False)
1214- content.set_border_width(5)
1215-
1216- layout = gtk.VBox()
1217- layout.pack_start(menubar, False)
1218- layout.pack_start(content, True)
1219-
1220- self.add(layout)
1221-
1222- # Apply the user's settings
1223- self.resize(*self.model.settings["window_size"])
1224- self.move(*self.model.settings["window_position"])
1225- self.input_splitter.set_position(self.model.settings["window_splitter"])
1226-
1227- if hasattr(self.stream_view, "splitter"):
1228- self.stream_view.splitter.set_position(
1229- self.model.settings["sidebar_splitter"])
1230-
1231- self.show_all()
1232-
1233- self.stream_view.set_state(streams)
1234- self.update_menu_availability()
1235- for stream in streams:
1236- if stream["stream"]:
1237- gobject.idle_add(lambda: self.service.UpdateIndicators(stream["stream"]))
1238-
1239-
1240- def on_toggle_window_visibility(self, w):
1241- if self.get_property("visible"):
1242- self.last_position = self.get_position()
1243- self.hide()
1244- else:
1245- self.present()
1246- self.move(*self.last_position)
1247-
1248- def set_view(self, view=None):
1249- state = None
1250- if view: self.view_class = getattr(gwui, view)
1251- if self.stream_view:
1252- state = self.stream_view.get_state()
1253- self.stream_view.destroy()
1254-
1255- self.stream_view = self.view_class(self.model)
1256- self.stream_view.connect("action", self.on_action)
1257- self.stream_view.connect("search", self.on_perform_search)
1258- self.stream_view.connect("stream-changed", self.on_stream_changed)
1259- self.stream_view.connect("stream-closed", self.on_stream_closed)
1260-
1261- if isinstance(self.stream_view, gwui.MultiStreamUi):
1262- self.stream_view.connect("pane-closed", self.on_pane_closed)
1263-
1264- self.input_splitter.add1(self.stream_view)
1265- self.stream_view.show_all()
1266- if state: self.stream_view.set_state(state)
1267-
1268- def setup_menu(self):
1269- ui_string = """
1270- <ui>
1271- <menubar name="menubar_main">
1272- <menu action="menu_gwibber">
1273- <menuitem action="refresh" />
1274- <menuitem action="search" />
1275- <separator/>
1276- <menuitem action="new_stream" />
1277- <menuitem action="close_window" />
1278- <menuitem action="close_stream" />
1279- <separator/>
1280- <menuitem action="quit" />
1281- </menu>
1282-
1283- <menu action="menu_edit">
1284- <menuitem action="accounts" />
1285- <menuitem action="preferences" />
1286- </menu>
1287-
1288- <menu action="menu_help">
1289- <menuitem action="help_online" />
1290- <menuitem action="help_translate" />
1291- <menuitem action="help_report" />
1292- <separator/>
1293- <menuitem action="about" />
1294- </menu>
1295- </menubar>
1296-
1297- <popup name="menu_tray">
1298- <menuitem action="refresh" />
1299- <separator />
1300- <menuitem action="accounts" />
1301- <menuitem action="preferences" />
1302- <separator />
1303- <menuitem action="quit" />
1304- </popup>
1305- </ui>
1306- """
1307-
1308- self.actions = gtk.ActionGroup("Actions")
1309- self.actions.add_actions([
1310- ("menu_gwibber", None, _("_Gwibber")),
1311- ("menu_edit", None, _("_Edit")),
1312- ("menu_help", None, _("_Help")),
1313-
1314- ("refresh", gtk.STOCK_REFRESH, _("_Refresh"), "F5", None, self.on_refresh),
1315- ("search", gtk.STOCK_FIND, _("_Search"), "<ctrl>F", None, self.on_search),
1316- ("accounts", None, _("_Accounts"), "<ctrl><shift>A", None, self.on_accounts),
1317- ("preferences", gtk.STOCK_PREFERENCES, _("_Preferences"), "<ctrl>P", None, self.on_preferences),
1318- ("about", gtk.STOCK_ABOUT, _("_About"), None, None, self.on_about),
1319- ("quit", gtk.STOCK_QUIT, _("_Quit"), "<ctrl>Q", None, self.on_quit),
1320-
1321- ("new_stream", gtk.STOCK_NEW, _("_New Stream"), "<ctrl>n", None, self.on_new_stream),
1322- ("close_window", gtk.STOCK_CLOSE, _("_Close Window"), "<ctrl><shift>W", None, self.on_window_close),
1323- ("close_stream", gtk.STOCK_CLOSE, _("_Close Stream"), "<ctrl>W", None, self.on_close_stream),
1324-
1325- ("help_online", None, _("Get Help Online..."), None, None, lambda *a: util.load_url(QUESTIONS_URL)),
1326- ("help_translate", None, _("Translate This Application..."), None, None, lambda *a: util.load_url(TRANSLATE_URL)),
1327- ("help_report", None, _("Report A Problem..."), None, None, lambda *a: util.load_url(BUG_URL)),
1328- ])
1329-
1330- ui = gtk.UIManager()
1331- ui.insert_action_group(self.actions, pos=0)
1332- ui.add_ui_from_string(ui_string)
1333-
1334- # Add the old CTRL+R shortcut for legacy users
1335- refresh = ui.get_widget('/menubar_main/menu_gwibber/refresh')
1336- key, mod = gtk.accelerator_parse("<ctrl>R")
1337- refresh.add_accelerator("activate", ui.get_accel_group(), key, mod, gtk.ACCEL_VISIBLE)
1338-
1339- if appindicator:
1340- # Use appindicators to get quicklists in unity
1341- self.ind = appindicator.Indicator ("Gwibber",
1342- "applications-microblogging-panel",
1343- appindicator.CATEGORY_APPLICATION_STATUS)
1344-
1345- # create a menu
1346- self.ai_menu = gtk.Menu()
1347-
1348- self.ai_menu.append(gtk.SeparatorMenuItem())
1349- ai_refresh = gtk.MenuItem(_("_Refresh"))
1350- ai_refresh.connect("activate", self.on_refresh)
1351- self.ai_menu.append(ai_refresh)
1352-
1353- ai_accounts = gtk.MenuItem(_("_Accounts"))
1354- ai_accounts.connect("activate", self.on_accounts)
1355- self.ai_menu.append(ai_accounts)
1356-
1357- ai_preferences = gtk.MenuItem(_("_Preferences"))
1358- ai_preferences.connect("activate", self.on_preferences)
1359- self.ai_menu.append(ai_preferences)
1360-
1361- # show the items
1362- self.ai_menu.show_all()
1363-
1364- self.ind.set_menu(self.ai_menu)
1365-
1366- # End use appindicators to get quicklists in unity
1367-
1368- return ui
1369-
1370- def update_menu_availability(self):
1371- state = self.stream_view.get_state()
1372- if state:
1373- a = self.actions.get_action("close_stream")
1374- a.set_visible(bool(state[0].get("transient", False)))
1375-
1376- def update_view(self):
1377- self.stream_view.update()
1378-
1379- def private(self, message):
1380- features = self.model.services[message["service"]]["features"]
1381-
1382- if "private" in features:
1383- self.message_target.set_target(message, "private")
1384- self.input.textview.grab_focus()
1385- buf = self.input.textview.get_buffer()
1386- buf.place_cursor(buf.get_end_iter())
1387-
1388- def reply(self, message):
1389- features = self.model.services[message["service"]]["features"]
1390-
1391- if "reply" in features:
1392- if message["sender"].get("nick", 0) and not "thread" in features:
1393- s = "@%s: " if self.model.settings["reply_append_colon"] else "@%s "
1394- self.input.set_text(s % message["sender"]["nick"])
1395-
1396- self.message_target.set_target(message)
1397- self.input.textview.grab_focus()
1398- buf = self.input.textview.get_buffer()
1399- buf.place_cursor(buf.get_end_iter())
1400-
1401- def on_reply_cancel(self, widget):
1402- self.input.clear()
1403-
1404- def get_message(self, id):
1405- data = self.messages.Get(id)
1406- if data: return json.loads(data)
1407-
1408- def on_refresh(self, *args):
1409- self.service.Refresh()
1410-
1411- def add_stream(self, data, kind=None):
1412- if "operation" in data:
1413- stream = str(self.model.features[data["operation"]]["stream"])
1414- obj = self.model.streams
1415- else:
1416- stream = "search"
1417- obj = self.model.searches
1418-
1419- id = obj.Create(json.dumps(data))
1420- self.model.refresh()
1421- self.stream_view.new_stream({
1422- "stream": stream,
1423- "account": data.get("account", None),
1424- "transient": id,
1425- })
1426-
1427- self.service.PerformOp('{"id": "%s"}' % id)
1428- self.update_menu_availability()
1429-
1430- def save_window_settings(self):
1431- self.model.settings["streams"] = json.dumps(self.stream_view.get_state())
1432- self.model.settings["window_size"] = self.get_size()
1433- self.model.settings["window_position"] = self.get_position()
1434- self.model.settings["window_splitter"] = self.input_splitter.get_position()
1435-
1436- if hasattr(self.stream_view, "splitter"):
1437- self.model.settings["sidebar_splitter"] = self.stream_view.splitter.get_position()
1438-
1439- def on_pane_closed(self, widget, count):
1440- if count < 2 and isinstance(self.stream_view, gwui.MultiStreamUi):
1441- self.set_view("SingleStreamUi")
1442-
1443- def on_window_close(self, *args):
1444- if self.model.settings["minimize_to_tray"]:
1445- self.on_toggle_window_visibility(self)
1446- return True
1447- else:
1448- self.save_window_settings()
1449- logger.info("Gwibber Client closed")
1450- gtk.main_quit()
1451-
1452- def on_quit(self, *args):
1453- self.service.Quit()
1454- self.save_window_settings()
1455- logger.info("Gwibber Client quit")
1456- gtk.main_quit()
1457-
1458- def on_search(self, *args):
1459- self.stream_view.set_state([{
1460- "stream": "search",
1461- "account": None,
1462- "transient": False,
1463- }])
1464-
1465- self.stream_view.search_box.focus()
1466-
1467- def on_perform_search(self, widget, query):
1468- self.add_stream({"name": query, "query": query})
1469-
1470- def on_accounts(self, *args):
1471- if os.path.exists(os.path.join("bin", "gwibber-accounts")):
1472- cmd = os.path.join("bin", "gwibber-accounts")
1473- else:
1474- cmd = "gwibber-accounts"
1475- return subprocess.Popen(cmd, shell=False)
1476-
1477- def on_preferences(self, *args):
1478- if os.path.exists(os.path.join("bin", "gwibber-preferences")):
1479- cmd = os.path.join("bin", "gwibber-preferences")
1480- else:
1481- cmd = "gwibber-preferences"
1482- return subprocess.Popen(cmd, shell=False)
1483-
1484- def on_about(self, *args):
1485- self.ui.add_from_file (resources.get_ui_asset("gwibber-about-dialog.ui"))
1486- about_dialog = self.ui.get_object("about_dialog")
1487- about_dialog.set_version(str(VERSION_NUMBER))
1488- about_dialog.set_transient_for(self)
1489- about_dialog.connect("response", lambda *a: about_dialog.hide())
1490- about_dialog.show_all()
1491-
1492- def on_close_stream(self, *args):
1493- state = self.stream_view.get_state()
1494- if state and state[0].get("transient", 0):
1495- state = state[0]
1496- obj = "searches" if state.get("stream", 0) == "search" else "streams"
1497- getattr(self.model, obj).Delete(state["transient"])
1498- self.stream_view.set_state([{"stream": "messages", "account": None}])
1499-
1500- def on_message_action_menu(self, msg, view):
1501- theme = gtk.icon_theme_get_default()
1502- menu = gtk.Menu()
1503-
1504- def perform_action(mi, act, widget, msg): act(widget, self, msg)
1505-
1506- for a in actions.MENU_ITEMS:
1507- if a.action.__self__.__name__ == "private" and msg["sender"].get("is_me", 0):
1508- continue
1509-
1510- if a.include(self, msg):
1511- image = gtk.image_new_from_icon_name(a.icon, gtk.ICON_SIZE_MENU)
1512- mi = gtk.ImageMenuItem()
1513- mi.set_label(a.label)
1514- mi.set_image(image)
1515- mi.set_property("use_underline", True)
1516- mi.connect("activate", perform_action, a.action, view, msg)
1517- menu.append(mi)
1518-
1519- menu.show_all()
1520- menu.popup(None, None, None, 3, 0)
1521-
1522- def on_action(self, widget, uri, cmd, query, view):
1523- if hasattr(actions, cmd):
1524- if "msg" in query:
1525- query["msg"] = self.get_message(query["msg"])
1526- getattr(actions, cmd).action(view, self, **query)
1527-
1528- def on_stream_closed(self, widget, id, kind):
1529- self.model.streams.Delete(id)
1530- self.model.searches.Delete(id)
1531-
1532- def on_stream_changed(self, widget, stream):
1533- self.update_menu_availability()
1534- if stream["stream"]:
1535- gobject.idle_add(lambda: self.service.UpdateIndicators(stream["stream"]))
1536-
1537- def on_input_changed(self, w, text, cnt):
1538- self.input.textview.set_overlay_text(str(MAX_MESSAGE_LENGTH - cnt))
1539-
1540- def on_input_cleared(self, seq):
1541- self.message_target.end()
1542- self.input.clear()
1543-
1544- def on_input_activate(self, w, text, cnt):
1545- self.send_message(text)
1546- self.input.clear()
1547-
1548- def on_button_attach_clicked(self, w):
1549- file_upload = gtk.FileChooserDialog(title=_("Select file to upload"),
1550- action=gtk.FILE_CHOOSER_ACTION_OPEN,
1551- buttons=(gtk.STOCK_CANCEL,
1552- gtk.RESPONSE_CANCEL,
1553- gtk.STOCK_OPEN,
1554- gtk.RESPONSE_OK))
1555- file_upload.set_default_response(gtk.RESPONSE_OK)
1556- file_upload.connect("response", self.on_button_attach_file_selected)
1557- file_upload.show()
1558-
1559- def on_button_attach_file_selected(self, file_upload, response):
1560- attachment = None
1561- #import epdb;epdb.st()
1562- if response == gtk.RESPONSE_CANCEL:
1563- file_upload.destroy()
1564- return
1565-
1566- if response == gtk.RESPONSE_OK:
1567- attachment = file_upload.get_filename()
1568- file_upload.destroy()
1569-
1570- if attachment:
1571- buf = self.input.textview.get_buffer()
1572- # set a mark at iter, so that the callback knows where to insert
1573- iter = buf.get_end_iter()
1574- mark_start = buf.create_mark(None, iter, True)
1575- # insert a placeholder character
1576- buf.insert(iter, u"\u2328")
1577- # can't just get_insert() because that gets the *named* mark "insert"
1578- # and we want an anonymous mark so it won't get changed later
1579- iter_end = buf.get_iter_at_mark(buf.get_insert())
1580- mark_end = buf.create_mark(None, iter_end, True)
1581- gobject.idle_add(self.upload_attachment, attachment, iter, mark_start, mark_end)
1582-
1583- def upload_attachment(self, attachment, iter, mark_start, mark_end):
1584- buf = self.input.textview.get_buffer()
1585-
1586- def add_shortened(shortened_url):
1587- "Internal add-shortened-url-to-buffer function: a closure"
1588- iter_start = buf.get_iter_at_mark(mark_start)
1589- iter_end = buf.get_iter_at_mark(mark_end)
1590- buf.delete(iter_start, iter_end)
1591- buf.insert(iter_start, ("%s " % shortened_url))
1592- #buf.insert_at_cursor(" ")
1593- def error_shortened(dbus_exc):
1594- "Internal shortening-url-died function: a closure"
1595- iter = buf.get_iter_at_mark(mark)
1596- buf.insert(iter, text) # shortening failed
1597-
1598- text = self.uploader.Upload(attachment)
1599-
1600- if self.model.settings["shorten_urls"]:
1601- if text and text.startswith("http") and not " " in text \
1602- and len(text) > 30:
1603- self.shortener.Shorten(text,
1604- reply_handler=add_shortened,
1605- error_handler=error_shortened)
1606- else:
1607- add_shortened(text)
1608-
1609- def on_button_send_clicked(self, w):
1610- self.send_message(self.input.get_text())
1611- self.input.clear()
1612-
1613- def send_message(self, text):
1614- if len(text) == 0:
1615- return
1616- target = self.message_target.target
1617- action = self.message_target.action
1618-
1619- if target:
1620- if action == "reply":
1621- data = {"message": text, "target": target}
1622- self.service.Send(json.dumps(data))
1623- elif action == "repost":
1624- data = {"message": text, "accounts": [target["account"]]}
1625- self.service.Send(json.dumps(data))
1626- elif action == "private":
1627- data = {"message": text, "private": target}
1628- self.service.Send(json.dumps(data))
1629- self.message_target.end()
1630- else: self.service.SendMessage(text)
1631-
1632- def on_new_stream(self, *args):
1633- if isinstance(self.stream_view, gwui.MultiStreamUi):
1634- self.stream_view.new_stream()
1635- else:
1636- self.set_view("MultiStreamUi")
1637- self.stream_view.new_stream()
1638-
1639- def on_loading_started(self, *args):
1640- self.loading_spinner.set_from_animation(
1641- gtk.gdk.PixbufAnimation(resources.get_ui_asset("progress.gif")))
1642-
1643- def on_loading_complete(self, *args):
1644- self.loading_spinner.clear()
1645- self.update_view()
1646-
1647- def on_connection_online(self, *args):
1648- logger.info("Setting to Online")
1649- self.actions.get_action("refresh").set_sensitive(True)
1650-
1651- def on_connection_offline(self, *args):
1652- logger.info("Setting to Offline")
1653- self.actions.get_action("refresh").set_sensitive(False)
1654-
1655-class Client(dbus.service.Object):
1656- __dbus_object_path__ = "/com/GwibberClient"
1657-
1658- def __init__(self):
1659- # Setup a Client dbus interface
1660- self.bus = dbus.SessionBus()
1661- self.bus_name = dbus.service.BusName("com.GwibberClient", self.bus)
1662- dbus.service.Object.__init__(self, self.bus_name, self.__dbus_object_path__)
1663-
1664- # Methods the client exposes via dbus, return from the list method
1665- self.exposed_methods = ["focus_client", "show_stream"]
1666- self.w = GwibberClient()
1667-
1668- @dbus.service.method("com.GwibberClient", in_signature="", out_signature="")
1669- def focus_client(self):
1670- """
1671- This method focuses the client UI displaying the default view.
1672- Currently used when the client is activated via dbus activation.
1673- """
1674- self.w.present_with_time(int(time.mktime(datetime.datetime.now().timetuple())))
1675- try:
1676- self.w.move(*self.w.model.settings["window_position"])
1677- except:
1678- pass
1679-
1680- @dbus.service.method("com.GwibberClient", in_signature="s", out_signature="")
1681- def show_stream(self, stream):
1682- """
1683- This method focuses the client UI and displays the replies view.
1684- Currently used when activated via the messaging indicator.
1685- """
1686- self.w.present_with_time(int(time.mktime(datetime.datetime.now().timetuple())))
1687- self.w.move(*self.w.model.settings["window_position"])
1688- stream = {'account': None, 'stream': stream, 'transient': False}
1689- if isinstance(self.w.stream_view, gwui.MultiStreamUi):
1690- streams = self.w.stream_view.get_state()
1691- if stream["stream"] not in str(streams):
1692- streams.append(stream)
1693- self.w.stream_view.set_state(streams)
1694- else:
1695- self.w.stream_view.set_state([stream])
1696-
1697- @dbus.service.method("com.GwibberClient")
1698- def list(self):
1699- """
1700- This method returns a list of exposed dbus methods
1701- """
1702- return self.exposed_methods
1703
1704=== modified file 'gwibber/error.py'
1705--- gwibber/error.py 2010-10-06 23:33:22 +0000
1706+++ gwibber/error.py 2012-02-14 21:35:21 +0000
1707@@ -26,7 +26,7 @@
1708 gettext.bind_textdomain_codeset('gwibber','UTF-8')
1709 gettext.textdomain('gwibber')
1710
1711-import gtk
1712+from gi.repository import Gtk
1713
1714 class GwibberErrorService:
1715
1716@@ -63,18 +63,18 @@
1717
1718 self.notified[service] = type
1719 if condition == "info":
1720- condition = gtk.MESSAGE_INFO
1721+ condition = Gtk.MessageType.INFO
1722 else:
1723- condition = gtk.MESSAGE_ERROR
1724+ condition = Gtk.MessageType.ERROR
1725
1726 if title is None:
1727 title = _("Gwibber Error")
1728- dialog = gtk.MessageDialog(
1729+ dialog = Gtk.MessageDialog(
1730 parent = None,
1731 type = condition,
1732- buttons = gtk.BUTTONS_CLOSE,
1733+ buttons = Gtk.ButtonsType.CLOSE,
1734 message_format = message)
1735 dialog.set_title(title)
1736- dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
1737+ dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
1738 dialog.run()
1739 dialog.destroy()
1740
1741=== modified file 'gwibber/gwui.py'
1742--- gwibber/gwui.py 2011-04-22 21:00:15 +0000
1743+++ gwibber/gwui.py 2012-02-14 21:35:21 +0000
1744@@ -1,9 +1,10 @@
1745
1746 import os, json, urlparse, util
1747 import subprocess
1748-import gtk, gobject, pango, webkit, time, gconf
1749+import time
1750 import util
1751 import microblog.util
1752+from gi.repository import GObject, Gdk, Gtk, Pango, WebKit, Gio
1753 from microblog.util import resources
1754 from microblog import config
1755
1756@@ -28,17 +29,17 @@
1757 error_accounts = []
1758 notified_errors = {}
1759
1760-gtk.gdk.threads_init()
1761+Gdk.threads_init()
1762
1763 if "gwibber" not in urlparse.uses_query:
1764 urlparse.uses_query.append("gwibber")
1765
1766-class Model(gobject.GObject):
1767+class Model(GObject.Object):
1768 __gsignals__ = {
1769- "changed": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, ()),
1770+ "changed": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ()),
1771 }
1772 def __init__(self):
1773- gobject.GObject.__init__(self)
1774+ GObject.Object.__init__(self)
1775
1776 self.settings = config.Preferences()
1777 self.daemon = microblog.util.getbus("Service")
1778@@ -205,17 +206,17 @@
1779 items.append(searches)
1780 return items
1781
1782-class WebUi(webkit.WebView):
1783+class WebUi(WebKit.WebView):
1784 __gsignals__ = {
1785- "action": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, str, object)),
1786+ "action": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, str, object)),
1787 }
1788
1789 def __init__(self):
1790- webkit.WebView.__init__(self)
1791- self.web_settings = webkit.WebSettings()
1792+ WebKit.WebView.__init__(self)
1793+ self.web_settings = WebKit.WebSettings()
1794 self.set_settings(self.web_settings)
1795 self.web_settings.set_property("enable-plugins", False)
1796- self.gc = gconf.client_get_default()
1797+ self.settings = Gio.Settings("org.gnome.desktop.interface")
1798
1799 self.connect("navigation-requested", self.on_click_link)
1800 self.connect("populate-popup", self.on_popup)
1801@@ -238,7 +239,7 @@
1802 return True
1803
1804 def render(self, theme, template, **kwargs):
1805- default_font = self.gc.get_string("/desktop/gnome/interface/document_font_name")
1806+ default_font = self.settings.get_string("document-font-name")
1807 if default_font:
1808 font_name, font_size = default_font.rsplit(None, 1)
1809 self.web_settings.set_property("sans-serif-font-family", font_name)
1810@@ -264,8 +265,8 @@
1811
1812 class Navigation(WebUi):
1813 __gsignals__ = {
1814- "stream-selected": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (object,)),
1815- "stream-closed": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, str)),
1816+ "stream-selected": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (object,)),
1817+ "stream-closed": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, str)),
1818 }
1819
1820 def __init__(self, model):
1821@@ -298,27 +299,25 @@
1822 target = self.model.find(**query)
1823 if target: self.emit("stream-selected", target)
1824
1825-class SingleStreamUi(gtk.VBox):
1826+class SingleStreamUi(Gtk.VBox):
1827 __gsignals__ = {
1828- "action": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, str, object, object)),
1829- "stream-closed": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, str)),
1830- "stream-changed": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (object,)),
1831- "search": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str,)),
1832+ "action": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, str, object, object)),
1833+ "stream-closed": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, str)),
1834+ "stream-changed": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (object,)),
1835+ "search": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str,)),
1836 }
1837 def __init__(self, model):
1838- gtk.VBox.__init__(self)
1839+ Gtk.VBox.__init__(self)
1840 self.model = model
1841
1842- self.gc = gconf.client_get_default()
1843-
1844 # Build the side navigation bar
1845 self.navigation = Navigation(self.model)
1846 self.navigation.connect("stream-selected", self.on_stream_change)
1847 self.navigation.connect("stream-closed", self.on_stream_closed)
1848 self.navigation.render()
1849
1850- self.navigation_scroll = gtk.ScrolledWindow()
1851- self.navigation_scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
1852+ self.navigation_scroll = Gtk.ScrolledWindow()
1853+ self.navigation_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)
1854 self.navigation_scroll.add(self.navigation)
1855
1856 self.messages = MessageStream(self.model)
1857@@ -328,7 +327,7 @@
1858 self.search_box.connect("search", self.on_search)
1859
1860
1861- layout = gtk.VBox(spacing=5)
1862+ layout = Gtk.VBox(spacing=5)
1863 layout.pack_start(self.search_box, False)
1864 if hasattr(gtk, "InfoBar"):
1865 self.infobox = GwibberInfoBox()
1866@@ -336,7 +335,7 @@
1867 layout.pack_start(self.messages, True)
1868
1869 # Build the pane layout
1870- self.splitter = gtk.HPaned()
1871+ self.splitter = Gtk.HPaned()
1872 self.splitter.add1(self.navigation_scroll)
1873 self.splitter.add2(layout)
1874
1875@@ -345,14 +344,14 @@
1876
1877 def handle_splitter_position_change(self, pos):
1878 if pos < 70 and self.navigation.tree_enabled:
1879- #self.navigation_scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
1880- self.navigation_scroll.set_shadow_type(gtk.SHADOW_NONE)
1881+ #self.navigation_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)
1882+ self.navigation_scroll.set_shadow_type(Gtk.ShadowType.NONE)
1883 self.navigation.tree_enabled = False
1884 self.navigation.render()
1885
1886 if pos > 70 and not self.navigation.tree_enabled:
1887- #self.navigation_scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
1888- self.navigation_scroll.set_shadow_type(gtk.SHADOW_IN)
1889+ #self.navigation_scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER)
1890+ self.navigation_scroll.set_shadow_type(Gtk.ShadowType.IN)
1891 self.navigation.tree_enabled = True
1892 self.navigation.render()
1893
1894@@ -410,23 +409,23 @@
1895 self.update()
1896
1897
1898-class MultiStreamUi(gtk.HBox):
1899+class MultiStreamUi(Gtk.HBox):
1900 __gsignals__ = {
1901- "action": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, str, object, object)),
1902- "stream-closed": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, str)),
1903- "stream-changed": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (object,)),
1904- "pane-closed": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (int,)),
1905- "search": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str,)),
1906+ "action": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, str, object, object)),
1907+ "stream-closed": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, str)),
1908+ "stream-changed": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (object,)),
1909+ "pane-closed": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (int,)),
1910+ "search": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str,)),
1911 }
1912 def __init__(self, model):
1913- gtk.HBox.__init__(self)
1914+ Gtk.HBox.__init__(self)
1915 self.model = model
1916
1917- self.container = gtk.HBox(spacing=5)
1918+ self.container = Gtk.HBox(spacing=5)
1919 self.container.set_border_width(5)
1920
1921- self.scroll = gtk.ScrolledWindow()
1922- self.scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
1923+ self.scroll = Gtk.ScrolledWindow()
1924+ self.scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER)
1925 self.scroll.add_with_viewport(self.container)
1926
1927 self.pack_start(self.scroll, True)
1928@@ -469,44 +468,44 @@
1929 for stream in self.container:
1930 stream.update()
1931
1932-class MultiStreamPane(gtk.VBox):
1933+class MultiStreamPane(Gtk.VBox):
1934 __gsignals__ = {
1935- "action": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, str, object)),
1936- "stream-closed": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, str)),
1937- "pane-closed": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, ()),
1938- "search": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str,)),
1939+ "action": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, str, object)),
1940+ "stream-closed": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, str)),
1941+ "pane-closed": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ()),
1942+ "search": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str,)),
1943 }
1944
1945 def __init__(self, model):
1946- gtk.VBox.__init__(self, spacing = 2)
1947+ Gtk.VBox.__init__(self, spacing = 2)
1948 self.model = model
1949 self.selected_stream = None
1950
1951 # Build the top navigation bar
1952- close_icon = gtk.image_new_from_stock("gtk-close", gtk.ICON_SIZE_MENU)
1953- down_arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_NONE)
1954+ close_icon = Gtk.image_new_from_stock("gtk-close", Gtk.IconSize.MENU)
1955+ down_arrow = Gtk.Arrow(Gtk.ARROW_DOWN, Gtk.ShadowType.NONE)
1956
1957- btn_arrow = gtk.Button()
1958- btn_arrow.set_relief(gtk.RELIEF_NONE)
1959+ btn_arrow = Gtk.Button()
1960+ btn_arrow.set_relief(Gtk.ReliefType.NONE)
1961 btn_arrow.add(down_arrow)
1962 btn_arrow.connect("clicked", self.on_dropdown)
1963
1964- self.arrow = gtk.EventBox()
1965+ self.arrow = Gtk.EventBox()
1966 self.arrow.add(btn_arrow)
1967
1968- btn_close = gtk.Button()
1969- btn_close.set_relief(gtk.RELIEF_NONE)
1970+ btn_close = Gtk.Button()
1971+ btn_close.set_relief(Gtk.ReliefType.NONE)
1972 btn_close.set_image(close_icon)
1973 btn_close.connect("clicked", self.on_close)
1974
1975- self.icon_protocol = gtk.Image()
1976- self.icon_stream = gtk.Image()
1977- self.nav_label = gtk.Label()
1978+ self.icon_protocol = Gtk.Image()
1979+ self.icon_stream = Gtk.Image()
1980+ self.nav_label = Gtk.Label()
1981
1982 self.search_box = GwibberSearch()
1983 self.search_box.connect("search", self.on_search)
1984
1985- self.navigation_bar = gtk.HBox(spacing=5)
1986+ self.navigation_bar = Gtk.HBox(spacing=5)
1987 self.navigation_bar.pack_start(self.arrow, False)
1988 self.navigation_bar.pack_start(self.icon_protocol, False)
1989 self.navigation_bar.pack_start(self.icon_stream, False)
1990@@ -529,12 +528,12 @@
1991 w, h = self.arrow.window.get_geometry()[2:4]
1992 x, y = self.arrow.window.get_origin()
1993
1994- window = gtk.Window()
1995+ window = Gtk.Window()
1996 window.move(x, y + h)
1997 window.set_decorated(False)
1998 window.set_property("skip-taskbar-hint", True)
1999 window.set_property("skip-pager-hint", True)
2000- window.set_events(gtk.gdk.FOCUS_CHANGE_MASK)
2001+ window.set_events(Gdk.FOCUS_CHANGE_MASK)
2002 window.connect("focus-out-event", lambda w,x: w.destroy())
2003
2004 def on_change(widget, stream):
2005@@ -592,13 +591,13 @@
2006 self.set_stream(self.model.find(**stream) or self.model.find(stream="home", account=None))
2007 self.update()
2008
2009-class AccountTargetBar(gtk.HBox):
2010+class AccountTargetBar(Gtk.HBox):
2011 __gsignals__ = {
2012- "canceled": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, ())
2013+ "canceled": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ())
2014 }
2015
2016 def __init__(self, model):
2017- gtk.HBox.__init__(self, spacing=5)
2018+ Gtk.HBox.__init__(self, spacing=5)
2019 self.model = model
2020 self.model.connect("changed", self.on_account_changed)
2021 self.accounts = []
2022@@ -652,28 +651,28 @@
2023 action=self.action,
2024 accounts=self.accounts)
2025
2026-class MessageStream(gtk.HBox):
2027+class MessageStream(Gtk.HBox):
2028 def __init__(self, model):
2029- gtk.HBox.__init__(self, spacing=5)
2030+ Gtk.HBox.__init__(self, spacing=5)
2031
2032 self.previous_threshold = 100
2033 self.previous_position = 0
2034 self.previous_stream = None
2035 self.messages = None
2036
2037- self.add_events(gtk.gdk.KEY_PRESS_MASK | gtk.gdk.SCROLL_MASK)
2038+ self.add_events(Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.SCROLL_MASK)
2039 self.connect("scroll-event", self.on_viewport_scroll)
2040 self.connect("key-press-event", self.on_viewport_key)
2041
2042 self.message_view = MessageStreamView(model)
2043 self.message_view.connect("load-finished", self.on_scroll)
2044
2045- self.message_scroll = gtk.ScrolledWindow()
2046- self.message_scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
2047- self.message_scroll.set_shadow_type(gtk.SHADOW_IN)
2048+ self.message_scroll = Gtk.ScrolledWindow()
2049+ self.message_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)
2050+ self.message_scroll.set_shadow_type(Gtk.ShadowType.IN)
2051 self.message_scroll.add(self.message_view)
2052
2053- self.scrollbar = gtk.VScrollbar()
2054+ self.scrollbar = Gtk.VScrollbar()
2055 self.scrollbar.set_range(0, 100)
2056 self.scrollbar.set_increments(1, 10)
2057 self.scrollbar.connect("value-changed", self.on_scroll)
2058@@ -682,29 +681,29 @@
2059 self.pack_start(self.scrollbar, False)
2060
2061 def on_viewport_key(self, widget, event):
2062- if not event.state & gtk.gdk.SHIFT_MASK: return
2063- if 'Down' == gtk.gdk.keyval_name(event.keyval):
2064+ if not event.state & Gdk.SHIFT_MASK: return
2065+ if 'Down' == Gdk.keyval_name(event.keyval):
2066 value = int(self.scrollbar.get_value()) + 1
2067 self.scrollbar.set_value(value)
2068- elif 'Page_Down' == gtk.gdk.keyval_name(event.keyval):
2069+ elif 'Page_Down' == Gdk.keyval_name(event.keyval):
2070 value = int(self.scrollbar.get_value()) + 3
2071 self.scrollbar.set_value(value)
2072- elif 'Up' == gtk.gdk.keyval_name(event.keyval):
2073+ elif 'Up' == Gdk.keyval_name(event.keyval):
2074 value = int(self.scrollbar.get_value()) - 1
2075 self.scrollbar.set_value(value)
2076- elif 'Page_Up' == gtk.gdk.keyval_name(event.keyval):
2077+ elif 'Page_Up' == Gdk.keyval_name(event.keyval):
2078 value = int(self.scrollbar.get_value()) - 3
2079 self.scrollbar.set_value(value)
2080- elif 'Home' == gtk.gdk.keyval_name(event.keyval):
2081+ elif 'Home' == Gdk.keyval_name(event.keyval):
2082 self.scrollbar.set_value(0)
2083- elif 'End' == gtk.gdk.keyval_name(event.keyval):
2084+ elif 'End' == Gdk.keyval_name(event.keyval):
2085 self.scrollbar.set_value(100)
2086
2087 def on_viewport_scroll(self, widget, event):
2088 value = int(self.scrollbar.get_value())
2089
2090- if event.direction == gtk.gdk.SCROLL_DOWN: value += 1
2091- elif event.direction == gtk.gdk.SCROLL_UP: value -= 1
2092+ if event.direction == Gdk.ScrollDirection.DOWN: value += 1
2093+ elif event.direction == Gdk.ScrollDirection.UP: value -= 1
2094
2095 self.scrollbar.set_value(value)
2096
2097@@ -814,9 +813,9 @@
2098
2099 return [m["txtid"] for m in messages]
2100
2101-class GwibberInfoBox(gtk.VBox):
2102+class GwibberInfoBox(Gtk.VBox):
2103 def __init__(self, error=None):
2104- gtk.VBox.__init__(self, spacing=2)
2105+ Gtk.VBox.__init__(self, spacing=2)
2106 self.service = microblog.util.getbus("Service")
2107 self.service.connect_to_signal("Error", self.add_info_bar)
2108 self.show()
2109@@ -845,45 +844,45 @@
2110
2111 # FIXME if hasattr(gtk, "InfoBar"):
2112
2113-class GwibberInfoBar(hasattr(gtk, "InfoBar") and gtk.InfoBar or gtk.VBox):
2114+class GwibberInfoBar(hasattr(gtk, "InfoBar") and Gtk.InfoBar or Gtk.VBox):
2115 def __init__(self, data=None):
2116- gtk.InfoBar.__init__(self)
2117+ Gtk.InfoBar.__init__(self)
2118 self.service = microblog.util.getbus("Service")
2119- self.set_message_type(gtk.MESSAGE_ERROR)
2120+ self.set_message_type(Gtk.MessageType.ERROR)
2121 #self.set_no_show_all(True)
2122
2123 self.account = data["error"]["account"]
2124 content_area = self.get_content_area()
2125
2126 #if not account.has_key("service"):
2127- # icon = gtk.image_new_from_file(resources.get_ui_asset("gwibber.png"))
2128+ # icon = Gtk.image_new_from_file(resources.get_ui_asset("gwibber.png"))
2129 #else:
2130- icon = gtk.image_new_from_file(resources.get_ui_asset("icons/breakdance/16x16/%s.png" % data["error"]["account"]["service"]))
2131+ icon = Gtk.image_new_from_file(resources.get_ui_asset("icons/breakdance/16x16/%s.png" % data["error"]["account"]["service"]))
2132
2133- label = gtk.Label(data["error"]["message"])
2134+ label = Gtk.Label(data["error"]["message"])
2135
2136 label.set_use_markup(True)
2137- label.set_ellipsize(pango.ELLIPSIZE_END)
2138+ label.set_ellipsize(Pango.EllipsizeType.END)
2139
2140 content_area.pack_start(icon, False, False, 0)
2141 content_area.pack_start(label, True, True, 0)
2142 self.pack_start(content_area, False)
2143
2144- close_button = gtk.Button()
2145- close_button.set_image(gtk.image_new_from_stock (gtk.STOCK_CLOSE, gtk.ICON_SIZE_BUTTON))
2146+ close_button = Gtk.Button()
2147+ close_button.set_image(Gtk.image_new_from_stock (Gtk.STOCK_CLOSE, Gtk.IconSize.BUTTON))
2148 close_button.set_tooltip_text(_("Close"))
2149 close_button.connect("clicked", self.on_error_close_clicked_cb)
2150 self.pack_end(close_button, False)
2151
2152 if data["error"]["type"] == "auth":
2153- edit_button = gtk.Button()
2154- edit_button.set_image(gtk.image_new_from_stock (gtk.STOCK_EDIT, gtk.ICON_SIZE_BUTTON))
2155+ edit_button = Gtk.Button()
2156+ edit_button.set_image(Gtk.image_new_from_stock (Gtk.STOCK_EDIT, Gtk.IconSize.BUTTON))
2157 edit_button.set_tooltip_text(_("Edit Account"))
2158 edit_button.connect("clicked", self.on_error_edit_clicked_cb, data["error"]["account"]["id"], data["error"]["message"])
2159 self.pack_end(edit_button, False)
2160
2161- retry_button = gtk.Button()
2162- retry_button.set_image(gtk.image_new_from_stock (gtk.STOCK_REFRESH, gtk.ICON_SIZE_BUTTON))
2163+ retry_button = Gtk.Button()
2164+ retry_button.set_image(Gtk.image_new_from_stock (Gtk.STOCK_REFRESH, Gtk.IconSize.BUTTON))
2165 retry_button.set_tooltip_text(_("Retry"))
2166 retry_button.connect("clicked", self.on_error_retry_clicked_cb, data["error"]["account"]["id"])
2167 self.pack_end(retry_button, False)
2168@@ -911,26 +910,26 @@
2169 error_accounts.remove(self.account["id"])
2170
2171
2172-class GwibberSearch(gtk.HBox):
2173+class GwibberSearch(Gtk.HBox):
2174 __gsignals__ = {
2175- "search": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str,)),
2176+ "search": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str,)),
2177 }
2178
2179 def __init__(self):
2180- gtk.HBox.__init__(self, spacing=2)
2181+ Gtk.HBox.__init__(self, spacing=2)
2182
2183- self.entry = gtk.Entry()
2184+ self.entry = Gtk.Entry()
2185 self.entry.connect("activate", self.on_search)
2186 self.entry.connect("changed", self.on_changed)
2187
2188- self.button = gtk.Button(_("Search"))
2189+ self.button = Gtk.Button(_("Search"))
2190 self.button.connect("clicked", self.on_search)
2191
2192 self.pack_start(self.entry, True)
2193 self.pack_start(self.button, False)
2194
2195 try:
2196- self.entry.set_property("primary-icon-stock", gtk.STOCK_FIND)
2197+ self.entry.set_property("primary-icon-stock", Gtk.STOCK_FIND)
2198 self.entry.connect("icon-press", self.on_icon_press)
2199 except: pass
2200
2201@@ -946,7 +945,7 @@
2202
2203 def on_changed(self, widget):
2204 self.entry.set_property("secondary-icon-stock",
2205- gtk.STOCK_CLEAR if self.entry.get_text().strip() else None)
2206+ Gtk.STOCK_CLEAR if self.entry.get_text().strip() else None)
2207
2208 def set_visible(self, value):
2209 if value: self.hide()
2210@@ -955,23 +954,23 @@
2211 def focus(self):
2212 self.entry.grab_focus()
2213
2214-class Input(gtk.Frame):
2215+class Input(Gtk.Frame):
2216 __gsignals__ = {
2217- "submit": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, int)),
2218- "changed": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, int)),
2219- "clear": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, ())
2220+ "submit": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, int)),
2221+ "changed": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, int)),
2222+ "clear": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ())
2223 }
2224
2225 def __init__(self, content=None):
2226- gtk.Frame.__init__(self)
2227+ Gtk.Frame.__init__(self)
2228
2229 self.textview = InputTextView(content=content)
2230 self.textview.connect("submit", self.do_submit_event)
2231 self.textview.connect("clear", self.do_clear_event)
2232 self.textview.get_buffer().connect("changed", self.do_changed_event)
2233
2234- scroll = gtk.ScrolledWindow()
2235- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
2236+ scroll = Gtk.ScrolledWindow()
2237+ scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
2238 scroll.add(self.textview)
2239 self.add(scroll)
2240
2241@@ -1000,14 +999,14 @@
2242 chars = tv.get_char_count()
2243 self.emit("submit", text, chars)
2244
2245-class InputTextView(gtk.TextView):
2246+class InputTextView(Gtk.TextView):
2247 __gsignals__ = {
2248- "submit": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, ()),
2249- "clear": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, ())
2250+ "submit": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ()),
2251+ "clear": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ())
2252 }
2253
2254 def __init__(self, content=None):
2255- gtk.TextView.__init__(self)
2256+ Gtk.TextView.__init__(self)
2257 self.drawable = None
2258 self.model = Model()
2259
2260@@ -1032,14 +1031,14 @@
2261 self.set_accepts_tab(True)
2262 self.set_editable(False)
2263 self.set_cursor_visible(True)
2264- self.set_wrap_mode(gtk.WRAP_WORD_CHAR)
2265+ self.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
2266 self.set_left_margin(2)
2267 self.set_right_margin(2)
2268 self.set_pixels_above_lines(2)
2269 self.set_pixels_below_lines(2)
2270
2271- self.base_color = util.get_style().base[gtk.STATE_NORMAL]
2272- self.error_color = gtk.gdk.color_parse("indianred")
2273+ self.base_color = util.get_style().base[Gtk.StateType.NORMAL]
2274+ self.error_color = Gdk.color_parse("indianred")
2275
2276 # set state online/offline
2277 if not self.connection.isConnected():
2278@@ -1099,7 +1098,7 @@
2279
2280 def expose_view(self, window, event):
2281 if not self.drawable:
2282- self.drawable = self.get_window(gtk.TEXT_WINDOW_TEXT)
2283+ self.drawable = self.get_window(Gtk.TextWindowType.TEXT)
2284 self.pango_overlay = self.create_pango_layout("")
2285 self.set_overlay_text(MAX_MESSAGE_LENGTH)
2286
2287@@ -1115,7 +1114,7 @@
2288 def on_text_changed(self, w):
2289 chars = self.get_char_count()
2290 color = self.error_color if chars > MAX_MESSAGE_LENGTH else self.base_color
2291- self.modify_base(gtk.STATE_NORMAL, color)
2292+ self.modify_base(Gtk.StateType.NORMAL, color)
2293
2294 def on_connection_online(self, *args):
2295 self.set_sensitive(True)
2296@@ -1123,6 +1122,6 @@
2297 def on_connection_offline(self, *args):
2298 self.set_sensitive(False)
2299
2300-gtk.binding_entry_add_signal(InputTextView, gtk.keysyms.Return, 0, "submit")
2301-gtk.binding_entry_add_signal(InputTextView, gtk.keysyms.KP_Enter, 0, "submit")
2302-gtk.binding_entry_add_signal(InputTextView, gtk.keysyms.Escape, 0, "clear")
2303+Gtk.binding_entry_add_signal(InputTextView, Gdk.KEY_Return, 0, "submit")
2304+Gtk.binding_entry_add_signal(InputTextView, Gdk.KP_Enter, 0, "submit")
2305+Gtk.binding_entry_add_signal(InputTextView, Gdk.KEY_Escape, 0, "clear")
2306
2307=== modified file 'gwibber/lib/gtk/widgets.py'
2308--- gwibber/lib/gtk/widgets.py 2011-08-04 05:52:44 +0000
2309+++ gwibber/lib/gtk/widgets.py 2012-02-14 21:35:21 +0000
2310@@ -19,8 +19,8 @@
2311 #
2312
2313 from dbus.mainloop.glib import DBusGMainLoop
2314+from gi.repository import GLib, GObject, Gdk, Gtk
2315 import json
2316-import gobject, gtk
2317 from gwibber.microblog.util.const import *
2318 # Try to import * from custom, install custom.py to include packaging
2319 # customizations like distro API keys, etc
2320@@ -39,30 +39,30 @@
2321 gettext.bind_textdomain_codeset('gwibber','UTF-8')
2322 gettext.textdomain('gwibber')
2323
2324-class GwibberPosterVBox(gtk.VBox):
2325+class GwibberPosterVBox(Gtk.VBox):
2326 def __init__(self, content=None):
2327- gtk.VBox.__init__(self)
2328+ Gtk.VBox.__init__(self)
2329 DBusGMainLoop(set_as_default=True)
2330- loop = gobject.MainLoop()
2331+ loop = GLib.MainLoop()
2332 self.service = gwibber.microblog.util.getbus("Service")
2333
2334 self.input = Input(content=content)
2335 self.input.connect("submit", self.on_input_activate)
2336 self.input.connect("changed", self.on_input_changed)
2337- self.input_splitter = gtk.VPaned()
2338+ self.input_splitter = Gtk.VPaned()
2339 self.input_splitter.add1(self.input)
2340
2341- self.button_send = gtk.Button(_("Send"))
2342+ self.button_send = Gtk.Button(_("Send"))
2343 self.button_send.connect("clicked", self.on_button_send_clicked)
2344 self.message_target = AccountTargetBar()
2345 self.message_target.pack_end(self.button_send, False)
2346
2347- content = gtk.VBox(spacing=5)
2348+ content = Gtk.VBox(spacing=5)
2349 content.pack_start(self.input_splitter, True)
2350 content.pack_start(self.message_target, False)
2351 content.set_border_width(5)
2352
2353- layout = gtk.VBox()
2354+ layout = Gtk.VBox()
2355 layout.pack_start(content, True)
2356 self.add(layout)
2357
2358@@ -77,13 +77,13 @@
2359 self.service.SendMessage(self.input.get_text())
2360 self.input.clear()
2361
2362-class AccountTargetBar(gtk.HBox):
2363+class AccountTargetBar(Gtk.HBox):
2364 __gsignals__ = {
2365- "canceled": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, ())
2366+ "canceled": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ())
2367 }
2368
2369 def __init__(self):
2370- gtk.HBox.__init__(self, spacing=5)
2371+ Gtk.HBox.__init__(self, spacing=5)
2372
2373 self.accounts = gwibber.microblog.util.getbus("Accounts")
2374 self.daemon = gwibber.microblog.util.getbus("Service")
2375@@ -92,7 +92,7 @@
2376 self.accounts.connect_to_signal("Updated", self.on_account_changed)
2377 self.account_list = []
2378
2379- self.targetbar = gtk.HBox(False, 6)
2380+ self.targetbar = Gtk.HBox(False, 6)
2381 self.targetbar.set_size_request(0, 24)
2382 self.pack_start(self.targetbar, True)
2383
2384@@ -118,10 +118,10 @@
2385 self.account_list.append(account)
2386
2387 for account in self.account_list:
2388- img = gtk.Image ()
2389+ img = Gtk.Image ()
2390 img.set_from_file(resources.get_ui_asset("icons/breakdance/16x16/" + account["service"] + ".png"))
2391 img.show();
2392- but = gtk.ToggleButton ()
2393+ but = Gtk.ToggleButton ()
2394 but.set_active (account["send_enabled"])
2395 if not account["send_enabled"]:
2396 but.set_tooltip_text (account["service"] + "(" + account["username"] + ") - " + _("Disabled"))
2397@@ -139,23 +139,23 @@
2398 if account["send_enabled"] != w.get_active ():
2399 self.accounts.SendEnabled(id)
2400
2401-class Input(gtk.Frame):
2402+class Input(Gtk.Frame):
2403 __gsignals__ = {
2404- "submit": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, int)),
2405- "changed": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, int)),
2406- "clear": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, ())
2407+ "submit": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, int)),
2408+ "changed": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, (str, int)),
2409+ "clear": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ())
2410 }
2411
2412 def __init__(self, content=None):
2413- gtk.Frame.__init__(self)
2414+ Gtk.Frame.__init__(self)
2415
2416 self.textview = InputTextView(content=content)
2417 self.textview.connect("submit", self.do_submit_event)
2418 self.textview.connect("clear", self.do_clear_event)
2419 self.textview.get_buffer().connect("changed", self.do_changed_event)
2420
2421- scroll = gtk.ScrolledWindow()
2422- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
2423+ scroll = Gtk.ScrolledWindow()
2424+ scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
2425 scroll.add(self.textview)
2426 self.add(scroll)
2427
2428@@ -185,14 +185,14 @@
2429 self.emit("submit", text, chars)
2430
2431
2432-class InputTextView(gtk.TextView):
2433+class InputTextView(Gtk.TextView):
2434 __gsignals__ = {
2435- "submit": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, ()),
2436- "clear": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, ())
2437+ "submit": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ()),
2438+ "clear": (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ())
2439 }
2440
2441 def __init__(self, content=None):
2442- gtk.TextView.__init__(self)
2443+ Gtk.TextView.__init__(self)
2444 self.drawable = None
2445
2446 self.content = content
2447@@ -216,14 +216,14 @@
2448 self.set_accepts_tab(True)
2449 self.set_editable(False)
2450 self.set_cursor_visible(True)
2451- self.set_wrap_mode(gtk.WRAP_WORD_CHAR)
2452+ self.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
2453 self.set_left_margin(2)
2454 self.set_right_margin(2)
2455 self.set_pixels_above_lines(2)
2456 self.set_pixels_below_lines(2)
2457
2458- self.base_color = util.get_style().base[gtk.STATE_NORMAL]
2459- self.error_color = gtk.gdk.color_parse("indianred")
2460+ self.base_color = util.get_style().base[Gtk.StateType.NORMAL]
2461+ self.error_color = Gdk.Color.parse("indianred")
2462
2463 # set state online/offline
2464 if not self.connection.isConnected():
2465@@ -282,7 +282,7 @@
2466
2467 def expose_view(self, window, event):
2468 if not self.drawable:
2469- self.drawable = self.get_window(gtk.TEXT_WINDOW_TEXT)
2470+ self.drawable = self.get_window(Gtk.TextWindowType.TEXT)
2471 self.pango_overlay = self.create_pango_layout("")
2472 self.set_overlay_text(MAX_MESSAGE_LENGTH)
2473
2474@@ -298,7 +298,7 @@
2475 def on_text_changed(self, w):
2476 chars = self.get_char_count()
2477 color = self.error_color if chars > MAX_MESSAGE_LENGTH else self.base_color
2478- self.modify_base(gtk.STATE_NORMAL, color)
2479+ self.modify_base(Gtk.StateType.NORMAL, color)
2480
2481 def on_connection_online(self, *args):
2482 self.set_sensitive(True)
2483
2484=== modified file 'gwibber/microblog/dispatcher.py'
2485--- gwibber/microblog/dispatcher.py 2012-02-10 14:22:01 +0000
2486+++ gwibber/microblog/dispatcher.py 2012-02-14 21:35:21 +0000
2487@@ -2,10 +2,12 @@
2488 # -*- coding: utf-8 -*-
2489
2490 import traceback, json, random, string
2491-import gobject, dbus, dbus.service
2492+import dbus, dbus.service
2493 import sqlite3, mx.DateTime, re, uuid
2494 import urlshorter, storage, network, util, uploader
2495 from gettext import lgettext as _
2496+
2497+from gi.repository import GLib
2498 from threading import Thread
2499 from datetime import datetime, timedelta
2500
2501@@ -35,7 +37,7 @@
2502 except:
2503 indicate = None
2504
2505-gobject.threads_init()
2506+GLib.threads_init()
2507
2508 # Dynamically build a list of available service plugins
2509 PROTOCOLS = {}
2510@@ -348,9 +350,9 @@
2511
2512 if autorefresh:
2513 if self.refresh_timer_id:
2514- gobject.source_remove(self.refresh_timer_id)
2515+ GLib.source_remove(self.refresh_timer_id)
2516 # wait a few seconds before alerting the world we are online
2517- self.refresh_timer_id = gobject.timeout_add_seconds(int(10), self.refresh)
2518+ self.refresh_timer_id = GLib.timeout_add_seconds(int(10), self.refresh)
2519
2520 self.accounts_service = util.getbus("Accounts")
2521 self.accounts_service.connect_to_signal("Updated", self.on_account_updated)
2522@@ -387,9 +389,9 @@
2523 def do_maintenance(self, *args):
2524 # perform some needed MessageManager maintenance
2525 if self.maint_timer_id:
2526- gobject.source_remove(self.maint_timer_id)
2527+ GLib.source_remove(self.maint_timer_id)
2528 if self.refreshRunning:
2529- self.maint_timer_id = gobject.timeout_add_seconds(60, self.do_maintenance)
2530+ self.maint_timer_id = GLib.timeout_add_seconds(60, self.do_maintenance)
2531 return False
2532
2533 self.maintRunning = True
2534@@ -401,15 +403,15 @@
2535 def on_connection_online(self, *args):
2536 logger.info("Dispatcher Online, initiating a refresh")
2537 if self.refresh_timer_id:
2538- gobject.source_remove(self.refresh_timer_id)
2539+ GLib.source_remove(self.refresh_timer_id)
2540 # wait a few seconds before alerting the world we are online
2541- self.refresh_timer_id = gobject.timeout_add_seconds(int(10), self.refresh)
2542+ self.refresh_timer_id = GLib.timeout_add_seconds(int(10), self.refresh)
2543
2544 def on_connection_offline(self, *args):
2545 self.refreshRunning = False
2546 logger.info("Dispatcher Offline, suspending operations")
2547 if self.refresh_timer_id:
2548- gobject.source_remove(self.refresh_timer_id)
2549+ GLib.source_remove(self.refresh_timer_id)
2550
2551 def on_account_updated(self, account):
2552 pass
2553@@ -718,7 +720,7 @@
2554 ",".join(self.messages.columns),
2555 ",".join("?" * len(self.messages.columns))), items)
2556
2557- gobject.idle_add (self.update_indicators, self.unseen_counts)
2558+ GLib.idle_add (self.update_indicators, self.unseen_counts)
2559 query = """
2560 SELECT * FROM messages WHERE rowid > {0} AND
2561 ((operation == "receive" AND to_me = 0) OR
2562@@ -857,7 +859,7 @@
2563
2564 def new_search_message(self, data):
2565 message = json.loads(data[-1])
2566- gobject.idle_add(self.cache_avatar, message)
2567+ GLib.idle_add(self.cache_avatar, message)
2568
2569 def new_message(self, data):
2570 message = json.loads(data[-1])
2571@@ -867,10 +869,10 @@
2572 if util.can_notify and str(message["mid"]) not in self.notified_items:
2573 self.notified_items.append(message["mid"])
2574 if gsettings.get_boolean("notify-mentions-only") and message["to_me"]:
2575- gobject.idle_add(self.handle_notify_item, message)
2576+ GLib.idle_add(self.handle_notify_item, message)
2577 elif gsettings.get_boolean("show-notifications") and not gsettings.get_boolean("notify-mentions-only"):
2578- gobject.idle_add(self.handle_notify_item, message)
2579- gobject.idle_add(self.cache_avatar, message)
2580+ GLib.idle_add(self.handle_notify_item, message)
2581+ GLib.idle_add(self.cache_avatar, message)
2582
2583 def handle_notify_item(self, message):
2584 if gsettings.get_boolean("show-fullname"):
2585@@ -918,7 +920,7 @@
2586 def refresh(self, *args):
2587
2588 if self.refresh_timer_id:
2589- gobject.source_remove(self.refresh_timer_id)
2590+ GLib.source_remove(self.refresh_timer_id)
2591
2592 refresh_interval = gsettings.get_int("interval")
2593
2594@@ -937,12 +939,12 @@
2595 self.perform_async_operation(operations)
2596
2597
2598- self.refresh_timer_id = gobject.timeout_add_seconds(int(60 * refresh_interval), self.refresh)
2599+ self.refresh_timer_id = GLib.timeout_add_seconds(int(60 * refresh_interval), self.refresh)
2600 else:
2601- self.refresh_timer_id = gobject.timeout_add_seconds(int(30), self.refresh)
2602+ self.refresh_timer_id = GLib.timeout_add_seconds(int(30), self.refresh)
2603
2604 if not self.maintDone:
2605- self.maint_timer_id = gobject.timeout_add_seconds(60, self.do_maintenance)
2606+ self.maint_timer_id = GLib.timeout_add_seconds(60, self.do_maintenance)
2607
2608 return False
2609
2610
2611=== modified file 'gwibber/microblog/plugins/buzz/gtk/buzz/__init__.py'
2612--- gwibber/microblog/plugins/buzz/gtk/buzz/__init__.py 2011-01-03 21:04:56 +0000
2613+++ gwibber/microblog/plugins/buzz/gtk/buzz/__init__.py 2012-02-14 21:35:21 +0000
2614@@ -1,8 +1,7 @@
2615-import gtk, webkit, gnomekeyring
2616+from gi.repository import GLib, Gtk, WebKit
2617 import urllib, urllib2, json, urlparse, uuid
2618 from oauth import oauth
2619
2620-from gtk import Builder
2621 from gwibber.microblog.util import resources
2622 import gettext
2623 from gettext import gettext as _
2624@@ -10,23 +9,23 @@
2625 gettext.bind_textdomain_codeset('gwibber','UTF-8')
2626 gettext.textdomain('gwibber')
2627
2628-gtk.gdk.threads_init()
2629+GLib.threads_init()
2630
2631 sigmeth = oauth.OAuthSignatureMethod_HMAC_SHA1()
2632
2633-class AccountWidget(gtk.VBox):
2634+class AccountWidget(Gtk.VBox):
2635 """AccountWidget: A widget that provides a user interface for configuring facebook accounts in Gwibber
2636 """
2637
2638 def __init__(self, account=None, dialog=None):
2639 """Creates the account pane for configuring Buzz accounts"""
2640- gtk.VBox.__init__( self, False, 20 )
2641- self.ui = gtk.Builder()
2642+ Gtk.VBox.__init__( self, False, 20 )
2643+ self.ui = Gtk.Builder()
2644 self.ui.set_translation_domain ("gwibber")
2645 self.ui.add_from_file (resources.get_ui_asset("gwibber-accounts-buzz.ui"))
2646 self.ui.connect_signals(self)
2647 self.vbox_settings = self.ui.get_object("vbox_settings")
2648- self.pack_start(self.vbox_settings, False, False)
2649+ self.pack_start(self.vbox_settings, False, False, 0)
2650 self.show_all()
2651
2652 self.account = account or {}
2653@@ -44,7 +43,7 @@
2654 def on_buzz_auth_clicked(self, widget, data=None):
2655 self.winsize = self.window.get_size()
2656
2657- web = webkit.WebView()
2658+ web = WebKit.WebView()
2659 web.get_settings().set_property("enable-plugins", False)
2660 web.load_html_string(_("<p>Please wait...</p>"), "file:///")
2661
2662@@ -71,7 +70,7 @@
2663 web.set_size_request(450, 340)
2664 web.connect("title-changed", self.on_buzz_auth_title_change)
2665
2666- scroll = gtk.ScrolledWindow()
2667+ scroll = Gtk.ScrolledWindow()
2668 scroll.add(web)
2669
2670 self.pack_start(scroll, True, True, 0)
2671@@ -119,8 +118,8 @@
2672 self.ui.get_object("vbox_advanced").show()
2673
2674 if title.get_title() == "Failure":
2675- d = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR,
2676- gtk.BUTTONS_OK, _("Authorization failed. Please try again."))
2677+ d = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR,
2678+ Gtk.ButtonsType.OK, _("Authorization failed. Please try again."))
2679 if d.run(): d.destroy()
2680
2681 web.hide()
2682
2683=== modified file 'gwibber/microblog/plugins/digg/gtk/digg/__init__.py'
2684--- gwibber/microblog/plugins/digg/gtk/digg/__init__.py 2010-10-27 22:36:59 +0000
2685+++ gwibber/microblog/plugins/digg/gtk/digg/__init__.py 2012-02-14 21:35:21 +0000
2686@@ -18,23 +18,22 @@
2687 # Digg widgets for Gwibber
2688 #
2689
2690-import gtk
2691-from gtk import Builder
2692+from gi.repository import Gtk
2693 from gwibber.microblog.util import resources
2694
2695-class AccountWidget(gtk.VBox):
2696+class AccountWidget(Gtk.VBox):
2697 """AccountWidget: A widget that provides a user interface for configuring digg accounts in Gwibber
2698 """
2699
2700 def __init__(self, account=None, dialog=None):
2701 """Creates the account pane for configuring digg accounts"""
2702- gtk.VBox.__init__( self, False, 20 )
2703- self.ui = gtk.Builder()
2704+ Gtk.VBox.__init__( self, False, 20 )
2705+ self.ui = Gtk.Builder()
2706 self.ui.set_translation_domain ("gwibber")
2707 self.ui.add_from_file (resources.get_ui_asset("gwibber-accounts-digg.ui"))
2708 self.ui.connect_signals(self)
2709 self.vbox_settings = self.ui.get_object("vbox_settings")
2710- self.pack_start(self.vbox_settings, False, False)
2711+ self.pack_start(self.vbox_settings, False, False, 0)
2712 self.show_all()
2713 if dialog.ui:
2714 dialog.ui.get_object("vbox_create").show()
2715
2716=== modified file 'gwibber/microblog/plugins/facebook/gtk/facebook/__init__.py'
2717--- gwibber/microblog/plugins/facebook/gtk/facebook/__init__.py 2012-02-10 21:56:20 +0000
2718+++ gwibber/microblog/plugins/facebook/gtk/facebook/__init__.py 2012-02-14 21:35:21 +0000
2719@@ -18,14 +18,14 @@
2720 # facebook widgets for Gwibber
2721 #
2722
2723-import gtk
2724 import urllib
2725-import webkit
2726 import string
2727
2728-from gtk import Builder
2729+from gi.repository import Gdk, Gtk, WebKit, Pango
2730+from gi.repository.Gtk import Builder
2731 from gwibber.microblog.util import resources
2732 from gwibber.microblog.util.const import *
2733+from gwibber.microblog.util.keyring import get_from_keyring
2734 # Try to import * from custom, install custom.py to include packaging
2735 # customizations like distro API keys, etc
2736 try:
2737@@ -33,7 +33,7 @@
2738 except:
2739 pass
2740
2741-import json, urlparse, gnomekeyring, uuid
2742+import json, urlparse, uuid
2743 import gettext
2744 from gettext import gettext as _
2745 if hasattr(gettext, 'bind_textdomain_codeset'):
2746@@ -41,36 +41,36 @@
2747 gettext.textdomain('gwibber')
2748
2749 """
2750-gtk.gdk.threads_init()
2751+Gdk.threads_init()
2752
2753 APP_KEY = "71b85c6d8cb5bbb9f1a3f8bbdcdd4b05"
2754 """
2755
2756-class AccountWidget(gtk.VBox):
2757+class AccountWidget(Gtk.VBox):
2758 """AccountWidget: A widget that provides a user interface for configuring facebook accounts in Gwibber
2759 """
2760
2761 def __init__(self, account=None, dialog=None):
2762 """Creates the account pane for configuring facebook accounts"""
2763- gtk.VBox.__init__( self, False, 20 )
2764- self.ui = gtk.Builder()
2765+ Gtk.VBox.__init__( self, False, 20 )
2766+ self.ui = Gtk.Builder()
2767 self.ui.set_translation_domain ("gwibber")
2768 self.ui.add_from_file (resources.get_ui_asset("gwibber-accounts-facebook.ui"))
2769 self.ui.connect_signals(self)
2770 self.vbox_settings = self.ui.get_object("vbox_settings")
2771- self.pack_start(self.vbox_settings, False, False)
2772+ self.pack_start(self.vbox_settings, False, False, 0)
2773 self.show_all()
2774 if account:
2775 self.account = account
2776 else:
2777 self.account = {}
2778 self.dialog = dialog
2779- has_access_token = True
2780+ self.window = dialog.dialog
2781+ has_access_token = False
2782 if self.account.has_key("id"):
2783- try:
2784- value = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET, {"id": str("%s/%s" % (self.account["id"], "access_token"))})[0].secret
2785- except gnomekeyring.NoMatchError:
2786- has_access_token = False
2787+ has_secret_key = get_from_keyring(self.account['id'],
2788+ 'secret_token') is not None
2789+
2790 try:
2791 if self.account["access_token"] and self.account["username"] and has_access_token and not self.dialog.condition:
2792 self.ui.get_object("hbox_facebook_auth").hide()
2793@@ -85,11 +85,16 @@
2794 if self.dialog.ui:
2795 self.dialog.ui.get_object("vbox_create").hide()
2796
2797+ def console_message_cb (self, *args):
2798+ return True
2799+
2800 def on_facebook_auth_clicked(self, widget, data=None):
2801- (self.win_w, self.win_h) = self.window.get_size()
2802+ self.winsize = self.window.get_size()
2803
2804- web = webkit.WebView()
2805+ web = WebKit.WebView()
2806 web.get_settings().set_property("enable-plugins", False)
2807+ web.get_settings().set_property("enable-developer-extras", False)
2808+ web.connect("console-message", self.console_message_cb)
2809 web.load_html_string(_("<p>Please wait...</p>"), "file:///")
2810
2811 url = urllib.urlencode({
2812@@ -99,31 +104,45 @@
2813 "scope": "publish_stream,read_stream,status_update,offline_access,user_photos,friends_photos",
2814 "redirect_uri": "http://www.facebook.com/connect/login_success.html",
2815 })
2816- web.set_size_request(450, 340)
2817 web.load_uri("https://graph.facebook.com/oauth/authorize?" + url)
2818 web.connect("title-changed", self.on_facebook_auth_title_change)
2819
2820- scroll = gtk.ScrolledWindow()
2821- scroll.add(web)
2822+ self.scroll = Gtk.ScrolledWindow()
2823+
2824+ self.scroll.add(web)
2825+ self.scroll.set_size_request(450, 340)
2826
2827- self.pack_start(scroll, True, True, 0)
2828+ self.pack_start(self.scroll, True, True, 0)
2829 self.show_all()
2830 self.ui.get_object("vbox1").hide()
2831 self.ui.get_object("vbox_advanced").hide()
2832
2833 def on_facebook_auth_title_change(self, web=None, title=None, data=None):
2834 saved = False
2835+ if hasattr(self.dialog, "infobar_content_area"):
2836+ for child in self.dialog.infobar_content_area.get_children(): child.destroy()
2837+ self.dialog.infobar_content_area = self.dialog.infobar.get_content_area()
2838+ self.dialog.infobar_content_area.show()
2839+
2840 url = web.get_main_frame().get_uri()
2841 if title.get_title() == "Success":
2842- url = web.get_main_frame().get_uri()
2843 try:
2844 self.account["access_token"] = str(urlparse.parse_qs(url.split("#", 1)[1])["access_token"][0])
2845 except:
2846- web.hide()
2847+ self.scroll.destroy()
2848 self.ui.get_object("vbox1").show()
2849 self.ui.get_object("vbox_advanced").show()
2850+ self.window.resize(*self.winsize)
2851+ self.dialog.select_account ()
2852 return
2853
2854+ message_label = Gtk.Label (_("Verifying"))
2855+ message_label.set_use_markup(True)
2856+ message_label.set_ellipsize(Pango.EllipsizeMode.END)
2857+ self.dialog.infobar_content_area.add(message_label)
2858+ self.dialog.infobar.show_all()
2859+ self.scroll.destroy()
2860+
2861 data = json.loads(urllib.urlopen("https://graph.facebook.com/me?access_token=" + self.account["access_token"]).read())
2862 if isinstance(data, dict):
2863 if data.has_key("id") and data.has_key("name"):
2864@@ -143,6 +162,10 @@
2865 else:
2866 print "Failed"
2867
2868+ if saved:
2869+ message_label.set_text(_("Successful"))
2870+ self.dialog.infobar.set_message_type(Gtk.MessageType.INFO)
2871+
2872 self.ui.get_object("hbox_facebook_auth").hide()
2873 self.ui.get_object("fb_auth_done_label").set_label(_("%s has been authorized by Facebook") % str(self.account["username"]))
2874 self.ui.get_object("hbox_facebook_auth_done").show()
2875@@ -151,17 +174,22 @@
2876 elif self.dialog.ui and not saved:
2877 self.dialog.ui.get_object("vbox_create").show()
2878
2879- web.hide()
2880- self.window.resize(self.win_w, self.win_h)
2881 self.ui.get_object("vbox1").show()
2882 self.ui.get_object("vbox_advanced").show()
2883+ self.window.resize(*self.winsize)
2884+ self.dialog.select_account ()
2885
2886 if title.get_title() == "Failure":
2887- gtk.gdk.threads_enter()
2888- d = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR,
2889- gtk.BUTTONS_OK, _("Facebook authorization failed. Please try again."))
2890- if d.run(): d.destroy()
2891- gtk.gdk.threads_leave()
2892-
2893- web.hide()
2894- self.window.resize(self.win_w, self.win_h)
2895+ self.dialog.infobar.set_message_type(Gtk.MessageType.ERROR)
2896+ message_label = Gtk.Label (_("Authorization failed. Please try again."))
2897+ message_label.set_use_markup(True)
2898+ message_label.set_ellipsize(Pango.EllipsizeMode.END)
2899+ self.dialog.infobar_content_area.add(message_label)
2900+ self.dialog.infobar.show_all()
2901+
2902+ self.ui.get_object("vbox1").show()
2903+ self.ui.get_object("vbox_advanced").show()
2904+ self.scroll.destroy()
2905+ self.window.resize(*self.winsize)
2906+ self.dialog.select_account ()
2907+
2908
2909=== modified file 'gwibber/microblog/plugins/flickr/gtk/flickr/__init__.py'
2910--- gwibber/microblog/plugins/flickr/gtk/flickr/__init__.py 2010-11-18 05:02:37 +0000
2911+++ gwibber/microblog/plugins/flickr/gtk/flickr/__init__.py 2012-02-14 21:35:21 +0000
2912@@ -18,23 +18,22 @@
2913 # Flickr widgets for Gwibber
2914 #
2915
2916-import gtk
2917-from gtk import Builder
2918+from gi.repository import Gtk
2919 from gwibber.microblog.util import resources
2920
2921-class AccountWidget(gtk.VBox):
2922+class AccountWidget(Gtk.VBox):
2923 """AccountWidget: A widget that provides a user interface for configuring flickr accounts in Gwibber
2924 """
2925
2926 def __init__(self, account=None, dialog=None):
2927 """Creates the account pane for configuring flickr accounts"""
2928- gtk.VBox.__init__( self, False, 20 )
2929- self.ui = gtk.Builder()
2930+ Gtk.VBox.__init__( self, False, 20 )
2931+ self.ui = Gtk.Builder()
2932 self.ui.set_translation_domain ("gwibber")
2933 self.ui.add_from_file (resources.get_ui_asset("gwibber-accounts-flickr.ui"))
2934 self.ui.connect_signals(self)
2935 self.vbox_settings = self.ui.get_object("vbox_settings")
2936- self.pack_start(self.vbox_settings, False, False)
2937+ self.pack_start(self.vbox_settings, False, False, 0)
2938 self.show_all()
2939 if dialog.ui:
2940 dialog.ui.get_object("vbox_create").show()
2941
2942=== modified file 'gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py'
2943--- gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py 2011-07-28 23:57:24 +0000
2944+++ gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py 2012-02-14 21:35:21 +0000
2945@@ -1,16 +1,16 @@
2946-import gtk, pango, webkit, gnomekeyring
2947+from gi.repository import GLib, Gtk, Pango, WebKit
2948 import urllib, urllib2, json, urlparse, uuid
2949 from oauth import oauth
2950
2951-from gtk import Builder
2952 from gwibber.microblog.util import resources
2953+from gwibber.microblog.util.keyring import get_from_keyring
2954 import gettext
2955 from gettext import gettext as _
2956 if hasattr(gettext, 'bind_textdomain_codeset'):
2957 gettext.bind_textdomain_codeset('gwibber','UTF-8')
2958 gettext.textdomain('gwibber')
2959
2960-gtk.gdk.threads_init()
2961+GLib.threads_init()
2962
2963 sigmeth = oauth.OAuthSignatureMethod_HMAC_SHA1()
2964
2965@@ -18,29 +18,28 @@
2966 CLIENT_SECRET = "TS1LGTEZSJATQG22K5SXNASF021KPXI5LJTBQOVTX4JGOTYH"
2967 REDIRECT_URI = "http://gwibber.com/0/auth.html"
2968
2969-class AccountWidget(gtk.VBox):
2970+class AccountWidget(Gtk.VBox):
2971 """AccountWidget: A widget that provides a user interface for configuring foursquare accounts in Gwibber
2972 """
2973
2974 def __init__(self, account=None, dialog=None):
2975 """Creates the account pane for configuring Foursquare accounts"""
2976- gtk.VBox.__init__( self, False, 20 )
2977- self.ui = gtk.Builder()
2978+ Gtk.VBox.__init__( self, False, 20 )
2979+ self.ui = Gtk.Builder()
2980 self.ui.set_translation_domain ("gwibber")
2981 self.ui.add_from_file (resources.get_ui_asset("gwibber-accounts-foursquare.ui"))
2982 self.ui.connect_signals(self)
2983 self.vbox_settings = self.ui.get_object("vbox_settings")
2984- self.pack_start(self.vbox_settings, False, False)
2985+ self.pack_start(self.vbox_settings, False, False, 0)
2986 self.show_all()
2987
2988 self.account = account or {}
2989 self.dialog = dialog
2990- has_secret_key = True
2991+ self.window = dialog.dialog
2992+ has_secret_key = False
2993 if self.account.has_key("id"):
2994- try:
2995- value = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET, {"id": str("%s/%s" % (self.account["id"], "secret_token"))})[0].secret
2996- except gnomekeyring.NoMatchError:
2997- has_secret_key = False
2998+ has_secret_key = get_from_keyring(self.account['id'],
2999+ 'secret_token') is not None
3000
3001 try:
3002 if self.account.has_key("access_token") and self.account.has_key("secret_token") and self.account.has_key("username") and has_secret_key and not self.dialog.condition:
3003@@ -56,21 +55,25 @@
3004 if self.dialog.ui:
3005 self.dialog.ui.get_object("vbox_create").hide()
3006
3007+ def console_message_cb (self, *args):
3008+ return True
3009
3010 def on_foursquare_auth_clicked(self, widget, data=None):
3011 self.winsize = self.window.get_size()
3012
3013- web = webkit.WebView()
3014+ web = WebKit.WebView()
3015 web.get_settings().set_property("enable-plugins", False)
3016+ web.get_settings().set_property("enable-developer-extras", False)
3017+ web.connect("console-message", self.console_message_cb)
3018 web.load_html_string(_("<p>Please wait...</p>"), "file:///")
3019
3020 url = 'https://foursquare.com/oauth2/authenticate?client_id=' + CLIENT_ID + '&response_type=code&display=touch&redirect_uri='+ REDIRECT_URI
3021
3022 web.load_uri(url)
3023- web.set_size_request(500, 400)
3024 web.connect("title-changed", self.on_foursquare_auth_title_change)
3025
3026- self.scroll = gtk.ScrolledWindow()
3027+ self.scroll = Gtk.ScrolledWindow()
3028+ self.scroll.set_size_request(500, 400)
3029 self.scroll.add(web)
3030
3031 self.pack_start(self.scroll, True, True, 0)
3032@@ -78,24 +81,22 @@
3033
3034 self.ui.get_object("vbox1").hide()
3035 self.ui.get_object("vbox_advanced").hide()
3036- self.dialog.infobar.set_message_type(gtk.MESSAGE_INFO)
3037+ self.dialog.infobar.set_message_type(Gtk.MessageType.INFO)
3038
3039 def on_foursquare_auth_title_change(self, web=None, title=None, data=None):
3040 saved = False
3041+ if hasattr(self.dialog, "infobar_content_area"):
3042+ for child in self.dialog.infobar_content_area.get_children(): child.destroy()
3043+ self.dialog.infobar_content_area = self.dialog.infobar.get_content_area()
3044+ self.dialog.infobar_content_area.show()
3045+
3046 if title.get_title() == "Success":
3047-
3048- if hasattr(self.dialog, "infobar_content_area"):
3049- for child in self.dialog.infobar_content_area.get_children(): child.destroy()
3050- self.dialog.infobar_content_area = self.dialog.infobar.get_content_area()
3051- self.dialog.infobar_content_area.show()
3052- self.dialog.infobar.show()
3053-
3054- message_label = gtk.Label(_("Verifying"))
3055+ message_label = Gtk.Label(_("Verifying"))
3056 message_label.set_use_markup(True)
3057- message_label.set_ellipsize(pango.ELLIPSIZE_END)
3058+ message_label.set_ellipsize(Pango.EllipsizeMode.END)
3059 self.dialog.infobar_content_area.add(message_label)
3060 self.dialog.infobar.show_all()
3061- self.scroll.hide()
3062+ self.scroll.destroy()
3063
3064 #Get the code from the callback uri (it's formatted as http://gwibber.com/0/auth.html/?code=CODE)
3065 url = web.get_main_frame().get_uri()
3066@@ -128,16 +129,16 @@
3067 saved = self.dialog.on_edit_account_save()
3068 else:
3069 print "Failed"
3070- self.dialog.infobar.set_message_type(gtk.MESSAGE_ERROR)
3071+ self.dialog.infobar.set_message_type(Gtk.MessageType.ERROR)
3072 message_label.set_text(_("Authorization failed. Please try again."))
3073 else:
3074 print "Failed"
3075- self.dialog.infobar.set_message_type(gtk.MESSAGE_ERROR)
3076+ self.dialog.infobar.set_message_type(Gtk.MessageType.ERROR)
3077 message_label.set_text(_("Authorization failed. Please try again."))
3078
3079 if saved:
3080 message_label.set_text(_("Successful"))
3081- self.dialog.infobar.set_message_type(gtk.MESSAGE_INFO)
3082+ self.dialog.infobar.set_message_type(Gtk.MessageType.INFO)
3083 #self.dialog.infobar.hide()
3084
3085 self.ui.get_object("hbox_foursquare_auth").hide()
3086@@ -148,14 +149,18 @@
3087 elif self.dialog.ui and not saved:
3088 self.dialog.ui.get_object("vbox_create").show()
3089
3090- self.window.resize(*self.winsize)
3091+ self.window.resize(*self.winsize)
3092
3093 if title.get_title() == "Failure":
3094- web.hide()
3095- self.dialog.infobar.set_message_type(gtk.MESSAGE_ERROR)
3096- message_label.set_text(_("Authorization failed. Please try again."))
3097+ self.dialog.infobar.set_message_type(Gtk.MessageType.ERROR)
3098+ message_label = Gtk.Label(_("Authorization failed. Please try again."))
3099+ message_label.set_use_markup(True)
3100+ message_label.set_ellipsize(Pango.EllipsizeMode.END)
3101+ self.dialog.infobar_content_area.add(message_label)
3102 self.dialog.infobar.show_all()
3103
3104 self.ui.get_object("vbox1").show()
3105 self.ui.get_object("vbox_advanced").show()
3106+ self.scroll.destroy()
3107 self.window.resize(*self.winsize)
3108+
3109
3110=== modified file 'gwibber/microblog/plugins/friendfeed/gtk/friendfeed/__init__.py'
3111--- gwibber/microblog/plugins/friendfeed/gtk/friendfeed/__init__.py 2010-10-27 22:36:59 +0000
3112+++ gwibber/microblog/plugins/friendfeed/gtk/friendfeed/__init__.py 2012-02-14 21:35:21 +0000
3113@@ -18,23 +18,22 @@
3114 # FriendFeed widgets for Gwibber
3115 #
3116
3117-import gtk
3118-from gtk import Builder
3119+from gi.repository import Gtk
3120 from gwibber.microblog.util import resources
3121
3122-class AccountWidget(gtk.VBox):
3123+class AccountWidget(Gtk.VBox):
3124 """AccountWidget: A widget that provides a user interface for configuring friendfeed accounts in Gwibber
3125 """
3126
3127 def __init__(self, account=None, dialog=None):
3128 """Creates the account pane for configuring friendfeed accounts"""
3129- gtk.VBox.__init__( self, False, 20 )
3130- self.ui = gtk.Builder()
3131+ Gtk.VBox.__init__( self, False, 20 )
3132+ self.ui = Gtk.Builder()
3133 self.ui.set_translation_domain ("gwibber")
3134 self.ui.add_from_file (resources.get_ui_asset("gwibber-accounts-friendfeed.ui"))
3135 self.ui.connect_signals(self)
3136 self.vbox_settings = self.ui.get_object("vbox_settings")
3137- self.pack_start(self.vbox_settings, False, False)
3138+ self.pack_start(self.vbox_settings, False, False, 0)
3139 self.show_all()
3140 if dialog.ui:
3141 dialog.ui.get_object("vbox_create").show()
3142
3143=== modified file 'gwibber/microblog/plugins/identica/gtk/identica/__init__.py'
3144--- gwibber/microblog/plugins/identica/gtk/identica/__init__.py 2011-01-03 21:04:56 +0000
3145+++ gwibber/microblog/plugins/identica/gtk/identica/__init__.py 2012-02-14 21:35:21 +0000
3146@@ -1,45 +1,43 @@
3147-import gtk, webkit, gnomekeyring
3148+from gi.repository import GLib, Gtk, WebKit
3149 import urllib, urllib2, json, urlparse, uuid
3150 from oauth import oauth
3151
3152-from gtk import Builder
3153-import gwibber.microblog
3154 from gwibber.microblog.util import resources
3155+from gwibber.microblog.util.keyring import get_from_keyring
3156 import gettext
3157 from gettext import gettext as _
3158 if hasattr(gettext, 'bind_textdomain_codeset'):
3159 gettext.bind_textdomain_codeset('gwibber','UTF-8')
3160 gettext.textdomain('gwibber')
3161
3162-gtk.gdk.threads_init()
3163+GLib.threads_init()
3164
3165 sigmeth = oauth.OAuthSignatureMethod_HMAC_SHA1()
3166
3167
3168-class AccountWidget(gtk.VBox):
3169+class AccountWidget(Gtk.VBox):
3170 """AccountWidget: A widget that provides a user interface for configuring identi.ca accounts in Gwibber
3171 """
3172
3173 def __init__(self, account=None, dialog=None):
3174 """Creates the account pane for configuring identi.ca accounts"""
3175- gtk.VBox.__init__( self, False, 20 )
3176- self.ui = gtk.Builder()
3177+ Gtk.VBox.__init__( self, False, 20 )
3178+ self.ui = Gtk.Builder()
3179 self.ui.set_translation_domain ("gwibber")
3180 self.ui.add_from_file (resources.get_ui_asset("gwibber-accounts-identica.ui"))
3181 self.ui.connect_signals(self)
3182 self.vbox_settings = self.ui.get_object("vbox_settings")
3183- self.pack_start(self.vbox_settings, False, False)
3184+ self.pack_start(self.vbox_settings, False, False, 0)
3185 self.show_all()
3186
3187 self.account = account or {}
3188 self.dialog = dialog
3189+ self.window = dialog.dialog
3190 self.url_prefix = "https://identi.ca"
3191- has_secret_key = True
3192+ has_secret_key = False
3193 if self.account.has_key("id"):
3194- try:
3195- value = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET, {"id": str("%s/%s" % (self.account["id"], "secret_token"))})[0].secret
3196- except gnomekeyring.NoMatchError:
3197- has_secret_key = False
3198+ has_secret_key = get_from_keyring(self.account['id'],
3199+ 'secret_token') is not None
3200
3201 try:
3202 if self.account.has_key("access_token") and self.account.has_key("secret_token") and self.account.has_key("username") and has_secret_key:
3203@@ -55,11 +53,17 @@
3204 if self.dialog.ui:
3205 self.dialog.ui.get_object("vbox_create").hide()
3206
3207+ def console_message_cb (self, *args):
3208+ return True
3209+
3210 def on_statusnet_auth_clicked(self, widget, data=None):
3211 self.winsize = self.window.get_size()
3212
3213- web = webkit.WebView()
3214+ web = WebKit.WebView()
3215 web.get_settings().set_property("enable-plugins", False)
3216+ web.get_settings().set_property("enable-developer-extras", False)
3217+ web.connect("console-message", self.console_message_cb)
3218+
3219 web.load_html_string(_("<p>Please wait...</p>"), "file:///")
3220
3221 self.consumer = oauth.OAuthConsumer("anonymous", "anonymous")
3222@@ -76,15 +80,13 @@
3223 url = self.url_prefix + "/api/oauth/authorize?mode=desktop&oauth_token=" + self.token.key
3224
3225 web.load_uri(url)
3226- #web.set_size_request(500, 420)
3227- web.set_size_request(550, 400)
3228-
3229 web.connect("title-changed", self.on_statusnet_auth_title_change)
3230
3231- scroll = gtk.ScrolledWindow()
3232- scroll.add(web)
3233+ self.scroll = Gtk.ScrolledWindow()
3234+ self.scroll.set_size_request(550, 400)
3235+ self.scroll.add(web)
3236
3237- self.pack_start(scroll, True, True, 0)
3238+ self.pack_start(self.scroll, True, True, 0)
3239 self.show_all()
3240
3241 self.ui.get_object("vbox1").hide()
3242@@ -202,15 +204,11 @@
3243 except:
3244 pass
3245
3246- web.hide()
3247- self.window.resize(*self.winsize)
3248 self.ui.get_object("vbox1").show()
3249 self.ui.get_object("vbox_advanced").show()
3250+ self.scroll.destroy ()
3251+ self.window.resize(*self.winsize)
3252
3253 if title.get_title() == "Failure":
3254- d = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR,
3255- gtk.BUTTONS_OK, _("Authorization failed. Please try again."))
3256- if d.run(): d.destroy()
3257-
3258- web.hide()
3259+ self.scroll.destroy ()
3260 self.window.resize(*self.winsize)
3261
3262=== modified file 'gwibber/microblog/plugins/pingfm/gtk/pingfm/__init__.py'
3263--- gwibber/microblog/plugins/pingfm/gtk/pingfm/__init__.py 2010-10-27 22:36:59 +0000
3264+++ gwibber/microblog/plugins/pingfm/gtk/pingfm/__init__.py 2012-02-14 21:35:21 +0000
3265@@ -18,23 +18,22 @@
3266 # Ping.fm widgets for Gwibber
3267 #
3268
3269-import gtk
3270-from gtk import Builder
3271+from gi.repository import Gtk
3272 from gwibber.microblog.util import resources
3273
3274-class AccountWidget(gtk.VBox):
3275+class AccountWidget(Gtk.VBox):
3276 """AccountWidget: A widget that provides a user interface for configuring pingfm accounts in Gwibber
3277 """
3278
3279 def __init__(self, account=None, dialog=None):
3280 """Creates the account pane for configuring pingfm accounts"""
3281- gtk.VBox.__init__( self, False, 20 )
3282- self.ui = gtk.Builder()
3283+ Gtk.VBox.__init__( self, False, 20 )
3284+ self.ui = Gtk.Builder()
3285 self.ui.set_translation_domain ("gwibber")
3286 self.ui.add_from_file (resources.get_ui_asset("gwibber-accounts-pingfm.ui"))
3287 self.ui.connect_signals(self)
3288 self.vbox_settings = self.ui.get_object("vbox_settings")
3289- self.pack_start(self.vbox_settings, False, False)
3290+ self.pack_start(self.vbox_settings, False, False, 0)
3291 self.show_all()
3292 if dialog.ui:
3293 dialog.ui.get_object("vbox_create").show()
3294
3295=== modified file 'gwibber/microblog/plugins/qaiku/gtk/qaiku/__init__.py'
3296--- gwibber/microblog/plugins/qaiku/gtk/qaiku/__init__.py 2010-10-27 22:36:59 +0000
3297+++ gwibber/microblog/plugins/qaiku/gtk/qaiku/__init__.py 2012-02-14 21:35:21 +0000
3298@@ -18,23 +18,22 @@
3299 # Twitter widgets for Gwibber
3300 #
3301
3302-import gtk
3303-from gtk import Builder
3304+from gi.repository import Gtk
3305 from gwibber.microblog.util import resources
3306
3307-class AccountWidget(gtk.VBox):
3308+class AccountWidget(Gtk.VBox):
3309 """AccountWidget: A widget that provides a user interface for configuring qaiku accounts in Gwibber
3310 """
3311
3312 def __init__(self, account=None, dialog=None):
3313 """Creates the account pane for configuring qaiku accounts"""
3314- gtk.VBox.__init__( self, False, 20 )
3315- self.ui = gtk.Builder()
3316+ Gtk.VBox.__init__( self, False, 20 )
3317+ self.ui = Gtk.Builder()
3318 self.ui.set_translation_domain ("gwibber")
3319 self.ui.add_from_file (resources.get_ui_asset("gwibber-accounts-qaiku.ui"))
3320 self.ui.connect_signals(self)
3321 self.vbox_settings = self.ui.get_object("vbox_settings")
3322- self.pack_start(self.vbox_settings, False, False)
3323+ self.pack_start(self.vbox_settings, False, False, 0)
3324 self.show_all()
3325 if dialog.ui:
3326 dialog.ui.get_object("vbox_create").show()
3327
3328=== modified file 'gwibber/microblog/plugins/statusnet/gtk/statusnet/__init__.py'
3329--- gwibber/microblog/plugins/statusnet/gtk/statusnet/__init__.py 2011-01-03 21:04:56 +0000
3330+++ gwibber/microblog/plugins/statusnet/gtk/statusnet/__init__.py 2012-02-14 21:35:21 +0000
3331@@ -1,44 +1,45 @@
3332-import gtk, webkit, gnomekeyring
3333+from gi.repository import GLib, Gtk, WebKit
3334 import urllib, urllib2, json, urlparse, uuid
3335 from oauth import oauth
3336
3337-from gtk import Builder
3338-import gwibber.microblog
3339 from gwibber.microblog.util import resources
3340+from gwibber.microblog.util.keyring import get_from_keyring
3341 import gettext
3342 from gettext import gettext as _
3343 if hasattr(gettext, 'bind_textdomain_codeset'):
3344 gettext.bind_textdomain_codeset('gwibber','UTF-8')
3345 gettext.textdomain('gwibber')
3346
3347-gtk.gdk.threads_init()
3348+GLib.threads_init()
3349
3350 sigmeth = oauth.OAuthSignatureMethod_HMAC_SHA1()
3351
3352
3353-class AccountWidget(gtk.VBox):
3354+class AccountWidget(Gtk.VBox):
3355 """AccountWidget: A widget that provides a user interface for configuring statusnet accounts in Gwibber
3356 """
3357
3358 def __init__(self, account=None, dialog=None):
3359 """Creates the account pane for configuring statusnet accounts"""
3360- gtk.VBox.__init__( self, False, 20 )
3361- self.ui = gtk.Builder()
3362+ Gtk.VBox.__init__( self, False, 20 )
3363+ self.set_homogeneous(False)
3364+ self.set_vexpand(True)
3365+ self.set_hexpand(True)
3366+ self.ui = Gtk.Builder()
3367 self.ui.set_translation_domain ("gwibber")
3368 self.ui.add_from_file (resources.get_ui_asset("gwibber-accounts-statusnet.ui"))
3369 self.ui.connect_signals(self)
3370 self.vbox_settings = self.ui.get_object("vbox_settings")
3371- self.pack_start(self.vbox_settings, False, False)
3372+ self.pack_start(self.vbox_settings, True, True, 0)
3373 self.show_all()
3374
3375 self.account = account or {}
3376 self.dialog = dialog
3377- has_secret_key = True
3378+ self.window = dialog.dialog
3379+ has_secret_key = False
3380 if self.account.has_key("id"):
3381- try:
3382- value = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET, {"id": str("%s/%s" % (self.account["id"], "secret_token"))})[0].secret
3383- except gnomekeyring.NoMatchError:
3384- has_secret_key = False
3385+ has_secret_key = get_from_keyring(self.account['id'],
3386+ 'secret_token') is not None
3387
3388 try:
3389 if self.account.has_key("access_token") and self.account.has_key("secret_token") and self.account.has_key("username") and has_secret_key:
3390@@ -60,6 +61,9 @@
3391 if self.dialog.ui:
3392 self.dialog.ui.get_object("vbox_create").hide()
3393
3394+ def console_message_cb (self, *args):
3395+ return True
3396+
3397 def on_statusnet_auth_clicked(self, widget, data=None):
3398 self.url_prefix = self.ui.get_object("url_prefix").get_text()
3399 pref = "" if self.url_prefix.startswith("http") else "https://"
3400@@ -68,8 +72,10 @@
3401
3402 self.winsize = self.window.get_size()
3403
3404- web = webkit.WebView()
3405+ web = WebKit.WebView()
3406 web.get_settings().set_property("enable-plugins", False)
3407+ web.get_settings().set_property("enable-developer-extras", False)
3408+ web.connect("console-message", self.console_message_cb)
3409 web.load_html_string(_("<p>Please wait...</p>"), "file:///")
3410
3411 self.consumer = oauth.OAuthConsumer("anonymous", "anonymous")
3412@@ -86,15 +92,14 @@
3413 url = self.url_prefix + "/api/oauth/authorize?mode=desktop&oauth_token=" + self.token.key
3414
3415 web.load_uri(url)
3416- #web.set_size_request(500, 420)
3417- web.set_size_request(550, 400)
3418
3419 web.connect("title-changed", self.on_statusnet_auth_title_change)
3420
3421- scroll = gtk.ScrolledWindow()
3422- scroll.add(web)
3423+ self.scroll = Gtk.ScrolledWindow()
3424+ self.scroll.set_size_request(550, 400)
3425+ self.scroll.add(web)
3426
3427- self.pack_start(scroll, True, True, 0)
3428+ self.pack_start(self.scroll, True, True, 0)
3429 self.show_all()
3430
3431 self.ui.get_object("table_common_settings").hide()
3432@@ -215,16 +220,12 @@
3433 except:
3434 pass
3435
3436- web.hide()
3437- self.window.resize(*self.winsize)
3438 self.ui.get_object("table_common_settings").show()
3439 self.ui.get_object("vbox1").show()
3440 self.ui.get_object("vbox_advanced").show()
3441+ self.scroll.destroy()
3442+ self.window.resize(*self.winsize)
3443
3444 if title.get_title() == "Failure":
3445- d = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR,
3446- gtk.BUTTONS_OK, _("Authorization failed. Please try again."))
3447- if d.run(): d.destroy()
3448-
3449- web.hide()
3450+ self.scroll.destroy()
3451 self.window.resize(*self.winsize)
3452
3453=== modified file 'gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py'
3454--- gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py 2011-08-02 17:03:52 +0000
3455+++ gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py 2012-02-14 21:35:21 +0000
3456@@ -1,42 +1,41 @@
3457-import gtk, pango, webkit, gnomekeyring
3458+from gi.repository import GLib, Gtk, Pango, WebKit
3459 import urllib, urllib2, json, urlparse, uuid
3460 from oauth import oauth
3461
3462-from gtk import Builder
3463 from gwibber.microblog.util import resources
3464+from gwibber.microblog.util.keyring import get_from_keyring
3465 import gettext
3466 from gettext import gettext as _
3467 if hasattr(gettext, 'bind_textdomain_codeset'):
3468 gettext.bind_textdomain_codeset('gwibber','UTF-8')
3469 gettext.textdomain('gwibber')
3470
3471-gtk.gdk.threads_init()
3472+GLib.threads_init()
3473
3474 sigmeth = oauth.OAuthSignatureMethod_HMAC_SHA1()
3475
3476-class AccountWidget(gtk.VBox):
3477+class AccountWidget(Gtk.VBox):
3478 """AccountWidget: A widget that provides a user interface for configuring twitter accounts in Gwibber
3479 """
3480
3481 def __init__(self, account=None, dialog=None):
3482 """Creates the account pane for configuring Twitter accounts"""
3483- gtk.VBox.__init__( self, False, 20 )
3484- self.ui = gtk.Builder()
3485+ Gtk.VBox.__init__( self, False, 20 )
3486+ self.ui = Gtk.Builder()
3487 self.ui.set_translation_domain ("gwibber")
3488 self.ui.add_from_file (resources.get_ui_asset("gwibber-accounts-twitter.ui"))
3489 self.ui.connect_signals(self)
3490 self.vbox_settings = self.ui.get_object("vbox_settings")
3491- self.pack_start(self.vbox_settings, False, False)
3492+ self.pack_start(self.vbox_settings, True, True, 0)
3493 self.show_all()
3494
3495 self.account = account or {}
3496 self.dialog = dialog
3497- has_secret_key = True
3498+ self.window = dialog.dialog
3499+ has_secret_key = False
3500 if self.account.has_key("id"):
3501- try:
3502- value = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET, {"id": str("%s/%s" % (self.account["id"], "secret_token"))})[0].secret
3503- except gnomekeyring.NoMatchError:
3504- has_secret_key = False
3505+ has_secret_key = get_from_keyring(self.account['id'],
3506+ 'secret_token') is not None
3507
3508 try:
3509 if self.account.has_key("access_token") and self.account.has_key("secret_token") and self.account.has_key("username") and has_secret_key and not self.dialog.condition:
3510@@ -53,11 +52,16 @@
3511 self.dialog.ui.get_object("vbox_create").hide()
3512
3513
3514+ def console_message_cb (self, *args):
3515+ return True
3516+
3517 def on_twitter_auth_clicked(self, widget, data=None):
3518 self.winsize = self.window.get_size()
3519
3520- web = webkit.WebView()
3521+ web = WebKit.WebView()
3522 web.get_settings().set_property("enable-plugins", False)
3523+ web.get_settings().set_property("enable-developer-extras", False)
3524+ web.connect("console-message", self.console_message_cb)
3525 web.load_html_string(_("<p>Please wait...</p>"), "file:///")
3526
3527 self.consumer = oauth.OAuthConsumer(*resources.get_twitter_keys())
3528@@ -74,10 +78,10 @@
3529 url = "http://api.twitter.com/oauth/authorize?oauth_token=" + self.token.key
3530
3531 web.load_uri(url)
3532- web.set_size_request(550, 450)
3533 web.connect("title-changed", self.on_twitter_auth_title_change)
3534
3535- self.scroll = gtk.ScrolledWindow()
3536+ self.scroll = Gtk.ScrolledWindow()
3537+ self.scroll.set_size_request(550, 450)
3538 self.scroll.add(web)
3539
3540 self.pack_start(self.scroll, True, True, 0)
3541@@ -85,24 +89,29 @@
3542
3543 self.ui.get_object("vbox1").hide()
3544 self.ui.get_object("vbox_advanced").hide()
3545- self.dialog.infobar.set_message_type(gtk.MESSAGE_INFO)
3546+ self.dialog.infobar.set_message_type(Gtk.MessageType.INFO)
3547
3548 def on_twitter_auth_title_change(self, web=None, title=None, data=None):
3549 saved = False
3550+ uri = title.get_uri ()
3551+ if hasattr(self.dialog, "infobar_content_area"):
3552+ for child in self.dialog.infobar_content_area.get_children(): child.destroy()
3553+ self.dialog.infobar_content_area = self.dialog.infobar.get_content_area()
3554+ self.dialog.infobar_content_area.show()
3555+ #self.dialog.infobar.show()
3556+
3557 if title.get_title() == "Success":
3558-
3559- if hasattr(self.dialog, "infobar_content_area"):
3560- for child in self.dialog.infobar_content_area.get_children(): child.destroy()
3561- self.dialog.infobar_content_area = self.dialog.infobar.get_content_area()
3562- self.dialog.infobar_content_area.show()
3563- self.dialog.infobar.show()
3564-
3565- message_label = gtk.Label(_("Verifying"))
3566+ if "denied" in uri:
3567+ self.scroll.destroy()
3568+ self.window.resize(*self.winsize)
3569+ return
3570+
3571+ message_label = Gtk.Label (_("Verifying"))
3572 message_label.set_use_markup(True)
3573- message_label.set_ellipsize(pango.ELLIPSIZE_END)
3574+ message_label.set_ellipsize(Pango.EllipsizeMode.END)
3575 self.dialog.infobar_content_area.add(message_label)
3576 self.dialog.infobar.show_all()
3577- self.scroll.hide()
3578+ self.scroll.destroy()
3579 url = web.get_main_frame().get_uri()
3580 data = urlparse.parse_qs(url.split("?", 1)[1])
3581
3582@@ -142,16 +151,18 @@
3583 saved = self.dialog.on_edit_account_save()
3584 else:
3585 print "Failed"
3586- self.dialog.infobar.set_message_type(gtk.MESSAGE_ERROR)
3587- message_label.set_text(_("Authorization failed. Please try again."))
3588+ self.dialog.infobar.set_message_type(Gtk.MessageType.ERROR)
3589+ message_label.set_text (_("Authorization failed. Please try again."))
3590+ self.dialog.infobar_content_area.add(message_label)
3591+ self.dialog.infobar.show_all()
3592 else:
3593 print "Failed"
3594- self.dialog.infobar.set_message_type(gtk.MESSAGE_ERROR)
3595+ self.dialog.infobar.set_message_type(Gtk.MessageType.ERROR)
3596 message_label.set_text(_("Authorization failed. Please try again."))
3597
3598 if saved:
3599 message_label.set_text(_("Successful"))
3600- self.dialog.infobar.set_message_type(gtk.MESSAGE_INFO)
3601+ self.dialog.infobar.set_message_type(Gtk.MessageType.INFO)
3602 #self.dialog.infobar.hide()
3603
3604 self.ui.get_object("hbox_twitter_auth").hide()
3605@@ -162,12 +173,17 @@
3606 elif self.dialog.ui and not saved:
3607 self.dialog.ui.get_object("vbox_create").show()
3608
3609- self.window.resize(*self.winsize)
3610+ self.window.resize(*self.winsize)
3611
3612 if title.get_title() == "Failure":
3613- web.hide()
3614- self.dialog.infobar.set_message_type(gtk.MESSAGE_ERROR)
3615- message_label.set_text(_("Authorization failed. Please try again."))
3616+ self.scroll.destroy()
3617+ self.window.resize(*self.winsize)
3618+ self.scroll.destroy()
3619+ self.dialog.infobar.set_message_type(Gtk.MessageType.ERROR)
3620+ message_label = Gtk.Label (_("Authorization failed. Please try again."))
3621+ message_label.set_use_markup(True)
3622+ message_label.set_ellipsize(Pango.EllipsizeMode.END)
3623+ self.dialog.infobar_content_area.add(message_label)
3624 self.dialog.infobar.show_all()
3625
3626 self.ui.get_object("vbox1").show()
3627
3628=== modified file 'gwibber/microblog/storage.py'
3629--- gwibber/microblog/storage.py 2012-02-10 10:06:59 +0000
3630+++ gwibber/microblog/storage.py 2012-02-14 21:35:21 +0000
3631@@ -1,7 +1,7 @@
3632 #!/usr/bin/env python
3633
3634 import json, sqlite3, uuid
3635-import gtk, gobject, dbus, dbus.service
3636+import dbus, dbus.service
3637 import util, util.keyring, atexit
3638 from dbus.mainloop.glib import DBusGMainLoop
3639
3640
3641=== modified file 'gwibber/microblog/uploader/ubuntuone_uploader/__init__.py'
3642--- gwibber/microblog/uploader/ubuntuone_uploader/__init__.py 2011-07-19 15:31:48 +0000
3643+++ gwibber/microblog/uploader/ubuntuone_uploader/__init__.py 2012-02-14 21:35:21 +0000
3644@@ -1,6 +1,8 @@
3645 "Ubuntu One uploader and publisher"
3646
3647-import dbus, gio, os
3648+import dbus, os
3649+from gi.repository import Gio
3650+
3651 try:
3652 from ubuntuone.platform.tools import SyncDaemonTool, DBusClient, DBUS_IFACE_STATUS_NAME
3653 except ImportError:
3654@@ -63,8 +65,8 @@
3655 # OSError is OK if the folder already existed
3656 fdir, ffullname = os.path.split(self.path)
3657 fname, fext = os.path.splitext(ffullname)
3658- src = gio.File(self.path)
3659- dest = gio.File(os.path.join(fol, ffullname))
3660+ src = Gio.File(self.path)
3661+ dest = Gio.File(os.path.join(fol, ffullname))
3662
3663 # We connect to the UploadFinished signal from syncdaemon here,
3664 # before we even copy the file, so we know that it's right.
3665@@ -74,14 +76,14 @@
3666
3667 try:
3668 src.copy(dest)
3669- except gio.Error:
3670+ except Gio.Error:
3671 # file with this name exists. Try creating a file with a number in
3672 differentiator = 1
3673 while 1:
3674 try:
3675- dest = gio.File(os.path.join(fol, "%s (%s)%s" % (fname, differentiator, fext)))
3676+ dest = Gio.File(os.path.join(fol, "%s (%s)%s" % (fname, differentiator, fext)))
3677 src.copy(dest)
3678- except gio.Error:
3679+ except Gio.Error:
3680 differentiator += 1
3681 else:
3682 break
3683@@ -98,8 +100,3 @@
3684
3685 def __published(self, info):
3686 self.success_callback(self.path, info["public_url"])
3687-
3688-
3689-
3690-
3691-
3692
3693=== modified file 'gwibber/microblog/util/__init__.py'
3694--- gwibber/microblog/util/__init__.py 2012-02-10 10:06:59 +0000
3695+++ gwibber/microblog/util/__init__.py 2012-02-14 21:35:21 +0000
3696@@ -164,22 +164,21 @@
3697 return False
3698
3699 try:
3700- import pynotify
3701- import gtk, gtk.gdk, glib
3702- pynotify.init("Gwibber")
3703+ from gi.repository import GdkPixbuf, GLib, Notify
3704+ Notify.init("Gwibber")
3705
3706 def notify(title, text, icon = None, timeout = None, iconsize = 48):
3707 if icon is None:
3708 icon = resources.get_ui_asset("gwibber.svg")
3709
3710- caps = pynotify.get_server_caps()
3711+ caps = Notify.get_server_caps()
3712
3713- notification = pynotify.Notification(title, text)
3714+ notification = Notify.Notification.new(title, text, "gwibber")
3715
3716 try:
3717- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(icon, iconsize, iconsize)
3718+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(icon, iconsize, iconsize)
3719 notification.set_icon_from_pixbuf(pixbuf)
3720- except glib.GError as e:
3721+ except GLib.Error as e:
3722 logger.error("Avatar failure - %s - %s", icon, e.message)
3723 resources.del_avatar(icon)
3724
3725@@ -187,7 +186,7 @@
3726 notification.set_timeout(timeout)
3727
3728 if "x-canonical-append" in caps:
3729- notification.set_hint('x-canonical-append', 'allowed')
3730+ notification.set_hint_string('x-canonical-append', 'allowed')
3731
3732 try:
3733 notification.show ()
3734
3735=== modified file 'gwibber/microblog/util/keyring.py'
3736--- gwibber/microblog/util/keyring.py 2012-02-07 17:38:41 +0000
3737+++ gwibber/microblog/util/keyring.py 2012-02-14 21:35:21 +0000
3738@@ -1,25 +1,68 @@
3739 from const import *
3740+from gi.repository import GnomeKeyring, GLib
3741
3742 import ctypes
3743-import gnomekeyring
3744 import exceptions
3745
3746+
3747+def get_from_keyring(acctid, name):
3748+ """Get the entry from the keyring for @acctid with @name."""
3749+ attributes = GnomeKeyring.Attribute.list_new()
3750+ GnomeKeyring.Attribute.list_append_string(attributes, 'id',
3751+ str("%s/%s" % (acctid, name)))
3752+ result, value = GnomeKeyring.find_items_sync(
3753+ GnomeKeyring.ItemType.GENERIC_SECRET,
3754+ attributes)
3755+
3756+ if result == GnomeKeyring.Result.OK:
3757+ return value[0].secret
3758+
3759+ return None
3760+
3761+
3762+def put_in_keyring(acctid, name, value):
3763+ """Store a value in the keyring."""
3764+ id = "%s/%s" % (acctid, name)
3765+ attributes = GnomeKeyring.Attribute.list_new()
3766+ GnomeKeyring.Attribute.list_append_string(attributes, 'id', str(id))
3767+ keyring = GnomeKeyring.get_default_keyring_sync()[1]
3768+ value = GnomeKeyring.item_create_sync(
3769+ keyring, GnomeKeyring.ItemType.GENERIC_SECRET,
3770+ "Gwibber preference: %s" % id,
3771+ attributes, str(value), True)
3772+ return value[1]
3773+
3774+
3775+def del_from_keyring(keyring_id):
3776+ """Delete an entry from the keyring."""
3777+ keyring = GnomeKeyring.get_default_keyring_sync()[1]
3778+ GnomeKeyring.item_delete_sync(keyring, keyring_id)
3779+
3780+
3781 def get_secret(id):
3782+ """Get a locked secret for threaded/multiprocessing use."""
3783 value = ""
3784- try:
3785- value = gnomekeyring.find_items_sync(
3786- gnomekeyring.ITEM_GENERIC_SECRET,
3787- {"id": str(id)})[0].secret
3788- mlock(value)
3789- except gnomekeyring.NoMatchError:
3790+ attrlist = GnomeKeyring.Attribute.list_new()
3791+ GnomeKeyring.Attribute.list_append_string(attrlist, 'id', str(id))
3792+ result, found = GnomeKeyring.find_items_sync(
3793+ GnomeKeyring.ItemType.GENERIC_SECRET,
3794+ attrlist)
3795+ value = found[0].secret
3796+ mlock(value)
3797+
3798+ if result == GnomeKeyring.Result.NO_MATCH:
3799+ print id
3800 raise exceptions.GwibberServiceError("keyring")
3801
3802 return value
3803
3804+
3805 libc = ctypes.CDLL("libc.so.6")
3806
3807+
3808 def mlock(var):
3809 libc.mlock(var, len(var))
3810
3811+
3812 def munlock(var):
3813 libc.munlock(var, len(var))
3814
3815=== modified file 'gwibber/microblog/util/resources.py'
3816--- gwibber/microblog/util/resources.py 2012-02-13 04:21:17 +0000
3817+++ gwibber/microblog/util/resources.py 2012-02-14 21:35:21 +0000
3818@@ -10,7 +10,7 @@
3819 import Image
3820 import mx.DateTime
3821 from gwibber.microblog import network
3822-from const import *
3823+from gwibber.microblog.util.const import *
3824 import inspect
3825
3826 import logging
3827@@ -171,6 +171,10 @@
3828 return asset_path
3829
3830 for base in DATA_DIRS:
3831+ asset_path = os.path.join(base, 'data', asset_name)
3832+ if os.path.exists(asset_path):
3833+ return asset_path
3834+
3835 asset_path = os.path.join(base, UI_DIR_NAME, asset_name)
3836 if os.path.exists(asset_path):
3837 return asset_path
3838
3839=== removed file 'gwibber/preferences.py'
3840--- gwibber/preferences.py 2010-10-18 19:32:16 +0000
3841+++ gwibber/preferences.py 1970-01-01 00:00:00 +0000
3842@@ -1,123 +0,0 @@
3843-#
3844-# Copyright (C) 2010 Canonical Ltd
3845-#
3846-# This program is free software: you can redistribute it and/or modify
3847-# it under the terms of the GNU General Public License version 2 as
3848-# published by the Free Software Foundation.
3849-#
3850-# This program is distributed in the hope that it will be useful,
3851-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3852-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3853-# GNU General Public License for more details.
3854-#
3855-# You should have received a copy of the GNU General Public License
3856-# along with this program. If not, see <http://www.gnu.org/licenses/>.
3857-#
3858-# Copyright (C) 2010 Ken VanDine <ken.vandine@canonical.com>
3859-#
3860-# Preferences interface for Gwibber
3861-#
3862-
3863-import pygtk
3864-try:
3865- pygtk.require("2.0")
3866-except:
3867- print "Requires pygtk 2.0 or later"
3868- exit
3869-
3870-import gtk, gconf
3871-from gwibber import util
3872-from microblog.util import resources
3873-from microblog import config
3874-
3875-import gettext
3876-from gettext import lgettext as _
3877-if hasattr(gettext, 'bind_textdomain_codeset'):
3878- gettext.bind_textdomain_codeset('gwibber','UTF-8')
3879-gettext.textdomain('gwibber')
3880-
3881-from microblog.util.const import *
3882-# Try to import * from custom, install custom.py to include packaging
3883-# customizations like distro API keys, etc
3884-try:
3885- from microblog.util.custom import *
3886-except:
3887- pass
3888-
3889-from microblog.urlshorter import PROTOCOLS as urlshorters
3890-
3891-from dbus.mainloop.glib import DBusGMainLoop
3892-
3893-DBusGMainLoop(set_as_default=True)
3894-
3895-class GwibberPreferences(object):
3896- def __init__(self):
3897- self.ui = gtk.Builder()
3898- self.ui.set_translation_domain("gwibber")
3899- self.ui.add_from_file(resources.get_ui_asset("gwibber-preferences-dialog.ui"))
3900- self.ui.connect_signals(self)
3901- self.gc = gconf.client_get_default()
3902- dialog = self.ui.get_object("prefs_dialog")
3903- dialog.set_icon_from_file(resources.get_ui_asset("gwibber.svg"))
3904-
3905- self.settings = config.Preferences()
3906-
3907- setting_keys = [
3908- "autostart",
3909- "show_notifications",
3910- "notify_mentions_only",
3911- "no_notifications",
3912- "show_fullname",
3913- "shorten_urls",
3914- "reply_append_colon",
3915- "global_retweet",
3916- "interval",
3917- "minimize_to_tray",
3918- "hide_taskbar_entry",
3919- "show_tray_icon",
3920- ]
3921-
3922- for key in setting_keys:
3923- self.settings.bind(self.ui.get_object(key), key)
3924-
3925- self.populate_settings_widgets()
3926-
3927- for key in ["theme", "urlshorter", "retweet_style"]:
3928- # Don't blow up if these values aren't set to something expected
3929- # just reset to the default and carry on
3930- try:
3931- self.settings.bind(getattr(self, key + "_selector"), key)
3932- except:
3933- config.GCONF.set_value(config.GCONF_PREFERENCES_DIR + "/" + key, self.settings.defaults[key])
3934- self.settings.bind(getattr(self, key + "_selector"), key)
3935-
3936- dialog.show_all()
3937-
3938- def populate_settings_widgets(self):
3939- self.theme_selector = gtk.combo_box_new_text()
3940- for theme in sorted(resources.get_themes()): self.theme_selector.append_text(theme)
3941- self.ui.get_object("theme_container").pack_start(self.theme_selector, True, True)
3942- self.theme_selector.set_active_iter(dict([(x[0].strip(), x.iter) for x in self.theme_selector.get_model()]).get(
3943- self.settings["theme"], self.theme_selector.get_model().get_iter_root()))
3944- self.theme_selector.show_all()
3945- self.urlshorter_selector = gtk.combo_box_new_text()
3946- for urlshorter in urlshorters.keys(): self.urlshorter_selector.append_text(urlshorter)
3947- self.ui.get_object("urlshorter_container").pack_start(self.urlshorter_selector, True, True)
3948-
3949- self.urlshorter_selector.set_active_iter(dict([(x[0].strip(), x.iter) for x in self.urlshorter_selector.get_model()]).get(
3950- self.settings["urlshorter"], self.urlshorter_selector.get_model().get_iter_root()))
3951- self.urlshorter_selector.show_all()
3952-
3953- self.retweet_style_selector = gtk.combo_box_new_text()
3954- for format in RETWEET_FORMATS: self.retweet_style_selector.append_text(format)
3955- self.ui.get_object("retweet_style_container").pack_start(self.retweet_style_selector, True, True)
3956- self.retweet_style_selector.set_active_iter(dict([(x[0].strip(), x.iter) for x in self.retweet_style_selector.get_model()]).get(
3957- self.settings["retweet_style"], self.retweet_style_selector.get_model().get_iter_root()))
3958- self.retweet_style_selector.show_all()
3959-
3960- def on_close_button_clicked(self, widget, data=None):
3961- gtk.main_quit()
3962-
3963- def on_prefs_dialog_destroy_event(self, widget, data=None):
3964- gtk.main_quit()
3965-
3966
3967=== modified file 'gwibber/util.py'
3968--- gwibber/util.py 2011-03-11 20:05:56 +0000
3969+++ gwibber/util.py 2012-02-14 21:35:21 +0000
3970@@ -1,6 +1,6 @@
3971-import gtk, dbus, os, mx.DateTime, webbrowser
3972+import dbus, os, mx.DateTime, webbrowser
3973 import subprocess
3974-import gobject
3975+from gi.repository import GLib, Gdk, GdkPixbuf, Gtk
3976 from microblog.util import resources
3977 from microblog.util.const import *
3978 # Try to import * from custom, install custom.py to include packaging
3979@@ -31,29 +31,29 @@
3980
3981 @classmethod
3982 def from_gtk_color(self, c):
3983- if isinstance(c, gtk.gdk.Color): c = c.to_string()
3984+ if isinstance(c, Gdk.Color): c = c.to_string()
3985 return self("#" + "".join([c[1:3], c[5:7], c[9:11]]))
3986
3987 def get_style():
3988- w = gtk.Window()
3989+ w = Gtk.Window()
3990 w.realize()
3991 return w.get_style()
3992
3993-def get_theme_colors(w = gtk.Window()):
3994+def get_theme_colors(w = Gtk.Window()):
3995 w.realize()
3996 style = w.get_style()
3997 output = {}
3998
3999 for i in ["base", "text", "fg", "bg"]:
4000- c = getattr(style, i)[gtk.STATE_NORMAL]
4001+ c = getattr(style, i)[Gtk.StateType.NORMAL]
4002 output[i] = Color.from_gtk_color(c)
4003- c = getattr(style, i)[gtk.STATE_SELECTED]
4004+ c = getattr(style, i)[Gtk.StateType.SELECTED]
4005 output["%s_selected" % i] = Color.from_gtk_color(c)
4006
4007 return output
4008
4009 def pixbuf(path):
4010- return gtk.gdk.pixbuf_new_from_file(resources.get_ui_asset(path))
4011+ return GdkPixbuf.Pixbuf.new_from_file(resources.get_ui_asset(path))
4012
4013 def icon(name, size=16, use_theme=True):
4014 if use_theme:
4015@@ -64,12 +64,12 @@
4016 if os.path.exists(fname + ext):
4017 return fname + ext
4018
4019- theme = gtk.icon_theme_get_default()
4020+ theme = Gtk.IconTheme.get_default()
4021 finfo = theme.lookup_icon(name, size, 0)
4022 return finfo.get_filename() if finfo else None
4023
4024 def get_service_icon(name, size=16):
4025- theme = gtk.icon_theme_get_default()
4026+ theme = Gtk.IconTheme.get_default()
4027 finfo = theme.lookup_icon(name, size, 0)
4028 if finfo:
4029 return finfo.get_filename()
4030@@ -90,7 +90,8 @@
4031 if not x.startswith('http://') and not x.startswith("https://"))
4032
4033 try:
4034- import gtkspell
4035+ #import gtkspell
4036+ gtkspell = None
4037 except:
4038 gtkspell = None
4039
4040@@ -142,7 +143,7 @@
4041 cmd.insert(0, "gwibber-accounts")
4042 print cmd
4043 process = subprocess.Popen(cmd)
4044- gobject.timeout_add(500, check_ret, process, obj, callback)
4045+ GLib.timeout_add(500, check_ret, process, obj, callback)
4046
4047 def check_ret(process, obj=None, callback=None):
4048 if callback == None:
4049
4050=== removed file 'po/Makefile.in.in'
4051--- po/Makefile.in.in 2012-02-10 22:34:33 +0000
4052+++ po/Makefile.in.in 1970-01-01 00:00:00 +0000
4053@@ -1,222 +0,0 @@
4054-# Makefile for program source directory in GNU NLS utilities package.
4055-# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
4056-# Copyright (C) 2004-2008 Rodney Dawes <dobey.pwns@gmail.com>
4057-#
4058-# This file may be copied and used freely without restrictions. It may
4059-# be used in projects which are not available under a GNU Public License,
4060-# but which still want to provide support for the GNU gettext functionality.
4061-#
4062-# - Modified by Owen Taylor <otaylor@redhat.com> to use GETTEXT_PACKAGE
4063-# instead of PACKAGE and to look for po2tbl in ./ not in intl/
4064-#
4065-# - Modified by jacob berkman <jacob@ximian.com> to install
4066-# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize
4067-#
4068-# - Modified by Rodney Dawes <dobey.pwns@gmail.com> for use with intltool
4069-#
4070-# We have the following line for use by intltoolize:
4071-# INTLTOOL_MAKEFILE
4072-
4073-GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
4074-PACKAGE = @PACKAGE@
4075-VERSION = @VERSION@
4076-
4077-SHELL = @SHELL@
4078-
4079-srcdir = @srcdir@
4080-top_srcdir = @top_srcdir@
4081-top_builddir = @top_builddir@
4082-VPATH = @srcdir@
4083-
4084-prefix = @prefix@
4085-exec_prefix = @exec_prefix@
4086-datadir = @datadir@
4087-datarootdir = @datarootdir@
4088-libdir = @libdir@
4089-DATADIRNAME = @DATADIRNAME@
4090-itlocaledir = $(prefix)/$(DATADIRNAME)/locale
4091-subdir = po
4092-install_sh = @install_sh@
4093-# Automake >= 1.8 provides @mkdir_p@.
4094-# Until it can be supposed, use the safe fallback:
4095-mkdir_p = $(install_sh) -d
4096-
4097-INSTALL = @INSTALL@
4098-INSTALL_DATA = @INSTALL_DATA@
4099-
4100-GMSGFMT = @GMSGFMT@
4101-MSGFMT = @MSGFMT@
4102-XGETTEXT = @XGETTEXT@
4103-INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
4104-INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
4105-MSGMERGE = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist
4106-GENPOT = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot
4107-
4108-ALL_LINGUAS = @ALL_LINGUAS@
4109-
4110-PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi)
4111-
4112-USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep \^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep \^$$lang$$`"; then printf "$$lang "; fi; done; fi)
4113-
4114-USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done)
4115-
4116-POFILES=$(shell LINGUAS="$(PO_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done)
4117-
4118-DISTFILES = Makefile.in.in POTFILES.in $(POFILES)
4119-EXTRA_DISTFILES = ChangeLog POTFILES.skip Makevars LINGUAS
4120-
4121-POTFILES = \
4122-# This comment gets stripped out
4123-
4124-CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done)
4125-
4126-.SUFFIXES:
4127-.SUFFIXES: .po .pox .gmo .mo .msg .cat
4128-
4129-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
4130-INTLTOOL_V_MSGFMT = $(INTLTOOL__v_MSGFMT_$(V))
4131-INTLTOOL__v_MSGFMT_= $(INTLTOOL__v_MSGFMT_$(AM_DEFAULT_VERBOSITY))
4132-INTLTOOL__v_MSGFMT_0 = @echo " MSGFMT" $@;
4133-
4134-.po.pox:
4135- $(MAKE) $(GETTEXT_PACKAGE).pot
4136- $(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox
4137-
4138-.po.mo:
4139- $(INTLTOOL_V_MSGFMT)$(MSGFMT) -o $@ $<
4140-
4141-.po.gmo:
4142- $(INTLTOOL_V_MSGFMT)file=`echo $* | sed 's,.*/,,'`.gmo \
4143- && rm -f $$file && $(GMSGFMT) -o $$file $<
4144-
4145-.po.cat:
4146- sed -f ../intl/po2msg.sed < $< > $*.msg \
4147- && rm -f $@ && gencat $@ $*.msg
4148-
4149-
4150-all: all-@USE_NLS@
4151-
4152-all-yes: $(CATALOGS)
4153-all-no:
4154-
4155-$(GETTEXT_PACKAGE).pot: $(POTFILES)
4156- $(GENPOT)
4157-
4158-install: install-data
4159-install-data: install-data-@USE_NLS@
4160-install-data-no: all
4161-install-data-yes: all
4162- linguas="$(USE_LINGUAS)"; \
4163- for lang in $$linguas; do \
4164- dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \
4165- $(mkdir_p) $$dir; \
4166- if test -r $$lang.gmo; then \
4167- $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
4168- echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \
4169- else \
4170- $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
4171- echo "installing $(srcdir)/$$lang.gmo as" \
4172- "$$dir/$(GETTEXT_PACKAGE).mo"; \
4173- fi; \
4174- if test -r $$lang.gmo.m; then \
4175- $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \
4176- echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \
4177- else \
4178- if test -r $(srcdir)/$$lang.gmo.m ; then \
4179- $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \
4180- $$dir/$(GETTEXT_PACKAGE).mo.m; \
4181- echo "installing $(srcdir)/$$lang.gmo.m as" \
4182- "$$dir/$(GETTEXT_PACKAGE).mo.m"; \
4183- else \
4184- true; \
4185- fi; \
4186- fi; \
4187- done
4188-
4189-# Empty stubs to satisfy archaic automake needs
4190-dvi info ctags tags CTAGS TAGS ID:
4191-
4192-# Define this as empty until I found a useful application.
4193-install-exec installcheck:
4194-
4195-uninstall:
4196- linguas="$(USE_LINGUAS)"; \
4197- for lang in $$linguas; do \
4198- rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \
4199- rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \
4200- done
4201-
4202-check: all $(GETTEXT_PACKAGE).pot
4203- rm -f missing notexist
4204- srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m
4205- if [ -r missing -o -r notexist ]; then \
4206- exit 1; \
4207- fi
4208-
4209-mostlyclean:
4210- rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp
4211- rm -f .intltool-merge-cache
4212-
4213-clean: mostlyclean
4214-
4215-distclean: clean
4216- rm -f Makefile Makefile.in POTFILES stamp-it
4217- rm -f *.mo *.msg *.cat *.cat.m *.gmo
4218-
4219-maintainer-clean: distclean
4220- @echo "This command is intended for maintainers to use;"
4221- @echo "it deletes files that may require special tools to rebuild."
4222- rm -f Makefile.in.in
4223-
4224-distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
4225-dist distdir: $(DISTFILES)
4226- dists="$(DISTFILES)"; \
4227- extra_dists="$(EXTRA_DISTFILES)"; \
4228- for file in $$extra_dists; do \
4229- test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \
4230- done; \
4231- for file in $$dists; do \
4232- test -f $$file || file="$(srcdir)/$$file"; \
4233- ln $$file $(distdir) 2> /dev/null \
4234- || cp -p $$file $(distdir); \
4235- done
4236-
4237-update-po: Makefile
4238- $(MAKE) $(GETTEXT_PACKAGE).pot
4239- tmpdir=`pwd`; \
4240- linguas="$(USE_LINGUAS)"; \
4241- for lang in $$linguas; do \
4242- echo "$$lang:"; \
4243- result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \
4244- if $$result; then \
4245- if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
4246- rm -f $$tmpdir/$$lang.new.po; \
4247- else \
4248- if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
4249- :; \
4250- else \
4251- echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
4252- rm -f $$tmpdir/$$lang.new.po; \
4253- exit 1; \
4254- fi; \
4255- fi; \
4256- else \
4257- echo "msgmerge for $$lang.gmo failed!"; \
4258- rm -f $$tmpdir/$$lang.new.po; \
4259- fi; \
4260- done
4261-
4262-Makefile POTFILES: stamp-it
4263- @if test ! -f $@; then \
4264- rm -f stamp-it; \
4265- $(MAKE) stamp-it; \
4266- fi
4267-
4268-stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in
4269- cd $(top_builddir) \
4270- && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \
4271- $(SHELL) ./config.status
4272-
4273-# Tell versions [3.59,3.63) of GNU make not to export all variables.
4274-# Otherwise a system limit (for SysV at least) may be exceeded.
4275-.NOEXPORT:
4276
4277=== removed file 'po/gwibber.pot'
4278--- po/gwibber.pot 2012-01-13 11:30:33 +0000
4279+++ po/gwibber.pot 1970-01-01 00:00:00 +0000
4280@@ -1,1043 +0,0 @@
4281-# SOME DESCRIPTIVE TITLE.
4282-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
4283-# This file is distributed under the same license as the PACKAGE package.
4284-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
4285-#
4286-#, fuzzy
4287-msgid ""
4288-msgstr ""
4289-"Project-Id-Version: PACKAGE VERSION\n"
4290-"Report-Msgid-Bugs-To: ken@vandine.org\n"
4291-"POT-Creation-Date: 2012-01-13 12:28+0100\n"
4292-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
4293-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
4294-"Language-Team: LANGUAGE <LL@li.org>\n"
4295-"Language: \n"
4296-"MIME-Version: 1.0\n"
4297-"Content-Type: text/plain; charset=UTF-8\n"
4298-"Content-Transfer-Encoding: 8bit\n"
4299-"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
4300-
4301-#: ../data/gwibber.desktop.in.in.h:1
4302-#: ../gwibber/microblog/util/exceptions.py:42
4303-#: ../lens/data/gwibber.lens.in.in.h:1
4304-msgid "Gwibber"
4305-msgstr ""
4306-
4307-#: ../data/gwibber.desktop.in.in.h:2
4308-msgid "Social Client"
4309-msgstr ""
4310-
4311-#: ../data/gwibber.desktop.in.in.h:3
4312-msgid "Gwibber Social Client"
4313-msgstr ""
4314-
4315-#: ../data/gwibber.desktop.in.in.h:4
4316-msgid "Update your microblog and follow your contacts' statuses"
4317-msgstr ""
4318-
4319-#: ../data/gwibber-accounts.desktop.in.h:1
4320-#: ../data/gwibber-accounts-dialog.ui.h:1
4321-msgid "Broadcast Accounts"
4322-msgstr ""
4323-
4324-#: ../data/gwibber-accounts.desktop.in.h:2
4325-msgid "Add, edit, and delete your broadcast accounts"
4326-msgstr ""
4327-
4328-#: ../data/gwibber-preferences.desktop.in.h:1
4329-msgid "Broadcast Preferences"
4330-msgstr ""
4331-
4332-#: ../data/gwibber-preferences.desktop.in.h:2
4333-msgid "Change your broadcast preferences"
4334-msgstr ""
4335-
4336-#: ../data/org.gwibber.gschema.xml.in.in.h:1
4337-msgid "Autostart service"
4338-msgstr ""
4339-
4340-#: ../data/org.gwibber.gschema.xml.in.in.h:2
4341-msgid "Autostart the Gwibber Service"
4342-msgstr ""
4343-
4344-#: ../data/org.gwibber.gschema.xml.in.in.h:3
4345-msgid "Refresh interval"
4346-msgstr ""
4347-
4348-#: ../data/org.gwibber.gschema.xml.in.in.h:4
4349-#: ../data/gwibber-preferences-dialog.ui.h:8
4350-msgid "Do not display notifications"
4351-msgstr ""
4352-
4353-#: ../data/org.gwibber.gschema.xml.in.in.h:5
4354-#: ../data/gwibber-preferences-dialog.ui.h:6
4355-msgid "Mentions and replies only"
4356-msgstr ""
4357-
4358-#: ../data/org.gwibber.gschema.xml.in.in.h:6
4359-msgid "Display notifications for mentions and replies only"
4360-msgstr ""
4361-
4362-#: ../data/org.gwibber.gschema.xml.in.in.h:7
4363-#: ../data/gwibber-preferences-dialog.ui.h:4
4364-msgid "All messages"
4365-msgstr ""
4366-
4367-#: ../data/org.gwibber.gschema.xml.in.in.h:8
4368-msgid "Display notifications for all messages"
4369-msgstr ""
4370-
4371-#: ../data/org.gwibber.gschema.xml.in.in.h:9
4372-msgid "Check current presence status"
4373-msgstr ""
4374-
4375-#: ../data/org.gwibber.gschema.xml.in.in.h:10
4376-msgid "Check the current presence status"
4377-msgstr ""
4378-
4379-#: ../data/org.gwibber.gschema.xml.in.in.h:11
4380-msgid "Show fullnames in posts"
4381-msgstr ""
4382-
4383-#: ../data/org.gwibber.gschema.xml.in.in.h:12
4384-msgid "Append a colon when replying"
4385-msgstr ""
4386-
4387-#: ../data/org.gwibber.gschema.xml.in.in.h:13
4388-msgid "Shorten URLS"
4389-msgstr ""
4390-
4391-#: ../data/org.gwibber.gschema.xml.in.in.h:14
4392-msgid "Shorten URLs in posts"
4393-msgstr ""
4394-
4395-#: ../data/org.gwibber.gschema.xml.in.in.h:15
4396-msgid "URL shortening service"
4397-msgstr ""
4398-
4399-#: ../data/org.gwibber.gschema.xml.in.in.h:16
4400-msgid "Preferred URL shortening service"
4401-msgstr ""
4402-
4403-#: ../data/org.gwibber.gschema.xml.in.in.h:17
4404-msgid "Imaging uploading service"
4405-msgstr ""
4406-
4407-#: ../data/org.gwibber.gschema.xml.in.in.h:18
4408-msgid "Preferred Image uploading service"
4409-msgstr ""
4410-
4411-#: ../data/org.gwibber.gschema.xml.in.in.h:19
4412-msgid "Log debug messages"
4413-msgstr ""
4414-
4415-#: ../data/org.gwibber.gschema.xml.in.in.h:20
4416-msgid "Verbose debug logging"
4417-msgstr ""
4418-
4419-#: ../client/attachments-item.vala:26
4420-msgid "Attachments"
4421-msgstr ""
4422-
4423-#: ../client/attachments-item.vala:37 ../lens/src/daemon.vala:128
4424-#: ../lens/src/daemon.vala:199 ../gwibber/gwui.py:106
4425-msgid "Images"
4426-msgstr ""
4427-
4428-#: ../client/attachments-item.vala:48 ../lens/src/daemon.vala:130
4429-#: ../lens/src/daemon.vala:207 ../gwibber/gwui.py:106
4430-msgid "Links"
4431-msgstr ""
4432-
4433-#: ../client/attachments-item.vala:59 ../lens/src/daemon.vala:129
4434-#: ../lens/src/daemon.vala:203 ../gwibber/gwui.py:106
4435-msgid "Videos"
4436-msgstr ""
4437-
4438-#: ../client/home-item.vala:22 ../gwibber/gwui.py:98
4439-msgid "Home"
4440-msgstr ""
4441-
4442-#: ../client/replies-item.vala:23 ../lens/src/daemon.vala:127
4443-#: ../lens/src/daemon.vala:195 ../gwibber/gwui.py:106
4444-#: ../gwibber/microblog/dispatcher.py:730
4445-msgid "Replies"
4446-msgstr ""
4447-
4448-#: ../client/gwibber-client.vala:180 ../gwibber/client.py:341
4449-msgid "_Gwibber"
4450-msgstr ""
4451-
4452-#: ../client/gwibber-client.vala:182
4453-msgid "_View"
4454-msgstr ""
4455-
4456-#: ../client/gwibber-client.vala:184 ../gwibber/client.py:342
4457-msgid "_Edit"
4458-msgstr ""
4459-
4460-#: ../client/gwibber-client.vala:186 ../gwibber/client.py:343
4461-msgid "_Help"
4462-msgstr ""
4463-
4464-#: ../client/gwibber-client.vala:188 ../gwibber/client.py:345
4465-#: ../gwibber/client.py:380
4466-msgid "_Refresh"
4467-msgstr ""
4468-
4469-#: ../client/gwibber-client.vala:190 ../gwibber/client.py:350
4470-msgid "_Quit"
4471-msgstr ""
4472-
4473-#: ../client/gwibber-client.vala:192
4474-msgid "_Sort"
4475-msgstr ""
4476-
4477-#: ../client/gwibber-client.vala:194 ../gwibber/client.py:347
4478-#: ../gwibber/client.py:384
4479-msgid "_Accounts"
4480-msgstr ""
4481-
4482-#: ../client/gwibber-client.vala:196 ../gwibber/client.py:348
4483-#: ../gwibber/client.py:388
4484-msgid "_Preferences"
4485-msgstr ""
4486-
4487-#: ../client/gwibber-client.vala:198 ../gwibber/client.py:349
4488-msgid "_About"
4489-msgstr ""
4490-
4491-#: ../client/gwibber-client.vala:202
4492-msgid "_Ascending"
4493-msgstr ""
4494-
4495-#: ../client/gwibber-client.vala:204
4496-msgid "_Descending"
4497-msgstr ""
4498-
4499-#: ../client/gwibber-client.vala:289
4500-msgid ""
4501-"Gwibber is free software; you can redistribute it and/or modify it under the "
4502-"terms of the GNU General Public License as published by the Free Software "
4503-"Foundation; either version 2 of the License, or (at your option) any later "
4504-"version.\n"
4505-"\n"
4506-"Gwibber is distributed in the hope that it will be useful, but WITHOUT ANY "
4507-"WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS "
4508-"FOR A PARTICULAR PURPOSE. See the GNU General Public License for more "
4509-"details.\n"
4510-"\n"
4511-"You should have received a copy of the GNU General Public License along with "
4512-"Gwibber; if not, write to the Free Software Foundation, Inc., 51 Franklin "
4513-"Street, Fifth Floor, Boston, MA 02110-130159 USA"
4514-msgstr ""
4515-
4516-#: ../client/gwibber-client.vala:328 ../lens/src/daemon.vala:124
4517-msgid "Stream"
4518-msgstr ""
4519-
4520-#: ../client/gwibber-client.vala:328
4521-msgid "STREAM"
4522-msgstr ""
4523-
4524-#: ../client/gwibber-client.vala:373
4525-msgid "— Gwibber Client"
4526-msgstr ""
4527-
4528-#. This list is defined just to get the strings in the template for translation
4529-#: ../client/messages-item.vala:23 ../lens/src/daemon.vala:126
4530-#: ../lens/src/daemon.vala:191 ../gwibber/gwui.py:106
4531-#: ../gwibber/microblog/dispatcher.py:718
4532-#: ../data/gwibber-preferences-dialog.ui.h:20
4533-msgid "Messages"
4534-msgstr ""
4535-
4536-#: ../client/private-item.vala:23
4537-msgid "Private Messages"
4538-msgstr ""
4539-
4540-#: ../client/gwibber-preferences.vala:36
4541-#: ../data/gwibber-preferences-dialog.ui.h:2
4542-msgid "Broadcast Messaging Preferences"
4543-msgstr ""
4544-
4545-#: ../client/public-item.vala:23 ../lens/src/daemon.vala:132
4546-#: ../lens/src/daemon.vala:215
4547-msgid "Public"
4548-msgstr ""
4549-
4550-#: ../client/searches-item.vala:34
4551-msgid "Searches"
4552-msgstr ""
4553-
4554-#: ../client/searches-item.vala:134
4555-msgid "Saved Searches"
4556-msgstr ""
4557-
4558-#: ../client/tab-bar.vala:25
4559-msgid "New Message"
4560-msgstr ""
4561-
4562-#: ../client/users-item.vala:39
4563-msgid "Users"
4564-msgstr ""
4565-
4566-#: ../libgwibber/utils.vala:85
4567-msgid "a few seconds ago"
4568-msgstr ""
4569-
4570-#: ../libgwibber/utils.vala:87
4571-#, c-format
4572-msgid "%i minute ago"
4573-msgid_plural "%i minutes ago"
4574-msgstr[0] ""
4575-msgstr[1] ""
4576-
4577-#: ../libgwibber/utils.vala:89
4578-#, c-format
4579-msgid "%i hour ago"
4580-msgid_plural "%i hours ago"
4581-msgstr[0] ""
4582-msgstr[1] ""
4583-
4584-#: ../libgwibber/utils.vala:90
4585-#, c-format
4586-msgid "%i day ago"
4587-msgid_plural "%i days ago"
4588-msgstr[0] ""
4589-msgstr[1] ""
4590-
4591-#: ../libgwibber-gtk/entry.vala:337
4592-msgid "Send with:"
4593-msgstr ""
4594-
4595-#: ../libgwibber-gtk/entry.vala:364 ../libgwibber-gtk/entry.vala:489
4596-#: ../gwibber/client.py:233 ../gwibber/lib/gtk/widgets.py:55
4597-msgid "Send"
4598-msgstr ""
4599-
4600-#: ../libgwibber-gtk/entry.vala:401 ../libgwibber-gtk/entry.vala:440
4601-#: ../gwibber/lib/gtk/widgets.py:110 ../gwibber/lib/gtk/widgets.py:127
4602-msgid "Disabled"
4603-msgstr ""
4604-
4605-#: ../libgwibber-gtk/stream-view-tile.vala:667
4606-#, c-format
4607-msgid "%i person liked this"
4608-msgid_plural "%i people liked this"
4609-msgstr[0] ""
4610-msgstr[1] ""
4611-
4612-#: ../libgwibber-gtk/stream-view-tile.vala:726
4613-#: ../libgwibber-gtk/stream-view-tile.vala:731
4614-msgid "in reply to"
4615-msgstr ""
4616-
4617-#: ../libgwibber-gtk/stream-view-tile.vala:741
4618-#: ../libgwibber-gtk/stream-view-tile.vala:746
4619-msgid "shared by"
4620-msgstr ""
4621-
4622-#: ../libgwibber-gtk/action-box.vala:150 ../gwibber/actions.py:37
4623-msgid "_Reply"
4624-msgstr ""
4625-
4626-#: ../libgwibber-gtk/action-box.vala:189
4627-msgid "_Like"
4628-msgstr ""
4629-
4630-#: ../libgwibber-gtk/action-box.vala:227 ../gwibber/actions.py:127
4631-msgid "Liked"
4632-msgstr ""
4633-
4634-#: ../libgwibber-gtk/action-box.vala:227
4635-#, c-format
4636-msgid "Liked post from %s"
4637-msgstr ""
4638-
4639-#: ../libgwibber-gtk/action-box.vala:239
4640-msgid "Re_tweet"
4641-msgstr ""
4642-
4643-#: ../libgwibber-gtk/action-box.vala:243
4644-msgid "Re_peat"
4645-msgstr ""
4646-
4647-#: ../libgwibber-gtk/action-box.vala:248
4648-msgid "Shared"
4649-msgstr ""
4650-
4651-#: ../libgwibber-gtk/action-box.vala:248
4652-#, c-format
4653-msgid "Shared post from %s"
4654-msgstr ""
4655-
4656-#: ../libgwibber-gtk/action-box.vala:257
4657-msgid "View User _Profile"
4658-msgstr ""
4659-
4660-#: ../lens/src/daemon.vala:63 ../lens/data/gwibber.lens.in.in.h:3
4661-msgid "Enter name or content you would like to search for"
4662-msgstr ""
4663-
4664-#: ../lens/src/daemon.vala:131 ../lens/src/daemon.vala:211
4665-#: ../gwibber/gwui.py:106 ../gwibber/microblog/dispatcher.py:742
4666-msgid "Private"
4667-msgstr ""
4668-
4669-#: ../lens/src/daemon.vala:167
4670-msgid "Account"
4671-msgstr ""
4672-
4673-#: ../gwibber/actions.py:56
4674-msgid "View reply t_hread"
4675-msgstr ""
4676-
4677-#: ../gwibber/actions.py:66
4678-msgid "R_etweet"
4679-msgstr ""
4680-
4681-#: ../gwibber/actions.py:98
4682-msgid "_Direct Message"
4683-msgstr ""
4684-
4685-#: ../gwibber/actions.py:114
4686-msgid "_Like this message"
4687-msgstr ""
4688-
4689-#: ../gwibber/actions.py:127
4690-msgid "You have marked this message as liked."
4691-msgstr ""
4692-
4693-#: ../gwibber/actions.py:139
4694-msgid "_Delete this message"
4695-msgstr ""
4696-
4697-#: ../gwibber/actions.py:152
4698-msgid "Deleted"
4699-msgstr ""
4700-
4701-#: ../gwibber/actions.py:152
4702-msgid "The message has been deleted."
4703-msgstr ""
4704-
4705-#: ../gwibber/actions.py:164
4706-msgid "_Search for a query"
4707-msgstr ""
4708-
4709-#: ../gwibber/actions.py:172
4710-msgid "View _Message"
4711-msgstr ""
4712-
4713-#: ../gwibber/actions.py:199
4714-msgid "View user _Profile"
4715-msgstr ""
4716-
4717-#: ../gwibber/actions.py:225
4718-msgid "Tra_nslate"
4719-msgstr ""
4720-
4721-#: ../gwibber/actions.py:249
4722-msgid "Save to _Tomboy"
4723-msgstr ""
4724-
4725-#: ../gwibber/actions.py:254
4726-#, python-format
4727-msgid ""
4728-"%(service_name)s message from %(sender)s at %(time)s\n"
4729-"\n"
4730-"%(message)s\n"
4731-"\n"
4732-"Source: %(url)s"
4733-msgstr ""
4734-
4735-#: ../gwibber/client.py:169
4736-msgid "Social broadcast messages"
4737-msgstr ""
4738-
4739-#: ../gwibber/client.py:230
4740-msgid "Upload image"
4741-msgstr ""
4742-
4743-#: ../gwibber/client.py:234
4744-msgid "Post to all enabled services"
4745-msgstr ""
4746-
4747-#: ../gwibber/client.py:346
4748-msgid "_Search"
4749-msgstr ""
4750-
4751-#: ../gwibber/client.py:352
4752-msgid "_New Stream"
4753-msgstr ""
4754-
4755-#: ../gwibber/client.py:353
4756-msgid "_Close Window"
4757-msgstr ""
4758-
4759-#: ../gwibber/client.py:354
4760-msgid "_Close Stream"
4761-msgstr ""
4762-
4763-#: ../gwibber/client.py:356
4764-msgid "Get Help Online..."
4765-msgstr ""
4766-
4767-#: ../gwibber/client.py:357
4768-msgid "Translate This Application..."
4769-msgstr ""
4770-
4771-#: ../gwibber/client.py:358
4772-msgid "Report A Problem..."
4773-msgstr ""
4774-
4775-#: ../gwibber/client.py:580
4776-msgid "Select file to upload"
4777-msgstr ""
4778-
4779-#: ../gwibber/gwui.py:118 ../gwibber/gwui.py:155
4780-msgid "Sent"
4781-msgstr ""
4782-
4783-#: ../gwibber/gwui.py:172
4784-msgid "Lists"
4785-msgstr ""
4786-
4787-#: ../gwibber/gwui.py:187 ../gwibber/gwui.py:926
4788-msgid "Search"
4789-msgstr ""
4790-
4791-#: ../gwibber/gwui.py:874
4792-msgid "Close"
4793-msgstr ""
4794-
4795-#: ../gwibber/gwui.py:881
4796-msgid "Edit Account"
4797-msgstr ""
4798-
4799-#: ../gwibber/gwui.py:887
4800-msgid "Retry"
4801-msgstr ""
4802-
4803-#: ../gwibber/error.py:71
4804-msgid "Gwibber Error"
4805-msgstr ""
4806-
4807-#: ../gwibber/microblog/dispatcher.py:277
4808-#: ../gwibber/microblog/dispatcher.py:296
4809-msgid "Update Status"
4810-msgstr ""
4811-
4812-#: ../gwibber/microblog/dispatcher.py:302
4813-msgid "Refresh"
4814-msgstr ""
4815-
4816-#: ../gwibber/microblog/dispatcher.py:307
4817-msgid "Accounts"
4818-msgstr ""
4819-
4820-#: ../gwibber/microblog/dispatcher.py:312
4821-msgid "Preferences"
4822-msgstr ""
4823-
4824-#: ../gwibber/microblog/dispatcher.py:317
4825-msgid "Quit"
4826-msgstr ""
4827-
4828-#: ../gwibber/microblog/dispatcher.py:853
4829-msgid "has shared a photo"
4830-msgstr ""
4831-
4832-#: ../gwibber/microblog/dispatcher.py:855
4833-msgid "has shared a link"
4834-msgstr ""
4835-
4836-#: ../gwibber/microblog/dispatcher.py:857
4837-msgid "has shared a video"
4838-msgstr ""
4839-
4840-#: ../gwibber/microblog/util/exceptions.py:36
4841-#, python-format
4842-msgid ""
4843-"There was an %(kind)s failure from %(service)s for account %(account)s, "
4844-"error was %(error)s"
4845-msgstr ""
4846-
4847-#: ../gwibber/microblog/util/exceptions.py:45
4848-#, python-format
4849-msgid "Authentication error from %(service)s for account %(account)s"
4850-msgstr ""
4851-
4852-#: ../gwibber/microblog/util/exceptions.py:49
4853-msgid "Gwibber Authentication Error"
4854-msgstr ""
4855-
4856-#: ../gwibber/microblog/util/exceptions.py:52
4857-#, python-format
4858-msgid "There was a network error communicating with %(message)s"
4859-msgstr ""
4860-
4861-#: ../gwibber/microblog/util/exceptions.py:53
4862-msgid "Gwibber Network Error"
4863-msgstr ""
4864-
4865-#: ../gwibber/microblog/plugins/flickr/__init__.py:101
4866-#: ../gwibber/microblog/plugins/flickr/__init__.py:103
4867-msgid "Failed to find account"
4868-msgstr ""
4869-
4870-#: ../gwibber/microblog/plugins/facebook/__init__.py:72
4871-#: ../gwibber/microblog/plugins/facebook/__init__.py:88
4872-#: ../gwibber/microblog/plugins/twitter/__init__.py:260
4873-#: ../gwibber/microblog/plugins/foursquare/__init__.py:138
4874-msgid "Authentication failed"
4875-msgstr ""
4876-
4877-#: ../gwibber/microblog/plugins/facebook/__init__.py:74
4878-msgid "Authentication failed, please re-authorize"
4879-msgstr ""
4880-
4881-#: ../gwibber/microblog/plugins/facebook/__init__.py:92
4882-msgid "Session invalid"
4883-msgstr ""
4884-
4885-#: ../gwibber/microblog/plugins/facebook/__init__.py:96
4886-#: ../gwibber/microblog/plugins/twitter/__init__.py:265
4887-#: ../gwibber/microblog/plugins/foursquare/__init__.py:143
4888-msgid "Unknown failure"
4889-msgstr ""
4890-
4891-#: ../gwibber/microblog/plugins/facebook/gtk/facebook/__init__.py:78
4892-#: ../gwibber/microblog/plugins/facebook/gtk/facebook/__init__.py:148
4893-#, python-format
4894-msgid "%s has been authorized by Facebook"
4895-msgstr ""
4896-
4897-#: ../gwibber/microblog/plugins/facebook/gtk/facebook/__init__.py:94
4898-#: ../gwibber/microblog/plugins/statusnet/gtk/statusnet/__init__.py:73
4899-#: ../gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py:61
4900-#: ../gwibber/microblog/plugins/identica/gtk/identica/__init__.py:63
4901-#: ../gwibber/microblog/plugins/buzz/gtk/buzz/__init__.py:49
4902-#: ../gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py:65
4903-msgid "<p>Please wait...</p>"
4904-msgstr ""
4905-
4906-#: ../gwibber/microblog/plugins/facebook/gtk/facebook/__init__.py:163
4907-msgid "Facebook authorization failed. Please try again."
4908-msgstr ""
4909-
4910-#: ../gwibber/microblog/plugins/statusnet/__init__.py:213
4911-#: ../gwibber/microblog/plugins/statusnet/__init__.py:214
4912-#: ../gwibber/microblog/plugins/identica/__init__.py:211
4913-#: ../gwibber/microblog/plugins/identica/__init__.py:212
4914-msgid "Account needs to be re-authorized"
4915-msgstr ""
4916-
4917-#: ../gwibber/microblog/plugins/statusnet/__init__.py:246
4918-#: ../gwibber/microblog/plugins/twitter/__init__.py:279
4919-#: ../gwibber/microblog/plugins/identica/__init__.py:243
4920-#, python-format
4921-msgid "%s failed"
4922-msgstr ""
4923-
4924-#: ../gwibber/microblog/plugins/statusnet/gtk/statusnet/__init__.py:46
4925-#: ../gwibber/microblog/plugins/statusnet/gtk/statusnet/__init__.py:209
4926-#: ../gwibber/microblog/plugins/identica/gtk/identica/__init__.py:47
4927-#, python-format
4928-msgid "%s has been authorized by %s"
4929-msgstr ""
4930-
4931-#: ../gwibber/microblog/plugins/statusnet/gtk/statusnet/__init__.py:226
4932-#: ../gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py:146
4933-#: ../gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py:150
4934-#: ../gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py:170
4935-#: ../gwibber/microblog/plugins/identica/gtk/identica/__init__.py:212
4936-#: ../gwibber/microblog/plugins/buzz/gtk/buzz/__init__.py:123
4937-#: ../gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py:132
4938-#: ../gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py:136
4939-#: ../gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py:156
4940-msgid "Authorization failed. Please try again."
4941-msgstr ""
4942-
4943-#: ../gwibber/microblog/plugins/twitter/__init__.py:67
4944-#: ../gwibber/microblog/plugins/foursquare/__init__.py:40
4945-msgid "Failed to find credentials"
4946-msgstr ""
4947-
4948-#: ../gwibber/microblog/plugins/twitter/__init__.py:269
4949-#: ../gwibber/microblog/plugins/twitter/__init__.py:273
4950-#: ../gwibber/microblog/plugins/foursquare/__init__.py:147
4951-#: ../gwibber/microblog/plugins/foursquare/__init__.py:151
4952-msgid "Request failed"
4953-msgstr ""
4954-
4955-#: ../gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py:44
4956-#: ../gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py:158
4957-#, python-format
4958-msgid "%s has been authorized by Twitter"
4959-msgstr ""
4960-
4961-#: ../gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py:100
4962-#: ../gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py:93
4963-msgid "Verifying"
4964-msgstr ""
4965-
4966-#: ../gwibber/microblog/plugins/twitter/gtk/twitter/__init__.py:153
4967-#: ../gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py:139
4968-msgid "Successful"
4969-msgstr ""
4970-
4971-#: ../gwibber/microblog/plugins/identica/gtk/identica/__init__.py:196
4972-#, python-format
4973-msgid "%s has been authorized by Identi.ca"
4974-msgstr ""
4975-
4976-#: ../gwibber/microblog/plugins/buzz/gtk/buzz/__init__.py:37
4977-#: ../gwibber/microblog/plugins/buzz/gtk/buzz/__init__.py:111
4978-#, python-format
4979-msgid "%s has been authorized by Buzz"
4980-msgstr ""
4981-
4982-#: ../gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py:48
4983-#: ../gwibber/microblog/plugins/foursquare/gtk/foursquare/__init__.py:144
4984-#, python-format
4985-msgid "%s has been authorized by Foursquare"
4986-msgstr ""
4987-
4988-#: ../gwibber/util.py:113
4989-#, python-format
4990-msgid "%(year)d year ago"
4991-msgid_plural "%(year)d years ago"
4992-msgstr[0] ""
4993-msgstr[1] ""
4994-
4995-#: ../gwibber/util.py:116
4996-#, python-format
4997-msgid "%(day)d day ago"
4998-msgid_plural "%(day)d days ago"
4999-msgstr[0] ""
5000-msgstr[1] ""
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches