diff --git a/debug-viewer/GstDebugViewer/Common/Data.py b/debug-viewer/GstDebugViewer/Common/Data.py index 92b3f5afb1..cefb314265 100644 --- a/debug-viewer/GstDebugViewer/Common/Data.py +++ b/debug-viewer/GstDebugViewer/Common/Data.py @@ -19,10 +19,9 @@ """GStreamer Development Utilities Common Data module.""" -import pygtk -pygtk.require ("2.0") +import gi -import gobject +from gi.repository import GObject class Dispatcher (object): @@ -52,14 +51,14 @@ class GSourceDispatcher (Dispatcher): def __call__ (self, iterator): if self.source_id is not None: - gobject.source_remove (self.source_id) + GObject.source_remove (self.source_id) - self.source_id = gobject.idle_add (iterator.next, priority = gobject.PRIORITY_LOW) + self.source_id = GObject.idle_add (iterator.next, priority = GObject.PRIORITY_LOW) def cancel (self): if self.source_id is None: return - gobject.source_remove (self.source_id) + GObject.source_remove (self.source_id) self.source_id = None diff --git a/debug-viewer/GstDebugViewer/Common/GUI.py b/debug-viewer/GstDebugViewer/Common/GUI.py index 1b25851ff4..594315f5bd 100644 --- a/debug-viewer/GstDebugViewer/Common/GUI.py +++ b/debug-viewer/GstDebugViewer/Common/GUI.py @@ -23,15 +23,16 @@ import os import logging -import pygtk -pygtk.require ("2.0") -del pygtk +import gi -import gobject -import gtk +from gi.repository import GObject +from gi.repository import Gtk +from gi.repository import Gdk +from gi.types import GObjectMeta import GstDebugViewer from GstDebugViewer.Common import utils +from generictreemodel import GenericTreeModel def widget_add_popup_menu (widget, menu, button = 3): @@ -78,10 +79,10 @@ class Widgets (dict): def __init__ (self, builder): widgets = (obj for obj in builder.get_objects () - if isinstance(obj, gtk.Buildable)) - # gtk.Widget.get_name() shadows out the GtkBuildable interface method + if isinstance(obj, Gtk.Buildable)) + # Gtk.Widget.get_name() shadows out the GtkBuildable interface method # of the same name, hence calling the unbound interface method here: - items = ((gtk.Buildable.get_name (w), w,) for w in widgets) + items = ((Gtk.Buildable.get_name (w), w,) for w in widgets) dict.__init__ (self, items) @@ -108,7 +109,7 @@ class WidgetFactory (object): builder_filename = os.path.join (self.directory, filename) - builder = gtk.Builder () + builder = Gtk.Builder () builder.set_translation_domain (GstDebugViewer.GETTEXT_DOMAIN) builder.add_from_file (builder_filename) @@ -141,7 +142,7 @@ class UIFactory (object): def make (self, extra_actions = None): - ui_manager = gtk.UIManager () + ui_manager = Gtk.UIManager () for action_group in self.action_groups.values (): ui_manager.insert_action_group (action_group, 0) if extra_actions: @@ -152,7 +153,7 @@ class UIFactory (object): return ui_manager -class MetaModel (gobject.GObjectMeta): +class MetaModel (GObjectMeta): """Meta class for easy setup of gtk tree models. @@ -167,13 +168,13 @@ class MetaModel (gobject.GObjectMeta): cls.name2 = 1 ... - Example: A gtk.ListStore derived model can use + Example: A Gtk.ListStore derived model can use columns = ("COL_NAME", str, "COL_VALUE", str) and use this in __init__: - gtk.ListStore.__init__ (self, *self.column_types) + GObject.GObject.__init__ (self, *self.column_types) Then insert data like this: @@ -497,10 +498,10 @@ class WindowState (object): def handle_window_state_event (self, window, event): - if not event.changed_mask & gtk.gdk.WINDOW_STATE_MAXIMIZED: + if not event.changed_mask & Gdk.WindowState.MAXIMIZED: return - if event.new_window_state & gtk.gdk.WINDOW_STATE_MAXIMIZED: + if event.new_window_state & Gdk.WindowState.MAXIMIZED: self.logger.debug ("maximized") self.is_maximized = True else: diff --git a/debug-viewer/GstDebugViewer/Common/Main.py b/debug-viewer/GstDebugViewer/Common/Main.py index 1cb1c7edf9..e7b759c9ae 100644 --- a/debug-viewer/GstDebugViewer/Common/Main.py +++ b/debug-viewer/GstDebugViewer/Common/Main.py @@ -28,11 +28,10 @@ import locale import gettext from gettext import gettext as _, ngettext -import pygtk -pygtk.require ("2.0") -del pygtk +import gi -import gobject +from gi.repository import GObject +from gi.repository import Gtk; class ExceptionHandler (object): @@ -305,8 +304,8 @@ class OptionParser (object): # Remaining args parsing with pygobject does not work with glib before # 2.13.2 (e.g. Ubuntu Feisty). - ## if gobject.glib_version >= (2, 13, 2,): - ## self.__entries.append ((gobject.OPTION_REMAINING, "\0", 0, "", "",)) + ## if GObject.glib_version >= (2, 13, 2,): + ## self.__entries.append ((GObject.OPTION_REMAINING, "\0", 0, "", "",)) def add_option (self, long_name, short_name = None, description = None, arg_name = None, arg_parser = None, hidden = False): @@ -321,12 +320,12 @@ class OptionParser (object): description = "" if arg_name is None: - flags |= gobject.OPTION_FLAG_NO_ARG + flags |= GObject.OPTION_FLAG_NO_ARG elif arg_parser is not None: self.__parsers[long_name] = arg_parser if hidden: - flags |= gobject.OPTION_FLAG_HIDDEN + flags |= GObject.OPTION_FLAG_HIDDEN self.__entries.append ((long_name, short_name, flags, description, arg_name,)) @@ -334,7 +333,7 @@ class OptionParser (object): def __handle_option (self, option, arg, group): # See __init__ for glib requirement. - ## if option == gobject.OPTION_REMAINING: + ## if option == GObject.OPTION_REMAINING: ## self.__remaining_args.append (arg) ## return @@ -356,14 +355,14 @@ class OptionParser (object): def parse (self, argv): - context = gobject.OptionContext (self.get_parameter_string ()) - group = gobject.OptionGroup (None, None, None, self.__handle_option) + context = GObject.OptionContext (self.get_parameter_string ()) + group = GObject.OptionGroup (None, None, None, self.__handle_option) context.set_main_group (group) group.add_entries (self.__entries) try: result_argv = context.parse (argv) - except gobject.GError as exc: + except GObject.GError as exc: raise OptionError (exc.message) self.__remaining_args = result_argv[1:] diff --git a/debug-viewer/GstDebugViewer/Common/__init__.py b/debug-viewer/GstDebugViewer/Common/__init__.py index 7adb873ef8..b03a5fd69f 100644 --- a/debug-viewer/GstDebugViewer/Common/__init__.py +++ b/debug-viewer/GstDebugViewer/Common/__init__.py @@ -20,3 +20,4 @@ """GStreamer Development Utilities Common package.""" import Data, GUI, Main, utils + diff --git a/debug-viewer/GstDebugViewer/Common/generictreemodel.py b/debug-viewer/GstDebugViewer/Common/generictreemodel.py new file mode 100644 index 0000000000..1c264901d0 --- /dev/null +++ b/debug-viewer/GstDebugViewer/Common/generictreemodel.py @@ -0,0 +1,418 @@ +# -*- Mode: Python; py-indent-offset: 4 -*- +# generictreemodel - GenericTreeModel implementation for pygtk compatibility. +# Copyright (C) 2013 Simon Feltman +# +# generictreemodel.py: GenericTreeModel implementation for pygtk compatibility +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see . + + +# System +import sys +import random +import collections +import ctypes + +# GObject +from gi.repository import GObject +from gi.repository import Gtk + + +class _CTreeIter(ctypes.Structure): + _fields_ = [('stamp', ctypes.c_int), + ('user_data', ctypes.c_void_p), + ('user_data2', ctypes.c_void_p), + ('user_data3', ctypes.c_void_p)] + + @classmethod + def from_iter(cls, iter): + offset = sys.getsizeof(object()) # size of PyObject_HEAD + return ctypes.POINTER(cls).from_address(id(iter) + offset) + + +def _get_user_data_as_pyobject(iter): + citer = _CTreeIter.from_iter(iter) + return ctypes.cast(citer.contents.user_data, ctypes.py_object).value + + +def handle_exception(default_return): + """Returns a function which can act as a decorator for wrapping exceptions and + returning "default_return" upon an exception being thrown. + + This is used to wrap Gtk.TreeModel "do_" method implementations so we can return + a proper value from the override upon an exception occurring with client code + implemented by the "on_" methods. + """ + def decorator(func): + def wrapped_func(*args, **kargs): + try: + return func(*args, **kargs) + except: + # Use excepthook directly to avoid any printing to the screen + # if someone installed an except hook. + sys.excepthook(*sys.exc_info()) + return default_return + return wrapped_func + return decorator + + +class GenericTreeModel(GObject.GObject, Gtk.TreeModel): + """A base implementation of a Gtk.TreeModel for python. + + The GenericTreeModel eases implementing the Gtk.TreeModel interface in Python. + The class can be subclassed to provide a TreeModel implementation which works + directly with Python objects instead of iterators. + + All of the on_* methods should be overridden by subclasses to provide the + underlying implementation a way to access custom model data. For the purposes of + this API, all custom model data supplied or handed back through the overridable + API will use the argument names: node, parent, and child in regards to user data + python objects. + + The create_tree_iter, set_user_data, invalidate_iters, iter_is_valid methods are + available to help manage Gtk.TreeIter objects and their Python object references. + + GenericTreeModel manages a pool of user data nodes that have been used with iters. + This pool stores a references to user data nodes as a dictionary value with the + key being the integer id of the data. This id is what the Gtk.TreeIter objects + use to reference data in the pool. + References will be removed from the pool when the model is deleted or explicitly + by using the optional "node" argument to the "row_deleted" method when notifying + the model of row deletion. + """ + + leak_references = GObject.Property(default=True, type=bool, + blurb="If True, strong references to user data attached to iters are " + "stored in a dictionary pool (default). Otherwise the user data is " + "stored as a raw pointer to a python object without a reference.") + + # + # Methods + # + def __init__(self): + """Initialize. Make sure to call this from derived classes if overridden.""" + super(GenericTreeModel, self).__init__() + self.stamp = 0 + + #: Dictionary of (id(user_data): user_data), used when leak-refernces=False + self._held_refs = dict() + + # Set initial stamp + self.invalidate_iters() + + def iter_depth_first(self): + """Depth-first iteration of the entire TreeModel yielding the python nodes.""" + stack = collections.deque([None]) + while stack: + it = stack.popleft() + if it is not None: + yield self.get_user_data(it) + children = [self.iter_nth_child(it, i) for i in range(self.iter_n_children(it))] + stack.extendleft(reversed(children)) + + def invalidate_iter(self, iter): + """Clear user data and its reference from the iter and this model.""" + iter.stamp = 0 + if iter.user_data: + if iter.user_data in self._held_refs: + del self._held_refs[iter.user_data] + iter.user_data = None + + def invalidate_iters(self): + """ + This method invalidates all TreeIter objects associated with this custom tree model + and frees their locally pooled references. + """ + self.stamp = random.randint(-2147483648, 2147483647) + self._held_refs.clear() + + def iter_is_valid(self, iter): + """ + :Returns: + True if the gtk.TreeIter specified by iter is valid for the custom tree model. + """ + return iter.stamp == self.stamp + + def get_user_data(self, iter): + """Get the user_data associated with the given TreeIter. + + GenericTreeModel stores arbitrary Python objects mapped to instances of Gtk.TreeIter. + This method allows to retrieve the Python object held by the given iterator. + """ + if self.leak_references: + return self._held_refs[iter.user_data] + else: + return _get_user_data_as_pyobject(iter) + + def set_user_data(self, iter, user_data): + """Applies user_data and stamp to the given iter. + + If the models "leak_references" property is set, a reference to the + user_data is stored with the model to ensure we don't run into bad + memory problems with the TreeIter. + """ + iter.user_data = id(user_data) + + if user_data is None: + self.invalidate_iter(iter) + else: + iter.stamp = self.stamp + if self.leak_references: + self._held_refs[iter.user_data] = user_data + + def create_tree_iter(self, user_data): + """Create a Gtk.TreeIter instance with the given user_data specific for this model. + + Use this method to create Gtk.TreeIter instance instead of directly calling + Gtk.Treeiter(), this will ensure proper reference managment of wrapped used_data. + """ + iter = Gtk.TreeIter() + self.set_user_data(iter, user_data) + return iter + + def _create_tree_iter(self, data): + """Internal creation of a (bool, TreeIter) pair for returning directly + back to the view interfacing with this model.""" + if data is None: + return (False, None) + else: + it = self.create_tree_iter(data) + return (True, it) + + def row_deleted(self, path, node=None): + """Notify the model a row has been deleted. + + Use the node parameter to ensure the user_data reference associated + with the path is properly freed by this model. + + :Parameters: + path : Gtk.TreePath + Path to the row that has been deleted. + node : object + Python object used as the node returned from "on_get_iter". This is + optional but ensures the model will not leak references to this object. + """ + super(GenericTreeModel, self).row_deleted(path) + node_id = id(node) + if node_id in self._held_refs: + del self._held_refs[node_id] + + # + # GtkTreeModel Interface Implementation + # + @handle_exception(0) + def do_get_flags(self): + """Internal method.""" + return self.on_get_flags() + + @handle_exception(0) + def do_get_n_columns(self): + """Internal method.""" + return self.on_get_n_columns() + + @handle_exception(GObject.TYPE_INVALID) + def do_get_column_type(self, index): + """Internal method.""" + return self.on_get_column_type(index) + + @handle_exception((False, None)) + def do_get_iter(self, path): + """Internal method.""" + return self._create_tree_iter(self.on_get_iter(path)) + + @handle_exception(False) + def do_iter_next(self, iter): + """Internal method.""" + if iter is None: + next_data = self.on_iter_next(None) + else: + next_data = self.on_iter_next(self.get_user_data(iter)) + + self.set_user_data(iter, next_data) + return next_data is not None + + @handle_exception(None) + def do_get_path(self, iter): + """Internal method.""" + path = self.on_get_path(self.get_user_data(iter)) + if path is None: + return None + else: + return Gtk.TreePath(path) + + @handle_exception(None) + def do_get_value(self, iter, column): + """Internal method.""" + return self.on_get_value(self.get_user_data(iter), column) + + @handle_exception((False, None)) + def do_iter_children(self, parent): + """Internal method.""" + data = self.get_user_data(parent) if parent else None + return self._create_tree_iter(self.on_iter_children(data)) + + @handle_exception(False) + def do_iter_has_child(self, parent): + """Internal method.""" + return self.on_iter_has_child(self.get_user_data(parent)) + + @handle_exception(0) + def do_iter_n_children(self, iter): + """Internal method.""" + if iter is None: + return self.on_iter_n_children(None) + return self.on_iter_n_children(self.get_user_data(iter)) + + @handle_exception((False, None)) + def do_iter_nth_child(self, parent, n): + """Internal method.""" + if parent is None: + data = self.on_iter_nth_child(None, n) + else: + data = self.on_iter_nth_child(self.get_user_data(parent), n) + return self._create_tree_iter(data) + + @handle_exception((False, None)) + def do_iter_parent(self, child): + """Internal method.""" + return self._create_tree_iter(self.on_iter_parent(self.get_user_data(child))) + + @handle_exception(None) + def do_ref_node(self, iter): + self.on_ref_node(self.get_user_data(iter)) + + @handle_exception(None) + def do_unref_node(self, iter): + self.on_unref_node(self.get_user_data(iter)) + + # + # Python Subclass Overridables + # + def on_get_flags(self): + """Overridable. + + :Returns Gtk.TreeModelFlags: + The flags for this model. See: Gtk.TreeModelFlags + """ + raise NotImplementedError + + def on_get_n_columns(self): + """Overridable. + + :Returns: + The number of columns for this model. + """ + raise NotImplementedError + + def on_get_column_type(self, index): + """Overridable. + + :Returns: + The column type for the given index. + """ + raise NotImplementedError + + def on_get_iter(self, path): + """Overridable. + + :Returns: + A python object (node) for the given TreePath. + """ + raise NotImplementedError + + def on_iter_next(self, node): + """Overridable. + + :Parameters: + node : object + Node at current level. + + :Returns: + A python object (node) following the given node at the current level. + """ + raise NotImplementedError + + def on_get_path(self, node): + """Overridable. + + :Returns: + A TreePath for the given node. + """ + raise NotImplementedError + + def on_get_value(self, node, column): + """Overridable. + + :Parameters: + node : object + column : int + Column index to get the value from. + + :Returns: + The value of the column for the given node.""" + raise NotImplementedError + + def on_iter_children(self, parent): + """Overridable. + + :Returns: + The first child of parent or None if parent has no children. + If parent is None, return the first node of the model. + """ + raise NotImplementedError + + def on_iter_has_child(self, node): + """Overridable. + + :Returns: + True if the given node has children. + """ + raise NotImplementedError + + def on_iter_n_children(self, node): + """Overridable. + + :Returns: + The number of children for the given node. If node is None, + return the number of top level nodes. + """ + raise NotImplementedError + + def on_iter_nth_child(self, parent, n): + """Overridable. + + :Parameters: + parent : object + n : int + Index of child within parent. + + :Returns: + The child for the given parent index starting at 0. If parent None, + return the top level node corresponding to "n". + If "n" is larger then available nodes, return None. + """ + raise NotImplementedError + + def on_iter_parent(self, child): + """Overridable. + + :Returns: + The parent node of child or None if child is a top level node.""" + raise NotImplementedError + + def on_ref_node(self, node): + pass + + def on_unref_node(self, node): + pass diff --git a/debug-viewer/GstDebugViewer/Data.py b/debug-viewer/GstDebugViewer/Data.py index 22616457ce..1358716a3e 100644 --- a/debug-viewer/GstDebugViewer/Data.py +++ b/debug-viewer/GstDebugViewer/Data.py @@ -23,7 +23,7 @@ import os import logging import re -# Nanosecond resolution (like gst.SECOND) +# Nanosecond resolution (like Gst.SECOND) SECOND = 1000000000 def time_args (ts): diff --git a/debug-viewer/GstDebugViewer/GUI/__init__.py b/debug-viewer/GstDebugViewer/GUI/__init__.py index a3e3dd3e39..1db2be179d 100644 --- a/debug-viewer/GstDebugViewer/GUI/__init__.py +++ b/debug-viewer/GstDebugViewer/GUI/__init__.py @@ -22,9 +22,7 @@ __author__ = u"René Stadler " __version__ = "0.1" -import pygtk -pygtk.require ("2.0") -del pygtk +import gi from GstDebugViewer.GUI.app import App diff --git a/debug-viewer/GstDebugViewer/GUI/app.py b/debug-viewer/GstDebugViewer/GUI/app.py index da51149fbd..b1b1e985c2 100644 --- a/debug-viewer/GstDebugViewer/GUI/app.py +++ b/debug-viewer/GstDebugViewer/GUI/app.py @@ -21,8 +21,8 @@ import os.path -import gobject -import gtk +from gi.repository import GObject +from gi.repository import Gtk from GstDebugViewer import Common from GstDebugViewer.GUI.columns import ViewColumnManager @@ -94,7 +94,7 @@ class App (object): widget "*.log_view" style "no-expander-treeview-style" """ - gtk.rc_parse_string (rcstring) + Gtk.rc_parse_string (rcstring) self.open_window () @@ -107,7 +107,7 @@ class App (object): def run (self): try: - Common.Main.MainLoopWrapper (gtk.main, gtk.main_quit).run () + Common.Main.MainLoopWrapper (Gtk.main, Gtk.main_quit).run () except: raise else: @@ -123,7 +123,7 @@ class App (object): if not self.windows: # GtkTreeView takes some time to go down for large files. Let's block # until the window is hidden: - gobject.idle_add (gtk.main_quit) - gtk.main () + GObject.idle_add (Gtk.main_quit) + Gtk.main () - gtk.main_quit () + Gtk.main_quit () diff --git a/debug-viewer/GstDebugViewer/GUI/colors.py b/debug-viewer/GstDebugViewer/GUI/colors.py index 307ec237a5..c5bdddabaa 100644 --- a/debug-viewer/GstDebugViewer/GUI/colors.py +++ b/debug-viewer/GstDebugViewer/GUI/colors.py @@ -19,7 +19,8 @@ """GStreamer Debug Viewer GUI module.""" -import gtk +from gi.repository import Gtk +from gi.repository import Gdk from GstDebugViewer import Data @@ -36,7 +37,7 @@ class Color (object): def gdk_color (self): - return gtk.gdk.color_parse (self.hex_string ()) + return Gdk.color_parse (self.hex_string ()) def hex_string (self): diff --git a/debug-viewer/GstDebugViewer/GUI/columns.py b/debug-viewer/GstDebugViewer/GUI/columns.py index 2dc221d26a..d06b4c4f61 100644 --- a/debug-viewer/GstDebugViewer/GUI/columns.py +++ b/debug-viewer/GstDebugViewer/GUI/columns.py @@ -25,7 +25,7 @@ def _ (s): import logging import glib -import gtk +from gi.repository import Gtk from GstDebugViewer import Common, Data from GstDebugViewer.GUI.colors import LevelColorThemeTango @@ -45,7 +45,7 @@ class Column (object): def __init__ (self): - view_column = gtk.TreeViewColumn (self.label_header) + view_column = Gtk.TreeViewColumn (self.label_header) view_column.props.reorderable = True self.view_column = view_column @@ -68,8 +68,8 @@ class TextColumn (SizedColumn): Column.__init__ (self) column = self.view_column - cell = gtk.CellRendererText () - column.pack_start (cell) + cell = Gtk.CellRendererText () + column.pack_start (cell, True) cell.props.yalign = 0. cell.props.ypad = 0 @@ -83,7 +83,7 @@ class TextColumn (SizedColumn): assert data_func id_ = self.id if id_ is not None: - def cell_data_func (column, cell, model, tree_iter): + def cell_data_func (column, cell, model, tree_iter, user_data): data_func (cell.props, model.get_value (tree_iter, id_)) else: cell_data_func = data_func @@ -99,7 +99,7 @@ class TextColumn (SizedColumn): modify_func = self.get_modify_func () id_ = self.id - def cell_data_func (column, cell, model, tree_iter): + def cell_data_func (column, cell, model, tree_iter, user_data): cell.props.text = modify_func (model.get_value (tree_iter, id_)) column.set_cell_data_func (cell, cell_data_func) @@ -109,7 +109,7 @@ class TextColumn (SizedColumn): if not values: return SizedColumn.compute_default_size (self) - cell = self.view_column.get_cell_renderers ()[0] + cell = self.view_column.get_cells ()[0] if self.get_modify_func is not None: format = self.get_modify_func () @@ -120,7 +120,7 @@ class TextColumn (SizedColumn): max_width = 0 for value in values: cell.props.text = format (value) - rect, x, y, w, h = self.view_column.cell_get_size () + x, y, w, h = self.view_column.cell_get_size () max_width = max (max_width, w) return max_width @@ -171,7 +171,7 @@ class TimeColumn (TextColumn): self.base_time = base_time column = self.view_column - cell = column.get_cell_renderers ()[0] + cell = column.get_cells ()[0] self.update_modify_func (column, cell) class LevelColumn (TextColumn): @@ -184,7 +184,7 @@ class LevelColumn (TextColumn): TextColumn.__init__ (self) - cell = self.view_column.get_cell_renderers ()[0] + cell = self.view_column.get_cells ()[0] cell.props.xalign = .5 @staticmethod @@ -278,7 +278,7 @@ class CodeColumn (TextColumn): filename_id = LogModelBase.COL_FILENAME line_number_id = LogModelBase.COL_LINE_NUMBER - def filename_data_func (column, cell, model, tree_iter): + def filename_data_func (column, cell, model, tree_iter, user_data): args = model.get (tree_iter, filename_id, line_number_id) cell.props.text = "%s:%i" % args @@ -325,7 +325,7 @@ class MessageColumn (TextColumn): highlighters = self.highlighters id_ = LazyLogModel.COL_MESSAGE - def message_data_func (column, cell, model, tree_iter): + def message_data_func (column, cell, model, tree_iter, user_data): msg = model.get_value (tree_iter, id_) @@ -382,7 +382,7 @@ class ColumnManager (Common.GUI.Manager): self.columns = [] self.column_order = list (self.column_classes) - self.action_group = gtk.ActionGroup ("ColumnActions") + self.action_group = Gtk.ActionGroup ("ColumnActions") def make_entry (col_class): return ("show-%s-column" % (col_class.name,), @@ -449,12 +449,12 @@ class ColumnManager (Common.GUI.Manager): self.default_sort = tree_sortable_get_sort_column_id (sort_model) sort_model.set_sort_column_id (TREE_SORTABLE_UNSORTED_COLUMN_ID, - gtk.SORT_ASCENDING) + Gtk.SortType.ASCENDING) def set_zoom (self, scale): for column in self.columns: - cell = column.view_column.get_cell_renderers ()[0] + cell = column.view_column.get_cells ()[0] cell.props.scale = scale column.view_column.queue_resize () @@ -485,9 +485,9 @@ class ColumnManager (Common.GUI.Manager): pos = self.__get_column_insert_position (column) if self.view.props.fixed_height_mode: - column.view_column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED + column.view_column.props.sizing = Gtk.TreeViewColumnSizing.FIXED - cell = column.view_column.get_cell_renderers ()[0] + cell = column.view_column.get_cells ()[0] cell.props.scale = self.zoom self.columns.insert (pos, column) @@ -672,7 +672,7 @@ class WrappingMessageColumn (MessageColumn): col = self.view_column col.props.max_width = width - col.get_cell_renderers ()[0].props.wrap_width = width + col.get_cells ()[0].props.wrap_width = width col.queue_resize () class LineViewColumnManager (ColumnManager): diff --git a/debug-viewer/GstDebugViewer/GUI/models.py b/debug-viewer/GstDebugViewer/GUI/models.py index 3d8a0bb189..79601504be 100644 --- a/debug-viewer/GstDebugViewer/GUI/models.py +++ b/debug-viewer/GstDebugViewer/GUI/models.py @@ -23,18 +23,19 @@ from array import array from bisect import bisect_left import logging -import gobject -import gtk +from gi.repository import GObject +from gi.repository import Gtk from GstDebugViewer import Common, Data -class LogModelBase (gtk.GenericTreeModel): + +class LogModelBase (Common.GUI.GenericTreeModel): __metaclass__ = Common.GUI.MetaModel - columns = ("COL_TIME", gobject.TYPE_UINT64, + columns = ("COL_TIME", GObject.TYPE_UINT64, "COL_PID", int, - "COL_THREAD", gobject.TYPE_UINT64, + "COL_THREAD", GObject.TYPE_UINT64, "COL_LEVEL", object, "COL_CATEGORY", str, "COL_FILENAME", str, @@ -45,7 +46,7 @@ class LogModelBase (gtk.GenericTreeModel): def __init__ (self): - gtk.GenericTreeModel.__init__ (self) + Common.GUI.GenericTreeModel.__init__ (self) ##self.props.leak_references = False @@ -76,7 +77,7 @@ class LogModelBase (gtk.GenericTreeModel): def on_get_flags (self): - flags = gtk.TREE_MODEL_LIST_ONLY | gtk.TREE_MODEL_ITERS_PERSIST + flags = Gtk.TreeModelFlags.LIST_ONLY | Gtk.TreeModelFlags.ITERS_PERSIST return flags diff --git a/debug-viewer/GstDebugViewer/GUI/window.py b/debug-viewer/GstDebugViewer/GUI/window.py index b025fb17c5..a0b267d892 100644 --- a/debug-viewer/GstDebugViewer/GUI/window.py +++ b/debug-viewer/GstDebugViewer/GUI/window.py @@ -29,8 +29,9 @@ from bisect import bisect_right, bisect_left import logging import glib -import gobject -import gtk +from gi.repository import GObject +from gi.repository import Gtk +from gi.repository import Gdk from GstDebugViewer import Common, Data, Main from GstDebugViewer.GUI.columns import LineViewColumnManager, ViewColumnManager @@ -180,16 +181,16 @@ class ProgressDialog (object): def __init__ (self, window, title = ""): - bar = gtk.InfoBar () - bar.props.message_type = gtk.MESSAGE_INFO + bar = Gtk.InfoBar () + bar.props.message_type = Gtk.MessageType.INFO bar.connect ("response", self.__handle_info_bar_response) - bar.add_button (gtk.STOCK_CANCEL, 1) + bar.add_button (Gtk.STOCK_CANCEL, 1) area_box = bar.get_content_area () - box = gtk.HBox (spacing = 8) + box = Gtk.HBox (spacing = 8) - box.pack_start (gtk.Label (title), False, False, 0) + box.pack_start (Gtk.Label(label=title), False, False, 0) - progress = gtk.ProgressBar () + progress = Gtk.ProgressBar () box.pack_start (progress, False, False, 0) area_box.pack_start (box, False, False, 0) @@ -229,7 +230,7 @@ class Window (object): self.actions = Common.GUI.Actions () - group = gtk.ActionGroup ("MenuActions") + group = Gtk.ActionGroup ("MenuActions") group.add_actions ([("AppMenuAction", None, _("_Application")), ("ViewMenuAction", None, _("_View")), ("ViewColumnsMenuAction", None, _("_Columns")), @@ -237,26 +238,26 @@ class Window (object): ("LineViewContextMenuAction", None, "")]) self.actions.add_group (group) - group = gtk.ActionGroup ("WindowActions") - group.add_actions ([("new-window", gtk.STOCK_NEW, _("_New Window"), "N"), - ("open-file", gtk.STOCK_OPEN, _("_Open File"), "O"), - ("reload-file", gtk.STOCK_REFRESH, _("_Reload File"), "R"), - ("close-window", gtk.STOCK_CLOSE, _("Close _Window"), "W"), - ("cancel-load", gtk.STOCK_CANCEL, None,), - ("clear-line-view", gtk.STOCK_CLEAR, None), + group = Gtk.ActionGroup ("WindowActions") + group.add_actions ([("new-window", Gtk.STOCK_NEW, _("_New Window"), "N"), + ("open-file", Gtk.STOCK_OPEN, _("_Open File"), "O"), + ("reload-file", Gtk.STOCK_REFRESH, _("_Reload File"), "R"), + ("close-window", Gtk.STOCK_CLOSE, _("Close _Window"), "W"), + ("cancel-load", Gtk.STOCK_CANCEL, None,), + ("clear-line-view", Gtk.STOCK_CLEAR, None), ("show-about", None, _("About GStreamer Debug Viewer",)), - ("enlarge-text", gtk.STOCK_ZOOM_IN, _("Enlarge Text"), "plus"), - ("shrink-text", gtk.STOCK_ZOOM_OUT, _("Shrink Text"), "minus"), - ("reset-text", gtk.STOCK_ZOOM_100, _("Normal Text Size"), "0")]) + ("enlarge-text", Gtk.STOCK_ZOOM_IN, _("Enlarge Text"), "plus"), + ("shrink-text", Gtk.STOCK_ZOOM_OUT, _("Shrink Text"), "minus"), + ("reset-text", Gtk.STOCK_ZOOM_100, _("Normal Text Size"), "0")]) self.actions.add_group (group) self.actions.reload_file.props.sensitive = False - group = gtk.ActionGroup ("RowActions") + group = Gtk.ActionGroup ("RowActions") group.add_actions ([("hide-before-line", None, _("Hide lines before this point")), ("hide-after-line", None, _("Hide lines after this point")), ("show-hidden-lines", None, _("Show hidden lines")), - ("edit-copy-line", gtk.STOCK_COPY, _("Copy line"), "C"), - ("edit-copy-message", gtk.STOCK_COPY, _("Copy message"), ""), + ("edit-copy-line", Gtk.STOCK_COPY, _("Copy line"), "C"), + ("edit-copy-message", Gtk.STOCK_COPY, _("Copy message"), ""), ("set-base-time", None, _("Set base time")), ("hide-log-level", None, _("Hide log level")), ("hide-log-category", None, _("Hide log category")), @@ -327,8 +328,8 @@ class Window (object): self.window_state.attach (window = self.gtk_window, state = self.app.state_section) - self.clipboard = gtk.Clipboard (self.gtk_window.get_display (), - gtk.gdk.SELECTION_CLIPBOARD) + self.clipboard = Gtk.Clipboard.get_for_display (self.gtk_window.get_display (), + Gdk.SELECTION_CLIPBOARD) for action_name, handler in iter_actions (self): action = getattr (self.actions, action_name) @@ -348,7 +349,7 @@ class Window (object): # FIXME: With multiple selection mode, browsing the list with key # up/down slows to a crawl! WTF is wrong with this stupid widget??? sel = self.log_view.get_selection () - sel.set_mode (gtk.SELECTION_BROWSE) + sel.set_mode (Gtk.SelectionMode.BROWSE) self.line_view.attach (self) @@ -515,13 +516,13 @@ class Window (object): @action def handle_open_file_action_activate (self, action): - dialog = gtk.FileChooserDialog (None, self.gtk_window, - gtk.FILE_CHOOSER_ACTION_OPEN, - (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, - gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT,)) + dialog = Gtk.FileChooserDialog (None, self.gtk_window, + Gtk.FileChooserAction.OPEN, + (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, + Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT,)) response = dialog.run () dialog.hide () - if response == gtk.RESPONSE_ACCEPT: + if response == Gtk.ResponseType.ACCEPT: self.set_log_file (dialog.get_filename ()) dialog.destroy () @@ -544,7 +545,7 @@ class Window (object): self.hide_info () self.progress_dialog = None if self.update_progress_id is not None: - gobject.source_remove (self.update_progress_id) + GObject.source_remove (self.update_progress_id) self.update_progress_id = None self.set_sensitive (True) @@ -699,7 +700,7 @@ class Window (object): self.log_view.set_model (None) self.log_filter.add_filter (filter, dispatcher = dispatcher) - gobject.timeout_add (250, self.update_filter_progress) + GObject.timeout_add (250, self.update_filter_progress) self.set_sensitive (False) @@ -845,13 +846,13 @@ class Window (object): def show_error (self, message1, message2): - bar = gtk.InfoBar () - bar.props.message_type = gtk.MESSAGE_ERROR + bar = Gtk.InfoBar () + bar.props.message_type = Gtk.MessageType.ERROR box = bar.get_content_area () markup = "%s %s" % (glib.markup_escape_text (message1), glib.markup_escape_text (message2),) - label = gtk.Label () + label = Gtk.Label () label.props.use_markup = True label.props.label = markup label.props.selectable = True @@ -866,7 +867,7 @@ class Window (object): self.progress_dialog = ProgressDialog (self, _("Loading log file")) self.show_info (self.progress_dialog.widget) self.progress_dialog.handle_cancel = self.handle_load_progress_dialog_cancel - self.update_progress_id = gobject.timeout_add (250, self.update_load_progress) + self.update_progress_id = GObject.timeout_add (250, self.update_load_progress) self.set_sensitive (False) @@ -917,4 +918,4 @@ class Window (object): sel.select_path ((0,)) return False - gobject.idle_add (idle_set) + GObject.idle_add (idle_set) diff --git a/debug-viewer/GstDebugViewer/Plugins/FileProperties.py b/debug-viewer/GstDebugViewer/Plugins/FileProperties.py index 7c9383bbd0..34b8d8c3be 100644 --- a/debug-viewer/GstDebugViewer/Plugins/FileProperties.py +++ b/debug-viewer/GstDebugViewer/Plugins/FileProperties.py @@ -21,13 +21,13 @@ from GstDebugViewer.Plugins import * import logging -import gtk +from gi.repository import Gtk class FilePropertiesSentinel (object): pass -class FilePropertiesDialog (gtk.Dialog): +class FilePropertiesDialog (Gtk.Dialog): pass @@ -35,8 +35,8 @@ class FilePropertiesFeature (FeatureBase): def __init__ (self, *a, **kw): - self.action_group = gtk.ActionGroup ("FilePropertiesActions") - self.action_group.add_actions ([("show-file-properties", gtk.STOCK_PROPERTIES, + self.action_group = Gtk.ActionGroup ("FilePropertiesActions") + self.action_group.add_actions ([("show-file-properties", Gtk.STOCK_PROPERTIES, _("_Properties"), "P")]) def attach (self, window): @@ -47,7 +47,7 @@ class FilePropertiesFeature (FeatureBase): self.merge_id = ui.new_merge_id () ui.add_ui (self.merge_id, "/menubar/FileMenu/FileMenuAdditions", "FileProperties", "show-file-properties", - gtk.UI_MANAGER_MENUITEM, False) + Gtk.UIManagerItemType.MENUITEM, False) handler = self.handle_action_activate self.action_group.get_action ("show-file-properties").connect ("activate", handler) diff --git a/debug-viewer/GstDebugViewer/Plugins/FindBar.py b/debug-viewer/GstDebugViewer/Plugins/FindBar.py index 22462dc93a..60a146b8f8 100644 --- a/debug-viewer/GstDebugViewer/Plugins/FindBar.py +++ b/debug-viewer/GstDebugViewer/Plugins/FindBar.py @@ -25,7 +25,8 @@ from GstDebugViewer import Common, Data, GUI from GstDebugViewer.Plugins import * import glib -import gtk +from gi.repository import GObject +from gi.repository import Gtk class SearchOperation (object): @@ -127,32 +128,32 @@ class SearchSentinel (object): pass -class FindBarWidget (gtk.HBox): +class FindBarWidget (Gtk.HBox): __status = {"no-match-found" : _N("No match found"), "searching" : _N("Searching...")} def __init__ (self, action_group): - gtk.HBox.__init__ (self) + GObject.GObject.__init__ (self) - label = gtk.Label (_("Find:")) + label = Gtk.Label(label=_("Find:")) self.pack_start (label, False, False, 2) - self.entry = gtk.Entry () - self.pack_start (self.entry) + self.entry = Gtk.Entry () + self.pack_start (self.entry, True, True, 0) prev_action = action_group.get_action ("goto-previous-search-result") - prev_button = gtk.Button () - prev_action.connect_proxy (prev_button) + prev_button = Gtk.Button () + prev_button.set_related_action (prev_action) self.pack_start (prev_button, False, False, 0) next_action = action_group.get_action ("goto-next-search-result") - next_button = gtk.Button () - next_action.connect_proxy (next_button) + next_button = Gtk.Button () + next_button.set_related_action (next_action) self.pack_start (next_button, False, False, 0) - self.status_label = gtk.Label () + self.status_label = Gtk.Label () self.status_label.props.xalign = 0. self.status_label.props.use_markup = True self.pack_start (self.status_label, False, False, 6) @@ -170,8 +171,8 @@ class FindBarWidget (gtk.HBox): try: for status in self.__status.values (): self.__set_status (_(status)) - width, height = label.size_request () - max_width = max (max_width, width) + req = label.size_request () + max_width = max (max_width, req.width) label.set_size_request (max_width, -1) finally: label.props.label = old_markup @@ -206,7 +207,7 @@ class FindBarFeature (FeatureBase): self.logger = logging.getLogger ("ui.findbar") - self.action_group = gtk.ActionGroup ("FindBarActions") + self.action_group = Gtk.ActionGroup ("FindBarActions") self.action_group.add_toggle_actions ([("show-find-bar", None, _("Find Bar"), @@ -233,7 +234,7 @@ class FindBarFeature (FeatureBase): view = self.log_view - path = (line_index,) + path = Gtk.TreePath((line_index,)) start_path, end_path = view.get_visible_range () @@ -259,7 +260,7 @@ class FindBarFeature (FeatureBase): ("ViewNextResult", "goto-next-search-result",), ("ViewPrevResult", "goto-previous-search-result",)]: ui.add_ui (self.merge_id, "/menubar/ViewMenu/ViewMenuAdditions", - name, action_name, gtk.UI_MANAGER_MENUITEM, False) + name, action_name, Gtk.UIManagerItemType.MENUITEM, False) box = window.widgets.vbox_view self.bar = FindBarWidget (self.action_group) diff --git a/debug-viewer/GstDebugViewer/Plugins/Timeline.py b/debug-viewer/GstDebugViewer/Plugins/Timeline.py index a87a99ae81..127ccf8f37 100644 --- a/debug-viewer/GstDebugViewer/Plugins/Timeline.py +++ b/debug-viewer/GstDebugViewer/Plugins/Timeline.py @@ -25,8 +25,9 @@ from GstDebugViewer import Common, Data from GstDebugViewer.GUI.colors import LevelColorThemeTango, ThreadColorThemeTango from GstDebugViewer.Plugins import * -import gobject -import gtk +from gi.repository import GObject +from gi.repository import Gtk +from gi.repository import Gdk import cairo def iter_model_reversed (model): @@ -267,13 +268,13 @@ class UpdateProcess (object): pass -class VerticalTimelineWidget (gtk.DrawingArea): +class VerticalTimelineWidget (Gtk.DrawingArea): __gtype_name__ = "GstDebugViewerVerticalTimelineWidget" def __init__ (self, log_view): - gtk.DrawingArea.__init__ (self) + GObject.GObject.__init__ (self) self.logger = logging.getLogger ("ui.vtimeline") @@ -306,7 +307,11 @@ class VerticalTimelineWidget (gtk.DrawingArea): def __draw (self, drawable): ctx = drawable.cairo_create () - x, y, w, h = self.get_allocation () + alloc = self.get_allocation () + x = alloc.x + y = alloc.y + w = alloc.width + h = alloc.height # White background rectangle. ctx.set_line_width (0.) @@ -419,23 +424,23 @@ class VerticalTimelineWidget (gtk.DrawingArea): self.params = None self.queue_draw () -class TimelineWidget (gtk.DrawingArea): +class TimelineWidget (Gtk.DrawingArea): __gtype_name__ = "GstDebugViewerTimelineWidget" - __gsignals__ = {"change-position" : (gobject.SIGNAL_RUN_LAST, - gobject.TYPE_NONE, - (gobject.TYPE_INT,),)} + __gsignals__ = {"change-position" : (GObject.SignalFlags.RUN_LAST, + None, + (GObject.TYPE_INT,),)} def __init__ (self): - gtk.DrawingArea.__init__ (self) + GObject.GObject.__init__ (self) self.logger = logging.getLogger ("ui.timeline") - self.add_events (gtk.gdk.BUTTON1_MOTION_MASK | - gtk.gdk.BUTTON_PRESS_MASK | - gtk.gdk.BUTTON_RELEASE_MASK) + self.add_events (Gdk.EventMask.BUTTON1_MOTION_MASK | + Gdk.EventMask.BUTTON_PRESS_MASK | + Gdk.EventMask.BUTTON_RELEASE_MASK) self.process = UpdateProcess (None, None) self.process.handle_sentinel_progress = self.__handle_sentinel_progress @@ -473,22 +478,22 @@ class TimelineWidget (gtk.DrawingArea): def __ensure_offscreen (self): - x, y, width, height = self.get_allocation () - if self.__offscreen_size == (width, height): + alloc = self.get_allocation () + if self.__offscreen_size == (alloc.width, alloc.height): return - self.__offscreen = gtk.gdk.Pixmap (self.window, width, height, -1) - self.__offscreen_size = (width, height) - self.__offscreen_dirty = (0, width) + self.__offscreen = Gdk.Pixmap (self.window, alloc.width, alloc.height, -1) + self.__offscreen_size = (alloc.width, alloc.height) + self.__offscreen_dirty = (0, alloc.width) if not self.__offscreen: self.__offscreen_size = (0, 0) raise ValueError ("could not obtain pixmap") def __invalidate_offscreen (self, start, stop): - x, y, width, height = self.get_allocation () + alloc = self.get_allocation () if stop < 0: - stop += width + stop += alloc.width dirty_start, dirty_stop = self.__offscreen_dirty if dirty_start != dirty_stop: @@ -502,22 +507,22 @@ class TimelineWidget (gtk.DrawingArea): # Just like in __draw_offscreen. FIXME: Need this in one place! start -= 8 stop += 8 - self.queue_draw_area (start, 0, stop - start, height) + self.queue_draw_area (start, 0, stop - start, alloc.height) def __draw_from_offscreen (self, rect = None): if not self.props.visible: return - x, y, width, height = self.get_allocation () + alloc = self.get_allocation () offscreen_width, offscreen_height = self.__offscreen_size if rect is None: - rect = (0, 0, width, height) + rect = (0, 0, alloc.width, alloc.height) # Fill the background (where the offscreen pixmap doesn't fit) with # white. This happens after enlarging the window, until all sentinels # have finished running. - if offscreen_width < width or offscreen_height < height: + if offscreen_width < alloc.width or offscreen_height < alloc.height: ctx = self.window.cairo_create () if rect: @@ -526,17 +531,17 @@ class TimelineWidget (gtk.DrawingArea): rect.y + rect.height) ctx.clip () - if offscreen_width < width: - ctx.rectangle (offscreen_width, 0, width, offscreen_height) - if offscreen_height < height: + if offscreen_width < alloc.width: + ctx.rectangle (offscreen_width, 0, alloc.width, offscreen_height) + if offscreen_height < alloc.height: ctx.new_path () - ctx.rectangle (0, offscreen_height, width, height) + ctx.rectangle (0, offscreen_height, alloc.width, alloc.height) ctx.set_line_width (0.) ctx.set_source_rgb (1., 1., 1.) ctx.fill () - gc = gtk.gdk.GC (self.window) + gc = Gdk.GC (self.window) x, y, width, height = rect self.window.draw_drawable (gc, self.__offscreen, x, y, x, y, width, height) self.__draw_position (self.window, clip = rect) @@ -550,7 +555,7 @@ class TimelineWidget (gtk.DrawingArea): self.__dist_sentinel_progress = 0 self.process.freq_sentinel = LineFrequencySentinel (model) self.process.dist_sentinel = LevelDistributionSentinel (self.process.freq_sentinel, model) - width = self.get_allocation ()[2] + width = self.get_allocation ().width self.process.freq_sentinel.run_for (width) self.process.run () @@ -570,15 +575,15 @@ class TimelineWidget (gtk.DrawingArea): if not self.process.freq_sentinel.data: return - x, y, width, height = self.get_allocation () + alloc = self.get_allocation () # Queue old position rectangle for redraw: if self.__position_ts_range is not None: start, stop = self.ts_range_to_position (*self.__position_ts_range) - self.queue_draw_area (start - 1, 0, stop - start + 2, height) + self.queue_draw_area (start - 1, 0, stop - start + 2, alloc.height) # And the new one: start, stop = self.ts_range_to_position (start_ts, end_ts) - self.queue_draw_area (start - 1, 0, stop - start + 2, height) + self.queue_draw_area (start - 1, 0, stop - start + 2, alloc.height) self.__position_ts_range = (start_ts, end_ts,) @@ -766,7 +771,7 @@ class TimelineWidget (gtk.DrawingArea): return ctx = drawable.cairo_create () - x, y, width, height = self.get_allocation () + height = self.get_allocation ().height if clip: ctx.rectangle (*clip) @@ -840,13 +845,13 @@ class TimelineWidget (gtk.DrawingArea): x, y, mod = self.window.get_pointer () - if event.state & gtk.gdk.BUTTON1_MASK: + if event.get_state() & Gdk.ModifierType.BUTTON1_MASK: self.emit ("change-position", int (x)) - gtk.gdk.event_request_motions (event) + Gdk.event_request_motions (event) return True else: self._handle_motion (x, y) - gtk.gdk.event_request_motions (event) + Gdk.event_request_motions (event) return False def _handle_motion (self, x, y): @@ -868,18 +873,18 @@ class AttachedWindow (object): self.merge_id = ui.new_merge_id () ui.add_ui (self.merge_id, "/menubar/ViewMenu/ViewMenuAdditions", "ViewTimeline", "show-timeline", - gtk.UI_MANAGER_MENUITEM, False) + Gtk.UIManagerItemType.MENUITEM, False) ui.add_ui (self.merge_id, "/", "TimelineContextMenu", None, - gtk.UI_MANAGER_POPUP, False) + Gtk.UIManagerItemType.POPUP, False) # TODO: Make hide before/after operate on the partition that the mouse # is pointed at instead of the currently selected line. # ui.add_ui (self.merge_id, "/TimelineContextMenu", "TimelineHideLinesBefore", - # "hide-before-line", gtk.UI_MANAGER_MENUITEM, False) + # "hide-before-line", Gtk.UIManagerItemType.MENUITEM, False) # ui.add_ui (self.merge_id, "/TimelineContextMenu", "TimelineHideLinesAfter", - # "hide-after-line", gtk.UI_MANAGER_MENUITEM, False) + # "hide-after-line", Gtk.UIManagerItemType.MENUITEM, False) ui.add_ui (self.merge_id, "/TimelineContextMenu", "TimelineShowHiddenLines", - "show-hidden-lines", gtk.UI_MANAGER_MENUITEM, False) + "show-hidden-lines", Gtk.UIManagerItemType.MENUITEM, False) box = window.get_top_attach_point () @@ -928,7 +933,7 @@ class AttachedWindow (object): self.idle_scroll_path = None if self.idle_scroll_id is not None: - gobject.source_remove (self.idle_scroll_id) + GObject.source_remove (self.idle_scroll_id) self.idle_scroll_id = None def handle_detach_log_file (self, log_file): @@ -953,7 +958,7 @@ class AttachedWindow (object): self.update_timeline_position () self.vtimeline.update () return False - gobject.idle_add (idle_update, priority = gobject.PRIORITY_LOW) + GObject.idle_add (idle_update, priority = GObject.PRIORITY_LOW) def handle_log_view_adjustment_value_changed (self, adj): @@ -1016,7 +1021,7 @@ class AttachedWindow (object): self.idle_scroll_path = path if self.idle_scroll_id is None: - self.idle_scroll_id = gobject.idle_add (self.idle_scroll) + self.idle_scroll_id = GObject.idle_add (self.idle_scroll) return False @@ -1041,7 +1046,7 @@ class TimelineFeature (FeatureBase): self.logger = logging.getLogger ("ui.timeline") - self.action_group = gtk.ActionGroup ("TimelineActions") + self.action_group = Gtk.ActionGroup ("TimelineActions") self.action_group.add_toggle_actions ([("show-timeline", None, _("_Timeline"),)]) diff --git a/debug-viewer/README b/debug-viewer/README new file mode 100644 index 0000000000..3c5acd2e97 --- /dev/null +++ b/debug-viewer/README @@ -0,0 +1,28 @@ +# how to build # + +./setup.py build; sudo ./setup.py install --prefix=/usr +sudo chmod a+r /usr/share/gst-debug-viewer/*.ui + +# porting issues # + +http://stackoverflow.com/questions/11025700/generictreemodel-with-pygobject-introspection-gtk-3 + +# tips # + +OLD: prev_action.connect_proxy(prev_button) +NEW: prev_button.set_related_action (prev_action) + +OLD: box.pack_start (widget) +NEW: box.pack_start (widget, True, True, 0) + +OLD: column.pack_start (cell) +NEW: column.pack_start (cell, True) + +OLD: view_column.get_cell_renderers () +NEW: column.get_cells () + +GenericTreeModel +http://cgit.freedesktop.org/gstreamer/gst-devtools/tree/debug-viewer/GstDebugViewer/GUI/models.py +https://gist.github.com/andialbrecht/4463278 +http://mailman.daa.com.au/cgi-bin/pipermail/pygtk/2012-December/020510.html +https://github.com/GNOME/pygobject/blob/master/pygtkcompat/generictreemodel.py diff --git a/debug-viewer/tests/performance.py b/debug-viewer/tests/performance.py index 97e11d574b..cbd657c7ce 100755 --- a/debug-viewer/tests/performance.py +++ b/debug-viewer/tests/performance.py @@ -26,11 +26,9 @@ import os.path from glob import glob import time -import pygtk -pygtk.require ("2.0") -del pygtk +import gi -import gobject +from gi.repository import GObject sys.path.insert (0, os.path.join (sys.path[0], os.pardir)) @@ -40,7 +38,7 @@ class TestParsingPerformance (object): def __init__ (self, filename): - self.main_loop = gobject.MainLoop () + self.main_loop = GObject.MainLoop () self.log_file = Data.LogFile (filename, Common.Data.DefaultDispatcher ()) self.log_file.consumers.append (self)