From 95a6594ee5eb844ff5c87025a5e7c8ec0f0c8af7 Mon Sep 17 00:00:00 2001 From: flavio Date: Thu, 01 Nov 2012 23:57:20 +0000 Subject: Port to Gtk 3 --- diff --git a/.gitignore b/.gitignore index b9cb894..feb086b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ dist .0sugar +*.py[co] +*.bak diff --git a/activity.py b/activity.py index 40bde74..9b35c2a 100755 --- a/activity.py +++ b/activity.py @@ -12,15 +12,17 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -import gtk +import gi +from gi.repository import Gtk + from gettext import gettext as _ import logging logger = logging.getLogger('cartoon-builder') -from sugar.graphics.toolbutton import ToolButton -from sugar.graphics.toggletoolbutton import ToggleToolButton -from sugar.activity.activity import ActivityToolbox +from sugar3.graphics.toolbutton import ToolButton +from sugar3.graphics.toggletoolbutton import ToggleToolButton +#from sugar3.activity.activity import ActivityToolbox from toolkit.temposlider import TempoSlider from toolkit.activity import SharedActivity @@ -39,8 +41,10 @@ from utils import * class CartoonBuilderActivity(SharedActivity): + def __init__(self, handle): - self.notebook = gtk.Notebook() + + self.notebook = Gtk.Notebook() SharedActivity.__init__(self, self.notebook, SERVICE, handle) self.notebook.show() @@ -48,17 +52,17 @@ class CartoonBuilderActivity(SharedActivity): self.notebook.props.show_tabs = False self.montage = montage.View() - self.notebook.append_page(self.montage) + self.notebook.append_page(self.montage, Gtk.Label('')) self.lessons = lessons.View() self.lessons.show() - self.notebook.append_page(self.lessons) + self.notebook.append_page(self.lessons, Gtk.Label('')) toolbox = ToolbarBox() toolbox.show() toolbox.toolbar.insert(ActivityToolbarButton(self), -1) - separator = gtk.SeparatorToolItem() + separator = Gtk.SeparatorToolItem() separator.set_draw(False) toolbox.toolbar.insert(separator, -1) @@ -67,18 +71,18 @@ class CartoonBuilderActivity(SharedActivity): lessons_button.set_tooltip(_('Lessons')) toolbox.toolbar.insert(lessons_button, -1) - separator = gtk.SeparatorToolItem() + separator = Gtk.SeparatorToolItem() separator.set_draw(False) toolbox.toolbar.insert(separator, -1) - self.notebook_toolbar = gtk.Notebook() + self.notebook_toolbar = Gtk.Notebook() self.notebook_toolbar.props.show_border = False self.notebook_toolbar.props.show_tabs = False - self.notebook_toolbar.append_page(self._create_montage_toolbar()) - self.notebook_toolbar.append_page(self._create_lessons_toolbar()) + self.notebook_toolbar.append_page(self._create_montage_toolbar(), Gtk.Label('')) + self.notebook_toolbar.append_page(self._create_lessons_toolbar(), Gtk.Label('')) self.notebook_toolbar.show() - notebook_item = gtk.ToolItem() + notebook_item = Gtk.ToolItem() notebook_item.set_expand(True) notebook_item.add(self.notebook_toolbar) notebook_item.show() @@ -110,21 +114,21 @@ class CartoonBuilderActivity(SharedActivity): self.messenger = Messenger(tube_conn, initiating, self.montage) def _create_montage_toolbar(self): - toolbar = gtk.Toolbar() + toolbar = Gtk.Toolbar() - playButtonImg = gtk.Image() + playButtonImg = Gtk.Image() playButtonImg.show() playButtonImg.set_from_icon_name('media-playback-start', - gtk.ICON_SIZE_LARGE_TOOLBAR) + Gtk.IconSize.LARGE_TOOLBAR) - pauseButtonImg = gtk.Image() + pauseButtonImg = Gtk.Image() pauseButtonImg.show() pauseButtonImg.set_from_icon_name('media-playback-pause', - gtk.ICON_SIZE_LARGE_TOOLBAR) + Gtk.IconSize.LARGE_TOOLBAR) self.playButton = ToggleToolButton('media-playback-start') self.playButton.connect('toggled', self.__play_cb, playButtonImg, - pauseButtonImg) + pauseButtonImg) toolbar.insert(self.playButton, -1) self.playButton.set_tooltip(_('Play / Pause')) @@ -132,11 +136,11 @@ class CartoonBuilderActivity(SharedActivity): tempo.adjustment.connect("value-changed", self.__tempo_cb) tempo.set_size_request(250, -1) tempo.set_value(5) - tempo_item = gtk.ToolItem() + tempo_item = Gtk.ToolItem() tempo_item.add(tempo) toolbar.insert(tempo_item, -1) - separator = gtk.SeparatorToolItem() + separator = Gtk.SeparatorToolItem() toolbar.insert(separator,-1) clear_tape = ToolButton('sl-reset') @@ -156,21 +160,24 @@ class CartoonBuilderActivity(SharedActivity): self.montage.set_tempo(widget.value) def __play_cb(self, widget, playButtonImg, pauseButtonImg): + if widget.get_active(): widget.set_icon_widget(pauseButtonImg) sound.play() self.montage.play() + else: widget.set_icon_widget(playButtonImg) sound.stop() self.montage.stop() def _create_lessons_toolbar(self): - toolbar = gtk.Toolbar() + toolbar = Gtk.Toolbar() for lesson in lessons.THEMES: - button = gtk.RadioToolButton() + button = Gtk.RadioToolButton() button.set_label(lesson.name) + if toolbar.get_n_items(): button.props.group = toolbar.get_nth_item(0) button.connect('clicked', self.__lesson_clicked_cb, lesson) diff --git a/activity/activity.info b/activity/activity.info index 5bf31de..de1b815 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -10,8 +10,8 @@ stability = stable icon = activity-cartoonbuilder exec = sugar-activity activity.CartoonBuilderActivity -version = 17 +version = 18 #deprecated options bundle_id = com.ywwg.CartoonBuilderActivity -activity_version = 17 +activity_version = 18 diff --git a/char.py b/char.py index 176e4ee..77c8408 100644 --- a/char.py +++ b/char.py @@ -13,7 +13,9 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os -import gtk + +import gi +from gi.repository import Gtk import glob from gettext import gettext as _ diff --git a/document.py b/document.py index a7d9e91..1d29bab 100644 --- a/document.py +++ b/document.py @@ -13,7 +13,9 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os -import gtk + +import gi +from gi.repository import Gtk import logging import toolkit.json as json diff --git a/ground.py b/ground.py index f1cd069..c342f76 100644 --- a/ground.py +++ b/ground.py @@ -13,7 +13,10 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os -import gtk + +import gi +from gi.repository import Gtk + from gettext import gettext as _ import toolkit.chooser as chooser diff --git a/lessons.py b/lessons.py index e5ece14..1a36b7d 100644 --- a/lessons.py +++ b/lessons.py @@ -13,7 +13,11 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os -import gtk + +import gi +from gi.repository import Gtk +from gi.repository import Gdk + import locale import logging from glob import glob @@ -34,37 +38,37 @@ class Lesson: View.notebook.set_current_page(self.index) -class View(gtk.EventBox): +class View(Gtk.EventBox): notebook = None def __init__(self): - gtk.EventBox.__init__(self) + Gtk.EventBox.__init__(self) - View.notebook = gtk.Notebook() + View.notebook = Gtk.Notebook() View.notebook.props.show_border = False View.notebook.props.show_tabs = False self.add(View.notebook) for i in THEMES: - view = gtk.TextView() + view = Gtk.TextView() view.get_buffer().set_text(i.text) - view.set_wrap_mode(gtk.WRAP_WORD) + view.set_wrap_mode(Gtk.WrapMode.WORD) view.set_editable(False) - view_box = gtk.EventBox() + view_box = Gtk.EventBox() view_box.add(view) - view_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(theme.WHITE)) + view_box.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(theme.WHITE)) view_box.props.border_width = 10 - border_box = gtk.EventBox() + border_box = Gtk.EventBox() border_box.add(view_box) - border_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(theme.WHITE)) + border_box.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(theme.WHITE)) - scrolled_window = gtk.ScrolledWindow() - scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) + scrolled_window = Gtk.ScrolledWindow() + scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolled_window.add_with_viewport(border_box) - View.notebook.append_page(scrolled_window) + View.notebook.append_page(scrolled_window, Gtk.Label('')) self.show_all() diff --git a/messenger.py b/messenger.py index 57f6df3..7e16a6e 100644 --- a/messenger.py +++ b/messenger.py @@ -18,7 +18,7 @@ from dbus.gobject_service import ExportedGObject from dbus.service import method, signal import toolkit.json as json -from sugar.presence import presenceservice +from sugar3.presence import presenceservice import char import ground diff --git a/montage.py b/montage.py index 4769969..b8e248f 100644 --- a/montage.py +++ b/montage.py @@ -18,10 +18,12 @@ ### author: Ed Stoner (ed@whsd.net) ### (c) 2007 World Wide Workshop Foundation -import gtk -import gobject +import gi +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject +from gi.repository import GdkPixbuf import logging -from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT from toolkit.scrolledbox import VScrolledBox @@ -36,11 +38,16 @@ from utils import * logger = logging.getLogger('cartoon-builder') -class View(gtk.EventBox): +class View(Gtk.EventBox): + __gsignals__ = { - 'frame-changed': (SIGNAL_RUN_FIRST, None, 2 * [TYPE_PYOBJECT]), - 'ground-changed': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]), - 'sound-changed': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT])} + 'frame-changed': ( + GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, + (GObject.TYPE_PYOBJECT, GObject.TYPE_PYOBJECT)), + 'ground-changed': ( + GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_PYOBJECT,)), + 'sound-changed': ( + GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_PYOBJECT,))} def set_frame(self, value): tape_num, frame = value @@ -89,10 +96,10 @@ class View(gtk.EventBox): def set_emittion(self, value): self._emission = value - frame = gobject.property(type=object, getter=None, setter=set_frame) - ground = gobject.property(type=object, getter=None, setter=set_ground) - sound = gobject.property(type=object, getter=None, setter=set_sound) - emittion = gobject.property(type=bool, default=True, getter=get_emittion, + frame = GObject.property(type=object, getter=None, setter=set_frame) + ground = GObject.property(type=object, getter=None, setter=set_ground) + sound = GObject.property(type=object, getter=None, setter=set_sound) + emittion = GObject.property(type=bool, default=True, getter=get_emittion, setter=set_emittion) def restore(self): @@ -117,13 +124,13 @@ class View(gtk.EventBox): return combo self.controlbox.pack_start(new_combo(char.THEMES, self._char_cb), - False, False) + False, False, 0) self._ground_combo = new_combo(ground.THEMES, self._combo_cb, Document.ground, self._ground_cb) - self.controlbox.pack_start(self._ground_combo, False, False) + self.controlbox.pack_start(self._ground_combo, False, False, 0) self._sound_combo = new_combo(sound.THEMES, self._combo_cb, Document.sound, self._sound_cb) - self.controlbox.pack_start(self._sound_combo, False, False) + self.controlbox.pack_start(self._sound_combo, False, False, 0) for i in range(theme.TAPE_COUNT): self._tape[i].child.set_from_pixbuf(Document.tape[i].thumb()) @@ -131,7 +138,7 @@ class View(gtk.EventBox): def play(self): self._play_tape_num = 0 - self._playing = gobject.timeout_add(self._delay, self._play_tape) + self._playing = GObject.timeout_add(self._delay, self._play_tape) def stop(self): self._playing = None @@ -141,11 +148,11 @@ class View(gtk.EventBox): def set_tempo(self, tempo): self._delay = 10 + (10 - int(tempo)) * 100 if self._playing: - gobject.source_remove(self._playing) - self._playing = gobject.timeout_add(self._delay, self._play_tape) + GObject.source_remove(self._playing) + self._playing = GObject.timeout_add(self._delay, self._play_tape) def __init__(self): - gtk.EventBox.__init__(self) + Gtk.EventBox.__init__(self) self._screen = Screen() self._play_tape_num = 0 @@ -161,39 +168,40 @@ class View(gtk.EventBox): # frames table - self.table = gtk.Table( # theme.FRAME_ROWS, columns=theme.FRAME_COLS, + self.table = Gtk.Table( # theme.FRAME_ROWS, columns=theme.FRAME_COLS, homogeneous=False) for i in range(theme.FRAME_ROWS * theme.FRAME_COLS): self._add_frame(i) # frames box - - table_scroll = VScrolledBox() - table_scroll.set_viewport(self.table) - table_scroll.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) - - yellow_frames = gtk.EventBox() - yellow_frames.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(YELLOW)) - table_frames = gtk.EventBox() - table_frames.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BACKGROUND)) + # FIXME: There is no longer VscrooledBox + #table_scroll = VScrolledBox() + table_scroll = Gtk.ScrolledWindow() + table_scroll.add_with_viewport(self.table) + table_scroll.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BUTTON_BACKGROUND)) + + yellow_frames = Gtk.EventBox() + yellow_frames.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(YELLOW)) + table_frames = Gtk.EventBox() + table_frames.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BACKGROUND)) table_frames.set_border_width(5) table_frames.add(table_scroll) yellow_frames.add(table_frames) - yelow_arrow = gtk.Image() + yelow_arrow = Gtk.Image() yelow_arrow.set_from_file(theme.path('icons', 'yellow_arrow.png')) - frames_box = gtk.VBox() - frames_box.pack_start(yellow_frames, True, True) - frames_box.pack_start(yelow_arrow, False, False) + frames_box = Gtk.VBox() + frames_box.pack_start(yellow_frames, True, True, 0) + frames_box.pack_start(yelow_arrow, False, False, 0) frames_box.props.border_width = theme.BORDER_WIDTH # screen - screen_pink = gtk.EventBox() - screen_pink.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(PINK)) - screen_box = gtk.EventBox() + screen_pink = Gtk.EventBox() + screen_pink.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(PINK)) + screen_box = Gtk.EventBox() screen_box.set_border_width(5) screen_box.add(self._screen) screen_pink.add(screen_box) @@ -201,99 +209,100 @@ class View(gtk.EventBox): # tape - tape = gtk.HBox() + tape = Gtk.HBox() for i in range(TAPE_COUNT): - frame_box = gtk.VBox() + frame_box = Gtk.VBox() - filmstrip_pixbuf = gtk.gdk.pixbuf_new_from_file_at_scale( + filmstrip_pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( theme.path('icons', 'filmstrip.png'), THUMB_SIZE, -1, False) - filmstrip = gtk.Image() + filmstrip = Gtk.Image() filmstrip.set_from_pixbuf(filmstrip_pixbuf); - frame_box.pack_start(filmstrip, False, False) + frame_box.pack_start(filmstrip, False, False, 0) - frame = gtk.EventBox() - frame.set_events(gtk.gdk.BUTTON_PRESS_MASK) + frame = Gtk.EventBox() + frame.set_events(Gdk.EventMask.BUTTON_PRESS_MASK) frame.connect('button_press_event', self._tape_cb, i) - frame.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BLACK)) - frame.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.color_parse(BLACK)) + frame.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BLACK)) + frame.modify_bg(Gtk.StateType.PRELIGHT, Gdk.color_parse(BLACK)) frame.props.border_width = 2 frame.set_size_request(theme.THUMB_SIZE, theme.THUMB_SIZE) - frame_box.pack_start(frame) + frame_box.pack_start(frame, True, True, 0) self._tape.append(frame) - frame_image = gtk.Image() + frame_image = Gtk.Image() frame_image.set_from_pixbuf(theme.EMPTY_THUMB) frame.add(frame_image) - filmstrip = gtk.Image() + filmstrip = Gtk.Image() filmstrip.set_from_pixbuf(filmstrip_pixbuf); - frame_box.pack_start(filmstrip, False, False) + frame_box.pack_start(filmstrip, False, False, 0) - tape.pack_start(frame_box, False, False) + tape.pack_start(frame_box, False, False, 0) # left control box - self.controlbox = gtk.VBox() + self.controlbox = Gtk.VBox() self.controlbox.props.border_width = theme.BORDER_WIDTH self.controlbox.props.spacing = theme.BORDER_WIDTH - leftbox = gtk.VBox() - logo = gtk.Image() + leftbox = Gtk.VBox() + logo = Gtk.Image() logo.set_from_file(theme.path('icons', 'logo.png')) leftbox.set_size_request(logo.props.pixbuf.get_width(), -1) - leftbox.pack_start(logo, False, False) - leftbox.pack_start(self.controlbox, True, True) + leftbox.pack_start(logo, False, False, 0) + leftbox.pack_start(self.controlbox, True, True, 0) # screen box - screen_alignment = gtk.Alignment(0.5, 0.5, 0, 0) + screen_alignment = Gtk.Alignment() + screen_alignment.set(0.5, 0.5, 0, 0) screen_alignment.add(screen_pink) - box = gtk.EventBox() - box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BACKGROUND)) + box = Gtk.EventBox() + box.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BACKGROUND)) box.connect('size-allocate', self._screen_size_cb, screen_pink) box.add(screen_alignment) - cetralbox = gtk.HBox() - cetralbox.pack_start(box, expand=True, fill=True) - cetralbox.pack_start(frames_box, expand=False, fill=True) + cetralbox = Gtk.HBox() + cetralbox.pack_start(box, True, True, 0) + cetralbox.pack_start(frames_box, False, True, 0) - hdesktop = gtk.HBox() + hdesktop = Gtk.HBox() hdesktop.pack_start(leftbox, False, True, 0) hdesktop.pack_start(cetralbox, True, True, 0) # tape box - arrow = gtk.Image() + arrow = Gtk.Image() arrow.set_from_file(theme.path('icons', 'pink_arrow.png')) - tape_pink = gtk.EventBox() - tape_pink.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(PINK)) - tape_bg = gtk.EventBox() - tape_bg.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BACKGROUND)) + tape_pink = Gtk.EventBox() + tape_pink.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(PINK)) + tape_bg = Gtk.EventBox() + tape_bg.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BACKGROUND)) tape_bg.set_border_width(5) tape_bg.add(tape) tape_pink.add(tape_bg) - tape_hbox = gtk.HBox() - tape_hbox.pack_start(tape_pink, True, False) + tape_hbox = Gtk.HBox() + tape_hbox.pack_start(tape_pink, True, False, 0) - tape_box = gtk.VBox() + tape_box = Gtk.VBox() tape_box.props.border_width = theme.BORDER_WIDTH - tape_box.pack_start(arrow, False, False) - tape_box.pack_start(tape_hbox) + tape_box.pack_start(arrow, False, False, 0) + tape_box.pack_start(tape_hbox, True, True, 0) - desktop = gtk.VBox() + desktop = Gtk.VBox() desktop.pack_start(hdesktop, True, True, 0) desktop.pack_start(tape_box, False, False, 0) - greenbox = gtk.EventBox() - greenbox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BACKGROUND)) + greenbox = Gtk.EventBox() + greenbox.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BACKGROUND)) greenbox.set_border_width(5) greenbox.add(desktop) - self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(YELLOW)) + self.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(YELLOW)) self.add(greenbox) self.show_all() @@ -335,16 +344,16 @@ class View(gtk.EventBox): x = index - y * theme.FRAME_COLS logger.debug('add new frame x=%d y=%d index=%d' % (x, y, index)) - image = gtk.Image() + image = Gtk.Image() image.show() image.set_from_pixbuf(theme.EMPTY_THUMB) self._frames.append(image) - image_box = gtk.EventBox() - image_box.set_events(gtk.gdk.BUTTON_PRESS_MASK) + image_box = Gtk.EventBox() + image_box.set_events(Gdk.EventMask.BUTTON_PRESS_MASK) image_box.connect('button_press_event', self._frame_cb, index) - image_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BLACK)) - image_box.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.color_parse(BLACK)) + image_box.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BLACK)) + image_box.modify_bg(Gtk.StateType.PRELIGHT, Gdk.color_parse(BLACK)) image_box.props.border_width = 2 image_box.set_size_request(theme.THUMB_SIZE, theme.THUMB_SIZE) image_box.add(image) @@ -362,16 +371,16 @@ class View(gtk.EventBox): return tape = self._tape[index] - tape.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(YELLOW)) - tape.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.color_parse(YELLOW)) + tape.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(YELLOW)) + tape.modify_bg(Gtk.StateType.PRELIGHT, Gdk.color_parse(YELLOW)) if self._tape_selected != index: if self._tape_selected != -1: old_tape = self._tape[self._tape_selected] - old_tape.modify_bg(gtk.STATE_NORMAL, - gtk.gdk.color_parse(BLACK)) - old_tape.modify_bg(gtk.STATE_PRELIGHT, - gtk.gdk.color_parse(BLACK)) + old_tape.modify_bg(Gtk.StateType.NORMAL, + Gdk.color_parse(BLACK)) + old_tape.modify_bg(Gtk.StateType.PRELIGHT, + Gdk.color_parse(BLACK)) self._tape_selected = index self._screen.fgpixbuf = Document.tape[index].orig() @@ -435,5 +444,5 @@ class View(gtk.EventBox): return False if self._screen_size_id is not None: - gobject.source_remove(self._screen_size_id) - self._screen_size_id = gobject.timeout_add(500, set_size) + GObject.source_remove(self._screen_size_id) + self._screen_size_id = GObject.timeout_add(500, set_size) diff --git a/screenbuil.py b/screenbuil.py index 29ed2b7..37121ce 100644 --- a/screenbuil.py +++ b/screenbuil.py @@ -18,18 +18,21 @@ ### author: Ed Stoner (ed@whsd.net) ### (c) 2007 World Wide Workshop Foundation -import gtk +import gi +from gi.repository import Gtk import theme -class Screen(gtk.DrawingArea): +class Screen(Gtk.DrawingArea): def __init__(self): - gtk.DrawingArea.__init__(self) + Gtk.DrawingArea.__init__(self) self.gc = None # initialized in realize-event handler self.width = 0 # updated in size-allocate handler self.height = 0 # idem self.bgpixbuf = None self.fgpixbuf = None + # FIXME: Re escribir + ''' self.connect('size-allocate', self.on_size_allocate) self.connect('expose-event', self.on_expose_event) self.connect('realize', self.on_realize) @@ -55,4 +58,4 @@ class Screen(gtk.DrawingArea): widget.window.draw_pixbuf(self.gc, pixbuf, 0, 0, 0, 0, -1, -1, 0, 0) def draw(self): - self.queue_draw() + self.queue_draw()''' diff --git a/setup.py b/setup.py index 6a63e2f..0464656 100755 --- a/setup.py +++ b/setup.py @@ -14,5 +14,5 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -from sugar.activity import bundlebuilder +from sugar3.activity import bundlebuilder bundlebuilder.start() diff --git a/sound.py b/sound.py index 5fef049..edd6982 100644 --- a/sound.py +++ b/sound.py @@ -13,8 +13,12 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os -import gtk -import gst +import gi +gi.require_version('Gst', '1.0') +from gi.repository import Gtk +from gi.repository import GObject +from gi.repository import Gst +from gi.repository import GstVideo import shutil from glob import glob from gettext import gettext as _ @@ -23,7 +27,7 @@ import toolkit.chooser as chooser import theme from utils import * -from sugar.activity.activity import get_bundle_path +from sugar3.activity.activity import get_bundle_path def load(): @@ -32,6 +36,9 @@ def load(): if Document.sound and Document.sound.custom(): THEMES.append(Document.sound) +GObject.threads_init() +Gst.init([]) + class Sound: playing = False current = None @@ -55,11 +62,11 @@ class Sound: def select(self): if Sound.current != self: Sound.current = self - Sound.player.set_state(gst.STATE_NULL) + Sound.player.set_state(Gst.State.NULL) Sound.player.set_property('uri', 'file://' + theme.path(self._soundfile)) if Sound.playing: - Sound.player.set_state(gst.STATE_PLAYING) + Sound.player.set_state(Gst.State.PLAYING) return self class PreinstalledSound(Sound): @@ -81,7 +88,7 @@ class MuteSound(Sound): def select(self): Sound.current = self - Sound.player.set_state(gst.STATE_PAUSED) + Sound.player.set_state(Gst.State.PAUSED) return self class CustomSound(Sound): @@ -106,7 +113,7 @@ class JournalSound(Sound): soundfile = os.path.join(theme.SESSION_PATH, jobject.object_id) Sound.__init__(self, jobject.metadata['title'], jobject.object_id, soundfile, theme.SOUND_CUSTOM) - shutil.copy(jobject.file_path, soundfile) + shutil.copy(jobject.file_path, soundfile) THEMES.append(self) THEMES = [ @@ -124,19 +131,19 @@ def play(): def stop(): Sound.playing = False - Sound.player.set_state(gst.STATE_PAUSED) + Sound.player.set_state(Gst.State.PAUSED) # GSTREAMER STUFF def _reload_cb(bus, message): - Sound.player.set_state(gst.STATE_READY) - Sound.player.set_state(gst.STATE_PLAYING) + Sound.player.set_state(Gst.State.READY) + Sound.player.set_state(Gst.State.PLAYING) def _error_cb(bus, message): - Sound.player.set_state(gst.STATE_NULL) + Sound.player.set_state(Gst.State.NULL) -Sound.player = gst.element_factory_make("playbin", "player") -fakesink = gst.element_factory_make('fakesink', "my-fakesink") +Sound.player = Gst.ElementFactory.make("playbin", "player") +fakesink = Gst.ElementFactory.make('fakesink', "my-fakesink") Sound.player.set_property("video-sink", fakesink) bus = Sound.player.get_bus() diff --git a/theme.py b/theme.py index 026e2d4..1393560 100644 --- a/theme.py +++ b/theme.py @@ -13,12 +13,16 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os -import gtk +import gi +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GdkPixbuf +from gi.repository import GdkX11 import shutil from math import ceil -from sugar.activity.activity import get_bundle_path, get_activity_root -from sugar.graphics import style +from sugar3.activity.activity import get_bundle_path, get_activity_root +from sugar3.graphics import style SOUND_SPEAKER = 'images/sounds/speaker.png' SOUND_MUTE = 'images/sounds/mute.png' @@ -28,8 +32,9 @@ LOGO_WIDTH = style.zoom(275) TAPE_COUNT = 11 FRAME_COUNT = 14 -DESKTOP_WIDTH = gtk.gdk.screen_width() -DESKTOP_HEIGHT = gtk.gdk.screen_height() - style.LARGE_ICON_SIZE +screen = GdkX11.X11Screen() +DESKTOP_WIDTH = int(screen.width()) +DESKTOP_HEIGHT = int(screen.height()) - style.LARGE_ICON_SIZE # GRID_CELL_SIZE THUMB_SIZE = style.zoom(min(100, DESKTOP_WIDTH / (TAPE_COUNT+1))) @@ -53,25 +58,25 @@ BACKGROUND = "#66CC00" # light green BUTTON_FOREGROUND = "#CCFB99" # very light green BUTTON_BACKGROUND = "#027F01" # dark green COLOR_FG_BUTTONS = ( - (gtk.STATE_NORMAL,"#CCFF99"), - (gtk.STATE_ACTIVE,"#CCFF99"), - (gtk.STATE_PRELIGHT,"#CCFF99"), - (gtk.STATE_SELECTED,"#CCFF99"), - (gtk.STATE_INSENSITIVE,"#CCFF99"), + (Gtk.StateType.NORMAL,"#CCFF99"), + (Gtk.StateType.ACTIVE,"#CCFF99"), + (Gtk.StateType.PRELIGHT,"#CCFF99"), + (Gtk.StateType.SELECTED,"#CCFF99"), + (Gtk.StateType.INSENSITIVE,"#CCFF99"), ) # very light green COLOR_BG_BUTTONS = ( - (gtk.STATE_NORMAL,"#027F01"), - (gtk.STATE_ACTIVE,"#CCFF99"), - (gtk.STATE_PRELIGHT,"#016D01"), - (gtk.STATE_SELECTED,"#CCFF99"), - (gtk.STATE_INSENSITIVE,"#027F01"), + (Gtk.StateType.NORMAL,"#027F01"), + (Gtk.StateType.ACTIVE,"#CCFF99"), + (Gtk.StateType.PRELIGHT,"#016D01"), + (Gtk.StateType.SELECTED,"#CCFF99"), + (Gtk.StateType.INSENSITIVE,"#027F01"), ) OLD_COLOR_BG_BUTTONS = ( - (gtk.STATE_NORMAL,"#027F01"), - (gtk.STATE_ACTIVE,"#014D01"), - (gtk.STATE_PRELIGHT,"#016D01"), - (gtk.STATE_SELECTED,"#027F01"), - (gtk.STATE_INSENSITIVE,"#027F01"), + (Gtk.StateType.NORMAL,"#027F01"), + (Gtk.StateType.ACTIVE,"#014D01"), + (Gtk.StateType.PRELIGHT,"#016D01"), + (Gtk.StateType.SELECTED,"#027F01"), + (Gtk.StateType.INSENSITIVE,"#027F01"), ) SESSION_PATH = os.path.join(get_activity_root(), 'tmp', '.session') @@ -89,13 +94,13 @@ def path(*args): def pixbuf(file, size = None): if size: - out = gtk.gdk.pixbuf_new_from_file_at_size(path(file), size, size) + out = GdkPixbuf.Pixbuf.new_from_file_at_size(path(file), size, size) else: - out = gtk.gdk.pixbuf_new_from_file(path(file)) + out = GdkPixbuf.Pixbuf.new_from_file(path(file)) return out def scale(pixbuf, size = THUMB_SIZE): - return pixbuf.scale_simple(size, size, gtk.gdk.INTERP_BILINEAR) + return pixbuf.scale_simple(size, size, GdkPixbuf.InterpType.BILINEAR) EMPTY_FILENAME = 'images/pics/empty.png' EMPTY_ORIG = pixbuf(EMPTY_FILENAME) @@ -105,8 +110,9 @@ CUSTOM_FRAME_ORIG = pixbuf('images/pics/custom.png') CUSTOM_FRAME_THUMB = scale(CUSTOM_FRAME_ORIG) # customize theme -gtkrc = os.path.join(get_bundle_path(), 'gtkrc') -gtk.rc_add_default_file(gtkrc) -settings = gtk.settings_get_default() -gtk.rc_reset_styles(settings) -gtk.rc_reparse_all_for_settings(settings, True) +Gtkrc = os.path.join(get_bundle_path(), 'Gtkrc') +Gtk.rc_add_default_file(Gtkrc) +# FIXME: There is no longer Gtk.settings_get_default () +#settings = Gtk.settings_get_default() +#Gtk.rc_reset_styles(settings) +#Gtk.rc_reparse_all_for_settings(settings, True) diff --git a/toolkit/activity.py b/toolkit/activity.py index 1512610..49e0884 100644 --- a/toolkit/activity.py +++ b/toolkit/activity.py @@ -16,14 +16,15 @@ """Extend sugar-toolkit activity class""" -import gtk import logging import telepathy -import gobject +import gi +from gi.repository import Gtk +from gi.repository import Gdk -from sugar.activity import activity -from sugar.presence.sugartubeconn import SugarTubeConnection -from sugar.graphics.alert import ConfirmationAlert, NotifyAlert +from sugar3.activity import activity +from sugar3.presence.sugartubeconn import SugarTubeConnection +from sugar3.graphics.alert import ConfirmationAlert, NotifyAlert _NEW_INSTANCE = 0 @@ -40,9 +41,11 @@ class CursorFactory: self.__dict__ = self.__shared_state def get_cursor(self, cur_type): + if not self.cursors.has_key(cur_type): - cur = gtk.gdk.Cursor(cur_type) + cur = Gdk.Cursor(cur_type) self.cursors[cur_type] = cur + return self.cursors[cur_type] @@ -99,22 +102,28 @@ class Activity(activity.Activity): pass def set_toolbar_box(self, toolbox): + if hasattr(activity.Activity, 'set_toolbar_box'): activity.Activity.set_toolbar_box(self, toolbox) + else: self.set_toolbox(toolbox) def get_toolbar_box(self): + if hasattr(activity.Activity, 'get_toolbar_box'): return activity.Activity.get_toolbar_box(self) + else: return self.get_toolbox() toolbar_box = property(get_toolbar_box, set_toolbar_box) def get_shared_activity(self): + if hasattr(activity.Activity, 'get_shared_activity'): return activity.Activity.get_shared_activity(self) + else: return self._shared_activity @@ -135,7 +144,7 @@ class Activity(activity.Activity): def response(alert, response_id, self, cb, *cb_args): self.remove_alert(alert) - if response_id is gtk.RESPONSE_OK: + if response_id is Gtk.RESPONSE_OK: cb(*cb_args) alert.connect('response', response, self, cb, *cb_args) @@ -146,12 +155,13 @@ class Activity(activity.Activity): return self._cursor def set_cursor(self, cursor): - if not isinstance(cursor, gtk.gdk.Cursor): + + if not isinstance(cursor, Gdk.Cursor): cursor = CursorFactory().get_cursor(cursor) if self._cursor != cursor: self._cursor = cursor - self.window.set_cursor(self._cursor) + self.get_property('window').set_cursor(self._cursor) def __init__(self, canvas, handle): """ @@ -168,6 +178,7 @@ class Activity(activity.Activity): if handle.object_id: self.__state = _NEW_INSTANCE + else: self.__state = _NEW_INSTANCE @@ -176,7 +187,7 @@ class Activity(activity.Activity): self.__on_save_instance = [] self._cursor = None - self.set_cursor(gtk.gdk.LEFT_PTR) + self.set_cursor(Gdk.CursorType.LEFT_PTR) # XXX do it after(possible) read_file() invoking # have to rely on calling read_file() from map_cb in sugar-toolkit @@ -184,6 +195,7 @@ class Activity(activity.Activity): self.set_canvas(canvas) def __instance(self): + logging.debug('Activity.__instance') if self.__resume_filename: @@ -193,6 +205,7 @@ class Activity(activity.Activity): for i in self.__postponed_share: self.share_instance(*i) + self.__postponed_share = [] self.__state = _POST_INSTANCE @@ -205,37 +218,46 @@ class Activity(activity.Activity): if self.__state == _NEW_INSTANCE: self.__state = _PRE_INSTANCE + elif self.__state == _PRE_INSTANCE: self.__instance(); def write_file(self, filepath): """Subclass should not override this method""" + for cb, args in self.__on_save_instance: cb(*args) + self.save_instance(filepath) def __map_canvasactivity_cb(self, widget): + logging.debug('Activity.__map_canvasactivity_cb state=%s' % \ self.__state) if self.__state == _NEW_INSTANCE: self.__instance() + elif self.__state == _NEW_INSTANCE: self.__state = _PRE_INSTANCE + elif self.__state == _PRE_INSTANCE: self.__instance(); return False def _share(self, tube_conn, initiator): + logging.debug('Activity._share state=%s' % self.__state) if self.__state == _NEW_INSTANCE: self.__postponed_share.append((tube_conn, initiator)) self.__state = _PRE_INSTANCE + elif self.__state == _PRE_INSTANCE: self.__postponed_share.append((tube_conn, initiator)) - self.__instance(); + self.__instance() + elif self.__state == _POST_INSTANCE: self.share_instance(tube_conn, initiator) @@ -265,14 +287,16 @@ class SharedActivity(Activity): self.connect('shared', self._shared_cb) # Owner.props.key - if self._shared_activity: + if self.shared_activity: # We are joining the activity self.connect('joined', self._joined_cb) + if self.get_shared(): # We've already joined self._joined_cb() def _shared_cb(self, activity): + logging.debug('My activity was shared') self.__initiator = True self._sharing_setup() @@ -282,7 +306,8 @@ class SharedActivity(Activity): self.service, {}) def _joined_cb(self, activity): - if not self._shared_activity: + + if not self.shared_activity: return logging.debug('Joined an existing shared activity') @@ -296,17 +321,20 @@ class SharedActivity(Activity): error_handler=self._list_tubes_error_cb) def _sharing_setup(self): - if self._shared_activity is None: + + if self.shared_activity is None: logging.error('Failed to share or join activity') return - self._conn = self._shared_activity.telepathy_conn - self._tubes_chan = self._shared_activity.telepathy_tubes_chan - self._text_chan = self._shared_activity.telepathy_text_chan + + self._conn = self.shared_activity.telepathy_conn + self._tubes_chan = self.shared_activity.telepathy_tubes_chan + self._text_chan = self.shared_activity.telepathy_text_chan self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal( - 'NewTube', self._new_tube_cb) + 'NewTube', self._new_tube_cb) def _list_tubes_reply_cb(self, tubes): + for tube_info in tubes: self._new_tube_cb(*tube_info) @@ -314,15 +342,17 @@ class SharedActivity(Activity): logging.error('ListTubes() failed: %s', e) def _new_tube_cb(self, id, initiator, type, service, params, state): + logging.debug('New tube: ID=%d initator=%d type=%d service=%s ' - 'params=%r state=%d', id, initiator, type, service, - params, state) + 'params=%r state=%d', id, initiator, type, service, + params, state) if (type == telepathy.TUBE_TYPE_DBUS and - service == self.service): + service == self.service): + if state == telepathy.TUBE_STATE_LOCAL_PENDING: self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES] \ - .AcceptDBusTube(id) + .AcceptDBusTube(id) tube_conn = SugarTubeConnection(self._conn, self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES], id, diff --git a/toolkit/activity_widgets.py b/toolkit/activity_widgets.py index 9195af5..33ab0df 100644 --- a/toolkit/activity_widgets.py +++ b/toolkit/activity_widgets.py @@ -15,33 +15,38 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. -import gtk -import gobject +import gi +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject +from gi.repository import GdkX11 import gettext from sugar import profile -from sugar.graphics.toolbutton import ToolButton -from sugar.graphics.radiotoolbutton import RadioToolButton -from sugar.graphics.toolbox import Toolbox -from sugar.graphics.xocolor import XoColor -from sugar.graphics.icon import Icon -from sugar.bundle.activitybundle import ActivityBundle +from sugar3.graphics.toolbutton import ToolButton +from sugar3.graphics.radiotoolbutton import RadioToolButton +from sugar3.graphics.toolbox import Toolbox +from sugar3.graphics.xocolor import XoColor +from sugar3.graphics.icon import Icon +from sugar3.bundle.activitybundle import ActivityBundle from toolkit.toolbarbox import ToolbarButton from toolkit.radiopalette import RadioPalette from toolkit.radiopalette import RadioMenuButton -from sugar.graphics import style +from sugar3.graphics import style -_ = lambda msg: gettext.dgettext('sugar-toolkit', msg) +_ = lambda msg: gettext.dgettext('sugar3-toolkit', msg) def _create_activity_icon(metadata): + if metadata.get('icon-color', ''): color = XoColor(metadata['icon-color']) + else: color = profile.get_color() - from sugar.activity.activity import get_bundle_path + from sugar3.activity.activity import get_bundle_path bundle = ActivityBundle(get_bundle_path()) icon = Icon(file=bundle.get_icon(), xo_color=color) @@ -50,8 +55,9 @@ def _create_activity_icon(metadata): class ActivityButton(ToolButton): - def __init__(self, activity, **kwargs): - ToolButton.__init__(self, **kwargs) + def __init__(self, activity): + + ToolButton.__init__(self) icon = _create_activity_icon(activity.metadata) self.set_icon_widget(icon) @@ -66,7 +72,8 @@ class ActivityButton(ToolButton): class ActivityToolbarButton(ToolbarButton): - def __init__(self, activity, **kwargs): + def __init__(self, activity): + toolbar = ActivityToolbar(activity, orientation_left=True) toolbar.stop.hide() @@ -79,7 +86,8 @@ class ActivityToolbarButton(ToolbarButton): class StopButton(ToolButton): - def __init__(self, activity, **kwargs): + def __init__(self, activity): + ToolButton.__init__(self, 'activity-stop', **kwargs) self.props.tooltip = _('Stop') self.props.accelerator = 'Q' @@ -91,36 +99,41 @@ class StopButton(ToolButton): class UndoButton(ToolButton): - def __init__(self, **kwargs): - ToolButton.__init__(self, 'edit-undo', **kwargs) + def __init__(self): + + ToolButton.__init__(self, 'edit-undo') self.props.tooltip = _('Undo') self.props.accelerator = 'Z' class RedoButton(ToolButton): - def __init__(self, **kwargs): - ToolButton.__init__(self, 'edit-redo', **kwargs) + def __init__(self): + + ToolButton.__init__(self, 'edit-redo') self.props.tooltip = _('Redo') class CopyButton(ToolButton): - def __init__(self, **kwargs): - ToolButton.__init__(self, 'edit-copy', **kwargs) + def __init__(self): + + ToolButton.__init__(self, 'edit-copy') self.props.tooltip = _('Copy') class PasteButton(ToolButton): - def __init__(self, **kwargs): - ToolButton.__init__(self, 'edit-paste', **kwargs) + def __init__(self): + + ToolButton.__init__(self, 'edit-paste') self.props.tooltip = _('Paste') class ShareButton(RadioMenuButton): - def __init__(self, activity, **kwargs): + def __init__(self, activity): + palette = RadioPalette() self.private = RadioToolButton( @@ -137,7 +150,7 @@ class ShareButton(RadioMenuButton): activity.connect('shared', self.__update_share_cb) activity.connect('joined', self.__update_share_cb) - RadioMenuButton.__init__(self, **kwargs) + RadioMenuButton.__init__(self) self.props.palette = palette if activity.props.max_participants == 1: self.props.sensitive = False @@ -146,29 +159,35 @@ class ShareButton(RadioMenuButton): activity.share() def __update_share_cb(self, activity): + self.neighborhood.handler_block(self._neighborhood_handle) + try: if activity.get_shared(): self.private.props.sensitive = False self.neighborhood.props.sensitive = False self.neighborhood.props.active = True + else: self.private.props.sensitive = True self.neighborhood.props.sensitive = True self.private.props.active = True + finally: self.neighborhood.handler_unblock(self._neighborhood_handle) -class TitleEntry(gtk.ToolItem): +class TitleEntry(Gtk.ToolItem): - def __init__(self, activity, **kwargs): - gtk.ToolItem.__init__(self) + def __init__(self, activity): + + Gtk.ToolItem.__init__(self) self.set_expand(False) self._update_title_sid = None - self.entry = gtk.Entry(**kwargs) - self.entry.set_size_request(int(gtk.gdk.screen_width() / 3), -1) + self.entry = Gtk.Entry() + screen = GdkX11.X11Screen() + self.entry.set_size_request(int(screen.width() / 3), -1) self.entry.set_text(activity.metadata['title']) self.entry.connect('changed', self.__title_changed_cb, activity) self.entry.show() @@ -177,18 +196,21 @@ class TitleEntry(gtk.ToolItem): activity.metadata.connect('updated', self.__jobject_updated_cb) def modify_bg(self, state, color): - gtk.ToolItem.modify_bg(self, state, color) + + Gtk.ToolItem.modify_bg(self, state, color) self.entry.modify_bg(state, color) def __jobject_updated_cb(self, jobject): self.entry.set_text(jobject['title']) def __title_changed_cb(self, entry, activity): + if not self._update_title_sid: - self._update_title_sid = gobject.timeout_add_seconds( - 1, self.__update_title_cb, activity) + self._update_title_sid = GObject.timeout_add_seconds( + 1, self.__update_title_cb, activity) def __update_title_cb(self, activity): + title = self.entry.get_text() activity.metadata['title'] = title @@ -203,30 +225,34 @@ class TitleEntry(gtk.ToolItem): return False -class DescriptionItem(gtk.ToolItem): +class DescriptionItem(Gtk.ToolItem): - def __init__(self, activity, **kwargs): - gtk.ToolItem.__init__(self) + def __init__(self, activity): + + Gtk.ToolItem.__init__(self) description_button = ToolButton('edit-description') description_button.show() description_button.set_tooltip(_('Description')) self._palette = description_button.get_palette() - description_box = gtk.HBox() - sw = gtk.ScrolledWindow() - sw.set_size_request(int(gtk.gdk.screen_width() / 2), + description_box = Gtk.HBox() + sw = Gtk.ScrolledWindow() + screen = GdkX11.X11Screen() + sw.set_size_request(int(screen.width() / 2), 2 * style.GRID_CELL_SIZE) - sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self._text_view = gtk.TextView() + sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + self._text_view = Gtk.TextView() self._text_view.set_left_margin(style.DEFAULT_PADDING) self._text_view.set_right_margin(style.DEFAULT_PADDING) - text_buffer = gtk.TextBuffer() + text_buffer = Gtk.TextBuffer() + if 'description' in activity.metadata: text_buffer.set_text(activity.metadata['description']) + self._text_view.set_buffer(text_buffer) self._text_view.connect('focus-out-event', - self.__description_changed_cb, activity) + self.__description_changed_cb, activity) sw.add(self._text_view) description_box.pack_start(sw, False, True, 0) self._palette.set_content(description_box) @@ -234,23 +260,28 @@ class DescriptionItem(gtk.ToolItem): self.add(description_button) description_button.connect('clicked', - self.__description_button_clicked_cb) + self.__description_button_clicked_cb) activity.metadata.connect('updated', self.__jobject_updated_cb) def _get_text_from_buffer(self): + buf = self._text_view.get_buffer() start_iter = buf.get_start_iter() end_iter = buf.get_end_iter() return buf.get_text(start_iter, end_iter, False) def __jobject_updated_cb(self, jobject): + if self._text_view.has_focus(): return + if 'description' not in jobject: return + if self._get_text_from_buffer() == jobject['description']: return + buf = self._text_view.get_buffer() buf.set_text(jobject['description']) @@ -258,6 +289,7 @@ class DescriptionItem(gtk.ToolItem): self._palette.popup(immediate=True, state=1) def __description_changed_cb(self, widget, event, activity): + description = self._get_text_from_buffer() if 'description' in activity.metadata and \ description == activity.metadata['description']: @@ -268,7 +300,7 @@ class DescriptionItem(gtk.ToolItem): return False -class ActivityToolbar(gtk.Toolbar): +class ActivityToolbar(Gtk.Toolbar): """The Activity toolbar with the Journal entry title, sharing, and Stop buttons @@ -277,7 +309,8 @@ class ActivityToolbar(gtk.Toolbar): """ def __init__(self, activity, orientation_left=False): - gtk.Toolbar.__init__(self) + + Gtk.Toolbar.__init__(self) self._activity = activity @@ -288,7 +321,7 @@ class ActivityToolbar(gtk.Toolbar): self.title = title_button.entry if orientation_left == False: - separator = gtk.SeparatorToolItem() + separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self.insert(separator, -1) @@ -308,7 +341,7 @@ class ActivityToolbar(gtk.Toolbar): self.stop.show() -class EditToolbar(gtk.Toolbar): +class EditToolbar(Gtk.Toolbar): """Provides the standard edit toolbar for Activities. Members: @@ -343,7 +376,7 @@ class EditToolbar(gtk.Toolbar): """ def __init__(self): - gtk.Toolbar.__init__(self) + Gtk.Toolbar.__init__(self) self.undo = UndoButton() self.insert(self.undo, -1) @@ -353,7 +386,7 @@ class EditToolbar(gtk.Toolbar): self.insert(self.redo, -1) self.redo.show() - self.separator = gtk.SeparatorToolItem() + self.separator = Gtk.SeparatorToolItem() self.separator.set_draw(True) self.insert(self.separator, -1) self.separator.show() @@ -387,6 +420,7 @@ class ActivityToolbox(Toolbox): """ def __init__(self, activity): + Toolbox.__init__(self) self._activity_toolbar = ActivityToolbar(activity) diff --git a/toolkit/chooser.py b/toolkit/chooser.py index e957fd7..841ad86 100644 --- a/toolkit/chooser.py +++ b/toolkit/chooser.py @@ -16,11 +16,13 @@ """Object chooser method""" -import gtk +import gi +from gi.repository import Gtk + import logging -from sugar import mime -from sugar.graphics.objectchooser import ObjectChooser +from sugar3 import mime +from sugar3.graphics.objectchooser import ObjectChooser TEXT = hasattr(mime, 'GENERIC_TYPE_TEXT') and mime.GENERIC_TYPE_TEXT or None IMAGE = hasattr(mime, 'GENERIC_TYPE_IMAGE') and mime.GENERIC_TYPE_IMAGE or None @@ -39,7 +41,7 @@ def pick(cb=None, default=None, parent=None, what=None): * jobject, if object was choosen and cb is None * default, otherwise - NOTE: 'what' makes sense only for sugar >= 0.84 + NOTE: 'what' makes sense only for sugar3 >= 0.84 """ what = what and {'what_filter': what} or {} chooser = ObjectChooser(parent=parent, **what) @@ -48,7 +50,7 @@ def pick(cb=None, default=None, parent=None, what=None): out = None try: - if chooser.run() == gtk.RESPONSE_ACCEPT: + if chooser.run() == Gtk.ResponseType.ACCEPT: jobject = chooser.get_selected_object() logging.debug('ObjectChooser: %r' % jobject) diff --git a/toolkit/combobox.py b/toolkit/combobox.py index d021106..c9207e7 100644 --- a/toolkit/combobox.py +++ b/toolkit/combobox.py @@ -20,22 +20,25 @@ STABLE. """ -import gobject -import gtk +import gi +from gi.repository import GObject +from gi.repository import Gtk +from gi.repository import GdkPixbuf -class ComboBox(gtk.ComboBox): +class ComboBox(Gtk.ComboBox): def __init__(self): - gtk.ComboBox.__init__(self) + + Gtk.ComboBox.__init__(self) self._text_renderer = None self._icon_renderer = None - model = gtk.ListStore(gobject.TYPE_PYOBJECT, - gobject.TYPE_STRING, - gtk.gdk.Pixbuf, - gobject.TYPE_BOOLEAN) + model = Gtk.ListStore(GObject.TYPE_PYOBJECT, + GObject.TYPE_STRING, + GdkPixbuf.Pixbuf, + GObject.TYPE_BOOLEAN) self.set_model(model) self.set_row_separator_func(self._is_separator) @@ -56,15 +59,18 @@ class ComboBox(gtk.ComboBox): return None return row[0] - value = gobject.property( - type=object, getter=get_value, setter=None) + value = GObject.property( + type=Object, getter=get_value, setter=None) def _get_real_name_from_theme(self, name, size): - icon_theme = gtk.icon_theme_get_default() - width, height = gtk.icon_size_lookup(size) + + icon_theme = Gtk.icon_theme_get_default() + width, height = Gtk.icon_size_lookup(size) info = icon_theme.lookup_icon(name, max(width, height), 0) + if not info: raise ValueError("Icon '" + name + "' not found.") + fname = info.get_filename() del info return fname @@ -90,62 +96,71 @@ class ComboBox(gtk.ComboBox): self.get_model().append(item) def set_item(self, action_id, text=None, icon_name=None, file_name=None): + for i, value in enumerate(self.get_model()): if value[0] == action_id: item = self._item_new(action_id, text, icon_name, file_name) iter = self.get_model().iter_nth_child(None, i) + if text is not None: self.get_model().set(iter, 1, item[1]) + if icon_name is not None or file_name is not None: self.get_model().set(iter, 2, item[2]) + return True return False def select(self, action_id=None, text=None): + if action_id is not None: column = 0 value = action_id + elif text is not None: column = 1 value = text + else: return for i, item in enumerate(self.get_model()): if item[column] != value: continue + self.set_active(i) break def _item_new(self, action_id, text, icon_name, file_name): + if not self._icon_renderer and (icon_name or file_name): - self._icon_renderer = gtk.CellRendererPixbuf() + self._icon_renderer = Gtk.CellRendererPixbuf() settings = self.get_settings() - w, h = gtk.icon_size_lookup_for_settings( - settings, gtk.ICON_SIZE_MENU) + w, h = Gtk.icon_size_lookup_for_settings( + settings, Gtk.IconSize.MENU) self._icon_renderer.props.stock_size = max(w, h) self.pack_start(self._icon_renderer, False) self.add_attribute(self._icon_renderer, 'pixbuf', 2) if not self._text_renderer and text: - self._text_renderer = gtk.CellRendererText() + self._text_renderer = Gtk.CellRendererText() self.pack_end(self._text_renderer, True) self.add_attribute(self._text_renderer, 'text', 1) if icon_name or file_name: if text: - size = gtk.ICON_SIZE_MENU + size = Gtk.IconSize.MENU else: - size = gtk.ICON_SIZE_LARGE_TOOLBAR - width, height = gtk.icon_size_lookup(size) + size = Gtk.IconSize.LARGE_TOOLBAR + width, height = Gtk.icon_size_lookup(size) if icon_name: file_name = self._get_real_name_from_theme(icon_name, size) - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size( - file_name, width, height) + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( + file_name, width, height) else: pixbuf = None diff --git a/toolkit/internals/palettewindow.py b/toolkit/internals/palettewindow.py index d8c4326..50fc567 100644 --- a/toolkit/internals/palettewindow.py +++ b/toolkit/internals/palettewindow.py @@ -23,41 +23,50 @@ STABLE. import logging -import gtk -import gobject -import hippo +import gi +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject +# FIXME: We do not use hippo +#import hippo -from sugar.graphics import palettegroup -from sugar.graphics import animator -from sugar.graphics import style +from sugar3.graphics import palettegroup +from sugar3.graphics import animator +from sugar3.graphics import style def _calculate_gap(a, b): """Helper function to find the gap position and size of widget a""" # Test for each side if the palette and invoker are # adjacent to each other. + gap = True if a.y + a.height == b.y: - gap_side = gtk.POS_BOTTOM + gap_side = Gtk.PositionType.BOTTOM + elif a.x + a.width == b.x: - gap_side = gtk.POS_RIGHT + gap_side = Gtk.PositionType.RIGHT + elif a.x == b.x + b.width: - gap_side = gtk.POS_LEFT + gap_side = Gtk.PositionType.LEFT + elif a.y == b.y + b.height: - gap_side = gtk.POS_TOP + gap_side = Gtk.PositionType.TOP + else: gap = False if gap: - if gap_side == gtk.POS_BOTTOM or gap_side == gtk.POS_TOP: + if gap_side == Gtk.PositionType.BOTTOM or gap_side == Gtk.PositionType.TOP: gap_start = min(a.width, max(0, b.x - a.x)) gap_size = max(0, min(a.width, - (b.x + b.width) - a.x) - gap_start) - elif gap_side == gtk.POS_RIGHT or gap_side == gtk.POS_LEFT: + (b.x + b.width) - a.x) - gap_start) + + elif gap_side == Gtk.PositionType.RIGHT or gap_side == Gtk.PositionType.LEFT: gap_start = min(a.height, max(0, b.y - a.y)) gap_size = max(0, min(a.height, - (b.y + b.height) - a.y) - gap_start) + (b.y + b.height) - a.y) - gap_start) if gap and gap_size > 0: return (gap_side, gap_start, gap_size) @@ -65,11 +74,11 @@ def _calculate_gap(a, b): return False -class MouseSpeedDetector(gobject.GObject): +class MouseSpeedDetector(GObject.GObject): __gsignals__ = { - 'motion-slow': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'motion-fast': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), + 'motion-slow': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'motion-fast': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), } _MOTION_SLOW = 1 @@ -80,7 +89,7 @@ class MouseSpeedDetector(gobject.GObject): delay in msec threshold in pixels (per tick of 'delay' msec)""" - gobject.GObject.__init__(self) + GObject.GObject.__init__(self) self._threshold = thresh self._parent = parent @@ -90,37 +99,48 @@ class MouseSpeedDetector(gobject.GObject): self._mouse_pos = None def start(self): + self.stop() self._mouse_pos = self._get_mouse_position() - self._timeout_hid = gobject.timeout_add(self._delay, self._timer_cb) + self._timeout_hid = GObject.timeout_add(self._delay, self._timer_cb) def stop(self): + if self._timeout_hid is not None: - gobject.source_remove(self._timeout_hid) + GObject.source_remove(self._timeout_hid) + self._state = None def _get_mouse_position(self): - display = gtk.gdk.display_get_default() + + display = Gdk.display_get_default() screen_, x, y, mask_ = display.get_pointer() + return (x, y) def _detect_motion(self): + oldx, oldy = self._mouse_pos (x, y) = self._get_mouse_position() self._mouse_pos = (x, y) dist2 = (oldx - x)**2 + (oldy - y)**2 + if dist2 > self._threshold**2: return True + else: return False def _timer_cb(self): + motion = self._detect_motion() + if motion and self._state != self._MOTION_FAST: self.emit('motion-fast') self._state = self._MOTION_FAST + elif not motion and self._state != self._MOTION_SLOW: self.emit('motion-slow') self._state = self._MOTION_SLOW @@ -128,15 +148,16 @@ class MouseSpeedDetector(gobject.GObject): return True -class PaletteWindow(gtk.Window): +class PaletteWindow(Gtk.Window): __gsignals__ = { - 'popup': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'popdown': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'activate': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), + 'popup': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'popdown': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'activate': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), } - def __init__(self, **kwargs): + def __init__(self): + self._group_id = None self._invoker = None self._invoker_hids = [] @@ -152,14 +173,14 @@ class PaletteWindow(gtk.Window): self._popdown_anim = animator.Animator(0.6, 10) self._popdown_anim.add(_PopdownAnimation(self)) - gobject.GObject.__init__(self, **kwargs) + GObject.GObject.__init__(self) self.set_decorated(False) self.set_resizable(False) # Just assume xthickness and ythickness are the same self.set_border_width(self.get_style().xthickness) - accel_group = gtk.AccelGroup() + accel_group = Gtk.AccelGroup() self.set_data('sugar-accel-group', accel_group) self.add_accel_group(accel_group) @@ -176,14 +197,17 @@ class PaletteWindow(gtk.Window): self._mouse_detector.connect('motion-slow', self._mouse_slow_cb) def __destroy_cb(self, palette): + self.set_group_id(None) def set_invoker(self, invoker): + for hid in self._invoker_hids[:]: self._invoker.disconnect(hid) self._invoker_hids.remove(hid) self._invoker = invoker + if invoker is not None: self._invoker_hids.append(self._invoker.connect( 'mouse-enter', self._invoker_mouse_enter_cb)) @@ -193,20 +217,26 @@ class PaletteWindow(gtk.Window): 'right-click', self._invoker_right_click_cb)) def get_invoker(self): + return self._invoker - invoker = gobject.property(type=object, - getter=get_invoker, - setter=set_invoker) + invoker = GObject.property( + type=object, + getter=get_invoker, + setter=set_invoker) def __realize_cb(self, widget): - self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) + + #self.window.set_type_hint(Gdk.WINDOW_TYPE_HINT_DIALOG) + self.window.set_type_hint(Gdk.WindowType.POPUP) def _mouse_slow_cb(self, widget): + self._mouse_detector.stop() self._palette_do_popup() def _palette_do_popup(self): + immediate = False if self.is_up(): @@ -222,30 +252,37 @@ class PaletteWindow(gtk.Window): self.popup(immediate=immediate) def is_up(self): + return self._up def set_group_id(self, group_id): + if self._group_id: group = palettegroup.get_group(self._group_id) group.remove(self) + if group_id: self._group_id = group_id group = palettegroup.get_group(group_id) group.add(self) def get_group_id(self): + return self._group_id - group_id = gobject.property(type=str, - getter=get_group_id, - setter=set_group_id) + group_id = GObject.property( + type=str, + getter=get_group_id, + setter=set_group_id) def do_size_request(self, requisition): - gtk.Window.do_size_request(self, requisition) + + Gtk.Window.do_size_request(self, requisition) requisition.width = max(requisition.width, style.GRID_CELL_SIZE * 2) def do_size_allocate(self, allocation): - gtk.Window.do_size_allocate(self, allocation) + + Gtk.Window.do_size_allocate(self, allocation) if self._old_alloc is None or \ self._old_alloc.x != allocation.x or \ @@ -268,6 +305,7 @@ class PaletteWindow(gtk.Window): palette = self.get_rect() gap = _calculate_gap(palette, invoker) + else: gap = False @@ -275,18 +313,19 @@ class PaletteWindow(gtk.Window): wstyle = self.get_style() if gap: - wstyle.paint_box_gap(event.window, gtk.STATE_PRELIGHT, - gtk.SHADOW_IN, event.area, self, "palette", - 0, 0, allocation.width, allocation.height, - gap[0], gap[1], gap[2]) + wstyle.paint_box_gap(event.window, Gtk.StateType.PRELIGHT, + Gtk.ShadowType.IN, event.area, self, "palette", + 0, 0, allocation.width, allocation.height, + gap[0], gap[1], gap[2]) + else: - wstyle.paint_box(event.window, gtk.STATE_PRELIGHT, - gtk.SHADOW_IN, event.area, self, "palette", - 0, 0, allocation.width, allocation.height) + wstyle.paint_box(event.window, Gtk.StateType.PRELIGHT, + Gtk.ShadowType.IN, event.area, self, "palette", + 0, 0, allocation.width, allocation.height) # Fall trough to the container expose handler. # (Leaving out the window expose handler which redraws everything) - gtk.Bin.do_expose_event(self, event) + Gtk.Bin.do_expose_event(self, event) def update_position(self): invoker = self._invoker @@ -360,13 +399,13 @@ class PaletteWindow(gtk.Window): self.popup(immediate=True) def __enter_notify_event_cb(self, widget, event): - if event.detail != gtk.gdk.NOTIFY_INFERIOR and \ - event.mode == gtk.gdk.CROSSING_NORMAL: + if event.detail != Gdk.NotifyType.INFERIOR and \ + event.mode == Gdk.CROSSING_NORMAL: self.on_enter(event) def __leave_notify_event_cb(self, widget, event): - if event.detail != gtk.gdk.NOTIFY_INFERIOR and \ - event.mode == gtk.gdk.CROSSING_NORMAL: + if event.detail != Gdk.NotifyType.INFERIOR and \ + event.mode == Gdk.CROSSING_NORMAL: self.on_leave(event) def __show_cb(self, widget): @@ -393,7 +432,7 @@ class PaletteWindow(gtk.Window): y = win_y + rectangle.y width, height = self.size_request() - return gtk.gdk.Rectangle(x, y, width, height) + return Gdk.Rectangle(x, y, width, height) def get_palette_state(self): return self._palette_state @@ -429,13 +468,13 @@ class _PopdownAnimation(animator.Animation): self._palette.popdown(immediate=True) -class Invoker(gobject.GObject): +class Invoker(GObject.GObject): __gsignals__ = { - 'mouse-enter': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'mouse-leave': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'right-click': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'focus-out': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), + 'mouse-enter': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'mouse-leave': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'right-click': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'focus-out': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), } ANCHORED = 0 @@ -447,12 +486,13 @@ class Invoker(gobject.GObject): LEFT = [(-1.0, 0.0, 0.0, 0.0), (-1.0, -1.0, 0.0, 1.0)] def __init__(self): - gobject.GObject.__init__(self) + GObject.GObject.__init__(self) self.parent = None - self._screen_area = gtk.gdk.Rectangle(0, 0, gtk.gdk.screen_width(), - gtk.gdk.screen_height()) + self._screen_area = Gdk.Rectangle(0, 0, + Gdk.screen_width(), + Gdk.screen_height()) self._position_hint = self.ANCHORED self._cursor_x = -1 self._cursor_y = -1 @@ -474,7 +514,7 @@ class Invoker(gobject.GObject): invoker_valign = alignment[3] if self._cursor_x == -1 or self._cursor_y == -1: - display = gtk.gdk.display_get_default() + display = Gdk.display_get_default() screen_, x, y, mask_ = display.get_pointer() self._cursor_x = x self._cursor_y = y @@ -483,9 +523,9 @@ class Invoker(gobject.GObject): rect = self.get_rect() else: dist = style.PALETTE_CURSOR_DISTANCE - rect = gtk.gdk.Rectangle(self._cursor_x - dist, - self._cursor_y - dist, - dist * 2, dist * 2) + rect = Gdk.Rectangle(self._cursor_x - dist, + self._cursor_y - dist, + dist * 2, dist * 2) palette_width, palette_height = palette_dim @@ -495,8 +535,8 @@ class Invoker(gobject.GObject): y = rect.y + rect.height * invoker_valign + \ palette_height * palette_valign - return gtk.gdk.Rectangle(int(x), int(y), - palette_width, palette_height) + return Gdk.Rectangle(int(x), int(y), + palette_width, palette_height) def _in_screen(self, rect): return rect.x >= self._screen_area.x and \ @@ -526,13 +566,16 @@ class Invoker(gobject.GObject): return self.BOTTOM + self.RIGHT + self.TOP + self.LEFT def get_position_for_alignment(self, alignment, palette_dim): + rect = self._get_position_for_alignment(alignment, palette_dim) if self._in_screen(rect): return rect + else: return None def get_position(self, palette_dim): + alignment = self.get_alignment(palette_dim) rect = self._get_position_for_alignment(alignment, palette_dim) @@ -548,8 +591,10 @@ class Invoker(gobject.GObject): return rect def get_alignment(self, palette_dim): + best_alignment = None best_area = -1 + for alignment in self._get_alignments(): pos = self._get_position_for_alignment(alignment, palette_dim) if self._in_screen(pos): @@ -617,8 +662,10 @@ class Invoker(gobject.GObject): self._cursor_y = -1 def _ensure_palette_exists(self): + if self.parent and self.palette is None: palette = self.parent.create_palette() + if palette is not None: self.palette = palette @@ -637,6 +684,7 @@ class Invoker(gobject.GObject): return self._palette def set_palette(self, palette): + if self._palette is not None: self._palette.popdown(immediate=True) @@ -648,13 +696,14 @@ class Invoker(gobject.GObject): if self._palette: self._palette.props.invoker = self - palette = gobject.property( + palette = GObject.property( type=object, setter=set_palette, getter=get_palette) class WidgetInvoker(Invoker): def __init__(self, parent=None, widget=None): + Invoker.__init__(self) self._widget = None @@ -666,8 +715,10 @@ class WidgetInvoker(Invoker): self.attach_widget(parent, widget) def attach_widget(self, parent, widget=None): + if widget: self._widget = widget + else: self._widget = parent @@ -683,36 +734,41 @@ class WidgetInvoker(Invoker): self.attach(parent) def detach(self): + Invoker.detach(self) self._widget.disconnect(self._enter_hid) self._widget.disconnect(self._leave_hid) self._widget.disconnect(self._release_hid) def get_rect(self): + allocation = self._widget.get_allocation() if self._widget.window is not None: x, y = self._widget.window.get_origin() + else: logging.warning( "Trying to position palette with invoker that's not realized.") x = 0 y = 0 - if self._widget.flags() & gtk.NO_WINDOW: + if self._widget.flags() & Gtk.NO_WINDOW: x += allocation.x y += allocation.y width = allocation.width height = allocation.height - return gtk.gdk.Rectangle(x, y, width, height) + return Gdk.Rectangle(x, y, width, height) def has_rectangle_gap(self): return True def draw_rectangle(self, event, palette): - if self._widget.flags() & gtk.NO_WINDOW: + + if self._widget.flags() & Gtk.NO_WINDOW: x, y = self._widget.allocation.x, self._widget.allocation.y + else: x = y = 0 @@ -720,18 +776,18 @@ class WidgetInvoker(Invoker): gap = _calculate_gap(self.get_rect(), palette.get_rect()) if gap: - wstyle.paint_box_gap(event.window, gtk.STATE_PRELIGHT, - gtk.SHADOW_IN, event.area, self._widget, - "palette-invoker", x, y, - self._widget.allocation.width, - self._widget.allocation.height, - gap[0], gap[1], gap[2]) + wstyle.paint_box_gap(event.window, Gtk.SateType.PRELIGHT, + Gtk.ShadowType.IN, event.area, self._widget, + "palette-invoker", x, y, + self._widget.allocation.width, + self._widget.allocation.height, + gap[0], gap[1], gap[2]) else: - wstyle.paint_box(event.window, gtk.STATE_PRELIGHT, - gtk.SHADOW_IN, event.area, self._widget, - "palette-invoker", x, y, - self._widget.allocation.width, - self._widget.allocation.height) + wstyle.paint_box(event.window, Gtk.StateType.PRELIGHT, + Gtk.ShadowType.IN, event.area, self._widget, + "palette-invoker", x, y, + self._widget.allocation.width, + self._widget.allocation.height) def __enter_notify_event_cb(self, widget, event): self.notify_mouse_enter() @@ -740,9 +796,11 @@ class WidgetInvoker(Invoker): self.notify_mouse_leave() def __button_release_event_cb(self, widget, event): + if event.button == 3: self.notify_right_click() return True + else: return False @@ -759,7 +817,7 @@ class WidgetInvoker(Invoker): def _get_widget(self): return self._widget - widget = gobject.property(type=object, getter=_get_widget, setter=None) + widget = GObject.property(type=object, getter=_get_widget, setter=None) class CanvasInvoker(Invoker): @@ -780,9 +838,9 @@ class CanvasInvoker(Invoker): self._item = parent self._motion_hid = self._item.connect('motion-notify-event', - self.__motion_notify_event_cb) + self.__motion_notify_event_cb) self._release_hid = self._item.connect('button-release-event', - self.__button_release_event_cb) + self.__button_release_event_cb) def detach(self): Invoker.detach(self) @@ -797,15 +855,16 @@ class CanvasInvoker(Invoker): if context: x, y = context.translate_to_screen(self._item) width, height = self._item.get_allocation() - return gtk.gdk.Rectangle(x, y, width, height) + return Gdk.Rectangle(x, y, width, height) else: - return gtk.gdk.Rectangle() + return Gdk.Rectangle() def __motion_notify_event_cb(self, button, event): - if event.detail == hippo.MOTION_DETAIL_ENTER: - self.notify_mouse_enter() - elif event.detail == hippo.MOTION_DETAIL_LEAVE: - self.notify_mouse_leave() + # FIXME: We do not use hippo + #if event.detail == hippo.MOTION_DETAIL_ENTER: + # self.notify_mouse_enter() + #elif event.detail == hippo.MOTION_DETAIL_LEAVE: + # self.notify_mouse_leave() return False @@ -817,7 +876,9 @@ class CanvasInvoker(Invoker): return False def get_toplevel(self): - return hippo.get_canvas_for_item(self._item).get_toplevel() + # FIXME: We do not use hippo + #return hippo.get_canvas_for_item(self._item).get_toplevel() + pass class ToolInvoker(WidgetInvoker): @@ -836,7 +897,7 @@ class ToolInvoker(WidgetInvoker): if parent is None: return WidgetInvoker._get_alignments() - if parent.get_orientation() is gtk.ORIENTATION_HORIZONTAL: + if parent.get_orientation() is Gtk.Orientation.HORIZONTAL: return self.BOTTOM + self.TOP else: return self.LEFT + self.RIGHT @@ -845,6 +906,7 @@ class ToolInvoker(WidgetInvoker): class CellRendererInvoker(Invoker): def __init__(self): + Invoker.__init__(self) self._position_hint = self.AT_CURSOR @@ -860,11 +922,11 @@ class CellRendererInvoker(Invoker): self._cell_renderer = cell_renderer self._motion_hid = tree_view.connect('motion-notify-event', - self.__motion_notify_event_cb) + self.__motion_notify_event_cb) self._leave_hid = tree_view.connect('leave-notify-event', - self.__leave_notify_event_cb) + self.__leave_notify_event_cb) self._release_hid = tree_view.connect('button-release-event', - self.__button_release_event_cb) + self.__button_release_event_cb) self.attach(cell_renderer) @@ -875,53 +937,65 @@ class CellRendererInvoker(Invoker): self._tree_view.disconnect(self._release_hid) def get_rect(self): + allocation = self._tree_view.get_allocation() if self._tree_view.window is not None: x, y = self._tree_view.window.get_origin() + else: logging.warning( "Trying to position palette with invoker that's not realized.") x = 0 y = 0 - if self._tree_view.flags() & gtk.NO_WINDOW: + if self._tree_view.flags() & Gtk.NO_WINDOW: x += allocation.x y += allocation.y width = allocation.width height = allocation.height - return gtk.gdk.Rectangle(x, y, width, height) + return Gdk.Rectangle(x, y, width, height) def __motion_notify_event_cb(self, widget, event): + if event.window != widget.get_bin_window(): return + if self._point_in_cell_renderer(event.x, event.y): tree_view = self._tree_view path, column_, x_, y_ = tree_view.get_path_at_pos(int(event.x), - int(event.y)) + int(event.y)) + if path != self.path: if self.path is not None: self._redraw_path(self.path) + if path is not None: self._redraw_path(path) + if self.palette is not None: self.palette.popdown(immediate=True) self.palette = None + self.path = path self.notify_mouse_enter() + else: if self.path is not None: self._redraw_path(self.path) + self.path = None self.notify_mouse_leave() def _redraw_path(self, path): + for column in self._tree_view.get_columns(): if self._cell_renderer in column.get_cell_renderers(): break + area = self._tree_view.get_background_area(path, column) x, y = \ self._tree_view.convert_bin_window_to_widget_coords(area.x, area.y) @@ -931,22 +1005,26 @@ class CellRendererInvoker(Invoker): self.notify_mouse_leave() def __button_release_event_cb(self, widget, event): + if event.button == 1 and self._point_in_cell_renderer(event.x, event.y): tree_view = self._tree_view path, column_, x_, y_ = tree_view.get_path_at_pos(int(event.x), - int(event.y)) + int(event.y)) self._cell_renderer.emit('clicked', path) # So the treeview receives it and knows a drag isn't going on return False + if event.button == 3 and self._point_in_cell_renderer(event.x, event.y): self.notify_right_click() return True + else: return False def _point_in_cell_renderer(self, event_x, event_y): + pos = self._tree_view.get_path_at_pos(int(event_x), int(event_y)) if pos is None: return False @@ -958,6 +1036,7 @@ class CellRendererInvoker(Invoker): cell_x, cell_width = column.cell_get_position(cell_renderer) if x > cell_x and x < (cell_x + cell_width): return True + return False return False diff --git a/toolkit/pixbuf.py b/toolkit/pixbuf.py index c3bb7d1..bb01b9a 100644 --- a/toolkit/pixbuf.py +++ b/toolkit/pixbuf.py @@ -18,14 +18,17 @@ import re import cStringIO -import gtk import rsvg import cairo import logging -from sugar.graphics import style -from sugar.graphics.xocolor import XoColor, is_valid -from sugar.util import LRU +import gi +from gi.repository import Gtk +from gi.repository import GdkPixbuf + +from sugar3.graphics import style +from sugar3.graphics.xocolor import XoColor, is_valid +from sugar3.util import LRU def to_file(pixbuf): @@ -47,20 +50,23 @@ def to_str(pixbuf): def from_str(str): """Convert string to pixbuf object""" - loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png') + loader = GdkPixbuf.PixbufLoader.new_with_mime_type('image/png') try: loader.write(str) + except Exception, e: logging.error('pixbuf.from_str: %s' % e) return None + finally: loader.close() return loader.get_pixbuf() -def at_size_with_ratio(pixbuf, width, height, type=gtk.gdk.INTERP_BILINEAR): +def at_size_with_ratio(pixbuf, width, height, type=GdkPixbuf.InterpType.BILINEAR): + image_width = pixbuf.get_width() image_height = pixbuf.get_height() @@ -71,6 +77,7 @@ def at_size_with_ratio(pixbuf, width, height, type=gtk.gdk.INTERP_BILINEAR): if ratio_width != ratio: ratio_width = ratio width = int(image_width * ratio) + elif ratio_height != ratio: ratio_height = ratio height = int(image_height * ratio) @@ -97,6 +104,7 @@ def from_svg_at_size(filename=None, width=None, height=None, handle=None, if ratio_width != ratio: ratio_width = ratio width = int(icon_width * ratio) + elif ratio_height != ratio: ratio_height = ratio height = int(icon_height * ratio) @@ -109,7 +117,7 @@ def from_svg_at_size(filename=None, width=None, height=None, handle=None, context.scale(ratio_width, ratio_height) handle.render_cairo(context) - loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png') + loader = GdkPixbuf.PixbufLoader.new_with_mime_type('image/png') surface.write_to_png(loader) loader.close() diff --git a/toolkit/radiopalette.py b/toolkit/radiopalette.py index 9c902b1..6357414 100644 --- a/toolkit/radiopalette.py +++ b/toolkit/radiopalette.py @@ -15,16 +15,18 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. -import gtk +import gi +from gi.repository import Gtk -from sugar.graphics.toolbutton import ToolButton -from sugar.graphics.palette import Palette +from sugar3.graphics.toolbutton import ToolButton +from sugar3.graphics.palette import Palette class RadioMenuButton(ToolButton): - def __init__(self, **kwargs): - ToolButton.__init__(self, **kwargs) + def __init__(self): + + ToolButton.__init__(self) self.selected_button = None if self.props.palette: @@ -34,18 +36,23 @@ class RadioMenuButton(ToolButton): self.connect('notify::palette', self.__palette_cb) def _do_clicked(self): + if self.palette is None: return + if self.palette.is_up() and \ self.palette.palette_state == Palette.SECONDARY: self.palette.popdown(immediate=True) + else: self.palette.popup(immediate=True) self.palette.props.invoker.emit('right-click') def __palette_cb(self, widget, pspec): + if not isinstance(self.props.palette, RadioPalette): return + self.props.palette.update_button() def __clicked_cb(self, button): @@ -54,10 +61,12 @@ class RadioMenuButton(ToolButton): class RadioToolsButton(RadioMenuButton): - def __init__(self, **kwargs): - RadioMenuButton.__init__(self, **kwargs) + def __init__(self): + + RadioMenuButton.__init__(self) def _do_clicked(self): + if not self.selected_button: return self.selected_button.emit('clicked') @@ -65,14 +74,16 @@ class RadioToolsButton(RadioMenuButton): class RadioPalette(Palette): - def __init__(self, **kwargs): - Palette.__init__(self, **kwargs) + def __init__(self): + + Palette.__init__(self) - self.button_box = gtk.HBox() + self.button_box = Gtk.HBox() self.button_box.show() self.set_content(self.button_box) def append(self, button, label): + children = self.button_box.get_children() if button.palette is not None: @@ -87,10 +98,12 @@ class RadioPalette(Palette): self.__clicked_cb(button) def update_button(self): + for i in self.button_box.get_children(): self.__clicked_cb(i) def __clicked_cb(self, button): + if not button.get_active(): return @@ -99,8 +112,10 @@ class RadioPalette(Palette): if self.props.invoker is not None: parent = self.props.invoker.parent + else: parent = None + if not isinstance(parent, RadioMenuButton): return diff --git a/toolkit/scrolledbox.py b/toolkit/scrolledbox.py index c95dae0..77496d2 100644 --- a/toolkit/scrolledbox.py +++ b/toolkit/scrolledbox.py @@ -12,28 +12,34 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -import gtk +import gi +from gi.repository import Gtk +from gi.repository import Gdk -from sugar.graphics.icon import Icon +from sugar3.graphics.icon import Icon -class ScrollButton(gtk.ToolButton): +class ScrollButton(Gtk.ToolButton): + def __init__(self, icon_name): - gtk.ToolButton.__init__(self) + + Gtk.ToolButton.__init__(self) icon = Icon(icon_name = icon_name, - icon_size=gtk.ICON_SIZE_SMALL_TOOLBAR) + icon_size=Gdk.IconSize.SMALL_TOOLBAR) # The alignment is a hack to work around gtk.ToolButton code # that sets the icon_size when the icon_widget is a gtk.Image - alignment = gtk.Alignment(0.5, 0.5) + alignment = Gtk.Alignment(0.5, 0.5) alignment.add(icon) self.set_icon_widget(alignment) -class ScrolledBox(gtk.EventBox): +class ScrolledBox(Gtk.EventBox): + def __init__(self, orientation, - arrows_policy=gtk.POLICY_AUTOMATIC, - scroll_policy=gtk.POLICY_AUTOMATIC): + arrows_policy=Gtk.PolicyType.AUTOMATIC, + scroll_policy=Gtk.PolicyType.AUTOMATIC): - gtk.EventBox.__init__(self) + Gtk.EventBox.__init__(self) + self.orientation = orientation self._viewport = None self._abox = None @@ -44,68 +50,83 @@ class ScrolledBox(gtk.EventBox): self._left = None self._right = None - if orientation == gtk.ORIENTATION_HORIZONTAL: - box = gtk.HBox() + if orientation == Gtk.Orientation.HORIZONTAL: + box = Gtk.HBox() + else: - box = gtk.VBox() - if self._arrows_policy == gtk.POLICY_AUTOMATIC: + box = Gtk.VBox() + + if self._arrows_policy == Gtk.PolicyType.AUTOMATIC: box.connect("size-allocate", self._box_allocate_cb) self.add(box) - if self._arrows_policy != gtk.POLICY_NEVER: - if orientation == gtk.ORIENTATION_HORIZONTAL: + if self._arrows_policy != Gtk.PolicyType.NEVER: + if orientation == Gtk.Orientation.HORIZONTAL: self._left = ScrollButton('go-left') + else: self._left = ScrollButton('go-up') + self._left.connect('clicked', self._scroll_cb, - gtk.gdk.SCROLL_LEFT) + Gdk.ScrollDirection.LEFT) box.pack_start(self._left, False, False, 0) - self._scrolled = gtk.ScrolledWindow() - if orientation == gtk.ORIENTATION_HORIZONTAL: - self._scrolled.set_policy(scroll_policy, gtk.POLICY_NEVER) + self._scrolled = Gtk.ScrolledWindow() + if orientation == Gtk.Orientation.HORIZONTAL: + self._scrolled.set_policy(scroll_policy, Gtk.PolicyType.NEVER) else: - self._scrolled.set_policy(gtk.POLICY_NEVER, scroll_policy) + self._scrolled.set_policy(Gtk.PolicyType.NEVER, scroll_policy) + self._scrolled.connect('scroll-event', self._scroll_event_cb) box.pack_start(self._scrolled, True, True, 0) - if orientation == gtk.ORIENTATION_HORIZONTAL: + if orientation == Gtk.Orientation.HORIZONTAL: self._adj = self._scrolled.get_hadjustment() + else: self._adj = self._scrolled.get_vadjustment() + self._adj.connect('changed', self._scroll_changed_cb) self._adj.connect('value-changed', self._scroll_changed_cb) - if self._arrows_policy != gtk.POLICY_NEVER: - if orientation == gtk.ORIENTATION_HORIZONTAL: + if self._arrows_policy != Gtk.PolicyType.NEVER: + if orientation == Gtk.Orientation.HORIZONTAL: self._right = ScrollButton('go-right') + else: self._right = ScrollButton('go-down') + self._right.connect('clicked', self._scroll_cb, - gtk.gdk.SCROLL_RIGHT) + Gdk.ScrollDirection.RIGHT) box.pack_start(self._right, False, False, 0) def modify_fg(self, state, bg): - gtk.EventBox.modify_fg(self, state, bg) + + Gtk.EventBox.modify_fg(self, state, bg) self._viewport.get_parent().modify_fg(state, bg) def modify_bg(self, state, bg): - gtk.EventBox.modify_bg(self, state, bg) + + Gtk.EventBox.modify_bg(self, state, bg) self._viewport.get_parent().modify_bg(state, bg) def set_viewport(self, widget): + if widget == self._viewport: return + if self._viewport and self._aviewport_sig: self._viewport.disconnect(self._aviewport_sig) + self._viewport = widget - if self._arrows_policy == gtk.POLICY_AUTOMATIC: + if self._arrows_policy == Gtk.PolicyType.AUTOMATIC: self._aviewport_sig = self._viewport.connect('size-allocate', - self._viewport_allocate_cb) + self._viewport_allocate_cb) self._scrolled.add_with_viewport(widget) def get_viewport_allocation(self): + alloc = self._scrolled.get_allocation() alloc.x -= self._adj.get_value() return alloc @@ -114,6 +135,7 @@ class ScrolledBox(gtk.EventBox): return self._adj def _box_allocate_cb(self, w, a): + self._abox = a self._update_arrows() @@ -124,52 +146,63 @@ class ScrolledBox(gtk.EventBox): def _update_arrows(self): if not self._abox or not self._aviewport: return - if self.orientation == gtk.ORIENTATION_HORIZONTAL: + if self.orientation == Gtk.Orientation.HORIZONTAL: show_flag = self._abox.width < self._aviewport.width + else: show_flag = self._abox.height < self._aviewport.height if show_flag: self._left.show() self._right.show() + else: self._left.hide() self._right.hide() def _scroll_event_cb(self, widget, event): - if self.orientation == gtk.ORIENTATION_HORIZONTAL: - if event.direction == gtk.gdk.SCROLL_UP: - event.direction = gtk.gdk.SCROLL_LEFT - if event.direction == gtk.gdk.SCROLL_DOWN: - event.direction = gtk.gdk.SCROLL_RIGHT + + if self.orientation == Gtk.Orientation.HORIZONTAL: + if event.direction == Gdk.ScrollDirection.UP: + event.direction = Gdk.ScrollDirection.LEFT + + if event.direction == Gdk.ScrollDirection.DOWN: + event.direction = Gdk.ScrollDirection.RIGHT + else: - if event.direction == gtk.gdk.SCROLL_LEFT: - event.direction = gtk.gdk.SCROLL_UP - if event.direction == gtk.gdk.SCROLL_RIGHT: - event.direction = gtk.gdk.SCROLL_DOWN + if event.direction == Gdk.ScrollDirection.LEFT: + event.direction = Gdk.ScrollDirection.UP + + if event.direction == Gdk.ScrollDirection.RIGHT: + event.direction = Gdk.ScrollDirection.DOWN - if self._scroll_policy == gtk.POLICY_NEVER: + if self._scroll_policy == Gtk.PolicyType.NEVER: self._scroll_cb(None, event.direction) return False def _scroll_cb(self, widget, direction): - if direction in (gtk.gdk.SCROLL_LEFT, gtk.gdk.SCROLL_UP): + + if direction in (Gdk.ScrollDirection.LEFT, Gdk.ScrollDirection.UP): val = max(self._adj.get_property('lower'), self._adj.get_value() - - self._adj.get_property('page_increment')) + - self._adj.get_property('page_increment')) + else: val = min(self._adj.get_property('upper') - - self._adj.get_property('page_size'), - self._adj.get_value() - + self._adj.get_property('page_increment')) + - self._adj.get_property('page_size'), + self._adj.get_value() + + self._adj.get_property('page_increment')) self._adj.set_value(val) def _scroll_changed_cb(self, widget): + val = self._adj.get_value() + if self._left: if val == 0: self._left.set_sensitive(False) + else: self._left.set_sensitive(True) @@ -177,13 +210,16 @@ class ScrolledBox(gtk.EventBox): if val >= self._adj.get_property('upper') - \ self._adj.get_property('page_size'): self._right.set_sensitive(False) + else: self._right.set_sensitive(True) class HScrolledBox(ScrolledBox): - def __init__(self, **kwargs): - ScrolledBox.__init__(self, gtk.ORIENTATION_HORIZONTAL, **kwargs) + + def __init__(self): + ScrolledBox.__init__(self, Gtk.Orientation.HORIZONTAL) class VScrolledBox(ScrolledBox): - def __init__(self, **kwargs): - ScrolledBox.__init__(self, gtk.ORIENTATION_VERTICAL, **kwargs) + + def __init__(self): + ScrolledBox.__init__(self, Gtk.Orientation.VERTICAL) diff --git a/toolkit/tarball.py b/toolkit/tarball.py index 0a4a1b2..30483ea 100644 --- a/toolkit/tarball.py +++ b/toolkit/tarball.py @@ -20,7 +20,6 @@ import os import time import tarfile import cStringIO -import gtk import zipfile import tempfile import shutil @@ -64,8 +63,10 @@ class Tarball: """ def __init__(self, name=None, mode='r', mtime=None): + if not mode.startswith('r') or tarfile.is_tarfile(name): self.__tar = tarfile.TarFile(name=name, mode=mode) + else: # convert for tar @@ -85,6 +86,7 @@ class Tarball: tar.close() self.__tar = tarfile.TarFile(name=tmp_name, mode=mode) + finally: tmp_fo.close() os.unlink(tmp_name) @@ -92,6 +94,7 @@ class Tarball: if mtime: self.mtime = mtime + else: self.mtime = time.time() @@ -106,8 +109,10 @@ class Tarball: def read(self, arcname): """Returns sring with content of given file from tarball.""" file_o = self.__tar.extractfile(arcname.encode('utf8')) + if not file_o: return None + out = file_o.read() file_o.close() return out diff --git a/toolkit/temposlider.py b/toolkit/temposlider.py index 44b23d2..d8e633d 100644 --- a/toolkit/temposlider.py +++ b/toolkit/temposlider.py @@ -14,30 +14,35 @@ # Widget was copy&pasted from TamTam activities -import gtk +import gi +from gi.repository import Gtk +from gi.repository import GdkPixbuf + import rsvg import cairo -from sugar.graphics import style +from sugar3.graphics import style -class TempoSlider(gtk.HBox): +class TempoSlider(Gtk.HBox): + def __init__(self, min_value, max_value): - gtk.HBox.__init__(self) + + Gtk.HBox.__init__(self) self._pixbuf = [None] * 8 - self._image = gtk.Image() + self._image = Gtk.Image() self._image.show() # used to store tempo updates while the slider is active self._delayed = 0 self._active = False - self.adjustment = gtk.Adjustment(min_value, min_value, max_value, - (max_value - min_value) / 8, (max_value - min_value) / 8, 0) + self.adjustment = Gtk.Adjustment(min_value, min_value, max_value, + (max_value - min_value) / 8, (max_value - min_value) / 8, 0) self._adjustment_h = self.adjustment.connect('value-changed', self._changed_cb) - slider = gtk.HScale(adjustment = self.adjustment) + slider = Gtk.HScale(adjustment = self.adjustment) slider.show() slider.set_draw_value(False) slider.connect("button-press-event", self._press_cb) @@ -47,13 +52,16 @@ class TempoSlider(gtk.HBox): self.pack_end(self._image, False, False) def set_value(self, tempo, quiet = False): + if self._active: self._delayed = tempo + elif quiet: self.adjustment.handler_block(self._adjustment_h) self.adjustment.set_value(tempo) self._update(tempo) self.adjustment.handler_unblock(self._adjustment_h) + else: self.adjustment.set_value(tempo) @@ -61,9 +69,11 @@ class TempoSlider(gtk.HBox): self._update(widget.get_value()) def _update(self, tempo): + def map_range(value, ilower, iupper, olower, oupper): if value == iupper: return oupper + return olower + int((oupper-olower+1) * (value-ilower) / float(iupper-ilower)) @@ -82,6 +92,7 @@ class TempoSlider(gtk.HBox): self._active = True def _release_cb(self, widget, event): + self._active = False if self._delayed != 0: self.set_value(self._delayed, True) @@ -104,12 +115,15 @@ def _from_svg_at_size(filename=None, width=None, height=None, handle=None, if keep_ratio: ratio = min(ratio_width, ratio_height) + if ratio_width != ratio: ratio_width = ratio width = int(icon_width * ratio) + elif ratio_height != ratio: ratio_height = ratio height = int(icon_height * ratio) + else: ratio_width = 1 ratio_height = 1 @@ -119,7 +133,7 @@ def _from_svg_at_size(filename=None, width=None, height=None, handle=None, context.scale(ratio_width, ratio_height) handle.render_cairo(context) - loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png') + loader = GdkPixbuf.PixbufLoader.new_with_mime_type('image/png') surface.write_to_png(loader) loader.close() diff --git a/toolkit/toolbarbox.py b/toolkit/toolbarbox.py index 7172b8b..923bed1 100644 --- a/toolkit/toolbarbox.py +++ b/toolkit/toolbarbox.py @@ -15,12 +15,13 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. -import gtk -import gobject +import gi +from gi.repository import Gtk +from gi.repository import GObject -from sugar.graphics import style -from sugar.graphics.toolbutton import ToolButton -from sugar.graphics import palettegroup +from sugar3.graphics import style +from sugar3.graphics.toolbutton import ToolButton +from sugar3.graphics import palettegroup from toolkit.internals.palettewindow import PaletteWindow from toolkit.internals.palettewindow import ToolInvoker @@ -31,8 +32,9 @@ _LINE_WIDTH = 2 class ToolbarButton(ToolButton): - def __init__(self, page=None, **kwargs): - ToolButton.__init__(self, **kwargs) + def __init__(self, page=None): + + ToolButton.__init__(self) self.page_widget = None @@ -43,31 +45,36 @@ class ToolbarButton(ToolButton): self.connect('size-allocate', self.__size_allocate_cb) def get_toolbar_box(self): + if not hasattr(self.parent, 'owner'): return None + return self.parent.owner toolbar_box = property(get_toolbar_box) def get_page(self): + if self.page_widget is None: return None + return _get_embedded_page(self.page_widget) def set_page(self, page): + if page is None: self.page_widget = None return self.page_widget, alignment_ = _embed_page(_Box, page) - w_, h = gtk.icon_size_lookup(gtk.ICON_SIZE_LARGE_TOOLBAR) + w_, h = Gtk.icon_size_lookup(Gtk.IconSize.LARGE_TOOLBAR) page.show() if self.props.palette is None: self.props.palette = _ToolbarPalette(invoker=ToolInvoker(self)) self._move_page_to_palette() - page = gobject.property(type=object, getter=get_page, setter=set_page) + page = GObject.property(type=object, getter=get_page, setter=set_page) def is_in_palette(self): return self.page is not None and \ @@ -97,14 +104,15 @@ class ToolbarButton(ToolButton): if box.expanded_button.window is not None: # need to redraw it to erase arrow box.expanded_button.window.invalidate_rect(None, True) + box.expanded_button.set_expanded(False) box.expanded_button = self self._unparent() - self.modify_bg(gtk.STATE_NORMAL, box.background) + self.modify_bg(Gtk.StateType.NORMAL, box.background) _setup_page(self.page_widget, box.background, box.props.padding) - box.pack_start(self.page_widget) + box.pack_start(self.page_widget, False, False, 0) def _move_page_to_palette(self): if self.is_in_palette(): @@ -121,50 +129,53 @@ class ToolbarButton(ToolButton): self.page_widget.parent.remove(self.page_widget) def do_expose_event(self, event): + if not self.is_expanded() or self.props.palette is not None and \ self.props.palette.is_up(): ToolButton.do_expose_event(self, event) - _paint_arrow(self, event, gtk.ARROW_DOWN) + _paint_arrow(self, event, Gtk.ArrowType.DOWN) return alloc = self.allocation self.get_style().paint_box(event.window, - gtk.STATE_NORMAL, gtk.SHADOW_IN, event.area, self, + Gtk.StateType.NORMAL, Gtk.ShadowType.IN, event.area, self, 'palette-invoker', alloc.x, 0, alloc.width, alloc.height + _LINE_WIDTH) - if self.child.state != gtk.STATE_PRELIGHT: + if self.child.state != Gtk.StateType.PRELIGHT: self.get_style().paint_box(event.window, - gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, self, None, - alloc.x + _LINE_WIDTH, _LINE_WIDTH, - alloc.width - _LINE_WIDTH * 2, alloc.height) + Gtk.StateType.NORMAL, Gtk.ShadowType.NONE, event.area, self, None, + alloc.x + _LINE_WIDTH, _LINE_WIDTH, + alloc.width - _LINE_WIDTH * 2, alloc.height) - gtk.ToolButton.do_expose_event(self, event) - _paint_arrow(self, event, gtk.ARROW_UP) + Gtk.ToolButton.do_expose_event(self, event) + _paint_arrow(self, event, Gtk.ArrowType.UP) def __size_allocate_cb(self, button, allocation): if self.page_widget is not None: self.page_widget.set_size_request(-1, allocation.height) -class ToolbarBox(gtk.VBox): +class ToolbarBox(Gtk.VBox): def __init__(self, padding=style.TOOLBOX_HORIZONTAL_PADDING): - gtk.VBox.__init__(self) + + Gtk.VBox.__init__(self) + self._expanded_button_index = -1 self.background = None - self._toolbar = gtk.Toolbar() + self._toolbar = Gtk.Toolbar() self._toolbar.owner = self self._toolbar.connect('remove', self.__remove_cb) self._toolbar_widget, self._toolbar_alignment = \ - _embed_page(gtk.EventBox, self._toolbar) - self.pack_start(self._toolbar_widget) + _embed_page(Gtk.EventBox, self._toolbar) + self.pack_start(self._toolbar_widget, False, False, 0) self.props.padding = padding - self.modify_bg(gtk.STATE_NORMAL, + self.modify_bg(Gtk.StateType.NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color()) def get_toolbar(self): @@ -173,14 +184,18 @@ class ToolbarBox(gtk.VBox): toolbar = property(get_toolbar) def get_expanded_button(self): + if self._expanded_button_index == -1: return None + return self.toolbar.get_nth_item(self._expanded_button_index) def set_expanded_button(self, button): + if not button in self.toolbar: self._expanded_button_index = -1 return + self._expanded_button_index = self.toolbar.get_item_index(button) expanded_button = property(get_expanded_button, set_expanded_button) @@ -191,19 +206,24 @@ class ToolbarBox(gtk.VBox): def set_padding(self, pad): self._toolbar_alignment.set_padding(0, 0, pad, pad) - padding = gobject.property(type=object, + padding = GObject.property(type=object, getter=get_padding, setter=set_padding) def modify_bg(self, state, color): - if state == gtk.STATE_NORMAL: + + if state == Gtk.StateType.NORMAL: self.background = color + self._toolbar_widget.modify_bg(state, color) self.toolbar.modify_bg(state, color) def __remove_cb(self, sender, button): + if not isinstance(button, ToolbarButton): return + button.popdown() + if button == self.expanded_button: self.remove(button.page_widget) self._expanded_button_index = -1 @@ -211,8 +231,9 @@ class ToolbarBox(gtk.VBox): class _ToolbarPalette(PaletteWindow): - def __init__(self, **kwargs): - PaletteWindow.__init__(self, **kwargs) + def __init__(self): + + PaletteWindow.__init__(self) self.set_border_width(0) self._has_focus = False @@ -242,24 +263,30 @@ class _ToolbarPalette(PaletteWindow): self._set_focus(False) def _set_focus(self, new_focus): + self._has_focus = new_focus + if not self._has_focus: group = palettegroup.get_group('default') if not group.is_up(): self.popdown() def do_size_request(self, requisition): - gtk.Window.do_size_request(self, requisition) + + Gtk.Window.do_size_request(self, requisition) requisition.width = max(requisition.width, - gtk.gdk.screen_width()) + Gdk.screen_width()) def popup(self, immediate=False): + button = self.expanded_button + if button.is_expanded(): return + box = button.toolbar_box _setup_page(button.page_widget, style.COLOR_BLACK.get_gdk_color(), - box.props.padding) + box.props.padding) PaletteWindow.popup(self, immediate) def __group_popdown_cb(self, group): @@ -267,52 +294,59 @@ class _ToolbarPalette(PaletteWindow): self.popdown(immediate=True) -class _Box(gtk.EventBox): +class _Box(Gtk.EventBox): def __init__(self): - gtk.EventBox.__init__(self) + + Gtk.EventBox.__init__(self) self.connect('expose-event', self.do_expose_event) self.set_app_paintable(True) def do_expose_event(self, widget, event): + if self.parent.expanded_button is None: return + alloc = self.parent.expanded_button.allocation self.get_style().paint_box(event.window, - gtk.STATE_NORMAL, gtk.SHADOW_IN, event.area, self, - 'palette-invoker', -_LINE_WIDTH, 0, - self.allocation.width + _LINE_WIDTH * 2, - self.allocation.height + _LINE_WIDTH) + Gtk.StateType.NORMAL, Gtk.ShadowType.IN, event.area, self, + 'palette-invoker', -_LINE_WIDTH, 0, + self.allocation.width + _LINE_WIDTH * 2, + self.allocation.height + _LINE_WIDTH) + self.get_style().paint_box(event.window, - gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, self, None, - alloc.x + _LINE_WIDTH, 0, - alloc.width - _LINE_WIDTH * 2, _LINE_WIDTH) + Gtk.StateType.NORMAL, Gtk.ShadowType.NONE, event.area, self, None, + alloc.x + _LINE_WIDTH, 0, + alloc.width - _LINE_WIDTH * 2, _LINE_WIDTH) def _setup_page(page_widget, color, hpad): + vpad = _LINE_WIDTH page_widget.child.set_padding(vpad, vpad, hpad, hpad) page = _get_embedded_page(page_widget) - page.modify_bg(gtk.STATE_NORMAL, color) - if isinstance(page, gtk.Container): + page.modify_bg(Gtk.StateType.NORMAL, color) + + if isinstance(page, Gtk.Container): for i in page.get_children(): - i.modify_bg(gtk.STATE_INSENSITIVE, color) + i.modify_bg(Gtk.StateType.INSENSITIVE, color) - page_widget.modify_bg(gtk.STATE_NORMAL, color) - page_widget.modify_bg(gtk.STATE_PRELIGHT, color) + page_widget.modify_bg(Gtk.StateType.NORMAL, color) + page_widget.modify_bg(Gtk.StateType.PRELIGHT, color) def _embed_page(box_class, page): page.show() - alignment = gtk.Alignment(0.0, 0.0, 1.0, 1.0) + alignment = Gtk.Alignment() + alignment.set(0.0, 0.0, 1.0, 1.0) alignment.add(page) alignment.show() page_widget = box_class() - page_widget.modify_bg(gtk.STATE_ACTIVE, - style.COLOR_BUTTON_GREY.get_gdk_color()) + page_widget.modify_bg(Gtk.StateType.ACTIVE, + style.COLOR_BUTTON_GREY.get_gdk_color()) page_widget.add(alignment) page_widget.show() @@ -329,5 +363,5 @@ def _paint_arrow(widget, event, arrow_type): y = alloc.y + alloc.height - int(_ARROW_SIZE * .85) widget.get_style().paint_arrow(event.window, - gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, widget, - None, arrow_type, True, x, y, _ARROW_SIZE, _ARROW_SIZE) + Gtk.StateType.NORMAL, Gtk.ShadowType.NONE, event.area, widget, + None, arrow_type, True, x, y, _ARROW_SIZE, _ARROW_SIZE) diff --git a/toolkit/toolitem.py b/toolkit/toolitem.py index e490c22..428f109 100644 --- a/toolkit/toolitem.py +++ b/toolkit/toolitem.py @@ -17,30 +17,32 @@ """A set of toolitem widets""" -import gtk -import gobject +import gi +from gi.repository import Gtk +from gi.repository import GObject -from sugar.graphics import style +from sugar3.graphics import style from toolkit.combobox import ComboBox -class ToolWidget(gtk.ToolItem): +class ToolWidget(Gtk.ToolItem): - def __init__(self, **kwargs): + def __init__(self): + self._widget = None self._label = None self._label_text = None - self._box = gtk.HBox(False, style.DEFAULT_SPACING) + self._box = Gtk.HBox(False, style.DEFAULT_SPACING) - gobject.GObject.__init__(self, **kwargs) + GObject.GObject.__init__(self) self.props.border_width = style.DEFAULT_PADDING self._box.show() self.add(self._box) if self.label is None: - self.label = gtk.Label() + self.label = Gtk.Label() def get_label_text(self): return self._label_text @@ -50,30 +52,34 @@ class ToolWidget(gtk.ToolItem): if self.label is not None and value: self.label.set_text(self._label_text) - label_text = gobject.property(getter=get_label_text, setter=set_label_text) + label_text = GObject.property(getter=get_label_text, setter=set_label_text) def get_label(self): return self._label def set_label(self, label): + if self._label is not None: self._box.remove(self._label) + self._label = label self._box.pack_start(label, False) self._box.reorder_child(label, 0) label.show() self.set_label_text(self._label_text) - label = gobject.property(getter=get_label, setter=set_label) + label = GObject.property(getter=get_label, setter=set_label) def get_widget(self): return self._widget def set_widget(self, widget): + if self._widget is not None: self._box.remove(self._widget) + self._widget = widget self._box.pack_end(widget) widget.show() - widget = gobject.property(getter=get_widget, setter=set_widget) + widget = GObject.property(getter=get_widget, setter=set_widget) diff --git a/utils.py b/utils.py index cb5b53f..5fa965e 100644 --- a/utils.py +++ b/utils.py @@ -12,13 +12,15 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -import gtk -import pango +import gi +from gi.repository import Gtk +from gi.repository import GdkPixbuf +from gi.repository import Pango -from sugar.graphics import style -from sugar.graphics.icon import Icon -from sugar.graphics.icon import Icon -from sugar.graphics.combobox import ComboBox as _ComboBox +from sugar3.graphics import style +from sugar3.graphics.icon import Icon +from sugar3.graphics.icon import Icon +from sugar3.graphics.combobox import ComboBox as _ComboBox from theme import * @@ -32,11 +34,11 @@ class ComboBox(_ComboBox): pixbuf=None, position=None): if not self._icon_renderer and (icon_name or pixbuf): - self._icon_renderer = gtk.CellRendererPixbuf() + self._icon_renderer = Gtk.CellRendererPixbuf() settings = self.get_settings() - w, h = gtk.icon_size_lookup_for_settings(settings, - gtk.ICON_SIZE_MENU) + w, h = Gtk.icon_size_lookup_for_settings(settings, + Gtk.IconSize.MENU) self._icon_renderer.props.stock_size = w self._icon_renderer.props.xpad = 4 @@ -46,19 +48,20 @@ class ComboBox(_ComboBox): self.add_attribute(self._icon_renderer, 'pixbuf', 2) if not self._text_renderer and text: - self._text_renderer = gtk.CellRendererText() - self._text_renderer.props.ellipsize = pango.ELLIPSIZE_END + self._text_renderer = Gtk.CellRendererText() + # FIXME: Re escribir + #self._text_renderer.props.ellipsize = Pango.ELLIPSIZE_END self.pack_end(self._text_renderer, True) self.add_attribute(self._text_renderer, 'text', 1) if not pixbuf: if icon_name: if not size: - size = gtk.ICON_SIZE_LARGE_TOOLBAR - width, height = gtk.icon_size_lookup(size) + size = Gtk.IconSize.LARGE_TOOLBAR + width, height = Gtk.icon_size_lookup(size) else: width, height = size - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(icon_name, + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(icon_name, width, height) else: pixbuf = None -- cgit v0.9.1