formatting: run autopep8 over all files

We have a commit hook on the repo. Get all files to match the pep8 guidelines.
This commit is contained in:
Stefan Sauer 2016-09-28 20:38:55 +02:00
parent 3da48e7d61
commit d783c9cf36
20 changed files with 2246 additions and 2021 deletions

View file

@ -23,6 +23,7 @@ import gi
from gi.repository import GObject
class Dispatcher (object):
def __call__(self, iterator):
@ -33,6 +34,7 @@ class Dispatcher (object):
pass
class DefaultDispatcher (Dispatcher):
def __call__(self, iterator):
@ -40,6 +42,7 @@ class DefaultDispatcher (Dispatcher):
for x in iterator:
pass
class GSourceDispatcher (Dispatcher):
def __init__(self):
@ -53,7 +56,8 @@ class GSourceDispatcher (Dispatcher):
if self.source_id is not None:
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):

View file

@ -35,16 +35,19 @@ import GstDebugViewer
from GstDebugViewer.Common import utils
from generictreemodel import GenericTreeModel
def widget_add_popup_menu(widget, menu, button=3):
def popup_callback(widget, event):
if event.button == button:
menu.popup (None, None, None, None, event.button, event.get_time ())
menu.popup(
None, None, None, None, event.button, event.get_time())
return False
widget.connect("button-press-event", popup_callback)
class Actions (dict):
def __init__(self):
@ -75,6 +78,7 @@ class Actions (dict):
for action in group.list_actions():
self[action.props.name] = action
class Widgets (dict):
def __init__(self, builder):
@ -100,6 +104,7 @@ class Widgets (dict):
raise AttributeError("no widget with name %r" % (name,))
class WidgetFactory (object):
def __init__(self, directory):
@ -131,6 +136,7 @@ class WidgetFactory (object):
return builder.get_object(widget_name)
class UIFactory (object):
def __init__(self, ui_filename, actions=None):
@ -154,6 +160,7 @@ class UIFactory (object):
return ui_manager
class MetaModel (GObjectMeta):
"""Meta class for easy setup of gtk tree models.
@ -200,6 +207,7 @@ class MetaModel (GObjectMeta):
cls.column_types = column_types
cls.column_ids = tuple(column_indices)
class Manager (object):
"""GUI Manager base class."""
@ -241,6 +249,7 @@ class Manager (object):
else:
raise KeyError("no item such that item.%s == %r" % (attr, value,))
class StateString (object):
"""Descriptor for binding to StateSection classes."""
@ -284,6 +293,7 @@ class StateString (object):
section.set(self, str(value))
class StateBool (StateString):
"""Descriptor for binding to StateSection classes."""
@ -292,6 +302,7 @@ class StateBool (StateString):
return section.state._parser.getboolean(section._name, self.option)
class StateInt (StateString):
"""Descriptor for binding to StateSection classes."""
@ -300,6 +311,7 @@ class StateInt (StateString):
return section.state._parser.getint(section._name, self.option)
class StateInt4 (StateString):
"""Descriptor for binding to StateSection classes. This implements storing
@ -329,6 +341,7 @@ class StateInt4 (StateString):
return StateString.set(self, section, svalue)
class StateItem (StateString):
"""Descriptor for binding to StateSection classes. This implements storing
@ -367,6 +380,7 @@ class StateItem (StateString):
except KeyError:
return None
class StateItemList (StateItem):
"""Descriptor for binding to StateSection classes. This implements storing
@ -406,6 +420,7 @@ class StateItemList (StateItem):
StateString.set(self, section, svalue)
class StateSection (object):
_name = None
@ -415,7 +430,8 @@ class StateSection (object):
self.state = state
if self._name is None:
raise NotImplementedError ("subclasses must override the _name attribute")
raise NotImplementedError(
"subclasses must override the _name attribute")
def get(self, state_string):
@ -433,6 +449,7 @@ class StateSection (object):
parser.add_section(self._name)
parser.set(self._name, state_string.option, value)
class State (object):
def __init__(self, filename, old_filenames=()):
@ -459,6 +476,7 @@ class State (object):
with utils.SaveWriteFile(self._filename, "wt") as fp:
self._parser.write(fp)
class WindowState (object):
def __init__(self):

View file

@ -31,7 +31,8 @@ from gettext import gettext as _, ngettext
import gi
from gi.repository import GObject
from gi.repository import Gtk;
from gi.repository import Gtk
class ExceptionHandler (object):
@ -43,7 +44,9 @@ class ExceptionHandler (object):
def __call__(self, exc_type, exc_value, exc_traceback):
raise NotImplementedError ("derived classes need to override this method")
raise NotImplementedError(
"derived classes need to override this method")
class DefaultExceptionHandler (ExceptionHandler):
@ -67,6 +70,7 @@ class DefaultExceptionHandler (ExceptionHandler):
return self.excepthook(*exc_info)
class ExitOnInterruptExceptionHandler (ExceptionHandler):
exc_types = (KeyboardInterrupt,)
@ -81,6 +85,7 @@ class ExitOnInterruptExceptionHandler (ExceptionHandler):
sys.exit(self.exit_status)
class MainLoopWrapper (ExceptionHandler):
priority = 95
@ -112,6 +117,7 @@ class MainLoopWrapper (ExceptionHandler):
exc_type, exc_value, exc_tb = self.exc_info
raise exc_type, exc_value, exc_tb
class ExceptHookManagerClass (object):
def __init__(self):
@ -223,6 +229,7 @@ class ExceptHookManagerClass (object):
ExceptHookManager = ExceptHookManagerClass()
class PathsBase (object):
data_dir = None
@ -231,14 +238,12 @@ class PathsBase (object):
@classmethod
def setup_installed(cls, data_prefix):
"""Set up paths for running from a regular installation."""
pass
@classmethod
def setup_uninstalled(cls, source_dir):
"""Set up paths for running 'uninstalled' (i.e. directly from the
source dist)."""
@ -246,11 +251,11 @@ class PathsBase (object):
@classmethod
def ensure_setup(cls):
"""If paths are still not set up, try to set from a fallback."""
if cls.data_dir is None:
source_dir = os.path.dirname (os.path.dirname (os.path.abspath (__file__)))
source_dir = os.path.dirname(
os.path.dirname(os.path.abspath(__file__)))
cls.setup_uninstalled(source_dir)
def __new__(cls):
@ -258,6 +263,7 @@ class PathsBase (object):
raise RuntimeError("do not create instances of this class -- "
"use the class object directly")
class PathsProgramBase (PathsBase):
program_name = None
@ -266,7 +272,8 @@ class PathsProgramBase (PathsBase):
def setup_installed(cls, data_prefix):
if cls.program_name is None:
raise NotImplementedError ("derived classes need to set program_name attribute")
raise NotImplementedError(
"derived classes need to set program_name attribute")
cls.data_dir = os.path.join(data_prefix, "share", cls.program_name)
cls.icon_dir = os.path.join(data_prefix, "share", "icons")
@ -274,7 +281,6 @@ class PathsProgramBase (PathsBase):
@classmethod
def setup_uninstalled(cls, source_dir):
"""Set up paths for running 'uninstalled' (i.e. directly from the
source dist)."""
@ -287,10 +293,12 @@ class PathsProgramBase (PathsBase):
# Not setting icon_dir. It is not useful since we don't employ the
# needed directory structure in the source dist.
class OptionError (Exception):
pass
class OptionParser (object):
def __init__(self, options):
@ -304,8 +312,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):
@ -333,9 +341,9 @@ class OptionParser (object):
def __handle_option(self, option, arg, group):
# See __init__ for glib requirement.
## if option == GObject.OPTION_REMAINING:
## self.__remaining_args.append (arg)
## return
# if option == GObject.OPTION_REMAINING:
# self.__remaining_args.append (arg)
# return
for entry in self.__entries:
long_name, short_name = entry[:2]
@ -377,6 +385,7 @@ class OptionParser (object):
pass
class LogOptionParser (OptionParser):
"""Like OptionParser, but adds a --log-level option."""
@ -422,15 +431,18 @@ class LogOptionParser (OptionParser):
4: logging.ERROR,
5: logging.CRITICAL}[level]
def _init_excepthooks():
ExceptHookManager.setup()
ExceptHookManager.register_handler(ExitOnInterruptExceptionHandler())
def _init_paths(paths):
paths.ensure_setup()
def _init_locale(gettext_domain=None):
if Paths.locale_dir and gettext_domain is not None:
@ -447,6 +459,7 @@ def _init_locale (gettext_domain = None):
gettext.textdomain(gettext_domain)
gettext.bind_textdomain_codeset(gettext_domain, "UTF-8")
def _init_options(option_parser=None):
if option_parser is None:
@ -460,6 +473,7 @@ def _init_options (option_parser = None):
return option_parser.options
def _init_logging(level=None):
logging.basicConfig(level=level,
@ -470,6 +484,7 @@ def _init_logging (level = None):
logger.debug("logging at level %s", logging.getLevelName(level))
logger.info("using Python %i.%i.%i %s %i", *sys.version_info)
def main(option_parser=None, gettext_domain=None, paths=None):
# FIXME:

View file

@ -19,5 +19,7 @@
"""GStreamer Development Utilities Common package."""
import Data, GUI, Main, utils
import Data
import GUI
import Main
import utils

View file

@ -68,6 +68,7 @@ def handle_exception(default_return):
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.
@ -118,7 +119,8 @@ class GenericTreeModel(GObject.GObject, Gtk.TreeModel):
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))]
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):

View file

@ -23,6 +23,7 @@ import os
import logging
import subprocess as _subprocess
class SingletonMeta (type):
def __init__(cls, name, bases, dict_):
@ -44,8 +45,8 @@ class SingletonMeta (type):
cls._singleton_instances[a + kw_key] = obj
return obj
def gettext_cache ():
def gettext_cache():
"""Return a callable object that operates like gettext.gettext, but is much
faster when a string is looked up more than once. This is very useful in
loops, where calling gettext.gettext can quickly become a major performance
@ -63,6 +64,7 @@ def gettext_cache ():
return gettext_cache_access
class ClassProperty (property):
"Like the property class, but also invokes the getter for class access."
@ -81,6 +83,7 @@ class ClassProperty (property):
else:
return ret
class _XDGClass (object):
"""Partial implementation of the XDG Base Directory specification v0.6.
@ -103,6 +106,7 @@ class _XDGClass (object):
XDG = _XDGClass()
class SaveWriteFile (object):
def __init__(self, filename, mode="wt"):
@ -210,6 +214,7 @@ class SaveWriteFile (object):
self.logger.warning("deleting temporary file failed: %s", exc)
self.temp_name = None
class TeeWriteFile (object):
# TODO Py2.5: Add context manager methods.
@ -238,6 +243,7 @@ class TeeWriteFile (object):
for file in self.files:
file.writelines(lines)
class FixedPopen (_subprocess.Popen):
def __init__(self, args, **kw):
@ -261,14 +267,17 @@ class FixedPopen (_subprocess.Popen):
fp.close()
setattr(self, name, None)
class DevhelpError (EnvironmentError):
pass
class DevhelpUnavailableError (DevhelpError):
pass
class DevhelpClient (object):
def available(self):
@ -321,4 +330,3 @@ class DevhelpClient (object):
except OSError as exc:
self._check_os_error(exc)
raise

View file

@ -26,6 +26,7 @@ import re
# Nanosecond resolution (like Gst.SECOND)
SECOND = 1000000000
def time_args(ts):
secs = ts // SECOND
@ -35,6 +36,7 @@ def time_args (ts):
secs % 60,
ts % SECOND,)
def time_diff_args(time_diff):
if time_diff >= 0:
@ -49,6 +51,7 @@ def time_diff_args (time_diff):
secs % 60,
abs(time_diff) % SECOND,)
def time_args_no_hours(ts):
secs = ts // SECOND
@ -57,8 +60,8 @@ def time_args_no_hours (ts):
secs % 60,
ts % SECOND,)
def parse_time (st):
def parse_time(st):
"""Parse time strings that look like "0:00:00.0000000"."""
h, m, s = st.split(":")
@ -67,9 +70,11 @@ def parse_time (st):
return (long((int(h) * 60 ** 2 + int(m) * 60) * SECOND) +
long(secs) * SECOND + long(subsecs))
class DebugLevel (int):
__names = ["NONE", "ERROR", "WARN", "INFO", "DEBUG", "LOG", "FIXME", "TRACE"]
__names = ["NONE", "ERROR", "WARN",
"INFO", "DEBUG", "LOG", "FIXME", "TRACE"]
__instances = {}
def __new__(cls, level):
@ -126,6 +131,8 @@ debug_levels = [debug_level_none,
# For stripping color codes:
_escape = re.compile("\x1b\\[[0-9;]*m")
def strip_escape(s):
# FIXME: This can be optimized further!
@ -134,6 +141,7 @@ def strip_escape (s):
s = _escape.sub("", s)
return s
def default_log_line_regex_():
# "DEBUG "
@ -160,16 +168,18 @@ def default_log_line_regex_ ():
CATEGORY, FILENAME, LINE, FUNCTION, ANSI,
OBJECT, ANSI, MESSAGE]
# Old log format:
## expressions = [LEVEL, THREAD, TIME, CATEGORY, PID, FILENAME, LINE,
## FUNCTION, OBJECT, MESSAGE]
# expressions = [LEVEL, THREAD, TIME, CATEGORY, PID, FILENAME, LINE,
# FUNCTION, OBJECT, MESSAGE]
return expressions
def default_log_line_regex():
expressions = default_log_line_regex_()
return re.compile("".join(expressions))
class Producer (object):
def __init__(self):
@ -186,6 +196,7 @@ class Producer (object):
for consumer in self.consumers:
consumer.handle_load_finished()
class SortHelper (object):
def __init__(self, fileobj, offsets):
@ -255,6 +266,7 @@ class SortHelper (object):
seek(save_offset)
class LineCache (Producer):
_lines_per_iteration = 50000
@ -344,17 +356,20 @@ class LineCache (Producer):
# time to integer. We also don't have to take a substring here,
# which would be a useless memcpy.
if line >= last_line:
levels_append (dict_levels_get (match.group (1), debug_level_none))
levels_append(
dict_levels_get(match.group(1), debug_level_none))
offsets_append(offset)
last_line = line
else:
pos = find_insert_position(line)
levels.insert (pos, dict_levels_get (match.group (1), debug_level_none))
levels.insert(
pos, dict_levels_get(match.group(1), debug_level_none))
offsets.insert(pos, offset)
self.have_load_finished()
yield False
class LogLine (list):
_line_regex = default_log_line_regex()
@ -364,7 +379,7 @@ class LogLine (list):
match = cls._line_regex.match(line_string)
if match is None:
## raise ValueError ("not a valid log line (%r)" % (line_string,))
# raise ValueError ("not a valid log line (%r)" % (line_string,))
groups = [0, 0, 0, 0, "", "", 0, "", "", 0]
return cls(groups)
@ -390,6 +405,7 @@ class LogLine (list):
return line
class LogLines (object):
def __init__(self, fileobj, line_cache):
@ -419,6 +435,7 @@ class LogLines (object):
yield self[i]
i += 1
class LogFile (Producer):
def __init__(self, filename, dispatcher):
@ -431,7 +448,8 @@ class LogFile (Producer):
self.path = os.path.normpath(os.path.abspath(filename))
self.__real_fileobj = file(filename, "rb")
self.fileobj = mmap.mmap (self.__real_fileobj.fileno (), 0, access = mmap.ACCESS_READ)
self.fileobj = mmap.mmap(
self.__real_fileobj.fileno(), 0, access=mmap.ACCESS_READ)
self.line_cache = LineCache(self.fileobj, dispatcher)
self.line_cache.consumers.append(self)
@ -465,4 +483,3 @@ class LogFile (Producer):
# Chain up to our consumers:
self.have_load_finished()

View file

@ -26,6 +26,7 @@ import gi
from GstDebugViewer.GUI.app import App
def main(options):
args = options["args"]

View file

@ -28,6 +28,7 @@ from GstDebugViewer import Common
from GstDebugViewer.GUI.columns import ViewColumnManager
from GstDebugViewer.GUI.window import Window
class AppStateSection (Common.GUI.StateSection):
_name = "state"
@ -36,10 +37,12 @@ class AppStateSection (Common.GUI.StateSection):
maximized = Common.GUI.StateBool("window-maximized")
column_order = Common.GUI.StateItemList("column-order", ViewColumnManager)
columns_visible = Common.GUI.StateItemList ("columns-visible", ViewColumnManager)
columns_visible = Common.GUI.StateItemList(
"columns-visible", ViewColumnManager)
zoom_level = Common.GUI.StateInt("zoom-level")
class AppState (Common.GUI.State):
def __init__(self, *a, **kw):
@ -48,6 +51,7 @@ class AppState (Common.GUI.State):
self.add_section_class(AppStateSection)
class App (object):
def __init__(self):
@ -58,7 +62,8 @@ class App (object):
from GstDebugViewer import Plugins
plugin_classes = list (Plugins.load ([os.path.dirname (Plugins.__file__)]))
plugin_classes = list(
Plugins.load([os.path.dirname(Plugins.__file__)]))
self.plugins = []
for plugin_class in plugin_classes:
plugin = plugin_class(self)
@ -74,7 +79,8 @@ class App (object):
config_home = Common.utils.XDG.CONFIG_HOME
state_filename = os.path.join (config_home, "gst-debug-viewer", "state")
state_filename = os.path.join(
config_home, "gst-debug-viewer", "state")
self.state = AppState(state_filename)
self.state_section = self.state.sections["state"]

View file

@ -24,6 +24,7 @@ from gi.repository import Gdk
from GstDebugViewer import Data
class Color (object):
def __init__(self, hex_24):
@ -55,6 +56,7 @@ class Color (object):
return tuple((x << 8 for x in self._fields))
class ColorPalette (object):
@classmethod
@ -66,6 +68,7 @@ class ColorPalette (object):
cls._instance = cls()
return cls._instance
class TangoPalette (ColorPalette):
def __init__(self):
@ -101,6 +104,7 @@ class TangoPalette (ColorPalette):
("aluminium6", 46, 52, 54)]:
setattr(self, name, Color("%02x%02x%02x" % (r, g, b,)))
class ColorTheme (object):
def __init__(self):
@ -111,10 +115,12 @@ class ColorTheme (object):
self.colors[key] = colors
class LevelColorTheme (ColorTheme):
pass
class LevelColorThemeTango (LevelColorTheme):
def __init__(self):
@ -131,10 +137,12 @@ class LevelColorThemeTango (LevelColorTheme):
self.add_color(Data.debug_level_warning, p.black, p.orange1)
self.add_color(Data.debug_level_error, p.white, p.scarletred1)
class ThreadColorTheme (ColorTheme):
pass
class ThreadColorThemeTango (ThreadColorTheme):
def __init__(self):

View file

@ -19,6 +19,7 @@
"""GStreamer Debug Viewer GUI module."""
def _(s):
return s
@ -31,6 +32,8 @@ from GstDebugViewer.GUI.colors import LevelColorThemeTango
from GstDebugViewer.GUI.models import LazyLogModel, LogModelBase
# Sync with gst-inspector!
class Column (object):
"""A single list view column, managed by a ColumnManager instance."""
@ -49,6 +52,7 @@ class Column (object):
self.view_column = view_column
class SizedColumn (Column):
default_size = None
@ -58,6 +62,8 @@ class SizedColumn (Column):
return None
# Sync with gst-inspector?
class TextColumn (SizedColumn):
font_family = None
@ -98,6 +104,7 @@ class TextColumn (SizedColumn):
modify_func = self.get_modify_func()
id_ = self.id
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)
@ -128,6 +135,7 @@ class TextColumn (SizedColumn):
return ()
class TimeColumn (TextColumn):
name = "time"
@ -146,11 +154,13 @@ class TimeColumn (TextColumn):
if self.base_time:
time_diff_args = Data.time_diff_args
base_time = self.base_time
def format_time(value):
# TODO: Hard coded to omit trailing zeroes, see below.
return time_diff_args(value - base_time)[:-3]
else:
time_args = Data.time_args
def format_time(value):
# TODO: This is hard coded to omit hours as well as the last 3
# digits at the end, since current gst uses g_get_current_time,
@ -173,6 +183,7 @@ class TimeColumn (TextColumn):
cell = column.get_cells()[0]
self.update_modify_func(column, cell)
class LevelColumn (TextColumn):
name = "level"
@ -202,6 +213,7 @@ class LevelColumn (TextColumn):
for c in theme.colors[level])),)
for level in Data.debug_levels
if level != Data.debug_level_none)
def level_data_func(cell_props, level):
cell_props.text = level.name[0]
if level in colors:
@ -221,6 +233,7 @@ class LevelColumn (TextColumn):
return values
class PidColumn (TextColumn):
name = "pid"
@ -237,6 +250,7 @@ class PidColumn (TextColumn):
return ["999999"]
class ThreadColumn (TextColumn):
name = "thread"
@ -256,6 +270,7 @@ class ThreadColumn (TextColumn):
return [int("ffffff", 16)]
class CategoryColumn (TextColumn):
name = "category"
@ -266,6 +281,7 @@ class CategoryColumn (TextColumn):
return ["GST_LONG_CATEGORY", "somelongelement"]
class CodeColumn (TextColumn):
name = "code"
@ -277,6 +293,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, user_data):
args = model.get(tree_iter, filename_id, line_number_id)
cell.props.text = "%s:%i" % args
@ -287,6 +304,7 @@ class CodeColumn (TextColumn):
return ["gstsomefilename.c:1234"]
class FunctionColumn (TextColumn):
name = "function"
@ -297,6 +315,7 @@ class FunctionColumn (TextColumn):
return ["gst_this_should_be_enough"]
class ObjectColumn (TextColumn):
name = "object"
@ -307,6 +326,7 @@ class ObjectColumn (TextColumn):
return ["longobjectname00"]
class MessageColumn (TextColumn):
name = "message"
@ -346,7 +366,8 @@ class MessageColumn (TextColumn):
end = None
for start, end in ranges:
if prev_end < start:
tags.append (GLib.markup_escape_text (msg[prev_end:start]))
tags.append(
GLib.markup_escape_text(msg[prev_end:start]))
msg_escape = GLib.markup_escape_text(msg[start:end])
tags.append("<span foreground=\'#FFFFFF\'"
" background=\'#0000FF\'>%s</span>" % (msg_escape,))
@ -363,6 +384,7 @@ class MessageColumn (TextColumn):
return values
class ColumnManager (Common.GUI.Manager):
column_classes = ()
@ -567,12 +589,15 @@ class ColumnManager (Common.GUI.Manager):
self.columns[:] = new_visible
self.column_order[:] = new_order
class ViewColumnManager (ColumnManager):
column_classes = (TimeColumn, LevelColumn, PidColumn, ThreadColumn, CategoryColumn,
column_classes = (
TimeColumn, LevelColumn, PidColumn, ThreadColumn, CategoryColumn,
CodeColumn, FunctionColumn, ObjectColumn, MessageColumn,)
default_column_classes = (TimeColumn, LevelColumn, CategoryColumn, CodeColumn,
default_column_classes = (
TimeColumn, LevelColumn, CategoryColumn, CodeColumn,
FunctionColumn, ObjectColumn, MessageColumn,)
def __init__(self, state):
@ -637,7 +662,8 @@ class ViewColumnManager (ColumnManager):
if default_size is None:
# Dummy fallback:
column.view_column.props.fixed_width = 50
self.logger.warning ("%s column does not implement default size", column.name)
self.logger.warning(
"%s column does not implement default size", column.name)
else:
column.view_column.props.fixed_width = default_size
@ -665,6 +691,7 @@ class ViewColumnManager (ColumnManager):
self.size_column(column)
self.columns_sized = True
class WrappingMessageColumn (MessageColumn):
def wrap_to_width(self, width):
@ -674,6 +701,7 @@ class WrappingMessageColumn (MessageColumn):
col.get_cells()[0].props.wrap_width = width
col.queue_resize()
class LineViewColumnManager (ColumnManager):
column_classes = (TimeColumn, WrappingMessageColumn,)

View file

@ -21,6 +21,7 @@
from GstDebugViewer.GUI.models import LogModelBase
def get_comparison_function(all_but_this):
if (all_but_this):
@ -28,10 +29,12 @@ def get_comparison_function (all_but_this):
else:
return lambda x, y: x != y
class Filter (object):
pass
class DebugLevelFilter (Filter):
only_this, all_but_this, this_and_above = range(3)
@ -42,38 +45,45 @@ class DebugLevelFilter (Filter):
if mode == self.this_and_above:
comparison_function = lambda x, y: x < y
else:
comparison_function = get_comparison_function (mode == self.all_but_this)
comparison_function = get_comparison_function(
mode == self.all_but_this)
def filter_func(row):
return comparison_function(row[col_id], debug_level)
self.filter_func = filter_func
class CategoryFilter (Filter):
def __init__(self, category, all_but_this=False):
col_id = LogModelBase.COL_CATEGORY
comparison_function = get_comparison_function(all_but_this)
def category_filter_func(row):
return comparison_function(row[col_id], category)
self.filter_func = category_filter_func
class ObjectFilter (Filter):
def __init__(self, object_, all_but_this=False):
col_id = LogModelBase.COL_OBJECT
comparison_function = get_comparison_function(all_but_this)
def object_filter_func(row):
return comparison_function(row[col_id], object_)
self.filter_func = object_filter_func
class FilenameFilter (Filter):
def __init__(self, filename, all_but_this=False):
col_id = LogModelBase.COL_FILENAME
comparison_function = get_comparison_function(all_but_this)
def filename_filter_func(row):
return comparison_function(row[col_id], filename)
self.filter_func = filename_filter_func

View file

@ -48,7 +48,7 @@ class LogModelBase (Common.GUI.GenericTreeModel):
Common.GUI.GenericTreeModel.__init__(self)
##self.props.leak_references = False
# self.props.leak_references = False
self.line_offsets = array("I")
self.line_levels = [] # FIXME: Not so nice!
@ -175,13 +175,14 @@ class LogModelBase (Common.GUI.GenericTreeModel):
return None
## def on_ref_node (self, rowref):
# def on_ref_node (self, rowref):
## pass
# pass
## def on_unref_node (self, rowref):
# def on_unref_node (self, rowref):
# pass
## pass
class LazyLogModel (LogModelBase):
@ -221,6 +222,7 @@ class LazyLogModel (LogModelBase):
self.line_cache[line_offset] = Data.LogLine.parse_full(line)
class FilteredLogModelBase (LogModelBase):
def __init__(self, super_model):
@ -242,6 +244,7 @@ class FilteredLogModelBase (LogModelBase):
raise NotImplementedError("index conversion not supported")
class FilteredLogModel (FilteredLogModelBase):
def __init__(self, super_model):
@ -275,6 +278,7 @@ class FilteredLogModel (FilteredLogModelBase):
new_super_index = array("I")
level_id = self.COL_LEVEL
func = filter.filter_func
def enum():
i = 0
for row, offset in self.iter_rows_offset():
@ -356,7 +360,8 @@ class FilteredLogModel (FilteredLogModelBase):
def set_range(self, super_start, super_stop):
old_super_start = self.line_index_to_super(0)
old_super_stop = self.line_index_to_super (len (self.super_index) - 1) + 1
old_super_stop = self.line_index_to_super(
len(self.super_index) - 1) + 1
self.logger.debug("set range (%i, %i), current (%i, %i)",
super_start, super_stop, old_super_start, old_super_stop)
@ -387,6 +392,7 @@ class FilteredLogModel (FilteredLogModelBase):
self.line_offsets = SubRange(self.line_offsets, start, stop)
self.line_levels = SubRange(self.line_levels, start, stop)
class SubRange (object):
__slots__ = ("l", "start", "stop",)
@ -394,7 +400,8 @@ class SubRange (object):
def __init__(self, l, start, stop):
if start > stop:
raise ValueError ("need start <= stop (got %r, %r)" % (start, stop,))
raise ValueError(
"need start <= stop (got %r, %r)" % (start, stop,))
if type(l) == type(self):
# Another SubRange, don't stack:
@ -429,6 +436,7 @@ class SubRange (object):
for i in xrange(self.start, self.stop):
yield l[i]
class LineViewLogModel (FilteredLogModelBase):
def __init__(self, super_model):

View file

@ -21,6 +21,7 @@
ZOOM_FACTOR = 1.15
def _(s):
return s
@ -44,12 +45,14 @@ from GstDebugViewer.GUI.models import (FilteredLogModel,
LineViewLogModel,
LogModelBase)
def action(func):
func.is_action_handler = True
return func
def iter_actions(manager):
cls = type(manager)
@ -69,6 +72,7 @@ def iter_actions (manager):
yield (action_name, bound_method,)
class LineView (object):
def __init__(self):
@ -84,10 +88,12 @@ class LineView (object):
self.clear_action = window.actions.clear_line_view
self.line_view = window.widgets.line_view
self.line_view.connect ("row-activated", self.handle_line_view_row_activated)
self.line_view.connect(
"row-activated", self.handle_line_view_row_activated)
ui = window.ui_manager
self.popup = ui.get_widget ("/ui/context/LineViewContextMenu").get_submenu ()
self.popup = ui.get_widget(
"/ui/context/LineViewContextMenu").get_submenu()
Common.GUI.widget_add_popup_menu(self.line_view, self.popup)
self.log_view = log_view = window.log_view
@ -177,6 +183,7 @@ class LineView (object):
self.clear()
class ProgressDialog (object):
def __init__(self, window, title=""):
@ -213,6 +220,7 @@ class ProgressDialog (object):
self.__progress_bar.props.fraction = progress
class Window (object):
def __init__(self, app):
@ -239,33 +247,50 @@ class Window (object):
self.actions.add_group(group)
group = Gtk.ActionGroup("WindowActions")
group.add_actions ([("new-window", Gtk.STOCK_NEW, _("_New Window"), "<Ctrl>N"),
("open-file", Gtk.STOCK_OPEN, _("_Open File"), "<Ctrl>O"),
("reload-file", Gtk.STOCK_REFRESH, _("_Reload File"), "<Ctrl>R"),
("close-window", Gtk.STOCK_CLOSE, _("Close _Window"), "<Ctrl>W"),
group.add_actions(
[("new-window", Gtk.STOCK_NEW, _("_New Window"), "<Ctrl>N"),
("open-file", Gtk.STOCK_OPEN, _(
"_Open File"), "<Ctrl>O"),
("reload-file", Gtk.STOCK_REFRESH, _(
"_Reload File"), "<Ctrl>R"),
("close-window", Gtk.STOCK_CLOSE, _(
"Close _Window"), "<Ctrl>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"), "<Ctrl>plus"),
("shrink-text", Gtk.STOCK_ZOOM_OUT, _("Shrink Text"), "<Ctrl>minus"),
("show-about", None, _(
"About GStreamer Debug Viewer",)),
("enlarge-text", Gtk.STOCK_ZOOM_IN, _(
"Enlarge Text"), "<Ctrl>plus"),
("shrink-text", Gtk.STOCK_ZOOM_OUT, _(
"Shrink Text"), "<Ctrl>minus"),
("reset-text", Gtk.STOCK_ZOOM_100, _("Normal Text Size"), "<Ctrl>0")])
self.actions.add_group(group)
self.actions.reload_file.props.sensitive = False
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"), "<Ctrl>C"),
("edit-copy-message", Gtk.STOCK_COPY, _("Copy message"), ""),
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"), "<Ctrl>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-level-and-above", None, _("Hide this log level and above")),
("show-only-log-level", None, _("Show only log level")),
("hide-log-category", None, _("Hide log category")),
("show-only-log-category", None, _("Show only log category")),
("hide-log-level-and-above", None, _(
"Hide this log level and above")),
("show-only-log-level", None, _(
"Show only log level")),
("hide-log-category", None, _(
"Hide log category")),
("show-only-log-category", None, _(
"Show only log category")),
("hide-log-object", None, _("Hide object")),
("show-only-log-object", None, _("Show only object")),
("show-only-log-object", None, _(
"Show only object")),
("hide-filename", None, _("Hide filename")),
("show-only-filename", None, _("Show only filename"))])
group.props.sensitive = False
@ -278,7 +303,8 @@ class Window (object):
self.log_filter = None
self.widget_factory = Common.GUI.WidgetFactory(Main.Paths.data_dir)
self.widgets = self.widget_factory.make ("main-window.ui", "main_window")
self.widgets = self.widget_factory.make(
"main-window.ui", "main_window")
ui_filename = os.path.join(Main.Paths.data_dir, "menus.ui")
self.ui_factory = Common.GUI.UIFactory(ui_filename, self.actions)
@ -295,7 +321,8 @@ class Window (object):
sel = self.log_view.get_selection()
sel.connect("changed", self.handle_log_view_selection_changed)
self.view_popup = ui.get_widget ("/ui/context/LogViewContextMenu").get_submenu ()
self.view_popup = ui.get_widget(
"/ui/context/LogViewContextMenu").get_submenu()
Common.GUI.widget_add_popup_menu(self.log_view, self.view_popup)
# Widgets to set insensitive when the window is considered as
@ -315,6 +342,7 @@ class Window (object):
self.log_model = model
self.log_filter = FilteredLogModel(self.log_model)
self.log_filter.handle_process_finished = self.handle_log_filter_process_finished
def get_top_attach_point(self):
return self.widgets.vbox_main
@ -333,14 +361,16 @@ class Window (object):
self.window_state.attach(window=self.gtk_window,
state=self.app.state_section)
self.clipboard = Gtk.Clipboard.get_for_display (self.gtk_window.get_display (),
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)
action.connect("activate", handler)
self.gtk_window.connect ("delete-event", self.handle_window_delete_event)
self.gtk_window.connect(
"delete-event", self.handle_window_delete_event)
self.features = []
@ -360,7 +390,8 @@ class Window (object):
# Do not translate; fallback application name for e.g. gnome-shell if
# the desktop file is not installed:
self.gtk_window.set_wmclass ("gst-debug-viewer", "GStreamer Debug Viewer")
self.gtk_window.set_wmclass(
"gst-debug-viewer", "GStreamer Debug Viewer")
self.gtk_window.show()
@ -452,7 +483,8 @@ class Window (object):
try:
select_index = model.line_index_from_super(selected_index)
except IndexError as exc:
self.logger.debug ("abs line index %i filtered out, not reselecting",
self.logger.debug(
"abs line index %i filtered out, not reselecting",
selected_index)
else:
assert select_index >= 0
@ -461,7 +493,8 @@ class Window (object):
sel.select_path(path)
if start_index is None or scroll_to_selection:
self.log_view.scroll_to_cell (path, use_align = True, row_align = .5)
self.log_view.scroll_to_cell(
path, use_align=True, row_align=.5)
if start_index is not None and not scroll_to_selection:
@ -477,7 +510,8 @@ class Window (object):
continue
else:
path = (target_index,)
self.log_view.scroll_to_cell (path, use_align = True, row_align = 0.)
self.log_view.scroll_to_cell(
path, use_align=True, row_align=0.)
break
def update_view(self):
@ -502,7 +536,8 @@ class Window (object):
last_selected = True
else:
first_selected = (line_index == 0)
last_selected = (line_index == len (self.log_view.get_model ()) - 1)
last_selected = (
line_index == len(self.log_view.get_model()) - 1)
self.actions.hide_before_line.props.sensitive = not first_selected
self.actions.hide_after_line.props.sensitive = not last_selected
@ -582,7 +617,8 @@ class Window (object):
first_index = model.line_index_to_super(0)
last_index = model.line_index_to_super(filtered_line_index)
self.logger.info ("hiding lines after %i (abs %i), first line is abs %i",
self.logger.info(
"hiding lines after %i (abs %i), first line is abs %i",
filtered_line_index,
last_index,
first_index)
@ -590,7 +626,8 @@ class Window (object):
first_index = model.line_index_to_super(filtered_line_index)
last_index = model.line_index_to_super(len(model) - 1)
self.logger.info ("hiding lines before %i (abs %i), last line is abs %i",
self.logger.info(
"hiding lines before %i (abs %i), last line is abs %i",
filtered_line_index,
first_index,
last_index)
@ -787,14 +824,16 @@ class Window (object):
row = self.get_active_line()
debug_level = row[LogModelBase.COL_LEVEL]
self.add_model_filter (DebugLevelFilter (debug_level, DebugLevelFilter.this_and_above))
self.add_model_filter(
DebugLevelFilter(debug_level, DebugLevelFilter.this_and_above))
@action
def handle_show_only_log_level_action_activate(self, action):
row = self.get_active_line()
debug_level = row[LogModelBase.COL_LEVEL]
self.add_model_filter (DebugLevelFilter (debug_level, DebugLevelFilter.all_but_this))
self.add_model_filter(
DebugLevelFilter(debug_level, DebugLevelFilter.all_but_this))
@action
def handle_show_only_log_category_action_activate(self, action):
@ -822,7 +861,8 @@ class Window (object):
from GstDebugViewer import version
dialog = self.widget_factory.make_one ("about-dialog.ui", "about_dialog")
dialog = self.widget_factory.make_one(
"about-dialog.ui", "about_dialog")
dialog.props.version = version
dialog.run()
dialog.destroy()
@ -875,7 +915,8 @@ class Window (object):
return
basename = os.path.basename(filename)
self.gtk_window.props.title = _("%s - GStreamer Debug Viewer") % (basename,)
self.gtk_window.props.title = _(
"%s - GStreamer Debug Viewer") % (basename,)
self.log_file.consumers.append(self)
self.log_file.start_loading()
@ -907,7 +948,8 @@ 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)
@ -918,7 +960,8 @@ class Window (object):
def update_load_progress(self):
if self.progress_dialog is None:
self.logger.debug ("progress dialog is gone, removing progress update timeout")
self.logger.debug(
"progress dialog is gone, removing progress update timeout")
self.update_progress_id = None
return False
@ -944,7 +987,8 @@ class Window (object):
self.set_sensitive(True)
if len(self.log_model) == 0:
self.show_error (_("The file does not contain any parsable lines."),
self.show_error(
_("The file does not contain any parsable lines."),
_("It is not a GStreamer log file."))
def idle_set():

View file

@ -27,16 +27,19 @@ Common = GstDebugViewer.Common
GETTEXT_DOMAIN = "gst-debug-viewer"
def main_version():
from GstDebugViewer import version
print "GStreamer Debug Viewer %s" % (version,)
class Paths (Common.Main.PathsProgramBase):
program_name = "gst-debug-viewer"
class OptionParser (Common.Main.LogOptionParser):
def __init__(self, options):
@ -68,6 +71,7 @@ class OptionParser (Common.Main.LogOptionParser):
self.options["args"][:] = remaining_args
def main():
options = {}

View file

@ -21,6 +21,7 @@
from GstDebugViewer.Plugins import FeatureBase, PluginBase
class ColorizeLevels (FeatureBase):
def attach(self, window):
@ -31,6 +32,7 @@ class ColorizeLevels (FeatureBase):
pass
class LevelColorSentinel (object):
def processor(self, proc):
@ -39,6 +41,7 @@ class LevelColorSentinel (object):
yield None
class ColorizeCategories (FeatureBase):
def attach(self, window):
@ -49,14 +52,14 @@ class ColorizeCategories (FeatureBase):
pass
class CategoryColorSentinel (object):
def processor(self):
pass
class Plugin (PluginBase):
features = [ColorizeLevels, ColorizeCategories]

View file

@ -26,20 +26,24 @@ from GstDebugViewer.Plugins import FeatureBase, PluginBase
from gettext import gettext as _
from gi.repository import Gtk
class FilePropertiesSentinel (object):
pass
class FilePropertiesDialog (Gtk.Dialog):
pass
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.add_actions(
[("show-file-properties", Gtk.STOCK_PROPERTIES,
_("_Properties"), "<Ctrl>P")])
def attach(self, window):
@ -53,12 +57,14 @@ class FilePropertiesFeature (FeatureBase):
Gtk.UIManagerItemType.MENUITEM, False)
handler = self.handle_action_activate
self.action_group.get_action ("show-file-properties").connect ("activate", handler)
self.action_group.get_action(
"show-file-properties").connect("activate", handler)
def handle_action_activate(self, action):
pass
class Plugin (PluginBase):
features = (FilePropertiesFeature,)

View file

@ -28,6 +28,7 @@ from gettext import gettext as _
from gi.repository import GObject, GLib
from gi.repository import Gtk
class SearchOperation (object):
def __init__(self, model, search_text, search_forward=True, start_position=None):
@ -58,6 +59,7 @@ class SearchOperation (object):
self.match_func = match_func
class SearchSentinel (object):
def __init__(self):
@ -95,11 +97,13 @@ class SearchSentinel (object):
else:
# FIXME: This is really ugly.
nth_child = model.iter_nth_child
def iter_next_():
for i in xrange(start_pos, -1, -1):
yield nth_child(None, i)
yield None
it_ = iter_next_()
def iter_next(it):
return it_.next()
@ -128,6 +132,7 @@ class SearchSentinel (object):
pass
class FindBarWidget (Gtk.HBox):
__status = {"no-match-found": _N("No match found"),
@ -199,6 +204,7 @@ class FindBarWidget (Gtk.HBox):
self.__set_status("")
class FindBarFeature (FeatureBase):
def __init__(self, app):
@ -239,7 +245,8 @@ class FindBarFeature (FeatureBase):
start_path, end_path = view.get_visible_range()
if path >= start_path and path <= end_path:
self.logger.debug ("line index %i already visible, not scrolling", line_index)
self.logger.debug(
"line index %i already visible, not scrolling", line_index)
return
self.logger.debug("scrolling to line_index %i", line_index)
@ -257,7 +264,8 @@ class FindBarFeature (FeatureBase):
self.merge_id = ui.new_merge_id()
for name, action_name in [("ViewFindBar", "show-find-bar",),
("ViewNextResult", "goto-next-search-result",),
("ViewNextResult",
"goto-next-search-result",),
("ViewPrevResult", "goto-previous-search-result",)]:
ui.add_ui(self.merge_id, "/menubar/ViewMenu/ViewMenuAdditions",
name, action_name, Gtk.UIManagerItemType.MENUITEM, False)
@ -298,7 +306,8 @@ class FindBarFeature (FeatureBase):
self.update_search()
else:
try:
column = self.window.column_manager.find_item (name = "message")
column = self.window.column_manager.find_item(
name="message")
del column.highlighters[self]
except KeyError:
pass
@ -306,7 +315,8 @@ class FindBarFeature (FeatureBase):
self.bar.hide()
for action_name in ["goto-next-search-result",
"goto-previous-search-result"]:
self.action_group.get_action (action_name).props.sensitive = False
self.action_group.get_action(
action_name).props.sensitive = False
def handle_goto_previous_search_result_action_activate(self, action):
@ -339,18 +349,18 @@ class FindBarFeature (FeatureBase):
forward=True)
# FIXME: Finish.
## model = self.log_view.get_model ()
# model = self.log_view.get_model ()
## start_path, end_path = self.log_view.get_visible_range ()
## start_index, end_index = start_path[0], end_path[0]
# start_path, end_path = self.log_view.get_visible_range ()
# start_index, end_index = start_path[0], end_path[0]
## for line_index in self.matches:
## if line_index > end_index:
## break
## else:
## return
# for line_index in self.matches:
# if line_index > end_index:
# break
# else:
# return
## self.scroll_view_to_line (line_index)
# self.scroll_view_to_line (line_index)
def handle_entry_changed(self, entry):
@ -380,7 +390,8 @@ class FindBarFeature (FeatureBase):
self.scroll_match = True
start_path = self.log_view.get_visible_range()[0]
self.start_search_operation (search_text, start_position = start_path[0])
self.start_search_operation(
search_text, start_position=start_path[0])
self.bar.status_searching()
column.highlighters[self] = self.operation.match_func
@ -409,7 +420,8 @@ class FindBarFeature (FeatureBase):
if search_text is None:
operation = self.operation
if operation is None:
raise ValueError ("search_text not given but have no previous search operation")
raise ValueError(
"search_text not given but have no previous search operation")
search_text = operation.search_text
self.operation = SearchOperation(model, search_text,
@ -420,7 +432,8 @@ class FindBarFeature (FeatureBase):
def handle_match_found(self, model, tree_iter):
if not self.search_state in ("search-forward", "search-backward",):
self.logger.warning ("inconsistent search state %r", self.search_state)
self.logger.warning(
"inconsistent search state %r", self.search_state)
return
line_index = model.get_path(tree_iter)[0]
@ -440,7 +453,8 @@ class FindBarFeature (FeatureBase):
self.scroll_view_to_line(line_index)
# Now search for the next one:
self.scroll_match = False
# FIXME: Start with first line that is outside of the visible range.
# FIXME: Start with first line that is outside of the visible
# range.
self.start_search_operation(start_position=line_index + 1,
forward=forward_search)
else:
@ -474,6 +488,7 @@ class FindBarFeature (FeatureBase):
if self.prev_match is None and self.next_match is None:
self.bar.status_no_match_found()
class Plugin (PluginBase):
features = [FindBarFeature]

View file

@ -31,12 +31,14 @@ from gi.repository import Gtk
from gi.repository import Gdk
import cairo
def iter_model_reversed(model):
count = model.iter_n_children(None)
for i in xrange(count - 1, 0, -1):
yield model[i]
class LineFrequencySentinel (object):
def __init__(self, model):
@ -140,6 +142,7 @@ class LineFrequencySentinel (object):
self.partitions = partitions
self.ts_range = (first_ts, last_ts,)
class LevelDistributionSentinel (object):
def __init__(self, freq_sentinel, model):
@ -210,6 +213,7 @@ class LevelDistributionSentinel (object):
yield False
class UpdateProcess (object):
def __init__(self, freq_sentinel, dist_sentinel):
@ -269,6 +273,7 @@ class UpdateProcess (object):
pass
class VerticalTimelineWidget (Gtk.DrawingArea):
__gtype_name__ = "GstDebugViewerVerticalTimelineWidget"
@ -335,7 +340,8 @@ class VerticalTimelineWidget (Gtk.DrawingArea):
self.next_thread_color += 1
if self.next_thread_color == len(self.theme.colors):
self.next_thread_color = 0
color = self.theme.colors[self.next_thread_color][0].float_tuple ()
color = self.theme.colors[
self.next_thread_color][0].float_tuple()
self.thread_colors[thread] = color
ctx.set_source_rgb(*color)
ts_fraction = float(ts - first_ts) / ts_range
@ -389,7 +395,8 @@ class VerticalTimelineWidget (Gtk.DrawingArea):
cell_height = bg_rect.height
cell_rect = view.get_cell_area(start_path, column)
try:
first_y = view.convert_bin_window_to_widget_coords (cell_rect.x, cell_rect.y)[1]
first_y = view.convert_bin_window_to_widget_coords(
cell_rect.x, cell_rect.y)[1]
except (AttributeError, SystemError,):
# AttributeError is with PyGTK before 2.12. SystemError is raised
# with PyGTK 2.12.0, pygtk bug #479012.
@ -409,7 +416,8 @@ class VerticalTimelineWidget (Gtk.DrawingArea):
if tree_iter is None:
return
while model.get_path(tree_iter) != end_path:
data.append (model.get (tree_iter, model.COL_TIME, model.COL_THREAD))
data.append(
model.get(tree_iter, model.COL_TIME, model.COL_THREAD))
tree_iter = model.iter_next(tree_iter)
self.params = (first_y, cell_height, data,)
@ -419,6 +427,7 @@ class VerticalTimelineWidget (Gtk.DrawingArea):
self.params = None
self.queue_draw()
class TimelineWidget (Gtk.DrawingArea):
__gtype_name__ = "GstDebugViewerTimelineWidget"
@ -477,7 +486,8 @@ class TimelineWidget (Gtk.DrawingArea):
if self.__offscreen_size == (alloc.width, alloc.height):
return
self.__offscreen = cairo.ImageSurface (cairo.FORMAT_ARGB32, alloc.width, alloc.height)
self.__offscreen = cairo.ImageSurface(
cairo.FORMAT_ARGB32, alloc.width, alloc.height)
self.__offscreen_size = (alloc.width, alloc.height)
self.__offscreen_dirty = (0, alloc.width)
if not self.__offscreen:
@ -522,7 +532,8 @@ class TimelineWidget (Gtk.DrawingArea):
ctx.clip()
if offscreen_width < alloc.width:
ctx.rectangle (offscreen_width, 0, alloc.width, offscreen_height)
ctx.rectangle(
offscreen_width, 0, alloc.width, offscreen_height)
if offscreen_height < alloc.height:
ctx.new_path()
ctx.rectangle(0, offscreen_height, alloc.width, alloc.height)
@ -545,7 +556,8 @@ class TimelineWidget (Gtk.DrawingArea):
if model is not None:
self.__dist_sentinel_progress = 0
self.process.freq_sentinel = LineFrequencySentinel(model)
self.process.dist_sentinel = LevelDistributionSentinel (self.process.freq_sentinel, model)
self.process.dist_sentinel = LevelDistributionSentinel(
self.process.freq_sentinel, model)
width = self.get_allocation().width
self.process.freq_sentinel.run_for(width)
self.process.run()
@ -687,7 +699,8 @@ class TimelineWidget (Gtk.DrawingArea):
level = Data.debug_level_trace
ctx.set_source_rgb(*(colors[level][1].float_tuple()))
self.__draw_graph (ctx, height, maximum, [counts[level] for counts in dist_data])
self.__draw_graph(ctx, height, maximum, [
counts[level] for counts in dist_data])
# Draw error and warning triangle indicators:
@ -760,7 +773,8 @@ class TimelineWidget (Gtk.DrawingArea):
if clip:
if clip.x + clip.width < position1 - 1 or clip.x > position2 + 1:
self.logger.debug ("outside of clip range: %d + %d, pos: %d, %d", clip.x, clip.width, position1, position2)
self.logger.debug(
"outside of clip range: %d + %d, pos: %d, %d", clip.x, clip.width, position1, position2)
return
ctx.rectangle(clip.x, clip.y, clip.width, clip.height)
ctx.clip()
@ -847,6 +861,7 @@ class TimelineWidget (Gtk.DrawingArea):
pass
class AttachedWindow (object):
def __init__(self, feature, window):
@ -870,7 +885,8 @@ class AttachedWindow (object):
# "hide-before-line", Gtk.UIManagerItemType.MENUITEM, False)
# ui.add_ui (self.merge_id, "/TimelineContextMenu", "TimelineHideLinesAfter",
# "hide-after-line", Gtk.UIManagerItemType.MENUITEM, False)
ui.add_ui (self.merge_id, "/TimelineContextMenu", "TimelineShowHiddenLines",
ui.add_ui(
self.merge_id, "/TimelineContextMenu", "TimelineShowHiddenLines",
"show-hidden-lines", Gtk.UIManagerItemType.MENUITEM, False)
box = window.get_top_attach_point()
@ -900,7 +916,8 @@ class AttachedWindow (object):
handler(action)
handler = self.handle_log_view_notify_model
self.notify_model_id = window.log_view.connect ("notify::model", handler)
self.notify_model_id = window.log_view.connect(
"notify::model", handler)
self.idle_scroll_path = None
self.idle_scroll_id = None
@ -1027,6 +1044,7 @@ class AttachedWindow (object):
return False
class TimelineFeature (FeatureBase):
def __init__(self, app):
@ -1073,12 +1091,14 @@ class TimelineFeature (FeatureBase):
attached_window = self.attached_windows[window]
attached_window.handle_detach_log_file(log_file)
class TimelineState (Common.GUI.StateSection):
_name = "timeline"
shown = Common.GUI.StateBool("shown", default=True)
class Plugin (PluginBase):
features = [TimelineFeature]

View file

@ -23,7 +23,10 @@ __all__ = ["_", "_N", "FeatureBase", "PluginBase"]
import os.path
def _N (s): return s
def _N(s):
return s
def load(paths=()):
@ -31,9 +34,11 @@ def load (paths = ()):
for plugin_module in _load_plugins(path):
yield plugin_module.Plugin
def _load_plugins(path):
import imp, glob
import imp
import glob
files = glob.glob(os.path.join(path, "*.py"))
@ -46,6 +51,7 @@ def _load_plugins (path):
module = imp.load_module(name, fp, pathname, description)
yield module
class FeatureBase (object):
def __init__(self, app):
@ -68,6 +74,7 @@ class FeatureBase (object):
pass
class PluginBase (object):
features = ()
@ -75,4 +82,3 @@ class PluginBase (object):
def __init__(self, app):
pass