Ticket #3681: 0001-Port-to-Gtk3-SL-3681.2.patch

File 0001-Port-to-Gtk3-SL-3681.2.patch, 54.2 KB (added by humitos, 11 years ago)

Version 2

  • GetIABooksActivity.py

    From f6fe772604aafa7d4d3811a85d8dac76a006d056 Mon Sep 17 00:00:00 2001
    From: Manuel Kaufmann <humitos@gmail.com>
    Date: Wed, 20 Jun 2012 10:35:07 -0300
    Subject: [PATCH GetBooks v2] Port to Gtk3 SL #3681
    
    This is a big change that ports Get Books to Gtk3. Here are the steps[1]
    that I followed to this port.
    
    There are some things that are not working as they worked before the
    port, but all of them are related with the Gtk3 theme instead with the
    Get Books itself.
    
    [1] http://wiki.sugarlabs.org/go/User:Humitos/PortingGetBooks
    
    Signed-off-by: Manuel Kaufmann <humitos@gmail.com>
    ---
     GetIABooksActivity.py |  312 ++++++++++++++++++++++++-------------------------
     devicemanager.py      |   43 +++----
     extListview.py        |  169 ++++++++++++++++-----------
     listview.py           |   57 +++++----
     opds.py               |   54 ++++-----
     setup.py              |    2 +-
     6 files changed, 330 insertions(+), 307 deletions(-)
    
    diff --git a/GetIABooksActivity.py b/GetIABooksActivity.py
    index 0a06069..9d818d7 100644
    a b  
    1919import os
    2020import logging
    2121import time
    22 import gtk
    23 
    24 OLD_TOOLBAR = False
    25 try:
    26     from sugar.graphics.toolbarbox import ToolbarBox
    27     from sugar.activity.widgets import StopButton
    28 except ImportError:
    29     OLD_TOOLBAR = True
    30 
    31 from sugar.graphics import style
    32 from sugar.graphics.toolbutton import ToolButton
    33 from sugar.graphics.toggletoolbutton import ToggleToolButton
    34 from sugar.graphics.toolcombobox import ToolComboBox
    35 from sugar.graphics.combobox import ComboBox
    36 from sugar.graphics import iconentry
    37 from sugar import profile
    38 from sugar.activity import activity
    39 from sugar.activity.widgets import ToolbarButton
    40 from sugar.bundle.activitybundle import ActivityBundle
    41 from sugar.datastore import datastore
    42 from sugar.graphics.alert import NotifyAlert
    43 from sugar.graphics.alert import Alert
    44 from sugar.graphics.icon import Icon
     22
     23from gi.repository import Gtk
     24from gi.repository import Gdk
     25from gi.repository import GdkPixbuf
     26from gi.repository import GObject
     27from gi.repository import Pango
     28
     29
     30from sugar3.graphics.toolbarbox import ToolbarBox
     31from sugar3.activity.widgets import StopButton
     32from sugar3.graphics import style
     33from sugar3.graphics.toolbutton import ToolButton
     34from sugar3.graphics.toggletoolbutton import ToggleToolButton
     35from sugar3.graphics.toolcombobox import ToolComboBox
     36from sugar3.graphics.combobox import ComboBox
     37from sugar3.graphics import iconentry
     38from sugar3 import profile
     39from sugar3.activity import activity
     40from sugar3.activity.widgets import ToolbarButton
     41from sugar3.bundle.activitybundle import ActivityBundle
     42from sugar3.datastore import datastore
     43from sugar3.graphics.alert import NotifyAlert
     44from sugar3.graphics.alert import Alert
     45from sugar3.graphics.icon import Icon
    4546from gettext import gettext as _
     47
    4648import dbus
    47 import gobject
    4849import ConfigParser
    4950import base64
    5051
    class GetIABooksActivity(activity.Activity): 
    8687        else:
    8788            self._read_configuration()
    8889
    89         if OLD_TOOLBAR:
    90             toolbox = activity.ActivityToolbox(self)
    91             activity_toolbar = toolbox.get_activity_toolbar()
    92 
    93             self.set_toolbox(toolbox)
    94             self._books_toolbar = gtk.Toolbar()
    95             self._add_search_controls(self._books_toolbar)
    96             self.toolbox.add_toolbar(_('Books'), self._books_toolbar)
    97             self._books_toolbar.show()
    98             toolbox.show()
    99             toolbox.set_current_toolbar(1)
    100         else:
    101             toolbar_box = ToolbarBox()
    102             activity_button = ToolButton()
    103             color = profile.get_color()
    104             bundle = ActivityBundle(activity.get_bundle_path())
    105             icon = Icon(file=bundle.get_icon(), xo_color=color)
    106             activity_button.set_icon_widget(icon)
    107             activity_button.show()
     90        toolbar_box = ToolbarBox()
     91        activity_button = ToolButton()
     92        color = profile.get_color()
     93        bundle = ActivityBundle(activity.get_bundle_path())
     94        icon = Icon(file=bundle.get_icon(), xo_color=color)
     95        activity_button.set_icon_widget(icon)
     96        activity_button.show()
    10897
    109             toolbar_box.toolbar.insert(activity_button, 0)
    110             self._add_search_controls(toolbar_box.toolbar)
     98        toolbar_box.toolbar.insert(activity_button, 0)
     99        self._add_search_controls(toolbar_box.toolbar)
    111100
    112             separator = gtk.SeparatorToolItem()
    113             separator.props.draw = False
    114             separator.set_expand(True)
    115             toolbar_box.toolbar.insert(separator, -1)
     101        separator = Gtk.SeparatorToolItem()
     102        separator.props.draw = False
     103        separator.set_expand(True)
     104        toolbar_box.toolbar.insert(separator, -1)
    116105
    117             toolbar_box.toolbar.insert(StopButton(self), -1)
     106        toolbar_box.toolbar.insert(StopButton(self), -1)
    118107
    119             self.set_toolbar_box(toolbar_box)
    120             toolbar_box.show_all()
    121             self._books_toolbar = toolbar_box.toolbar
     108        self.set_toolbar_box(toolbar_box)
     109        toolbar_box.show_all()
     110        self._books_toolbar = toolbar_box.toolbar
    122111
    123112        self._create_controls()
    124113
    class GetIABooksActivity(activity.Activity): 
    236225        logging.error('catalogs %s', self.catalogs)
    237226
    238227    def _add_search_controls(self, toolbar):
    239         book_search_item = gtk.ToolItem()
     228        book_search_item = Gtk.ToolItem()
    240229        toolbar.search_entry = iconentry.IconEntry()
    241230        toolbar.search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
    242231                                                'system-search')
    243232        toolbar.search_entry.add_clear_button()
    244233        toolbar.search_entry.connect('activate',
    245234                self.__search_entry_activate_cb)
    246         width = int(gtk.gdk.screen_width() / 4)
     235        width = int(Gdk.Screen.width() / 4)
    247236        toolbar.search_entry.set_size_request(width, -1)
    248237        book_search_item.add(toolbar.search_entry)
    249238        toolbar.search_entry.show()
    class GetIABooksActivity(activity.Activity): 
    268257        if len(self.languages) > 0:
    269258            toolbar.config_toolbarbutton = ToolbarButton()
    270259            toolbar.config_toolbarbutton.props.icon_name = 'preferences-system'
    271             toolbar.config_toolbarbox = gtk.Toolbar()
     260            toolbar.config_toolbarbox = Gtk.Toolbar()
    272261            toolbar.config_toolbarbutton.props.page = toolbar.config_toolbarbox
    273262            toolbar.language_combo = ComboBox()
    274263            toolbar.language_combo.props.sensitive = True
    class GetIABooksActivity(activity.Activity): 
    321310        self.queryresults = opds.RemoteQueryResult(catalog_config,
    322311                '', query_language)
    323312        self.show_message(_('Performing lookup, please wait...'))
    324         self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
     313        # README: I think we should create some global variables for
     314        # each cursor that we are using to avoid the creation of them
     315        # every time that we want to change it
     316        self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
    325317
    326318        self.queryresults.connect('updated', self.__query_updated_cb)
    327319
    class GetIABooksActivity(activity.Activity): 
    428420        treestore, coldex = \
    429421                self.catalog_listview.get_selection().get_selected()
    430422        len_cat = len(self.catalog_history)
    431         if self.catalog_history[len_cat - 1]['catalogs'] == []:
     423        if len_cat > 0 and self.catalog_history[len_cat - 1]['catalogs'] == []:
    432424            self.catalog_history.pop()
    433425            len_cat = len(self.catalog_history)
    434426
    435         self.catalog_history.append(\
     427        # README: when the Activity starts by default there is nothing
     428        # selected and this signal is called, so we have to avoid this
     429        # 'append' because it fails
     430        if coldex is not None:
     431            self.catalog_history.append(
    436432                {'title': treestore.get_value(coldex, 0),
    437433                'catalogs': []})
    438         self.__switch_catalog_cb(treestore.get_value(coldex, 0))
     434            self.__switch_catalog_cb(treestore.get_value(coldex, 0))
    439435
    440436    def _sort_logfile(self, treemodel, itera, iterb):
    441437        a = treemodel.get_value(itera, 0)
    class GetIABooksActivity(activity.Activity): 
    455451            self.tree_scroller.show_all()
    456452            self.separa.show()
    457453        else:
    458             self.tree_scroller.hide_all()
     454            # README: hide_all() doesn't exist anymore
     455            # http://developer.gnome.org/gtk3/3.5/GtkWidget.html#gtk-widget-hide
     456            self.tree_scroller.hide()
    459457            self.separa.hide()
    460458
    461459    def _create_controls(self):
    462460        self._download_content_length = 0
    463461        self._download_content_type = None
    464         self.progressbox = gtk.HBox(spacing=20)
    465         self.progressbar = gtk.ProgressBar()
    466         self.progressbar.set_orientation(gtk.PROGRESS_LEFT_TO_RIGHT)
     462        self.progressbox = Gtk.Box(spacing=20,
     463                                   orientation=Gtk.Orientation.HORIZONTAL)
     464        self.progressbar = Gtk.ProgressBar()
    467465        self.progressbar.set_fraction(0.0)
    468         self.progressbox.pack_start(self.progressbar, expand=True,
    469                 fill=True)
    470         self.cancel_btn = gtk.Button(stock=gtk.STOCK_CANCEL)
     466        self.progressbox.pack_start(self.progressbar, expand=True, fill=True,
     467                                    padding=0)
     468        self.cancel_btn = Gtk.Button(stock=Gtk.STOCK_CANCEL)
    471469        self.cancel_btn.connect('clicked', self.__cancel_btn_clicked_cb)
    472470        self.progressbox.pack_start(self.cancel_btn, expand=False,
    473                 fill=False)
     471                                    fill=False, padding=0)
    474472
    475         self.msg_label = gtk.Label()
     473        self.msg_label = Gtk.Label()
    476474
    477         self.list_box = gtk.HBox()
     475        self.list_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
    478476
    479477        # Catalogs treeview
    480         self.catalog_listview = gtk.TreeView()
     478        self.catalog_listview = Gtk.TreeView()
    481479        self.catalog_listview.headers_clickble = True
    482480        self.catalog_listview.hover_expand = True
    483481        self.catalog_listview.rules_hint = True
    484482        self.catalog_listview.connect('cursor-changed', self.move_down_catalog)
    485483        self.catalog_listview.set_enable_search(False)
    486         self.treemodel = gtk.ListStore(gobject.TYPE_STRING)
    487         sorter = gtk.TreeModelSort(self.treemodel)
    488         sorter.set_sort_column_id(0, gtk.SORT_ASCENDING)
    489         sorter.set_sort_func(0, self._sort_logfile)
    490         self.catalog_listview.set_model(sorter)
    491         renderer = gtk.CellRendererText()
    492         renderer.set_property('wrap-mode', gtk.WRAP_WORD)
    493         self.treecol = gtk.TreeViewColumn(_('Catalogs'), renderer, text=0)
     484
     485        self.treemodel = Gtk.ListStore(str)
     486        self.treemodel.set_sort_column_id(0, Gtk.SortType.ASCENDING)
     487        self.catalog_listview.set_model(self.treemodel)
     488
     489        renderer = Gtk.CellRendererText()
     490        renderer.set_property('wrap-mode', Pango.WrapMode.WORD)
     491        self.treecol = Gtk.TreeViewColumn(_('Catalogs'), renderer, text=0)
    494492        self.treecol.set_property('clickable', True)
    495493        self.treecol.connect('clicked', self.move_up_catalog)
    496494        self.catalog_listview.append_column(self.treecol)
    class GetIABooksActivity(activity.Activity): 
    508506            self.treemodel.clear()
    509507            for p in self.categories:
    510508                self.path_iter[p['text']] = self.treemodel.append([p['text']])
    511         self.tree_scroller = gtk.ScrolledWindow(hadjustment=None,
    512                 vadjustment=None)
    513         self.tree_scroller.set_policy(gtk.POLICY_NEVER,
    514                 gtk.POLICY_AUTOMATIC)
     509        self.tree_scroller = Gtk.ScrolledWindow(hadjustment=None,
     510                                                vadjustment=None)
     511        self.tree_scroller.set_policy(Gtk.PolicyType.NEVER,
     512                Gtk.PolicyType.AUTOMATIC)
    515513        self.tree_scroller.add(self.catalog_listview)
    516         self.list_box.pack_start(self.tree_scroller, expand=False, fill=False)
    517         self.separa = gtk.VSeparator()
    518         self.list_box.pack_start(self.separa, expand=False, fill=False)
     514        self.list_box.pack_start(self.tree_scroller, expand=False,
     515                                 fill=False, padding=0)
     516        self.separa = Gtk.VSeparator()
     517        self.list_box.pack_start(self.separa, expand=False,
     518                                 fill=False, padding=0)
    519519
    520520        # books listview
    521521        self.listview = ListView(self._lang_code_handler)
    522522        self.listview.connect('selection-changed', self.selection_cb)
    523523        self.listview.set_enable_search(False)
    524524
    525         self.list_scroller = gtk.ScrolledWindow(hadjustment=None,
    526                 vadjustment=None)
    527         self.list_scroller.set_policy(gtk.POLICY_AUTOMATIC,
    528                 gtk.POLICY_AUTOMATIC)
     525        self.list_scroller = Gtk.ScrolledWindow(hadjustment=None,
     526                                                vadjustment=None)
     527        self.list_scroller.set_policy(Gtk.PolicyType.AUTOMATIC,
     528                                      Gtk.PolicyType.AUTOMATIC)
    529529        vadjustment = self.list_scroller.get_vadjustment()
    530530        vadjustment.connect('value-changed',
    531531                self.__vadjustment_value_changed_cb)
    532532        self.list_scroller.add(self.listview)
    533         self.list_box.pack_start(self.list_scroller, expand=True, fill=True)
    534 
    535         self.scrolled = gtk.ScrolledWindow()
    536         self.scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
    537         self.scrolled.props.shadow_type = gtk.SHADOW_NONE
    538         self.textview = gtk.TextView()
     533        self.list_box.pack_start(self.list_scroller, expand=True,
     534                                 fill=True, padding=0)
     535
     536        self.scrolled = Gtk.ScrolledWindow()
     537        self.scrolled.set_policy(Gtk.PolicyType.NEVER,
     538                                 Gtk.PolicyType.AUTOMATIC)
     539        self.scrolled.props.shadow_type = Gtk.ShadowType.NONE
     540        self.textview = Gtk.TextView()
    539541        self.textview.set_editable(False)
    540542        self.textview.set_cursor_visible(False)
    541         self.textview.set_wrap_mode(gtk.WRAP_WORD)
    542         self.textview.set_justification(gtk.JUSTIFY_LEFT)
     543        self.textview.set_wrap_mode(Gtk.WrapMode.WORD)
     544        self.textview.set_justification(Gtk.Justification.LEFT)
    543545        self.textview.set_left_margin(20)
    544546        self.textview.set_right_margin(20)
    545547        self.scrolled.add(self.textview)
    class GetIABooksActivity(activity.Activity): 
    547549        self.separa.hide()
    548550        self.tree_scroller.hide()
    549551
    550         vbox_download = gtk.VBox()
     552        vbox_download = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
    551553
    552         hbox_format = gtk.HBox()
    553         format_label = gtk.Label(_('Format:'))
     554        hbox_format = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
     555        format_label = Gtk.Label(label=_('Format:'))
    554556        self.format_combo = ComboBox()
    555557        for key in _MIMETYPES.keys():
    556558            self.format_combo.append_item(_MIMETYPES[key], key)
    class GetIABooksActivity(activity.Activity): 
    563565        hbox_format.pack_start(self.format_combo, False, False, 10)
    564566        vbox_download.pack_start(hbox_format, False, False, 10)
    565567
    566         self._download = gtk.Button(_('Get Book'))
     568        self._download = Gtk.Button(_('Get Book'))
    567569        self._download.props.sensitive = False
    568570        self._download.connect('clicked', self.__get_book_cb)
    569571        vbox_download.pack_start(self._download, False, False, 10)
    570572
    571         bottom_hbox = gtk.HBox()
     573        bottom_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
    572574
    573575        if self.show_images:
    574576            self.__image_downloader = None
    575             self.image = gtk.Image()
     577            self.image = Gtk.Image()
    576578            self.add_default_image()
    577579            bottom_hbox.pack_start(self.image, False, False, 10)
    578580        bottom_hbox.pack_start(self.scrolled, True, True, 10)
    579581        bottom_hbox.pack_start(vbox_download, False, False, 10)
    580582        bottom_hbox.show_all()
    581583
    582         vbox = gtk.VBox()
     584        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
    583585        vbox.pack_start(self.msg_label, False, False, 10)
    584586        vbox.pack_start(self.progressbox, False, False, 10)
    585587        vbox.pack_start(self.list_box, True, True, 0)
    class GetIABooksActivity(activity.Activity): 
    596598        if len(self.catalogs) > 0:
    597599            self.bt_catalogs.set_active(True)
    598600
    599 
    600601    def can_close(self):
    601602        self._lang_code_handler.close()
    602603        if self.queryresults is not None:
    class GetIABooksActivity(activity.Activity): 
    679680
    680681    def get_pixbuf_from_buffer(self, image_buffer):
    681682        """Buffer To Pixbuf"""
    682         pixbuf_loader = gtk.gdk.PixbufLoader()
     683        pixbuf_loader = GdkPixbuf.PixbufLoader()
    683684        pixbuf_loader.write(image_buffer)
    684685        pixbuf_loader.close()
    685686        pixbuf = pixbuf_loader.get_pixbuf()
    class GetIABooksActivity(activity.Activity): 
    718719        self.add_image(file_path)
    719720
    720721    def add_image(self, file_path):
    721         pixbuf = gtk.gdk.pixbuf_new_from_file(file_path)
     722        pixbuf = GdkPixbuf.Pixbuf.new_from_file(file_path)
    722723        self.add_image_buffer(pixbuf)
    723724
    724725    def add_image_buffer(self, pixbuf):
    725         image_height = int(gtk.gdk.screen_height() / 4)
     726        image_height = int(Gdk.Screen.height() / 4)
    726727        image_width = image_height / 3 * 2
    727728        width, height = pixbuf.get_width(), pixbuf.get_height()
    728729        scale = 1
    class GetIABooksActivity(activity.Activity): 
    731732            scale_y = image_height / float(height)
    732733            scale = min(scale_x, scale_y)
    733734
    734         pixbuf2 = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, \
    735                             pixbuf.get_has_alpha(), \
    736                             pixbuf.get_bits_per_sample(), \
    737                             image_width, image_height)
    738         pixbuf2.fill(style.COLOR_PANEL_GREY.get_int())
     735        pixbuf2 = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB,
     736                                       pixbuf.get_has_alpha(),
     737                                       pixbuf.get_bits_per_sample(),
     738                                       image_width, image_height)
     739
     740        # FIXME: I used this darker color instead of
     741        # style.COLOR_PANEL_GREY because there is a big difference on
     742        # the image. We should find the way to use the same color on
     743        # the .png loaded than in the rest of the square and remove
     744        # the 1px border
     745        pixbuf2.fill(style.COLOR_BUTTON_GREY.get_int())
    739746
    740747        margin_x = int((image_width - (width * scale)) / 2)
    741748        margin_y = int((image_height - (height * scale)) / 2)
    742749
    743         pixbuf.scale(pixbuf2, margin_x, margin_y, \
    744                             image_width - (margin_x * 2), \
    745                             image_height - (margin_y * 2), \
    746                             margin_x, margin_y, scale, scale, \
    747                             gtk.gdk.INTERP_BILINEAR)
     750        pixbuf.scale(pixbuf2, margin_x, margin_y,
     751                     image_width - (margin_x * 2),
     752                     image_height - (margin_y * 2),
     753                     margin_x, margin_y, scale, scale,
     754                     GdkPixbuf.InterpType.BILINEAR)
    748755
    749756        self.image.set_from_pixbuf(pixbuf2)
    750757
    class GetIABooksActivity(activity.Activity): 
    793800                            self.source, search_text)
    794801
    795802            self.show_message(_('Performing lookup, please wait...'))
    796             self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
     803            self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
    797804            self.queryresults.connect('updated', self.__query_updated_cb)
    798805
    799806    def __query_updated_cb(self, query, midway):
    class GetIABooksActivity(activity.Activity): 
    818825                if only_english:
    819826                    self.show_message(
    820827                            _('Sorry, we only found english books.'))
    821         self.window.set_cursor(None)
     828        self.get_window().set_cursor(None)
    822829        self._allow_suspend()
    823830
    824831    def catalogs_updated(self, query, midway):
    class GetIABooksActivity(activity.Activity): 
    919926    def get_book(self):
    920927        self.enable_button(False)
    921928        self.progressbox.show_all()
    922         gobject.idle_add(self.download_book, self.download_url)
     929        GObject.idle_add(self.download_book, self.download_url)
    923930
    924931    def download_book(self,  url):
    925932        self._inhibit_suspend()
    class GetIABooksActivity(activity.Activity): 
    960967                          bytes_downloaded)
    961968        total = self._download_content_length
    962969        self.set_downloaded_bytes(bytes_downloaded,  total)
    963         while gtk.events_pending():
    964             gtk.main_iteration()
     970        while Gtk.events_pending():
     971            Gtk.main_iteration()
    965972
    966973    def _get_book_error_cb(self, getter, err):
    967974        self.listview.props.sensitive = True
    class GetIABooksActivity(activity.Activity): 
    10171024        textbuffer = self.textview.get_buffer()
    10181025        journal_entry.metadata['description'] = \
    10191026            textbuffer.get_text(textbuffer.get_start_iter(),
    1020                 textbuffer.get_end_iter())
     1027                                textbuffer.get_end_iter(), True)
    10211028        if self.exist_cover_image:
    10221029            image_buffer = self._get_preview_image_buffer()
    10231030            journal_entry.metadata['preview'] = dbus.ByteArray(image_buffer)
    class GetIABooksActivity(activity.Activity): 
    10461053        _stop_alert.props.title = title
    10471054        _stop_alert.props.msg = msg
    10481055        open_icon = Icon(icon_name='zoom-activity')
    1049         _stop_alert.add_button(gtk.RESPONSE_APPLY,
     1056        _stop_alert.add_button(Gtk.ResponseType.APPLY,
    10501057                                    _('Show in Journal'), open_icon)
    10511058        open_icon.show()
    10521059        ok_icon = Icon(icon_name='dialog-ok')
    1053         _stop_alert.add_button(gtk.RESPONSE_OK, _('Ok'), ok_icon)
     1060        _stop_alert.add_button(Gtk.ResponseType.OK, _('Ok'), ok_icon)
    10541061        ok_icon.show()
    10551062        # Remove other alerts
    10561063        for alert in self._alerts:
    class GetIABooksActivity(activity.Activity): 
    10611068        _stop_alert.show()
    10621069
    10631070    def __stop_response_cb(self, alert, response_id):
    1064         if response_id is gtk.RESPONSE_APPLY:
     1071        if response_id is Gtk.ResponseType.APPLY:
    10651072            activity.show_object_in_journal(self._object_id)
    10661073        self.remove_alert(alert)
    10671074
    class GetIABooksActivity(activity.Activity): 
    10771084            scale_y = preview_height / float(height)
    10781085            scale = min(scale_x, scale_y)
    10791086
    1080         pixbuf2 = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, \
    1081                             pixbuf.get_has_alpha(), \
    1082                             pixbuf.get_bits_per_sample(), \
    1083                             preview_width, preview_height)
     1087        pixbuf2 = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB,
     1088                                       pixbuf.get_has_alpha(),
     1089                                       pixbuf.get_bits_per_sample(),
     1090                                       preview_width, preview_height)
    10841091        pixbuf2.fill(style.COLOR_WHITE.get_int())
    10851092
    10861093        margin_x = int((preview_width - (width * scale)) / 2)
    10871094        margin_y = int((preview_height - (height * scale)) / 2)
    10881095
    1089         pixbuf.scale(pixbuf2, margin_x, margin_y, \
    1090                             preview_width - (margin_x * 2), \
    1091                             preview_height - (margin_y * 2), \
    1092                             margin_x, margin_y, scale, scale, \
    1093                             gtk.gdk.INTERP_BILINEAR)
    1094         preview_data = []
    1095 
    1096         def save_func(buf, data):
    1097             data.append(buf)
     1096        pixbuf.scale(pixbuf2, margin_x, margin_y,
     1097                     preview_width - (margin_x * 2),
     1098                     preview_height - (margin_y * 2),
     1099                     margin_x, margin_y, scale, scale,
     1100                     GdkPixbuf.InterpType.BILINEAR)
    10981101
    1099         pixbuf2.save_to_callback(save_func, 'png', user_data=preview_data)
    1100         preview_data = ''.join(preview_data)
    1101         return preview_data
     1102        # README: GdkPixbuf.Pixbuf.save_to_callback is no longer
     1103        # available, so we use save_to_bufferv instead.
     1104        succes, data = pixbuf2.save_to_bufferv('png', [], [])
     1105        return data
    11021106
    11031107    def _get_cover_image_buffer(self):
    11041108        pixbuf = self.image.get_pixbuf()
    1105         cover_data = []
    1106 
    1107         def save_func(buf, data):
    1108             data.append(buf)
    1109 
    1110         pixbuf.save_to_callback(save_func, 'png', user_data=cover_data)
    1111         cover_data = ''.join(cover_data)
    1112         return cover_data
     1109        succes, data = pixbuf.save_to_bufferv('png', [], [])
     1110        return data
    11131111
    11141112    def _show_error_alert(self, title, text=None):
    11151113        alert = NotifyAlert(timeout=20)
    class GetIABooksActivity(activity.Activity): 
    11901188        pass
    11911189
    11921190
    1193 class ButtonWithImage(gtk.Button):
     1191class ButtonWithImage(Gtk.Button):
    11941192
    11951193    def __init__(self, label_text):
    1196         gtk.Button.__init__(self, _('Catalogs'))
     1194        GObject.GObject.__init__(self,)
    11971195        self.icon_move_up = Icon(icon_name='go-up')
    1198         self.remove(self.get_children()[0])
    1199         self.hbox = gtk.HBox()
     1196        # self.remove(self.get_children()[0])
     1197        self.hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
    12001198        self.add(self.hbox)
    12011199        self.hbox.add(self.icon_move_up)
    1202         self.label = gtk.Label(label_text)
     1200        self.label = Gtk.Label(label=label_text)
    12031201        self.hbox.add(self.label)
    12041202        self.show_all()
    12051203
  • devicemanager.py

    diff --git a/devicemanager.py b/devicemanager.py
    index f673fce..7630126 100644
    a b  
    1818
    1919import os
    2020import logging
    21 import gobject
    2221import dbus
    2322
    24 UDISK_DEVICE_PATH = 'org.freedesktop.UDisks.Device'
     23from gi.repository import GObject
    2524
     25# UDISK_DEVICE_PATH = 'org.freedesktop.UDisks.Device'
    2626
    27 class DeviceManager(gobject.GObject):
     27
     28class DeviceManager(GObject.GObject):
    2829
    2930    __gsignals__ = {
    30         'device-changed': (gobject.SIGNAL_RUN_FIRST,
    31                           gobject.TYPE_NONE,
     31        'device-changed': (GObject.SignalFlags.RUN_FIRST,
     32                          None,
    3233                          ([])),
    3334    }
    3435
    3536    def __init__(self):
    36         gobject.GObject.__init__(self)
     37        GObject.GObject.__init__(self)
    3738
    3839        self._devices = {}
    3940        self._bus = dbus.SystemBus()
    class DeviceManager(gobject.GObject): 
    5960
    6061    def _get_props_from_device(self, device):
    6162        # http://hal.freedesktop.org/docs/udisks/Device.html
    62         device_obj = self._bus.get_object('org.freedesktop.UDisks', device)
    63         device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE)
    64         props = {}
    65         props['mounted'] = bool(device_props.Get(UDISK_DEVICE_PATH,
    66                 'DeviceIsMounted'))
    67         if props['mounted']:
    68             props['mount_path'] = str(device_props.Get(UDISK_DEVICE_PATH,
    69                     'DeviceMountPaths')[0])
    70             props['removable'] = bool(device_props.Get(UDISK_DEVICE_PATH,
    71                     'DriveCanDetach'))
    72             props['label'] = str(device_props.Get(UDISK_DEVICE_PATH,
    73                     'IdLabel'))
    74             props['size'] = int(device_props.Get(UDISK_DEVICE_PATH,
    75                     'DeviceSize'))
    76             return props
     63        # device_obj = self._bus.get_object('org.freedesktop.UDisks', device)
     64        # device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE)
     65        # props = {}
     66        # props['mounted'] = bool(device_props.Get(UDISK_DEVICE_PATH,
     67        #         'DeviceIsMounted'))
     68        # if props['mounted']:
     69        #     props['mount_path'] = str(device_props.Get(UDISK_DEVICE_PATH,
     70        #             'DeviceMountPaths')[0])
     71        #     props['removable'] = bool(device_props.Get(UDISK_DEVICE_PATH,
     72        #             'DriveCanDetach'))
     73        #     props['label'] = str(device_props.Get(UDISK_DEVICE_PATH,
     74        #             'IdLabel'))
     75        #     props['size'] = int(device_props.Get(UDISK_DEVICE_PATH,
     76        #             'DeviceSize'))
     77        #     return props
    7778        return None
    7879
    7980    def _have_catalog(self, props):
  • extListview.py

    diff --git a/extListview.py b/extListview.py
    index cf0b450..060eddc 100644
    a b  
    3434#
    3535# v1.3:
    3636#   * Greatly improved speed when sorting a lot of rows
    37 #   * Added support for gtk.CellRendererToggle
     37#   * Added support for Gtk.CellRendererToggle
    3838#   * Improved replaceContent() method
    3939#   * Added a call to set_cursor() when removing selected row(s)
    4040#   * Added getFirstSelectedRow(), appendRows(), addColumnAttribute(),
    4141#   unselectAll() and selectAll() methods
    42 #   * Set expand to False when calling pack_start()
     42#   * Set expand to False when calling pack_start(, True, True, 0)
    4343#
    4444# v1.2:
    4545#   * Fixed D'n'D reordering bugs
     
    5252#     the empty area
    5353#   * Sort indicators are now displayed whenever needed
    5454
    55 import gtk
    5655import random
     56import logging
    5757
    58 from gtk import gdk
    59 from gobject import signal_new, TYPE_INT, TYPE_STRING, TYPE_BOOLEAN, \
    60 TYPE_PYOBJECT, TYPE_NONE, SIGNAL_RUN_LAST
     58from gi.repository import Gtk
     59from gi.repository import GObject
     60from gi.repository import Gdk
    6161
    6262
    6363# Internal d'n'd (reordering)
    6464DND_REORDERING_ID = 1024
    6565DND_INTERNAL_TARGET = ('extListview-internal',
    66                         gtk.TARGET_SAME_WIDGET, DND_REORDERING_ID)
     66                        Gtk.TargetFlags.SAME_WIDGET, DND_REORDERING_ID)
    6767
    6868
    69 # Custom signals
    70 signal_new('extlistview-dnd', gtk.TreeView, SIGNAL_RUN_LAST, TYPE_NONE,
    71             (gdk.DragContext, TYPE_INT, TYPE_INT, gtk.SelectionData, TYPE_INT,
    72             TYPE_PYOBJECT))
    73 signal_new('extlistview-modified', gtk.TreeView, SIGNAL_RUN_LAST, TYPE_NONE,
    74             ())
    75 signal_new('extlistview-button-pressed', gtk.TreeView, SIGNAL_RUN_LAST,
    76             TYPE_NONE, (gdk.Event, TYPE_PYOBJECT))
    77 signal_new('extlistview-column-visibility-changed', gtk.TreeView,
    78             SIGNAL_RUN_LAST, TYPE_NONE, (TYPE_STRING, TYPE_BOOLEAN))
    79 signal_new('button-press-event', gtk.TreeViewColumn, SIGNAL_RUN_LAST,
    80             TYPE_NONE, (gdk.Event, ))
    81 
    82 
    83 class ExtListViewColumn(gtk.TreeViewColumn):
     69class ExtListViewColumn(Gtk.TreeViewColumn):
    8470    """
    8571        TreeViewColumn does not signal right-click events, and we need them
    8672        This subclass is equivalent to TreeViewColumn, but it signals these
    class ExtListViewColumn(gtk.TreeViewColumn): 
    9076        (http://www.sacredchao.net/quodlibet)
    9177    """
    9278
     79    __gsignals__ = {
     80        'button-press-event': (GObject.SignalFlags.RUN_LAST, None,
     81                               (object,)),
     82        }
     83
    9384    def __init__(self, title=None, cell_renderer=None, **args):
    94         """ Constructor, see gtk.TreeViewColumn """
    95         gtk.TreeViewColumn.__init__(self, title, cell_renderer, **args)
    96         label = gtk.Label(title)
     85        """ Constructor, see Gtk.TreeViewColumn """
     86        GObject.GObject.__init__(self)
     87        label = Gtk.Label(label=title)
    9788        self.set_widget(label)
    9889        label.show()
    9990        label.__realize = label.connect('realize', self.onRealize)
    class ExtListViewColumn(gtk.TreeViewColumn): 
    10192    def onRealize(self, widget):
    10293        widget.disconnect(widget.__realize)
    10394        del widget.__realize
    104         button = widget.get_ancestor(gtk.Button)
     95        button = widget.get_ancestor(Gtk.Button)
    10596        if button is not None:
    10697            button.connect('button-press-event', self.onButtonPressed)
    10798
    class ExtListViewColumn(gtk.TreeViewColumn): 
    109100        self.emit('button-press-event', event)
    110101
    111102
    112 class ExtListView(gtk.TreeView):
     103class ExtListView(Gtk.TreeView):
     104
     105    __gsignals__ = {
     106        'extlistview-modified': (GObject.SignalFlags.RUN_LAST, None,
     107                                 ()),
     108
     109        # README: I had to change gdk.Event to object on the arguments
     110        # sent to the callback because with Gdk.Event it didn't work
     111        # 'extlistview-button-pressed': (GObject.SignalFlags.RUN_LAST, None,
     112        #                                (object, bool)),
     113        }
    113114
    114115    def __init__(self, columns, sortable=True, dndTargets=[], useMarkup=False,
    115116            canShowHideColumns=True):
    class ExtListView(gtk.TreeView): 
    125126            If useMarkup is True, the 'markup' attributes is used instead of
    126127            'text' for CellRendererTexts
    127128        """
    128         gtk.TreeView.__init__(self)
     129        GObject.GObject.__init__(self)
    129130
    130131        self.selection = self.get_selection()
    131132
    class ExtListView(gtk.TreeView): 
    140141        self.set_rules_hint(True)
    141142        self.set_headers_visible(True)
    142143
    143         self.selection.set_mode(gtk.SELECTION_MULTIPLE)
     144        self.selection.set_mode(Gtk.SelectionMode.MULTIPLE)
    144145
    145146        # Create the columns
    146147        nbEntries = 0
    class ExtListView(gtk.TreeView): 
    152153            else:
    153154                column = ExtListViewColumn(title)
    154155                column.set_resizable(True)
    155                 #column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
     156                # column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
    156157                column.set_expand(expandable)
    157158                column.set_visible(visible)
    158159                if canShowHideColumns:
    class ExtListView(gtk.TreeView): 
    169170                    nbEntries += 1
    170171                    dataTypes.append(type)
    171172                    column.pack_start(renderer, False)
    172                     if isinstance(renderer, gtk.CellRendererToggle):
     173                    if isinstance(renderer, Gtk.CellRendererToggle):
    173174                        column.add_attribute(renderer, 'active', nbEntries - 1)
    174                     elif isinstance(renderer, gtk.CellRendererPixbuf):
     175                    elif isinstance(renderer, Gtk.CellRendererPixbuf):
    175176                        column.add_attribute(renderer, 'pixbuf', nbEntries - 1)
    176                     elif isinstance(renderer, gtk.CellRendererText):
     177                    elif isinstance(renderer, Gtk.CellRendererText):
    177178                        if useMarkup:
    178179                            column.add_attribute(renderer, 'markup',
    179180                                nbEntries - 1)
    class ExtListView(gtk.TreeView): 
    184185        # Mark management
    185186        self.markedRow = None
    186187        self.markColumn = len(dataTypes)
    187         dataTypes.append(TYPE_BOOLEAN)  # When there's no other solution,
    188                                         # this additional entry helps in
    189                                         # finding the marked row
     188        dataTypes.append(bool)  # When there's no other solution,
     189                                # this additional entry helps in
     190                                # finding the marked row
    190191
    191192        # Create the ListStore associated with this tree
    192         self.store = gtk.ListStore(*dataTypes)
     193        self.store = Gtk.ListStore(*dataTypes)
    193194        self.set_model(self.store)
    194195
    195196        # Drag'n'drop management
    class ExtListView(gtk.TreeView): 
    200201        self.dndReordering = False
    201202
    202203        if len(dndTargets) != 0:
    203             self.enable_model_drag_dest(dndTargets, gdk.ACTION_DEFAULT)
     204            self.enable_model_drag_dest(dndTargets, Gdk.DragAction.DEFAULT)
     205
     206        # self.connect('drag-begin', self.onDragBegin)
     207        # self.connect('drag-motion', self.onDragMotion)
    204208
    205         self.connect('drag-begin', self.onDragBegin)
    206         self.connect('drag-motion', self.onDragMotion)
    207         self.connect('button-press-event', self.onButtonPressed)
    208         self.connect('drag-data-received', self.onDragDataReceived)
    209         self.connect('button-release-event', self.onButtonReleased)
     209        # README: this function is disconnected because it emit twice
     210        # 'selection-changed'
     211        # self.connect('button-press-event', self.onButtonPressed)
     212
     213        # self.connect('drag-data-received', self.onDragDataReceived)
     214        # self.connect('button-release-event', self.onButtonReleased)
    210215
    211216        # Show the list
    212217        self.show()
    class ExtListView(gtk.TreeView): 
    314319        criteria = self.sortColCriteria[column]
    315320        rows.sort(lambda r1, r2: \
    316321                self.__cmpRows(r1, r2, criteria, self.sortAscending))
    317         self.store.reorder([r[-1] for r in rows])
     322        # FIXME: AttributeError: 'ListStore' object has no attribute 'reorder'
     323        # Bug filled upstream:
     324        #   - https://bugzilla.gnome.org/show_bug.cgi?id=677941
     325        # self.store.reorder([r[-1] for r in rows])
    318326
    319327        # Move the mark if needed
    320328        if self.markedRow is not None:
    class ExtListView(gtk.TreeView): 
    322330
    323331        column.set_sort_indicator(True)
    324332        if self.sortAscending:
    325             column.set_sort_order(gtk.SORT_ASCENDING)
     333            column.set_sort_order(Gtk.SortType.ASCENDING)
    326334        else:
    327             column.set_sort_order(gtk.SORT_DESCENDING)
     335            column.set_sort_order(Gtk.SortType.DESCENDING)
    328336
    329337        self.emit('extlistview-modified')
    330338
    class ExtListView(gtk.TreeView): 
    349357
    350358    def getFirstSelectedRow(self):
    351359        """ Return only the first selected row """
     360        # TODO: check if this fail on gtk2 version after click on the ListView
    352361        return tuple(self.store[self.selection.get_selected_rows()[1][0]])[:-1]
    353362
    354363    def getFirstSelectedRowIndex(self):
    class ExtListView(gtk.TreeView): 
    502511        """ Enable the use of Drag'n'Drop to reorder the list """
    503512        self.dndReordering = True
    504513        self.dndTargets.append(DND_INTERNAL_TARGET)
    505         self.enable_model_drag_dest(self.dndTargets, gdk.ACTION_DEFAULT)
     514        self.enable_model_drag_dest(self.dndTargets, Gdk.DragAction.DEFAULT)
    506515
    507516    def __isDropAfter(self, pos):
    508         """ Helper function, True if pos is gtk.TREE_VIEW_DROP_AFTER or
    509             gtk.TREE_VIEW_DROP_INTO_OR_AFTER """
    510         return pos == gtk.TREE_VIEW_DROP_AFTER or \
    511                 pos == gtk.TREE_VIEW_DROP_INTO_OR_AFTER
     517        """ Helper function, True if pos is Gtk.TreeViewDropPosition.AFTER or
     518            Gtk.TreeViewDropPosition.INTO_OR_AFTER """
     519        return pos == Gtk.TreeViewDropPosition.AFTER or \
     520                pos == Gtk.TreeViewDropPosition.INTO_OR_AFTER
    512521
    513522    def __moveSelectedRows(self, x, y):
    514523        """ Internal function used for drag'n'drop """
    class ExtListView(gtk.TreeView): 
    516525        dropInfo = self.get_dest_row_at_pos(int(x), int(y))
    517526
    518527        if dropInfo is None:
    519             pos, path = gtk.TREE_VIEW_DROP_INTO_OR_AFTER, len(self.store) - 1
     528            pos, path = (Gtk.TreeViewDropPosition.INTO_OR_AFTER,
     529                         len(self.store) - 1)
    520530        else:
    521             pos, path = dropInfo[1], dropInfo[0][0]
     531            pos, path = (dropInfo[1], dropInfo[0][0])
    522532            if self.__isDropAfter(pos) and path < len(self.store) - 1:
    523                 pos = gtk.TREE_VIEW_DROP_INTO_OR_BEFORE
     533                pos = Gtk.TreeViewDropPosition.INTO_OR_BEFORE
    524534                path += 1
    525535
    526536        self.freeze_child_notify()
    class ExtListView(gtk.TreeView): 
    567577
    568578        if event.button == 1 or event.button == 3:
    569579            if path is None:
     580                # README: this emit the signal: selection-changed and
     581                # there is nothing selected so we get an IndexError
    570582                self.selection.unselect_all()
    571583                tree.set_cursor(len(self.store))
    572584            else:
    573585                if self.dndReordering and self.motionEvtId is None \
    574586                    and event.button == 1:
    575587                    self.dndStartPos = (int(event.x), int(event.y))
    576                     self.motionEvtId = gtk.TreeView.connect(self, \
     588                    self.motionEvtId = Gtk.TreeView.connect(self, \
    577589                            'motion-notify-event', self.onMouseMotion)
    578590
    579                 stateClear = not (event.state & \
    580                             (gdk.SHIFT_MASK | gdk.CONTROL_MASK))
     591                stateClear = not (event.get_state() & \
     592                                      (Gdk.ModifierType.SHIFT_MASK |
     593                                       Gdk.ModifierType.CONTROL_MASK))
    581594
    582595                if stateClear and not self.selection.path_is_selected(path):
    583596                    self.selection.unselect_all()
    class ExtListView(gtk.TreeView): 
    586599                    retVal = (stateClear and self.getSelectedRowsCount() > 1 \
    587600                            and self.selection.path_is_selected(path))
    588601
    589         self.emit('extlistview-button-pressed', event, path)
     602        # self.emit('extlistview-button-pressed', event, path)
    590603
    591604        return retVal
    592605
    class ExtListView(gtk.TreeView): 
    599612
    600613            if len(self.dndTargets) != 0:
    601614                self.enable_model_drag_dest(self.dndTargets,
    602                     gdk.ACTION_DEFAULT)
     615                    Gdk.DragAction.DEFAULT)
    603616
    604         stateClear = not (event.state & (gdk.SHIFT_MASK | gdk.CONTROL_MASK))
     617        stateClear = not (event.get_state() & \
     618                              (Gdk.ModifierType.SHIFT_MASK |
     619                               Gdk.ModifierType.CONTROL_MASK))
    605620
    606         if stateClear and event.state & gdk.BUTTON1_MASK \
     621        if stateClear and event.get_state() & Gdk.ModifierType.BUTTON1_MASK \
    607622            and self.getSelectedRowsCount() > 1:
    608623            pathInfo = self.get_path_at_pos(int(event.x), int(event.y))
    609624            if pathInfo is not None:
    class ExtListView(gtk.TreeView): 
    616631            self.drag_check_threshold(self.dndStartPos[0], self.dndStartPos[1],
    617632            int(event.x), int(event.y)):
    618633            self.dndContext = self.drag_begin([DND_INTERNAL_TARGET],
    619                     gdk.ACTION_COPY, 1, event)
     634                    Gdk.DragAction.COPY, 1, event)
    620635
    621636    def onDragBegin(self, tree, context):
    622637        """ A drag'n'drop operation has begun """
    623638        if self.getSelectedRowsCount() == 1:
    624             context.set_icon_stock(gtk.STOCK_DND, 0, 0)
     639            context.set_icon_stock(Gtk.STOCK_DND, 0, 0)
    625640        else:
    626             context.set_icon_stock(gtk.STOCK_DND_MULTIPLE, 0, 0)
     641            context.set_icon_stock(Gtk.STOCK_DND_MULTIPLE, 0, 0)
    627642
    628643    def onDragDataReceived(self, tree, context, x, y, selection, dndId, time):
    629644        """ Some data has been dropped into the list """
    class ExtListView(gtk.TreeView): 
    639654        drop = self.get_dest_row_at_pos(int(x), int(y))
    640655
    641656        if drop is not None and \
    642             (drop[1] == gtk.TREE_VIEW_DROP_INTO_OR_AFTER or \
    643             drop[1] == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
     657            (drop[1] == Gtk.TreeViewDropPosition.INTO_OR_AFTER or \
     658            drop[1] == Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
    644659            self.enable_model_drag_dest([('invalid-position', 0, -1)],
    645                     gdk.ACTION_DEFAULT)
     660                    Gdk.DragAction.DEFAULT)
    646661        else:
    647             self.enable_model_drag_dest(self.dndTargets, gdk.ACTION_DEFAULT)
     662            self.enable_model_drag_dest(self.dndTargets,
     663                                        Gdk.DragAction.DEFAULT)
    648664
    649665    def onColumnHeaderClicked(self, column, event):
    650666        """ A column header has been clicked """
     667
    651668        if event.button == 3:
    652669            # Create a menu with a CheckMenuItem per column
    653             menu = gtk.Menu()
     670            menu = Gtk.Menu()
     671
     672            # README: it seems like we should use a Palette here
     673            # from sugar3.graphics.palette import Palette
     674            # menu = Palette('Humitos', text_maxlen=50)
     675
    654676            nbVisibleItems = 0
    655677            lastVisibleItem = None
    656678            for column in self.get_columns():
    657                 item = gtk.CheckMenuItem(column.get_title())
     679                item = Gtk.CheckMenuItem(column.get_title())
    658680                item.set_active(column.get_visible())
    659681                item.connect('toggled', self.onShowHideColumn, column)
    660682                item.show()
    class ExtListView(gtk.TreeView): 
    669691            if nbVisibleItems == 1:
    670692                lastVisibleItem.set_sensitive(False)
    671693
    672             menu.popup(None, None, None, event.button, event.get_time())
     694            # README: a new argument is needed. Although this is not working
     695            # http://developer.gnome.org/gtk3/3.5/GtkMenu.html#gtk-menu-popup
     696            menu.popup(None, None, None, None, event.button, event.get_time())
     697
     698            # FIXME: for some reason this menu.popup call is not
     699            # showing the popup
    673700
    674701    def onShowHideColumn(self, menuItem, column):
    675702        """ Switch the visibility of the given column """
  • listview.py

    diff --git a/listview.py b/listview.py
    index 7a1769a..8356bfc 100644
    a b  
    1616# along with this program; if not, write to the Free Software
    1717# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1818
    19 import gobject
    20 import gtk
    21 import pango
    22 import sys
    23 from gettext import gettext as _
    24 import logging
     19from gi.repository import GObject
     20from gi.repository import Gtk
     21from gi.repository import Pango
    2522
     23from gettext import gettext as _
    2624from extListview import ExtListView
    2725
    28 _logger = logging.getLogger('get-ia-books-activity')
    29 
    3026
    3127class ListView(ExtListView):
    32     __txtRdr = gtk.CellRendererText()
    33     __txtRdr.props.wrap_mode = pango.WRAP_WORD
     28    __txtRdr = Gtk.CellRendererText()
     29    __txtRdr.props.wrap_mode = Pango.WrapMode.WORD
    3430    __txtRdr.props.wrap_width = 500
    3531    __txtRdr.props.width = 500
    3632    (ROW_TITLE, ROW_AUTHOR, ROW_PUBLISHER,
    3733    ROW_LANGUAGE, ROW_PUB_DATE, ROW_BOOK) = range(6)
    3834
    39     columns = ((_('Title'), [(__txtRdr, gobject.TYPE_STRING)],
     35    columns = ((_('Title'), [(__txtRdr, GObject.TYPE_STRING)],
    4036                    (ROW_TITLE,), False, True),
    41                (_('Author'), [(__txtRdr, gobject.TYPE_STRING)],
     37               (_('Author'), [(__txtRdr, GObject.TYPE_STRING)],
    4238                    (ROW_AUTHOR, ROW_TITLE), False,  True),
    43                (_('Publisher'), [(__txtRdr, gobject.TYPE_STRING)],
     39               (_('Publisher'), [(__txtRdr, GObject.TYPE_STRING)],
    4440                    (ROW_AUTHOR, ROW_TITLE), False,  False),
    45                (_('Language'), [(__txtRdr, gobject.TYPE_STRING)],
     41               (_('Language'), [(__txtRdr, GObject.TYPE_STRING)],
    4642                    (ROW_AUTHOR, ROW_TITLE), False,  False),
    47                (_('Publish Date'), [(__txtRdr, gobject.TYPE_STRING)],
     43               (_('Publish Date'), [(__txtRdr, GObject.TYPE_STRING)],
    4844                    (ROW_AUTHOR, ROW_TITLE), False,  False),
    49                (None, [(None, gobject.TYPE_PYOBJECT)], (None,), False, False))
     45               (None, [(None, GObject.TYPE_PYOBJECT)], (None,), False, False))
     46
    5047    __gsignals__ = {
    51         'selection-changed': (gobject.SIGNAL_RUN_FIRST,
    52                           gobject.TYPE_NONE,
    53                           ([])),
    54     }
     48        'selection-changed': (GObject.SignalFlags.RUN_LAST,
     49                              None,
     50                              ([])),
     51        }
    5552
    5653    def __init__(self, lang_code_handler):
    5754        ExtListView.__init__(self, self.columns, sortable=True,
    class ListView(ExtListView): 
    6158        self._lang_code_handler = lang_code_handler
    6259
    6360        selection = self.get_selection()
    64         selection.set_mode(gtk.SELECTION_SINGLE)
    65         selection.connect("changed", self.__selection_changed_cb)
     61        selection.set_mode(Gtk.SelectionMode.SINGLE)
     62        selection.connect('changed', self.__selection_changed_cb)
    6663
    6764    def __selection_changed_cb(self, selection):
    6865        self.emit('selection-changed')
    class ListView(ExtListView): 
    7875            try:
    7976                lang = self._lang_code_handler.get_full_language_name(
    8077                                                        book.get_language())
    81             except:
     78            except KeyError:
    8279                pass
    83             try:
    84                 rows.append([book.get_title(), book.get_author(), \
    85                     book.get_publisher(), lang, \
    86                     book.get_published_year(), book])
    87             except:
    88                 _logger.debug(sys.exc_info())
    8980
    90         self.clear()
     81            rows.append([book.get_title(), book.get_author(),
     82                         book.get_publisher(), lang,
     83                         book.get_published_year(), book])
     84
     85        # README: I had to remove the self.clear() here because it
     86        # made the listview to scroll to the top on Gtk3
     87
    9188        self.insertRows(rows)
    9289
    9390    def get_selected_book(self):
  • opds.py

    diff --git a/opds.py b/opds.py
    index fc536f3..1cd6d62 100644
    a b  
    1616# along with this program; if not, write to the Free Software
    1717# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1818
    19 import logging
     19from gi.repository import GObject
     20from gi.repository import Gtk
     21
     22from sugar3 import network
    2023
     24import logging
    2125import threading
    2226import os
    2327import urllib
    24 import gobject
    25 import gtk
    2628import time
    2729import csv
    2830
    29 from sugar import network
    30 
    3131import sys
    3232sys.path.insert(0, './')
    3333import feedparser
    _REL_SUBSECTION = 'subsection' 
    3939_REL_OPDS_POPULAR = u'http://opds-spec.org/sort/popular'
    4040_REL_OPDS_NEW = u'http://opds-spec.org/sort/new'
    4141
    42 gobject.threads_init()
     42GObject.threads_init()
    4343
    4444
    4545class ReadURLDownloader(network.GlibURLDownloader):
    class DownloadThread(threading.Thread): 
    100100
    101101        self.obj._feedobj = feedobj
    102102        self.obj._ready = True
    103         gobject.idle_add(self.obj.notify_updated, self.midway)
     103        GObject.idle_add(self.obj.notify_updated, self.midway)
    104104        return False
    105105
    106106    def run(self):
    class Book(object): 
    222222        return False
    223223
    224224
    225 class QueryResult(gobject.GObject):
     225class QueryResult(GObject.GObject):
    226226
    227227    __gsignals__ = {
    228         'updated': (gobject.SIGNAL_RUN_FIRST,
    229                           gobject.TYPE_NONE,
    230                           ([gobject.TYPE_BOOLEAN])),
     228        'updated': (GObject.SignalFlags.RUN_FIRST,
     229                          None,
     230                          ([bool])),
    231231    }
    232232
    233233    def __init__(self, configuration, queryterm, language):
    234         gobject.GObject.__init__(self)
     234        GObject.GObject.__init__(self)
    235235        self._configuration = configuration
    236236        self._uri = self._configuration['query_uri']
    237237        self._queryterm = queryterm
    class DownloadIAThread(threading.Thread): 
    369369        self._download_content_type = None
    370370        self._booklist = []
    371371        queryterm = self.obj._queryterm
    372         search_tuple = queryterm.lower().split()
     372        # search_tuple = queryterm.lower().split()
    373373        FL = urllib.quote('fl[]')
    374374        SORT = urllib.quote('sort[]')
    375375        self.search_url = 'http://www.archive.org/advancedsearch.php?q=' +  \
    class DownloadIAThread(threading.Thread): 
    384384        self.stopthread = threading.Event()
    385385
    386386    def _download(self):
    387         gobject.idle_add(self.download_csv, self.search_url)
     387        GObject.idle_add(self.download_csv, self.search_url)
    388388
    389389    def download_csv(self, url):
    390390        logging.error('get csv from %s', url)
    class DownloadIAThread(threading.Thread): 
    428428        reader.next()  # skip the first header row.
    429429        for row in reader:
    430430            if len(row) < 7:
    431                 _logger.debug("Server Error",  self.search_url)
     431                _logger.debug("Server Error: %s",  self.search_url)
    432432                return
    433433            entry = {}
    434434            entry['author'] = row[0]
    class DownloadIAThread(threading.Thread): 
    461461            self.obj._booklist.append(IABook(None, entry, ''))
    462462
    463463        os.remove(tempfile)
    464         gobject.idle_add(self.obj.notify_updated, self.midway)
     464        GObject.idle_add(self.obj.notify_updated, self.midway)
    465465        self.obj._ready = True
    466466        return False
    467467
    class InternetArchiveQueryResult(QueryResult): 
    478478    # because the server implementation is not working very well
    479479
    480480    def __init__(self, queryterm, language, activity):
    481         gobject.GObject.__init__(self)
     481        GObject.GObject.__init__(self)
    482482        self._activity = activity
    483483        self._queryterm = queryterm
    484484        self._language = language
    class ImageDownloaderThread(threading.Thread): 
    519519            self._getter.start(path)
    520520        except:
    521521            _logger.debug("Connection timed out for")
    522             gobject.idle_add(self.obj.notify_updated, None)
     522            GObject.idle_add(self.obj.notify_updated, None)
    523523
    524524        self._download_content_length = \
    525525                self._getter.get_content_length()
    class ImageDownloaderThread(threading.Thread): 
    529529        _logger.debug("Got Cover Image %s (%s)", tempfile, suggested_name)
    530530        self._getter = None
    531531        if not self.stopthread.is_set():
    532             gobject.idle_add(self.obj.notify_updated, tempfile)
     532            GObject.idle_add(self.obj.notify_updated, tempfile)
    533533
    534534    def _get_image_progress_cb(self, getter, bytes_downloaded):
    535535        if self.stopthread.is_set():
    class ImageDownloaderThread(threading.Thread): 
    545545        else:
    546546            _logger.debug("Downloaded %u bytes...",
    547547                          bytes_downloaded)
    548         while gtk.events_pending():
    549             gtk.main_iteration()
     548        while Gtk.events_pending():
     549            Gtk.main_iteration()
    550550
    551551    def _get_image_error_cb(self, getter, err):
    552552        _logger.debug("Error getting image: %s", err)
    553553        self._download_content_length = 0
    554554        self._download_content_type = None
    555555        self._getter = None
    556         gobject.idle_add(self.obj.notify_updated, None)
     556        GObject.idle_add(self.obj.notify_updated, None)
    557557
    558558    def run(self):
    559559        self._download_image()
    class ImageDownloaderThread(threading.Thread): 
    562562        self.stopthread.set()
    563563
    564564
    565 class ImageDownloader(gobject.GObject):
     565class ImageDownloader(GObject.GObject):
    566566
    567567    __gsignals__ = {
    568         'updated': (gobject.SIGNAL_RUN_FIRST,
    569                           gobject.TYPE_NONE,
    570                           ([gobject.TYPE_STRING])),
     568        'updated': (GObject.SignalFlags.RUN_FIRST,
     569                          None,
     570                          ([GObject.TYPE_STRING])),
    571571    }
    572572
    573573    def __init__(self, activity, url):
    574         gobject.GObject.__init__(self)
     574        GObject.GObject.__init__(self)
    575575        self.threads = []
    576576        self._activity = activity
    577577        self._url = url
  • setup.py

    diff --git a/setup.py b/setup.py
    index d3ab3a3..2f2c143 100755
    a b  
    1616# along with this program; if not, write to the Free Software
    1717# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1818
    19 from sugar.activity import bundlebuilder
     19from sugar3.activity import bundlebuilder
    2020
    2121bundlebuilder.start()