Ticket #3681: 0001-Port-to-Gtk3-SL-3681.patch
File 0001-Port-to-Gtk3-SL-3681.patch, 55.2 KB (added by humitos, 11 years ago) |
---|
-
GetIABooksActivity.py
From f9f607547d1dc047868b21407172a86b8f8dae91 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann <humitos@gmail.com> Date: Tue, 19 Jun 2012 08:32:13 -0300 Subject: [PATCH Get Books] Port to Gtk3 SL #3681 This is a big change that ports Get Books to Gtk3. Read the steps that I did[1] if there are something that is not working as expected. 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 | 324 ++++++++++++++++++++++++------------------------- devicemanager.py | 43 +++---- extListview.py | 169 +++++++++++++++----------- listview.py | 59 +++++---- opds.py | 54 ++++----- setup.py | 2 +- 6 files changed, 337 insertions(+), 314 deletions(-) diff --git a/GetIABooksActivity.py b/GetIABooksActivity.py index 0a06069..ef2ec64 100644
a b 19 19 import os 20 20 import logging 21 21 import 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 23 from gi.repository import Gtk 24 from gi.repository import Gdk 25 from gi.repository import GdkPixbuf 26 from gi.repository import GObject 27 from gi.repository import Pango 28 29 30 from sugar3.graphics.toolbarbox import ToolbarBox 31 from sugar3.activity.widgets import StopButton 32 from sugar3.graphics import style 33 from sugar3.graphics.toolbutton import ToolButton 34 from sugar3.graphics.toggletoolbutton import ToggleToolButton 35 from sugar3.graphics.toolcombobox import ToolComboBox 36 from sugar3.graphics.combobox import ComboBox 37 from sugar3.graphics import iconentry 38 from sugar3 import profile 39 from sugar3.activity import activity 40 from sugar3.activity.widgets import ToolbarButton 41 from sugar3.bundle.activitybundle import ActivityBundle 42 from sugar3.datastore import datastore 43 from sugar3.graphics.alert import NotifyAlert 44 from sugar3.graphics.alert import Alert 45 from sugar3.graphics.icon import Icon 45 46 from gettext import gettext as _ 47 46 48 import dbus 47 import gobject48 49 import ConfigParser 49 50 import base64 50 51 … … class GetIABooksActivity(activity.Activity): 86 87 else: 87 88 self._read_configuration() 88 89 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() 108 97 109 110 98 toolbar_box.toolbar.insert(activity_button, 0) 99 self._add_search_controls(toolbar_box.toolbar) 111 100 112 separator = gtk.SeparatorToolItem()113 114 115 101 separator = Gtk.SeparatorToolItem() 102 separator.props.draw = False 103 separator.set_expand(True) 104 toolbar_box.toolbar.insert(separator, -1) 116 105 117 106 toolbar_box.toolbar.insert(StopButton(self), -1) 118 107 119 120 121 108 self.set_toolbar_box(toolbar_box) 109 toolbar_box.show_all() 110 self._books_toolbar = toolbar_box.toolbar 122 111 123 112 self._create_controls() 124 113 … … class GetIABooksActivity(activity.Activity): 236 225 logging.error('catalogs %s', self.catalogs) 237 226 238 227 def _add_search_controls(self, toolbar): 239 book_search_item = gtk.ToolItem()228 book_search_item = Gtk.ToolItem() 240 229 toolbar.search_entry = iconentry.IconEntry() 241 230 toolbar.search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, 242 231 'system-search') 243 232 toolbar.search_entry.add_clear_button() 244 233 toolbar.search_entry.connect('activate', 245 234 self.__search_entry_activate_cb) 246 width = int( gtk.gdk.screen_width() / 4)235 width = int(Gdk.Screen.width() / 4) 247 236 toolbar.search_entry.set_size_request(width, -1) 248 237 book_search_item.add(toolbar.search_entry) 249 238 toolbar.search_entry.show() … … class GetIABooksActivity(activity.Activity): 268 257 if len(self.languages) > 0: 269 258 toolbar.config_toolbarbutton = ToolbarButton() 270 259 toolbar.config_toolbarbutton.props.icon_name = 'preferences-system' 271 toolbar.config_toolbarbox = gtk.Toolbar()260 toolbar.config_toolbarbox = Gtk.Toolbar() 272 261 toolbar.config_toolbarbutton.props.page = toolbar.config_toolbarbox 273 262 toolbar.language_combo = ComboBox() 274 263 toolbar.language_combo.props.sensitive = True … … class GetIABooksActivity(activity.Activity): 319 308 self.queryresults = None 320 309 321 310 self.queryresults = opds.RemoteQueryResult(catalog_config, 322 '', query_language)311 '', query_language) 323 312 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)) 325 317 326 318 self.queryresults.connect('updated', self.__query_updated_cb) 327 319 … … class GetIABooksActivity(activity.Activity): 428 420 treestore, coldex = \ 429 421 self.catalog_listview.get_selection().get_selected() 430 422 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'] == []: 432 424 self.catalog_history.pop() 433 425 len_cat = len(self.catalog_history) 434 426 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( 436 432 {'title': treestore.get_value(coldex, 0), 437 'catalogs': []})438 self.__switch_catalog_cb(treestore.get_value(coldex, 0))433 'catalogs': []}) 434 self.__switch_catalog_cb(treestore.get_value(coldex, 0)) 439 435 440 436 def _sort_logfile(self, treemodel, itera, iterb): 441 437 a = treemodel.get_value(itera, 0) … … class GetIABooksActivity(activity.Activity): 455 451 self.tree_scroller.show_all() 456 452 self.separa.show() 457 453 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() 459 457 self.separa.hide() 460 458 461 459 def _create_controls(self): 462 460 self._download_content_length = 0 463 461 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() 467 465 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) 471 469 self.cancel_btn.connect('clicked', self.__cancel_btn_clicked_cb) 472 470 self.progressbox.pack_start(self.cancel_btn, expand=False, 473 fill=False)471 fill=False, padding=0) 474 472 475 self.msg_label = gtk.Label()473 self.msg_label = Gtk.Label() 476 474 477 self.list_box = gtk.HBox()475 self.list_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) 478 476 479 477 # Catalogs treeview 480 self.catalog_listview = gtk.TreeView()478 self.catalog_listview = Gtk.TreeView() 481 479 self.catalog_listview.headers_clickble = True 482 480 self.catalog_listview.hover_expand = True 483 481 self.catalog_listview.rules_hint = True 484 482 self.catalog_listview.connect('cursor-changed', self.move_down_catalog) 485 483 self.catalog_listview.set_enable_search(False) 486 self.treemodel = gtk.ListStore(gobject.TYPE_STRING) 487 s orter = gtk.TreeModelSort(self.treemodel)488 s orter.set_sort_column_id(0, gtk.SORT_ASCENDING)489 s orter.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) 494 492 self.treecol.set_property('clickable', True) 495 493 self.treecol.connect('clicked', self.move_up_catalog) 496 494 self.catalog_listview.append_column(self.treecol) … … class GetIABooksActivity(activity.Activity): 508 506 self.treemodel.clear() 509 507 for p in self.categories: 510 508 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) 515 513 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) 519 519 520 520 # books listview 521 521 self.listview = ListView(self._lang_code_handler) 522 522 self.listview.connect('selection-changed', self.selection_cb) 523 523 self.listview.set_enable_search(False) 524 524 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) 529 529 vadjustment = self.list_scroller.get_vadjustment() 530 530 vadjustment.connect('value-changed', 531 self.__vadjustment_value_changed_cb)531 self.__vadjustment_value_changed_cb) 532 532 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() 539 541 self.textview.set_editable(False) 540 542 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) 543 545 self.textview.set_left_margin(20) 544 546 self.textview.set_right_margin(20) 545 547 self.scrolled.add(self.textview) … … class GetIABooksActivity(activity.Activity): 547 549 self.separa.hide() 548 550 self.tree_scroller.hide() 549 551 550 vbox_download = gtk.VBox()552 vbox_download = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) 551 553 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:')) 554 556 self.format_combo = ComboBox() 555 557 for key in _MIMETYPES.keys(): 556 558 self.format_combo.append_item(_MIMETYPES[key], key) … … class GetIABooksActivity(activity.Activity): 563 565 hbox_format.pack_start(self.format_combo, False, False, 10) 564 566 vbox_download.pack_start(hbox_format, False, False, 10) 565 567 566 self._download = gtk.Button(_('Get Book'))568 self._download = Gtk.Button(_('Get Book')) 567 569 self._download.props.sensitive = False 568 570 self._download.connect('clicked', self.__get_book_cb) 569 571 vbox_download.pack_start(self._download, False, False, 10) 570 572 571 bottom_hbox = gtk.HBox()573 bottom_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) 572 574 573 575 if self.show_images: 574 576 self.__image_downloader = None 575 self.image = gtk.Image()577 self.image = Gtk.Image() 576 578 self.add_default_image() 577 579 bottom_hbox.pack_start(self.image, False, False, 10) 578 580 bottom_hbox.pack_start(self.scrolled, True, True, 10) 579 581 bottom_hbox.pack_start(vbox_download, False, False, 10) 580 582 bottom_hbox.show_all() 581 583 582 vbox = gtk.VBox()584 vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) 583 585 vbox.pack_start(self.msg_label, False, False, 10) 584 586 vbox.pack_start(self.progressbox, False, False, 10) 585 587 vbox.pack_start(self.list_box, True, True, 0) … … class GetIABooksActivity(activity.Activity): 596 598 if len(self.catalogs) > 0: 597 599 self.bt_catalogs.set_active(True) 598 600 599 600 601 def can_close(self): 601 602 self._lang_code_handler.close() 602 603 if self.queryresults is not None: … … class GetIABooksActivity(activity.Activity): 679 680 680 681 def get_pixbuf_from_buffer(self, image_buffer): 681 682 """Buffer To Pixbuf""" 682 pixbuf_loader = gtk.gdk.PixbufLoader()683 pixbuf_loader = GdkPixbuf.PixbufLoader() 683 684 pixbuf_loader.write(image_buffer) 684 685 pixbuf_loader.close() 685 686 pixbuf = pixbuf_loader.get_pixbuf() … … class GetIABooksActivity(activity.Activity): 714 715 715 716 def add_default_image(self): 716 717 file_path = os.path.join(activity.get_bundle_path(), 717 'generic_cover.png')718 'generic_cover.png') 718 719 self.add_image(file_path) 719 720 720 721 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) 722 723 self.add_image_buffer(pixbuf) 723 724 724 725 def add_image_buffer(self, pixbuf): 725 image_height = int( gtk.gdk.screen_height() / 4)726 image_height = int(Gdk.Screen.height() / 4) 726 727 image_width = image_height / 3 * 2 727 728 width, height = pixbuf.get_width(), pixbuf.get_height() 728 729 scale = 1 … … class GetIABooksActivity(activity.Activity): 731 732 scale_y = image_height / float(height) 732 733 scale = min(scale_x, scale_y) 733 734 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()) 739 746 740 747 margin_x = int((image_width - (width * scale)) / 2) 741 748 margin_y = int((image_height - (height * scale)) / 2) 742 749 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) 748 755 749 756 self.image.set_from_pixbuf(pixbuf2) 750 757 … … class GetIABooksActivity(activity.Activity): 793 800 self.source, search_text) 794 801 795 802 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)) 797 804 self.queryresults.connect('updated', self.__query_updated_cb) 798 805 799 806 def __query_updated_cb(self, query, midway): … … class GetIABooksActivity(activity.Activity): 818 825 if only_english: 819 826 self.show_message( 820 827 _('Sorry, we only found english books.')) 821 self. window.set_cursor(None)828 self.get_window().set_cursor(None) 822 829 self._allow_suspend() 823 830 824 831 def catalogs_updated(self, query, midway): … … class GetIABooksActivity(activity.Activity): 908 915 try: 909 916 self._getter.cancel() 910 917 except: 911 logging.debug('Got an exception while trying ' + \912 'to cancel download')918 logging.debug('Got an exception while trying ' 919 'to cancel download') 913 920 self.progressbox.hide() 914 921 self.listview.props.sensitive = True 915 922 self._books_toolbar.search_entry.set_sensitive(True) … … class GetIABooksActivity(activity.Activity): 919 926 def get_book(self): 920 927 self.enable_button(False) 921 928 self.progressbox.show_all() 922 gobject.idle_add(self.download_book,self.download_url)929 GObject.idle_add(self.download_book, self.download_url) 923 930 924 931 def download_book(self, url): 925 932 self._inhibit_suspend() … … class GetIABooksActivity(activity.Activity): 960 967 bytes_downloaded) 961 968 total = self._download_content_length 962 969 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() 965 972 966 973 def _get_book_error_cb(self, getter, err): 967 974 self.listview.props.sensitive = True … … class GetIABooksActivity(activity.Activity): 1017 1024 textbuffer = self.textview.get_buffer() 1018 1025 journal_entry.metadata['description'] = \ 1019 1026 textbuffer.get_text(textbuffer.get_start_iter(), 1020 textbuffer.get_end_iter())1027 textbuffer.get_end_iter(), True) 1021 1028 if self.exist_cover_image: 1022 1029 image_buffer = self._get_preview_image_buffer() 1023 1030 journal_entry.metadata['preview'] = dbus.ByteArray(image_buffer) … … class GetIABooksActivity(activity.Activity): 1046 1053 _stop_alert.props.title = title 1047 1054 _stop_alert.props.msg = msg 1048 1055 open_icon = Icon(icon_name='zoom-activity') 1049 _stop_alert.add_button( gtk.RESPONSE_APPLY,1056 _stop_alert.add_button(Gtk.ResponseType.APPLY, 1050 1057 _('Show in Journal'), open_icon) 1051 1058 open_icon.show() 1052 1059 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) 1054 1061 ok_icon.show() 1055 1062 # Remove other alerts 1056 1063 for alert in self._alerts: … … class GetIABooksActivity(activity.Activity): 1061 1068 _stop_alert.show() 1062 1069 1063 1070 def __stop_response_cb(self, alert, response_id): 1064 if response_id is gtk.RESPONSE_APPLY:1071 if response_id is Gtk.ResponseType.APPLY: 1065 1072 activity.show_object_in_journal(self._object_id) 1066 1073 self.remove_alert(alert) 1067 1074 … … class GetIABooksActivity(activity.Activity): 1077 1084 scale_y = preview_height / float(height) 1078 1085 scale = min(scale_x, scale_y) 1079 1086 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) 1084 1091 pixbuf2.fill(style.COLOR_WHITE.get_int()) 1085 1092 1086 1093 margin_x = int((preview_width - (width * scale)) / 2) 1087 1094 margin_y = int((preview_height - (height * scale)) / 2) 1088 1095 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) 1098 1101 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 1102 1106 1103 1107 def _get_cover_image_buffer(self): 1104 1108 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 1113 1111 1114 1112 def _show_error_alert(self, title, text=None): 1115 1113 alert = NotifyAlert(timeout=20) … … class GetIABooksActivity(activity.Activity): 1190 1188 pass 1191 1189 1192 1190 1193 class ButtonWithImage( gtk.Button):1191 class ButtonWithImage(Gtk.Button): 1194 1192 1195 1193 def __init__(self, label_text): 1196 gtk.Button.__init__(self, _('Catalogs'))1194 GObject.GObject.__init__(self,) 1197 1195 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) 1200 1198 self.add(self.hbox) 1201 1199 self.hbox.add(self.icon_move_up) 1202 self.label = gtk.Label(label_text)1200 self.label = Gtk.Label(label=label_text) 1203 1201 self.hbox.add(self.label) 1204 1202 self.show_all() 1205 1203 -
devicemanager.py
diff --git a/devicemanager.py b/devicemanager.py index f673fce..7630126 100644
a b 18 18 19 19 import os 20 20 import logging 21 import gobject22 21 import dbus 23 22 24 UDISK_DEVICE_PATH = 'org.freedesktop.UDisks.Device' 23 from gi.repository import GObject 25 24 25 # UDISK_DEVICE_PATH = 'org.freedesktop.UDisks.Device' 26 26 27 class DeviceManager(gobject.GObject): 27 28 class DeviceManager(GObject.GObject): 28 29 29 30 __gsignals__ = { 30 'device-changed': ( gobject.SIGNAL_RUN_FIRST,31 gobject.TYPE_NONE,31 'device-changed': (GObject.SignalFlags.RUN_FIRST, 32 None, 32 33 ([])), 33 34 } 34 35 35 36 def __init__(self): 36 gobject.GObject.__init__(self)37 GObject.GObject.__init__(self) 37 38 38 39 self._devices = {} 39 40 self._bus = dbus.SystemBus() … … class DeviceManager(gobject.GObject): 59 60 60 61 def _get_props_from_device(self, device): 61 62 # 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 props63 # 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 77 78 return None 78 79 79 80 def _have_catalog(self, props): -
extListview.py
diff --git a/extListview.py b/extListview.py index cf0b450..27d02eb 100644
a b 34 34 # 35 35 # v1.3: 36 36 # * Greatly improved speed when sorting a lot of rows 37 # * Added support for gtk.CellRendererToggle37 # * Added support for Gtk.CellRendererToggle 38 38 # * Improved replaceContent() method 39 39 # * Added a call to set_cursor() when removing selected row(s) 40 40 # * Added getFirstSelectedRow(), appendRows(), addColumnAttribute(), 41 41 # 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) 43 43 # 44 44 # v1.2: 45 45 # * Fixed D'n'D reordering bugs … … 52 52 # the empty area 53 53 # * Sort indicators are now displayed whenever needed 54 54 55 import gtk56 55 import random 56 import logging 57 57 58 from g tk import gdk59 from g object import signal_new, TYPE_INT, TYPE_STRING, TYPE_BOOLEAN, \60 TYPE_PYOBJECT, TYPE_NONE, SIGNAL_RUN_LAST 58 from gi.repository import Gtk 59 from gi.repository import GObject 60 from gi.repository import Gdk 61 61 62 62 63 63 # Internal d'n'd (reordering) 64 64 DND_REORDERING_ID = 1024 65 65 DND_INTERNAL_TARGET = ('extListview-internal', 66 gtk.TARGET_SAME_WIDGET, DND_REORDERING_ID)66 Gtk.TargetFlags.SAME_WIDGET, DND_REORDERING_ID) 67 67 68 68 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): 69 class ExtListViewColumn(Gtk.TreeViewColumn): 84 70 """ 85 71 TreeViewColumn does not signal right-click events, and we need them 86 72 This subclass is equivalent to TreeViewColumn, but it signals these … … class ExtListViewColumn(gtk.TreeViewColumn): 90 76 (http://www.sacredchao.net/quodlibet) 91 77 """ 92 78 79 __gsignals__ = { 80 'button-press-event': (GObject.SignalFlags.RUN_LAST, None, 81 (object,)), 82 } 83 93 84 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) 97 88 self.set_widget(label) 98 89 label.show() 99 90 label.__realize = label.connect('realize', self.onRealize) … … class ExtListViewColumn(gtk.TreeViewColumn): 101 92 def onRealize(self, widget): 102 93 widget.disconnect(widget.__realize) 103 94 del widget.__realize 104 button = widget.get_ancestor( gtk.Button)95 button = widget.get_ancestor(Gtk.Button) 105 96 if button is not None: 106 97 button.connect('button-press-event', self.onButtonPressed) 107 98 … … class ExtListViewColumn(gtk.TreeViewColumn): 109 100 self.emit('button-press-event', event) 110 101 111 102 112 class ExtListView(gtk.TreeView): 103 class 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 } 113 114 114 115 def __init__(self, columns, sortable=True, dndTargets=[], useMarkup=False, 115 116 canShowHideColumns=True): … … class ExtListView(gtk.TreeView): 125 126 If useMarkup is True, the 'markup' attributes is used instead of 126 127 'text' for CellRendererTexts 127 128 """ 128 gtk.TreeView.__init__(self)129 GObject.GObject.__init__(self) 129 130 130 131 self.selection = self.get_selection() 131 132 … … class ExtListView(gtk.TreeView): 140 141 self.set_rules_hint(True) 141 142 self.set_headers_visible(True) 142 143 143 self.selection.set_mode( gtk.SELECTION_MULTIPLE)144 self.selection.set_mode(Gtk.SelectionMode.MULTIPLE) 144 145 145 146 # Create the columns 146 147 nbEntries = 0 … … class ExtListView(gtk.TreeView): 152 153 else: 153 154 column = ExtListViewColumn(title) 154 155 column.set_resizable(True) 155 #column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)156 column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) 156 157 column.set_expand(expandable) 157 158 column.set_visible(visible) 158 159 if canShowHideColumns: … … class ExtListView(gtk.TreeView): 169 170 nbEntries += 1 170 171 dataTypes.append(type) 171 172 column.pack_start(renderer, False) 172 if isinstance(renderer, gtk.CellRendererToggle):173 if isinstance(renderer, Gtk.CellRendererToggle): 173 174 column.add_attribute(renderer, 'active', nbEntries - 1) 174 elif isinstance(renderer, gtk.CellRendererPixbuf):175 elif isinstance(renderer, Gtk.CellRendererPixbuf): 175 176 column.add_attribute(renderer, 'pixbuf', nbEntries - 1) 176 elif isinstance(renderer, gtk.CellRendererText):177 elif isinstance(renderer, Gtk.CellRendererText): 177 178 if useMarkup: 178 179 column.add_attribute(renderer, 'markup', 179 180 nbEntries - 1) … … class ExtListView(gtk.TreeView): 184 185 # Mark management 185 186 self.markedRow = None 186 187 self.markColumn = len(dataTypes) 187 dataTypes.append( TYPE_BOOLEAN) # When there's no other solution,188 189 188 dataTypes.append(bool) # When there's no other solution, 189 # this additional entry helps in 190 # finding the marked row 190 191 191 192 # Create the ListStore associated with this tree 192 self.store = gtk.ListStore(*dataTypes)193 self.store = Gtk.ListStore(*dataTypes) 193 194 self.set_model(self.store) 194 195 195 196 # Drag'n'drop management … … class ExtListView(gtk.TreeView): 200 201 self.dndReordering = False 201 202 202 203 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) 204 208 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) 210 215 211 216 # Show the list 212 217 self.show() … … class ExtListView(gtk.TreeView): 314 319 criteria = self.sortColCriteria[column] 315 320 rows.sort(lambda r1, r2: \ 316 321 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]) 318 326 319 327 # Move the mark if needed 320 328 if self.markedRow is not None: … … class ExtListView(gtk.TreeView): 322 330 323 331 column.set_sort_indicator(True) 324 332 if self.sortAscending: 325 column.set_sort_order( gtk.SORT_ASCENDING)333 column.set_sort_order(Gtk.SortType.ASCENDING) 326 334 else: 327 column.set_sort_order( gtk.SORT_DESCENDING)335 column.set_sort_order(Gtk.SortType.DESCENDING) 328 336 329 337 self.emit('extlistview-modified') 330 338 … … class ExtListView(gtk.TreeView): 349 357 350 358 def getFirstSelectedRow(self): 351 359 """ Return only the first selected row """ 360 # TODO: check if this fail on gtk2 version after click on the ListView 352 361 return tuple(self.store[self.selection.get_selected_rows()[1][0]])[:-1] 353 362 354 363 def getFirstSelectedRowIndex(self): … … class ExtListView(gtk.TreeView): 502 511 """ Enable the use of Drag'n'Drop to reorder the list """ 503 512 self.dndReordering = True 504 513 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) 506 515 507 516 def __isDropAfter(self, pos): 508 """ Helper function, True if pos is gtk.TREE_VIEW_DROP_AFTER or509 gtk.TREE_VIEW_DROP_INTO_OR_AFTER """510 return pos == gtk.TREE_VIEW_DROP_AFTER or \511 pos == gtk.TREE_VIEW_DROP_INTO_OR_AFTER517 """ 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 512 521 513 522 def __moveSelectedRows(self, x, y): 514 523 """ Internal function used for drag'n'drop """ … … class ExtListView(gtk.TreeView): 516 525 dropInfo = self.get_dest_row_at_pos(int(x), int(y)) 517 526 518 527 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) 520 530 else: 521 pos, path = dropInfo[1], dropInfo[0][0]531 pos, path = (dropInfo[1], dropInfo[0][0]) 522 532 if self.__isDropAfter(pos) and path < len(self.store) - 1: 523 pos = gtk.TREE_VIEW_DROP_INTO_OR_BEFORE533 pos = Gtk.TreeViewDropPosition.INTO_OR_BEFORE 524 534 path += 1 525 535 526 536 self.freeze_child_notify() … … class ExtListView(gtk.TreeView): 567 577 568 578 if event.button == 1 or event.button == 3: 569 579 if path is None: 580 # README: this emit the signal: selection-changed and 581 # there is nothing selected so we get an IndexError 570 582 self.selection.unselect_all() 571 583 tree.set_cursor(len(self.store)) 572 584 else: 573 585 if self.dndReordering and self.motionEvtId is None \ 574 586 and event.button == 1: 575 587 self.dndStartPos = (int(event.x), int(event.y)) 576 self.motionEvtId = gtk.TreeView.connect(self, \588 self.motionEvtId = Gtk.TreeView.connect(self, \ 577 589 'motion-notify-event', self.onMouseMotion) 578 590 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)) 581 594 582 595 if stateClear and not self.selection.path_is_selected(path): 583 596 self.selection.unselect_all() … … class ExtListView(gtk.TreeView): 586 599 retVal = (stateClear and self.getSelectedRowsCount() > 1 \ 587 600 and self.selection.path_is_selected(path)) 588 601 589 self.emit('extlistview-button-pressed', event, path)602 # self.emit('extlistview-button-pressed', event, path) 590 603 591 604 return retVal 592 605 … … class ExtListView(gtk.TreeView): 599 612 600 613 if len(self.dndTargets) != 0: 601 614 self.enable_model_drag_dest(self.dndTargets, 602 gdk.ACTION_DEFAULT)615 Gdk.DragAction.DEFAULT) 603 616 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)) 605 620 606 if stateClear and event. state & gdk.BUTTON1_MASK \621 if stateClear and event.get_state() & Gdk.ModifierType.BUTTON1_MASK \ 607 622 and self.getSelectedRowsCount() > 1: 608 623 pathInfo = self.get_path_at_pos(int(event.x), int(event.y)) 609 624 if pathInfo is not None: … … class ExtListView(gtk.TreeView): 616 631 self.drag_check_threshold(self.dndStartPos[0], self.dndStartPos[1], 617 632 int(event.x), int(event.y)): 618 633 self.dndContext = self.drag_begin([DND_INTERNAL_TARGET], 619 gdk.ACTION_COPY, 1, event)634 Gdk.DragAction.COPY, 1, event) 620 635 621 636 def onDragBegin(self, tree, context): 622 637 """ A drag'n'drop operation has begun """ 623 638 if self.getSelectedRowsCount() == 1: 624 context.set_icon_stock( gtk.STOCK_DND, 0, 0)639 context.set_icon_stock(Gtk.STOCK_DND, 0, 0) 625 640 else: 626 context.set_icon_stock( gtk.STOCK_DND_MULTIPLE, 0, 0)641 context.set_icon_stock(Gtk.STOCK_DND_MULTIPLE, 0, 0) 627 642 628 643 def onDragDataReceived(self, tree, context, x, y, selection, dndId, time): 629 644 """ Some data has been dropped into the list """ … … class ExtListView(gtk.TreeView): 639 654 drop = self.get_dest_row_at_pos(int(x), int(y)) 640 655 641 656 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): 644 659 self.enable_model_drag_dest([('invalid-position', 0, -1)], 645 gdk.ACTION_DEFAULT)660 Gdk.DragAction.DEFAULT) 646 661 else: 647 self.enable_model_drag_dest(self.dndTargets, gdk.ACTION_DEFAULT) 662 self.enable_model_drag_dest(self.dndTargets, 663 Gdk.DragAction.DEFAULT) 648 664 649 665 def onColumnHeaderClicked(self, column, event): 650 666 """ A column header has been clicked """ 667 651 668 if event.button == 3: 652 669 # 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 654 676 nbVisibleItems = 0 655 677 lastVisibleItem = None 656 678 for column in self.get_columns(): 657 item = gtk.CheckMenuItem(column.get_title())679 item = Gtk.CheckMenuItem(column.get_title()) 658 680 item.set_active(column.get_visible()) 659 681 item.connect('toggled', self.onShowHideColumn, column) 660 682 item.show() … … class ExtListView(gtk.TreeView): 669 691 if nbVisibleItems == 1: 670 692 lastVisibleItem.set_sensitive(False) 671 693 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 673 700 674 701 def onShowHideColumn(self, menuItem, column): 675 702 """ Switch the visibility of the given column """ -
listview.py
diff --git a/listview.py b/listview.py index 7a1769a..5822b03 100644
a b 16 16 # along with this program; if not, write to the Free Software 17 17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 18 19 import gobject 20 import gtk 21 import pango 22 import sys 23 from gettext import gettext as _ 24 import logging 19 from gi.repository import GObject 20 from gi.repository import Gtk 21 from gi.repository import Pango 25 22 23 from gettext import gettext as _ 26 24 from extListview import ExtListView 27 25 28 _logger = logging.getLogger('get-ia-books-activity')29 30 26 31 27 class ListView(ExtListView): 32 __txtRdr = gtk.CellRendererText()33 __txtRdr.props.wrap_mode = pango.WRAP_WORD28 __txtRdr = Gtk.CellRendererText() 29 __txtRdr.props.wrap_mode = Pango.WrapMode.WORD 34 30 __txtRdr.props.wrap_width = 500 35 31 __txtRdr.props.width = 500 36 32 (ROW_TITLE, ROW_AUTHOR, ROW_PUBLISHER, 37 33 ROW_LANGUAGE, ROW_PUB_DATE, ROW_BOOK) = range(6) 38 34 39 columns = ((_('Title'), [(__txtRdr, gobject.TYPE_STRING)],35 columns = ((_('Title'), [(__txtRdr, GObject.TYPE_STRING)], 40 36 (ROW_TITLE,), False, True), 41 (_('Author'), [(__txtRdr, gobject.TYPE_STRING)],37 (_('Author'), [(__txtRdr, GObject.TYPE_STRING)], 42 38 (ROW_AUTHOR, ROW_TITLE), False, True), 43 (_('Publisher'), [(__txtRdr, gobject.TYPE_STRING)],39 (_('Publisher'), [(__txtRdr, GObject.TYPE_STRING)], 44 40 (ROW_AUTHOR, ROW_TITLE), False, False), 45 (_('Language'), [(__txtRdr, gobject.TYPE_STRING)],41 (_('Language'), [(__txtRdr, GObject.TYPE_STRING)], 46 42 (ROW_AUTHOR, ROW_TITLE), False, False), 47 (_('Publish Date'), [(__txtRdr, gobject.TYPE_STRING)],43 (_('Publish Date'), [(__txtRdr, GObject.TYPE_STRING)], 48 44 (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 50 47 __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 } 55 52 56 53 def __init__(self, lang_code_handler): 57 54 ExtListView.__init__(self, self.columns, sortable=True, 58 useMarkup=False, canShowHideColumns=True)55 useMarkup=False, canShowHideColumns=True) 59 56 #self.enableDNDReordering() # Is this needed ? 60 57 61 58 self._lang_code_handler = lang_code_handler 62 59 63 60 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) 66 63 67 64 def __selection_changed_cb(self, selection): 68 65 self.emit('selection-changed') … … class ListView(ExtListView): 78 75 try: 79 76 lang = self._lang_code_handler.get_full_language_name( 80 77 book.get_language()) 81 except :78 except KeyError: 82 79 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())89 80 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 91 88 self.insertRows(rows) 92 89 93 90 def get_selected_book(self): -
opds.py
diff --git a/opds.py b/opds.py index fc536f3..1cd6d62 100644
a b 16 16 # along with this program; if not, write to the Free Software 17 17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 18 19 import logging 19 from gi.repository import GObject 20 from gi.repository import Gtk 21 22 from sugar3 import network 20 23 24 import logging 21 25 import threading 22 26 import os 23 27 import urllib 24 import gobject25 import gtk26 28 import time 27 29 import csv 28 30 29 from sugar import network30 31 31 import sys 32 32 sys.path.insert(0, './') 33 33 import feedparser … … _REL_SUBSECTION = 'subsection' 39 39 _REL_OPDS_POPULAR = u'http://opds-spec.org/sort/popular' 40 40 _REL_OPDS_NEW = u'http://opds-spec.org/sort/new' 41 41 42 gobject.threads_init()42 GObject.threads_init() 43 43 44 44 45 45 class ReadURLDownloader(network.GlibURLDownloader): … … class DownloadThread(threading.Thread): 100 100 101 101 self.obj._feedobj = feedobj 102 102 self.obj._ready = True 103 gobject.idle_add(self.obj.notify_updated, self.midway)103 GObject.idle_add(self.obj.notify_updated, self.midway) 104 104 return False 105 105 106 106 def run(self): … … class Book(object): 222 222 return False 223 223 224 224 225 class QueryResult( gobject.GObject):225 class QueryResult(GObject.GObject): 226 226 227 227 __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])), 231 231 } 232 232 233 233 def __init__(self, configuration, queryterm, language): 234 gobject.GObject.__init__(self)234 GObject.GObject.__init__(self) 235 235 self._configuration = configuration 236 236 self._uri = self._configuration['query_uri'] 237 237 self._queryterm = queryterm … … class DownloadIAThread(threading.Thread): 369 369 self._download_content_type = None 370 370 self._booklist = [] 371 371 queryterm = self.obj._queryterm 372 search_tuple = queryterm.lower().split()372 # search_tuple = queryterm.lower().split() 373 373 FL = urllib.quote('fl[]') 374 374 SORT = urllib.quote('sort[]') 375 375 self.search_url = 'http://www.archive.org/advancedsearch.php?q=' + \ … … class DownloadIAThread(threading.Thread): 384 384 self.stopthread = threading.Event() 385 385 386 386 def _download(self): 387 gobject.idle_add(self.download_csv, self.search_url)387 GObject.idle_add(self.download_csv, self.search_url) 388 388 389 389 def download_csv(self, url): 390 390 logging.error('get csv from %s', url) … … class DownloadIAThread(threading.Thread): 428 428 reader.next() # skip the first header row. 429 429 for row in reader: 430 430 if len(row) < 7: 431 _logger.debug("Server Error ", self.search_url)431 _logger.debug("Server Error: %s", self.search_url) 432 432 return 433 433 entry = {} 434 434 entry['author'] = row[0] … … class DownloadIAThread(threading.Thread): 461 461 self.obj._booklist.append(IABook(None, entry, '')) 462 462 463 463 os.remove(tempfile) 464 gobject.idle_add(self.obj.notify_updated, self.midway)464 GObject.idle_add(self.obj.notify_updated, self.midway) 465 465 self.obj._ready = True 466 466 return False 467 467 … … class InternetArchiveQueryResult(QueryResult): 478 478 # because the server implementation is not working very well 479 479 480 480 def __init__(self, queryterm, language, activity): 481 gobject.GObject.__init__(self)481 GObject.GObject.__init__(self) 482 482 self._activity = activity 483 483 self._queryterm = queryterm 484 484 self._language = language … … class ImageDownloaderThread(threading.Thread): 519 519 self._getter.start(path) 520 520 except: 521 521 _logger.debug("Connection timed out for") 522 gobject.idle_add(self.obj.notify_updated, None)522 GObject.idle_add(self.obj.notify_updated, None) 523 523 524 524 self._download_content_length = \ 525 525 self._getter.get_content_length() … … class ImageDownloaderThread(threading.Thread): 529 529 _logger.debug("Got Cover Image %s (%s)", tempfile, suggested_name) 530 530 self._getter = None 531 531 if not self.stopthread.is_set(): 532 gobject.idle_add(self.obj.notify_updated, tempfile)532 GObject.idle_add(self.obj.notify_updated, tempfile) 533 533 534 534 def _get_image_progress_cb(self, getter, bytes_downloaded): 535 535 if self.stopthread.is_set(): … … class ImageDownloaderThread(threading.Thread): 545 545 else: 546 546 _logger.debug("Downloaded %u bytes...", 547 547 bytes_downloaded) 548 while gtk.events_pending():549 gtk.main_iteration()548 while Gtk.events_pending(): 549 Gtk.main_iteration() 550 550 551 551 def _get_image_error_cb(self, getter, err): 552 552 _logger.debug("Error getting image: %s", err) 553 553 self._download_content_length = 0 554 554 self._download_content_type = None 555 555 self._getter = None 556 gobject.idle_add(self.obj.notify_updated, None)556 GObject.idle_add(self.obj.notify_updated, None) 557 557 558 558 def run(self): 559 559 self._download_image() … … class ImageDownloaderThread(threading.Thread): 562 562 self.stopthread.set() 563 563 564 564 565 class ImageDownloader( gobject.GObject):565 class ImageDownloader(GObject.GObject): 566 566 567 567 __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])), 571 571 } 572 572 573 573 def __init__(self, activity, url): 574 gobject.GObject.__init__(self)574 GObject.GObject.__init__(self) 575 575 self.threads = [] 576 576 self._activity = activity 577 577 self._url = url -
setup.py
diff --git a/setup.py b/setup.py index d3ab3a3..2f2c143 100755
a b 16 16 # along with this program; if not, write to the Free Software 17 17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 18 19 from sugar .activity import bundlebuilder19 from sugar3.activity import bundlebuilder 20 20 21 21 bundlebuilder.start()