mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
New import (the old repo got busted, just had 4 revs anyways)
This commit is contained in:
parent
07391578c9
commit
71cddb7d78
20 changed files with 4410 additions and 0 deletions
53
debug-viewer/GstDebugViewer/Common/Data.py
Normal file
53
debug-viewer/GstDebugViewer/Common/Data.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
# -*- coding: utf-8; mode: python; -*-
|
||||
#
|
||||
# GStreamer Development Utilities
|
||||
#
|
||||
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""GStreamer development utilities common Data module"""
|
||||
|
||||
import pygtk
|
||||
pygtk.require ("2.0")
|
||||
|
||||
import gobject
|
||||
|
||||
class Dispatcher (object):
|
||||
|
||||
def __call__ (self, iterator):
|
||||
|
||||
raise NotImplementedError ("derived classes must override this method")
|
||||
|
||||
class DefaultDispatcher (Dispatcher):
|
||||
|
||||
def __call__ (self, iterator):
|
||||
|
||||
for x in iterator:
|
||||
pass
|
||||
|
||||
class GSourceDispatcher (Dispatcher):
|
||||
|
||||
def __init__ (self):
|
||||
|
||||
Dispatcher.__init__ (self)
|
||||
|
||||
self.source_id = None
|
||||
|
||||
def __call__ (self, iterator):
|
||||
|
||||
if self.source_id is not None:
|
||||
gobject.source_remove (self.source_id)
|
||||
|
||||
self.source_id = gobject.idle_add (iterator.next)
|
467
debug-viewer/GstDebugViewer/Common/GUI.py
Normal file
467
debug-viewer/GstDebugViewer/Common/GUI.py
Normal file
|
@ -0,0 +1,467 @@
|
|||
# -*- coding: utf-8; mode: python; -*-
|
||||
#
|
||||
# GStreamer Development Utilities
|
||||
#
|
||||
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""GStreamer development utilities common GUI module"""
|
||||
|
||||
import logging
|
||||
|
||||
import pygtk
|
||||
pygtk.require ("2.0")
|
||||
del pygtk
|
||||
|
||||
import gobject
|
||||
import gtk
|
||||
|
||||
from GstDebugViewer.Common import utils
|
||||
|
||||
class Actions (dict):
|
||||
|
||||
def __init__ (self):
|
||||
|
||||
dict.__init__ (self)
|
||||
|
||||
self.groups = ()
|
||||
|
||||
def __getattr__ (self, name):
|
||||
|
||||
try:
|
||||
return self[name]
|
||||
except KeyError:
|
||||
if "_" in name:
|
||||
try:
|
||||
return self[name.replace ("_", "-")]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
raise AttributeError ("no action with name %r" % (name,))
|
||||
|
||||
def add_group (self, group):
|
||||
|
||||
self.groups += (group,)
|
||||
for action in group.list_actions ():
|
||||
self[action.props.name] = action
|
||||
|
||||
class Widgets (dict):
|
||||
|
||||
def __init__ (self, glade_tree):
|
||||
|
||||
widgets = glade_tree.get_widget_prefix ("")
|
||||
dict.__init__ (self, ((w.name, w,) for w in widgets))
|
||||
|
||||
def __getattr__ (self, name):
|
||||
|
||||
try:
|
||||
return self[name]
|
||||
except KeyError:
|
||||
if "_" in name:
|
||||
try:
|
||||
return self[name.replace ("_", "-")]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
raise AttributeError ("no widget with name %r" % (name,))
|
||||
|
||||
class WidgetFactory (object):
|
||||
|
||||
def __init__ (self, glade_filename):
|
||||
|
||||
self.filename = glade_filename
|
||||
|
||||
def make (self, widget_name, autoconnect = None):
|
||||
|
||||
glade_tree = gtk.glade.XML (self.filename, widget_name)
|
||||
|
||||
if autoconnect is not None:
|
||||
glade_tree.signal_autoconnect (autoconnect)
|
||||
|
||||
return Widgets (glade_tree)
|
||||
|
||||
def make_one (self, widget_name):
|
||||
|
||||
glade_tree = gtk.glade.XML (self.filename, widget_name)
|
||||
|
||||
return glade_tree.get_widget (widget_name)
|
||||
|
||||
class UIFactory (object):
|
||||
|
||||
def __init__ (self, ui_filename, actions = None):
|
||||
|
||||
self.filename = ui_filename
|
||||
if actions:
|
||||
self.action_groups = actions.groups
|
||||
else:
|
||||
self.action_groups = ()
|
||||
|
||||
def make (self, extra_actions = None):
|
||||
|
||||
ui_manager = gtk.UIManager ()
|
||||
for action_group in self.action_groups:
|
||||
ui_manager.insert_action_group (action_group, 0)
|
||||
if extra_actions:
|
||||
for action_group in extra_actions.groups:
|
||||
ui_manager.insert_action_group (action_group, 0)
|
||||
ui_manager.add_ui_from_file (self.filename)
|
||||
ui_manager.ensure_update ()
|
||||
|
||||
return ui_manager
|
||||
|
||||
class MetaModel (gobject.GObjectMeta):
|
||||
|
||||
"""Meta class for easy setup of gtk tree models.
|
||||
|
||||
Looks for a class attribute named `columns' which must be set to a
|
||||
sequence of the form name1, type1, name2, type2, ..., where the
|
||||
names are strings. This metaclass adds the following attributes
|
||||
to created classes:
|
||||
|
||||
cls.column_types = (type1, type2, ...)
|
||||
cls.column_ids = (0, 1, ...)
|
||||
cls.name1 = 0
|
||||
cls.name2 = 1
|
||||
...
|
||||
|
||||
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)
|
||||
|
||||
Then insert data like this:
|
||||
|
||||
self.set (self.append (),
|
||||
self.COL_NAME, "spam",
|
||||
self.COL_VALUE, "ham")
|
||||
"""
|
||||
|
||||
def __init__ (cls, name, bases, dict):
|
||||
|
||||
super (MetaModel, cls).__init__ (name, bases, dict)
|
||||
|
||||
spec = tuple (cls.columns)
|
||||
|
||||
column_names = spec[::2]
|
||||
column_types = spec[1::2]
|
||||
column_indices = range (len (column_names))
|
||||
|
||||
for col_index, col_name, in zip (column_indices, column_names):
|
||||
setattr (cls, col_name, col_index)
|
||||
|
||||
cls.column_types = column_types
|
||||
cls.column_ids = tuple (column_indices)
|
||||
|
||||
class Manager (object):
|
||||
|
||||
"""GUI Manager base class."""
|
||||
|
||||
@classmethod
|
||||
def iter_item_classes (cls):
|
||||
|
||||
msg = "%s class does not support manager item class access"
|
||||
raise NotImplementedError (msg % (cls.__name__,))
|
||||
|
||||
@classmethod
|
||||
def find_item_class (self, **kw):
|
||||
|
||||
return self.__find_by_attrs (self.iter_item_classes (), kw)
|
||||
|
||||
def iter_items (self):
|
||||
|
||||
msg = "%s object does not support manager item access"
|
||||
raise NotImplementedError (msg % (type (self).__name__,))
|
||||
|
||||
def find_item (self, **kw):
|
||||
|
||||
return self.__find_by_attrs (self.iter_items (), kw)
|
||||
|
||||
@staticmethod
|
||||
def __find_by_attrs (i, kw):
|
||||
|
||||
from operator import attrgetter
|
||||
|
||||
if len (kw) != 1:
|
||||
raise ValueError ("need exactly one keyword argument")
|
||||
|
||||
attr, value = kw.items ()[0]
|
||||
getter = attrgetter (attr)
|
||||
|
||||
for item in i:
|
||||
if getter (item) == value:
|
||||
return item
|
||||
else:
|
||||
raise KeyError ("no item such that item.%s == %r" % (attr, value,))
|
||||
|
||||
class StateString (object):
|
||||
|
||||
"""Descriptor for binding to AppState classes."""
|
||||
|
||||
def __init__ (self, option, section = None):
|
||||
|
||||
self.option = option
|
||||
self.section = section
|
||||
|
||||
def get_section (self, state):
|
||||
|
||||
if self.section is None:
|
||||
return state._default_section
|
||||
else:
|
||||
return self.section
|
||||
|
||||
def get_getter (self, state):
|
||||
|
||||
return state._parser.get
|
||||
|
||||
def get_default (self, state):
|
||||
|
||||
return None
|
||||
|
||||
def __get__ (self, state, state_class = None):
|
||||
|
||||
import ConfigParser
|
||||
|
||||
if state is None:
|
||||
return self
|
||||
|
||||
getter = self.get_getter (state)
|
||||
section = self.get_section (state)
|
||||
|
||||
try:
|
||||
return getter (section, self.option)
|
||||
except (ConfigParser.NoSectionError,
|
||||
ConfigParser.NoOptionError,):
|
||||
return self.get_default (state)
|
||||
|
||||
def __set__ (self, state, value):
|
||||
|
||||
import ConfigParser
|
||||
|
||||
if value is None:
|
||||
value = ""
|
||||
|
||||
section = self.get_section (state)
|
||||
option = self.option
|
||||
option_value = str (value)
|
||||
|
||||
try:
|
||||
state._parser.set (section, option, option_value)
|
||||
except ConfigParser.NoSectionError:
|
||||
state._parser.add_section (section)
|
||||
state._parser.set (section, option, option_value)
|
||||
|
||||
class StateBool (StateString):
|
||||
|
||||
"""Descriptor for binding to AppState classes."""
|
||||
|
||||
def get_getter (self, state):
|
||||
|
||||
return state._parser.getboolean
|
||||
|
||||
class StateInt (StateString):
|
||||
|
||||
"""Descriptor for binding to AppState classes."""
|
||||
|
||||
def get_getter (self, state):
|
||||
|
||||
return state._parser.getint
|
||||
|
||||
class StateInt4 (StateString):
|
||||
|
||||
"""Descriptor for binding to AppState classes. This implements storing a
|
||||
tuple of 4 integers."""
|
||||
|
||||
def __get__ (self, state, state_class = None):
|
||||
|
||||
if state is None:
|
||||
return self
|
||||
|
||||
value = StateString.__get__ (self, state)
|
||||
|
||||
try:
|
||||
l = value.split (",")
|
||||
if len (l) != 4:
|
||||
return None
|
||||
else:
|
||||
return tuple ((int (v) for v in l))
|
||||
except (AttributeError, TypeError, ValueError,):
|
||||
return None
|
||||
|
||||
def __set__ (self, state, value):
|
||||
|
||||
if value is None:
|
||||
svalue = ""
|
||||
elif len (value) != 4:
|
||||
raise ValueError ("value needs to be a 4-sequence, or None")
|
||||
else:
|
||||
svalue = ", ".join ((str (v) for v in value))
|
||||
|
||||
return StateString.__set__ (self, state, svalue)
|
||||
|
||||
class StateItem (StateString):
|
||||
|
||||
"""Descriptor for binding to AppState classes. This implements storing a
|
||||
class controlled by a Manager class."""
|
||||
|
||||
def __init__ (self, option, manager_class, section = None):
|
||||
|
||||
StateString.__init__ (self, option, section = section)
|
||||
|
||||
self.manager = manager_class
|
||||
|
||||
def __get__ (self, state, state_class = None):
|
||||
|
||||
if state is None:
|
||||
return self
|
||||
|
||||
value = StateString.__get__ (self, state)
|
||||
|
||||
if not value:
|
||||
return None
|
||||
|
||||
return self.parse_item (value)
|
||||
|
||||
def __set__ (self, state, value):
|
||||
|
||||
if value is None:
|
||||
svalue = ""
|
||||
else:
|
||||
svalue = value.name
|
||||
|
||||
StateString.__set__ (self, state, svalue)
|
||||
|
||||
def parse_item (self, value):
|
||||
|
||||
name = value.strip ()
|
||||
|
||||
try:
|
||||
return self.manager.find_item_class (name = name)
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
class StateItemList (StateItem):
|
||||
|
||||
"""Descriptor for binding to AppState classes. This implements storing an
|
||||
ordered set of Manager items."""
|
||||
|
||||
def __get__ (self, state, state_class = None):
|
||||
|
||||
if state is None:
|
||||
return self
|
||||
|
||||
value = StateString.__get__ (self, state)
|
||||
|
||||
if not value:
|
||||
return []
|
||||
|
||||
classes = []
|
||||
for name in value.split (","):
|
||||
item_class = self.parse_item (name)
|
||||
if item_class is None:
|
||||
continue
|
||||
if not item_class in classes:
|
||||
classes.append (item_class)
|
||||
|
||||
return classes
|
||||
|
||||
def __set__ (self, state, value):
|
||||
|
||||
if value is None:
|
||||
svalue = ""
|
||||
else:
|
||||
svalue = ", ".join ((v.name for v in value))
|
||||
|
||||
StateString.__set__ (self, state, svalue)
|
||||
|
||||
class AppState (object):
|
||||
|
||||
_default_section = "state"
|
||||
|
||||
def __init__ (self, filename, old_filenames = ()):
|
||||
|
||||
import ConfigParser
|
||||
|
||||
self._filename = filename
|
||||
self._parser = ConfigParser.RawConfigParser ()
|
||||
success = self._parser.read ([filename])
|
||||
if not success:
|
||||
for old_filename in old_filenames:
|
||||
success = self._parser.read ([old_filename])
|
||||
if success:
|
||||
break
|
||||
|
||||
def save (self):
|
||||
|
||||
# TODO Py2.5: Use 'with' statement.
|
||||
fp = utils.SaveWriteFile (self._filename, "wt")
|
||||
try:
|
||||
self._parser.write (fp)
|
||||
except:
|
||||
fp.discard ()
|
||||
else:
|
||||
fp.close ()
|
||||
|
||||
class WindowState (object):
|
||||
|
||||
def __init__ (self):
|
||||
|
||||
self.logger = logging.getLogger ("ui.window-state")
|
||||
|
||||
self.is_maximized = False
|
||||
|
||||
def attach (self, window, state):
|
||||
|
||||
self.window = window
|
||||
self.state = state
|
||||
|
||||
self.window.connect ("window-state-event",
|
||||
self.handle_window_state_event)
|
||||
|
||||
geometry = self.state.geometry
|
||||
if geometry:
|
||||
self.window.move (*geometry[:2])
|
||||
self.window.set_default_size (*geometry[2:])
|
||||
|
||||
if self.state.maximized:
|
||||
self.logger.debug ("initially maximized")
|
||||
self.window.maximize ()
|
||||
|
||||
def detach (self):
|
||||
|
||||
window = self.window
|
||||
|
||||
self.state.maximized = self.is_maximized
|
||||
if not self.is_maximized:
|
||||
position = tuple (window.get_position ())
|
||||
size = tuple (window.get_size ())
|
||||
self.state.geometry = position + size
|
||||
|
||||
self.window.disconnect_by_func (self.handle_window_state_event)
|
||||
self.window = None
|
||||
|
||||
def handle_window_state_event (self, window, event):
|
||||
|
||||
if not event.changed_mask & gtk.gdk.WINDOW_STATE_MAXIMIZED:
|
||||
return
|
||||
|
||||
if event.new_window_state & gtk.gdk.WINDOW_STATE_MAXIMIZED:
|
||||
self.logger.debug ("maximized")
|
||||
self.is_maximized = True
|
||||
else:
|
||||
self.logger.debug ("unmaximized")
|
||||
self.is_maximized = False
|
479
debug-viewer/GstDebugViewer/Common/Main.py
Normal file
479
debug-viewer/GstDebugViewer/Common/Main.py
Normal file
|
@ -0,0 +1,479 @@
|
|||
# -*- coding: utf-8; mode: python; -*-
|
||||
#
|
||||
# GStreamer Development Utilities
|
||||
#
|
||||
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""GStreamer development utilities common main module."""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import traceback
|
||||
from operator import attrgetter
|
||||
import logging
|
||||
import locale
|
||||
import gettext
|
||||
from gettext import gettext as _, ngettext
|
||||
|
||||
import pygtk
|
||||
pygtk.require ("2.0")
|
||||
del pygtk
|
||||
|
||||
import gobject
|
||||
|
||||
class ExceptionHandler (object):
|
||||
|
||||
exc_types = (Exception,)
|
||||
priority = 50
|
||||
inherit_fork = True
|
||||
|
||||
_handling_exception = False
|
||||
|
||||
def __call__ (self, exc_type, exc_value, exc_traceback):
|
||||
|
||||
raise NotImplementedError ("derived classes need to override this method")
|
||||
|
||||
class DefaultExceptionHandler (ExceptionHandler):
|
||||
|
||||
# TODO Py2.5: In Python 2.5, this succeeds. Remove the try...except block
|
||||
# once we depend on 2.5.
|
||||
try:
|
||||
exc_types = (BaseException,)
|
||||
except NameError:
|
||||
# Python < 2.5.
|
||||
exc_types = (Exception,)
|
||||
priority = 0
|
||||
inherit_fork = True
|
||||
|
||||
def __init__ (self, excepthook):
|
||||
|
||||
ExceptionHandler.__init__ (self)
|
||||
|
||||
self.excepthook = excepthook
|
||||
|
||||
def __call__ (self, *exc_info):
|
||||
|
||||
return self.excepthook (*exc_info)
|
||||
|
||||
class ExitOnInterruptExceptionHandler (ExceptionHandler):
|
||||
|
||||
exc_types = (KeyboardInterrupt,)
|
||||
priority = 100
|
||||
inherit_fork = False
|
||||
|
||||
exit_status = 2
|
||||
|
||||
def __call__ (self, *args):
|
||||
|
||||
print >> sys.stderr, "Interrupt caught, exiting."
|
||||
|
||||
sys.exit (self.exit_status)
|
||||
|
||||
class MainLoopWrapper (ExceptionHandler):
|
||||
|
||||
priority = 95
|
||||
inherit_fork = False
|
||||
|
||||
def __init__ (self, enter, exit):
|
||||
|
||||
ExceptionHandler.__init__ (self)
|
||||
|
||||
self.exc_info = (None,) * 3
|
||||
self.enter = enter
|
||||
self.exit = exit
|
||||
|
||||
def __call__ (self, *exc_info):
|
||||
|
||||
self.exc_info = exc_info
|
||||
self.exit ()
|
||||
|
||||
def run (self):
|
||||
|
||||
ExceptHookManager.register_handler (self)
|
||||
try:
|
||||
self.enter ()
|
||||
finally:
|
||||
ExceptHookManager.unregister_handler (self)
|
||||
|
||||
if self.exc_info != (None,) * 3:
|
||||
# Re-raise unhandled exception that occured while running the loop.
|
||||
exc_type, exc_value, exc_tb = self.exc_info
|
||||
raise exc_type, exc_value, exc_tb
|
||||
|
||||
class ExceptHookManagerClass (object):
|
||||
|
||||
def __init__ (self):
|
||||
|
||||
self._in_forked_child = False
|
||||
|
||||
self.handlers = []
|
||||
|
||||
def setup (self):
|
||||
|
||||
if sys.excepthook == self.__excepthook:
|
||||
raise ValueError ("already set up")
|
||||
|
||||
hook = sys.excepthook
|
||||
self.__instrument_excepthook ()
|
||||
self.__instrument_fork ()
|
||||
self.register_handler (DefaultExceptionHandler (hook))
|
||||
|
||||
def shutdown (self):
|
||||
|
||||
if sys.excepthook != self.__excepthook:
|
||||
raise ValueError ("not set up")
|
||||
|
||||
self.__restore_excepthook ()
|
||||
self.__restore_fork ()
|
||||
|
||||
def __instrument_excepthook (self):
|
||||
|
||||
hook = sys.excepthook
|
||||
self._original_excepthook = hook
|
||||
sys.excepthook = self.__excepthook
|
||||
|
||||
def __restore_excepthook (self):
|
||||
|
||||
sys.excepthook = self._original_excepthook
|
||||
|
||||
def __instrument_fork (self):
|
||||
|
||||
try:
|
||||
fork = os.fork
|
||||
except AttributeError:
|
||||
# System has no fork() system call.
|
||||
self._original_fork = None
|
||||
else:
|
||||
self._original_fork = fork
|
||||
os.fork = self.__fork
|
||||
|
||||
def __restore_fork (self):
|
||||
|
||||
if not hasattr (os, "fork"):
|
||||
return
|
||||
|
||||
os.fork = self._original_fork
|
||||
|
||||
def entered_forked_child (self):
|
||||
|
||||
self._in_forked_child = True
|
||||
|
||||
for handler in tuple (self.handlers):
|
||||
if not handler.inherit_fork:
|
||||
self.handlers.remove (handler)
|
||||
|
||||
def register_handler (self, handler):
|
||||
|
||||
if self._in_forked_child and not handler.inherit_fork:
|
||||
return
|
||||
|
||||
self.handlers.append (handler)
|
||||
|
||||
def unregister_handler (self, handler):
|
||||
|
||||
self.handlers.remove (handler)
|
||||
|
||||
def __fork (self):
|
||||
|
||||
pid = self._original_fork ()
|
||||
if pid == 0:
|
||||
# Child process.
|
||||
self.entered_forked_child ()
|
||||
return pid
|
||||
|
||||
def __excepthook (self, exc_type, exc_value, exc_traceback):
|
||||
|
||||
for handler in sorted (self.handlers,
|
||||
key = attrgetter ("priority"),
|
||||
reverse = True):
|
||||
|
||||
if handler._handling_exception:
|
||||
continue
|
||||
|
||||
for type_ in handler.exc_types:
|
||||
if issubclass (exc_type, type_):
|
||||
break
|
||||
else:
|
||||
continue
|
||||
|
||||
handler._handling_exception = True
|
||||
handler (exc_type, exc_value, exc_traceback)
|
||||
# Not using try...finally on purpose here. If the handler itself
|
||||
# fails with an exception, this prevents recursing into it again.
|
||||
handler._handling_exception = False
|
||||
return
|
||||
|
||||
else:
|
||||
from warnings import warn
|
||||
warn ("ExceptHookManager: unhandled %r" % (exc_value,),
|
||||
RuntimeWarning,
|
||||
stacklevel = 2)
|
||||
|
||||
ExceptHookManager = ExceptHookManagerClass ()
|
||||
|
||||
class PathsBase (object):
|
||||
|
||||
data_dir = None
|
||||
icon_dir = None
|
||||
locale_dir = None
|
||||
|
||||
@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)."""
|
||||
|
||||
pass
|
||||
|
||||
@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__)))
|
||||
cls.setup_uninstalled (source_dir)
|
||||
|
||||
def __new__ (cls):
|
||||
|
||||
raise RuntimeError ("do not create instances of this class -- "
|
||||
"use the class object directly")
|
||||
|
||||
class PathsProgramBase (PathsBase):
|
||||
|
||||
program_name = None
|
||||
|
||||
@classmethod
|
||||
def setup_installed (cls, data_prefix):
|
||||
|
||||
if cls.program_name is None:
|
||||
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")
|
||||
cls.locale_dir = os.path.join (data_prefix, "share", "locale")
|
||||
|
||||
@classmethod
|
||||
def setup_uninstalled (cls, source_dir):
|
||||
|
||||
"""Set up paths for running 'uninstalled' (i.e. directly from the
|
||||
source dist)."""
|
||||
|
||||
# This is essential: The GUI module needs to find the .glade file.
|
||||
cls.data_dir = os.path.join (source_dir, "data")
|
||||
|
||||
# The locale data might be missing if "setup.py build" wasn't run.
|
||||
cls.locale_dir = os.path.join (source_dir, "build", "mo")
|
||||
|
||||
# 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):
|
||||
|
||||
self.__entries = []
|
||||
self.__parsers = {}
|
||||
|
||||
self.options = options
|
||||
|
||||
def add_option (self, long_name, short_name = None, description = None,
|
||||
arg_name = None, arg_parser = None, hidden = False):
|
||||
|
||||
flags = 0
|
||||
|
||||
if not short_name:
|
||||
# A deficiency of pygobject:
|
||||
short_name = "\0"
|
||||
|
||||
if not description:
|
||||
description = ""
|
||||
|
||||
if arg_name is None:
|
||||
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
|
||||
|
||||
self.__entries.append ((long_name, short_name, flags, description,
|
||||
arg_name,))
|
||||
|
||||
def __handle_option (self, option, arg, group):
|
||||
|
||||
for entry in self.__entries:
|
||||
long_name, short_name = entry[:2]
|
||||
arg_name = entry[-1]
|
||||
if (option != "--%s" % (long_name,) and
|
||||
option != "-%s" % (short_name,)):
|
||||
continue
|
||||
attr = long_name.replace ("-", "_")
|
||||
if arg_name is None:
|
||||
value = True
|
||||
elif long_name in self.__parsers:
|
||||
value = self.__parsers[long_name](arg)
|
||||
else:
|
||||
value = arg
|
||||
self.options[attr] = value
|
||||
|
||||
def parse (self, argv):
|
||||
|
||||
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:
|
||||
context.parse (argv)
|
||||
except gobject.GError, exc:
|
||||
raise OptionError (exc.message)
|
||||
|
||||
self.handle_parse_complete ()
|
||||
|
||||
def get_parameter_string (self):
|
||||
|
||||
raise NotImplementedError ("derived classes must override this method")
|
||||
|
||||
def handle_parse_complete (self):
|
||||
|
||||
pass
|
||||
|
||||
class LogOptionParser (OptionParser):
|
||||
|
||||
"""Like OptionParser, but adds a --log-level option."""
|
||||
|
||||
def __init__ (self, *a, **kw):
|
||||
|
||||
OptionParser.__init__ (self, *a, **kw)
|
||||
|
||||
# TODO: Re-evaluate usage of log levels to use less of them. Like
|
||||
# unifying warning, error and critical.
|
||||
|
||||
self.add_option ("log-level", "l",
|
||||
"%s (debug, info, warning, error, critical)"
|
||||
% (_("Enable logging"),),
|
||||
"LEVEL", self.parse_log_level)
|
||||
|
||||
@staticmethod
|
||||
def parse_log_level (arg):
|
||||
|
||||
try:
|
||||
level = int (arg)
|
||||
except ValueError:
|
||||
level = {"off" : logging.NOTSET,
|
||||
"none" : logging.NOTSET,
|
||||
"debug" : logging.DEBUG,
|
||||
"info" : logging.INFO,
|
||||
"warning" : logging.WARNING,
|
||||
"error" : logging.ERROR,
|
||||
"critical" : logging.CRITICAL}.get (arg.strip ().lower ())
|
||||
if level is None:
|
||||
return logging.NOTSET
|
||||
else:
|
||||
return level
|
||||
else:
|
||||
if level < 0:
|
||||
level = 0
|
||||
elif level > 5:
|
||||
level = 5
|
||||
return {0 : logging.NOTSET,
|
||||
1 : logging.DEBUG,
|
||||
2 : logging.INFO,
|
||||
3 : logging.WARNING,
|
||||
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:
|
||||
try:
|
||||
locale.setlocale (locale.LC_ALL, "")
|
||||
except locale.Error, exc:
|
||||
from warnings import warn
|
||||
warn ("locale error: %s" % (exc,),
|
||||
RuntimeWarning,
|
||||
stacklevel = 2)
|
||||
Paths.locale_dir = None
|
||||
else:
|
||||
gettext.bindtextdomain (gettext_domain, Paths.locale_dir)
|
||||
gettext.textdomain (gettext_domain)
|
||||
gettext.bind_textdomain_codeset (gettext_domain, "UTF-8")
|
||||
|
||||
def _init_options (option_parser = None):
|
||||
|
||||
if option_parser is None:
|
||||
return {}
|
||||
|
||||
try:
|
||||
option_parser.parse (sys.argv)
|
||||
except OptionError, exc:
|
||||
print >> sys.stderr, exc.args[0]
|
||||
sys.exit (1)
|
||||
|
||||
return option_parser.options
|
||||
|
||||
def _init_logging (level = logging.NOTSET):
|
||||
|
||||
logging.basicConfig (level = level,
|
||||
format = '%(asctime)s.%(msecs)03d %(levelname)8s %(name)20s: %(message)s',
|
||||
datefmt = '%H:%M:%S')
|
||||
|
||||
logger = logging.getLogger ("main")
|
||||
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:
|
||||
global Paths
|
||||
Paths = paths
|
||||
|
||||
_init_excepthooks ()
|
||||
_init_paths (paths)
|
||||
_init_locale (gettext_domain)
|
||||
options = _init_options (option_parser)
|
||||
try:
|
||||
log_level = options["log_level"]
|
||||
except KeyError:
|
||||
_init_logging ()
|
||||
else:
|
||||
_init_logging (log_level)
|
||||
|
||||
try:
|
||||
options["main"] ()
|
||||
finally:
|
||||
logging.shutdown ()
|
19
debug-viewer/GstDebugViewer/Common/__init__.py
Normal file
19
debug-viewer/GstDebugViewer/Common/__init__.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
# -*- coding: utf-8; mode: python; -*-
|
||||
#
|
||||
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""GStreamer development utilities common module"""
|
||||
|
324
debug-viewer/GstDebugViewer/Common/utils.py
Normal file
324
debug-viewer/GstDebugViewer/Common/utils.py
Normal file
|
@ -0,0 +1,324 @@
|
|||
# -*- coding: utf-8; mode: python; -*-
|
||||
#
|
||||
# GStreamer Inspector - Multimedia system plugin introspection
|
||||
#
|
||||
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Misc utilities."""
|
||||
|
||||
import os
|
||||
import logging
|
||||
import subprocess as _subprocess
|
||||
|
||||
class SingletonMeta (type):
|
||||
|
||||
def __init__ (cls, name, bases, dict_):
|
||||
|
||||
from weakref import WeakValueDictionary
|
||||
|
||||
super (SingletonMeta, cls).__init__ (name, bases, dict_)
|
||||
|
||||
cls._singleton_instances = WeakValueDictionary ()
|
||||
|
||||
def __call__ (cls, *a, **kw):
|
||||
|
||||
kw_key = tuple (sorted (kw.iteritems ()))
|
||||
|
||||
try:
|
||||
obj = cls._singleton_instances[a + kw_key]
|
||||
except KeyError:
|
||||
obj = super (SingletonMeta, cls).__call__ (*a, **kw)
|
||||
cls._singleton_instances[a + kw_key] = obj
|
||||
return obj
|
||||
|
||||
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
|
||||
bottleneck."""
|
||||
|
||||
from gettext import gettext
|
||||
|
||||
d = {}
|
||||
|
||||
def gettext_cache_access (s):
|
||||
|
||||
if not s in d:
|
||||
d[s] = gettext (s)
|
||||
return d[s]
|
||||
|
||||
return gettext_cache_access
|
||||
|
||||
class ClassProperty (property):
|
||||
|
||||
"Like the property class, but also invokes the getter for class access."
|
||||
|
||||
def __init__ (self, fget = None, fset = None, fdel = None, doc = None):
|
||||
|
||||
property.__init__ (self, fget, fset, fdel, doc)
|
||||
|
||||
self.__fget = fget
|
||||
|
||||
def __get__ (self, obj, obj_class = None):
|
||||
|
||||
ret = property.__get__ (self, obj, obj_class)
|
||||
if ret == self:
|
||||
return self.__fget (None)
|
||||
else:
|
||||
return ret
|
||||
|
||||
class _XDGClass (object):
|
||||
|
||||
"""Partial implementation of the XDG Base Directory specification v0.6.
|
||||
|
||||
http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html"""
|
||||
|
||||
def __init__ (self):
|
||||
|
||||
self._add_base_dir ("DATA_HOME", "~/.local/share")
|
||||
self._add_base_dir ("CONFIG_HOME", "~/.config")
|
||||
self._add_base_dir ("CACHE_HOME", "~/.cache")
|
||||
|
||||
def _add_base_dir (self, name, default):
|
||||
|
||||
dir = os.environ.get ("XDG_%s" % (name,))
|
||||
if not dir:
|
||||
dir = os.path.expanduser (os.path.join (*default.split ("/")))
|
||||
|
||||
setattr (self, name, dir)
|
||||
|
||||
XDG = _XDGClass ()
|
||||
|
||||
class SaveWriteFile (object):
|
||||
|
||||
def __init__ (self, filename, mode = "wt"):
|
||||
|
||||
from tempfile import mkstemp
|
||||
|
||||
self.logger = logging.getLogger ("tempfile")
|
||||
|
||||
dir = os.path.dirname (filename)
|
||||
base_name = os.path.basename (filename)
|
||||
temp_prefix = "%s-tmp" % (base_name,)
|
||||
|
||||
if dir:
|
||||
# Destination dir differs from current directory, ensure that it
|
||||
# exists:
|
||||
try:
|
||||
os.makedirs (dir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
self.clean_stale (dir, temp_prefix)
|
||||
|
||||
fd, temp_name = mkstemp (dir = dir, prefix = temp_prefix)
|
||||
|
||||
self.target_name = filename
|
||||
self.temp_name = temp_name
|
||||
self.real_file = os.fdopen (fd, mode)
|
||||
|
||||
def __enter__ (self):
|
||||
|
||||
return self
|
||||
|
||||
def __exit__ (self, *exc_args):
|
||||
|
||||
if exc_args == (None, None, None,):
|
||||
self.close ()
|
||||
else:
|
||||
self.discard ()
|
||||
|
||||
def __del__ (self):
|
||||
|
||||
try:
|
||||
self.discard ()
|
||||
except AttributeError:
|
||||
# If __init__ failed, self has no real_file attribute.
|
||||
pass
|
||||
|
||||
def __close_real (self):
|
||||
|
||||
if self.real_file:
|
||||
self.real_file.close ()
|
||||
self.real_file = None
|
||||
|
||||
def clean_stale (self, dir, temp_prefix):
|
||||
|
||||
from time import time
|
||||
from glob import glob
|
||||
|
||||
now = time ()
|
||||
pattern = os.path.join (dir, "%s*" % (temp_prefix,))
|
||||
|
||||
for temp_filename in glob (pattern):
|
||||
mtime = os.stat (temp_filename).st_mtime
|
||||
if now - mtime > 3600:
|
||||
self.logger.info ("deleting stale temporary file %s",
|
||||
temp_filename)
|
||||
try:
|
||||
os.unlink (temp_filename)
|
||||
except EnvironmentError, exc:
|
||||
self.logger.warning ("deleting stale temporary file "
|
||||
"failed: %s", exc)
|
||||
|
||||
def tell (self, *a, **kw):
|
||||
|
||||
return self.real_file.tell (*a, **kw)
|
||||
|
||||
def write (self, *a, **kw):
|
||||
|
||||
return self.real_file.write (*a, **kw)
|
||||
|
||||
def close (self):
|
||||
|
||||
self.__close_real ()
|
||||
|
||||
if self.temp_name:
|
||||
try:
|
||||
os.rename (self.temp_name, self.target_name)
|
||||
except OSError, exc:
|
||||
import errno
|
||||
if exc.errno == errno.EEXIST:
|
||||
# We are probably on windows.
|
||||
os.unlink (self.target_name)
|
||||
os.rename (self.temp_name, self.target_name)
|
||||
self.temp_name = None
|
||||
|
||||
def discard (self):
|
||||
|
||||
self.__close_real ()
|
||||
|
||||
if self.temp_name:
|
||||
|
||||
try:
|
||||
os.unlink (self.temp_name)
|
||||
except EnvironmentError, exc:
|
||||
self.logger.warning ("deleting temporary file failed: %s", exc)
|
||||
self.temp_name = None
|
||||
|
||||
class TeeWriteFile (object):
|
||||
|
||||
# TODO Py2.5: Add context manager methods.
|
||||
|
||||
def __init__ (self, *file_objects):
|
||||
|
||||
self.files = list (file_objects)
|
||||
|
||||
def close (self):
|
||||
|
||||
for file in self.files:
|
||||
file.close ()
|
||||
|
||||
def flush (self):
|
||||
|
||||
for file in self.files:
|
||||
file.flush ()
|
||||
|
||||
def write (self, string):
|
||||
|
||||
for file in self.files:
|
||||
file.write (string)
|
||||
|
||||
def writelines (self, lines):
|
||||
|
||||
for file in self.files:
|
||||
file.writelines (lines)
|
||||
|
||||
class FixedPopen (_subprocess.Popen):
|
||||
|
||||
def __init__ (self, args, **kw):
|
||||
|
||||
# Unconditionally specify all descriptors as redirected, to
|
||||
# work around Python bug #1358527 (which is triggered for
|
||||
# console-less applications on Windows).
|
||||
|
||||
close = []
|
||||
|
||||
for name in ("stdin", "stdout", "stderr",):
|
||||
target = kw.get (name)
|
||||
if not target:
|
||||
kw[name] = _subprocess.PIPE
|
||||
close.append (name)
|
||||
|
||||
_subprocess.Popen.__init__ (self, args, **kw)
|
||||
|
||||
for name in close:
|
||||
fp = getattr (self, name)
|
||||
fp.close ()
|
||||
setattr (self, name, None)
|
||||
|
||||
class DevhelpError (EnvironmentError):
|
||||
|
||||
pass
|
||||
|
||||
class DevhelpUnavailableError (DevhelpError):
|
||||
|
||||
pass
|
||||
|
||||
class DevhelpClient (object):
|
||||
|
||||
def available (self):
|
||||
|
||||
try:
|
||||
self.version ()
|
||||
except DevhelpUnavailableError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def version (self):
|
||||
|
||||
return self._invoke ("--version")
|
||||
|
||||
def search (self, entry):
|
||||
|
||||
self._invoke_no_interact ("-s", entry)
|
||||
|
||||
def _check_os_error (self, exc):
|
||||
|
||||
import errno
|
||||
if exc.errno == errno.ENOENT:
|
||||
raise DevhelpUnavailableError ()
|
||||
|
||||
def _invoke (self, *args):
|
||||
|
||||
from subprocess import PIPE
|
||||
|
||||
try:
|
||||
proc = FixedPopen (("devhelp",) + args,
|
||||
stdout = PIPE)
|
||||
except OSError, exc:
|
||||
self._check_os_error (exc)
|
||||
raise
|
||||
|
||||
out, err = proc.communicate ()
|
||||
|
||||
if proc.returncode is not None and proc.returncode != 0:
|
||||
raise DevhelpError ("devhelp exited with status %i"
|
||||
% (proc.returncode,))
|
||||
return out
|
||||
|
||||
def _invoke_no_interact (self, *args):
|
||||
|
||||
from subprocess import PIPE
|
||||
|
||||
try:
|
||||
proc = FixedPopen (("devhelp",) + args)
|
||||
except OSError, exc:
|
||||
self._check_os_error (exc)
|
||||
raise
|
||||
|
247
debug-viewer/GstDebugViewer/Data.py
Normal file
247
debug-viewer/GstDebugViewer/Data.py
Normal file
|
@ -0,0 +1,247 @@
|
|||
# -*- coding: utf-8; mode: python; -*-
|
||||
#
|
||||
# GStreamer Debug Viewer
|
||||
#
|
||||
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""GStreamer debug viewer data module"""
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
# Nanosecond resolution (like gst.SECOND)
|
||||
SECOND = 1000000000
|
||||
|
||||
def time_args (ts):
|
||||
|
||||
secs = ts // SECOND
|
||||
|
||||
return "%i:%02i:%02i.%09i" % (secs // 60**2,
|
||||
secs // 60 % 60,
|
||||
secs % 60,
|
||||
ts % SECOND,)
|
||||
|
||||
def time_args_no_hours (ts):
|
||||
|
||||
secs = ts // SECOND
|
||||
|
||||
return "%02i:%02i.%09i" % (secs // 60,
|
||||
secs % 60,
|
||||
ts % SECOND,)
|
||||
|
||||
def parse_time (st):
|
||||
|
||||
"""Parse time strings that look like "0:00:00.0000000"."""
|
||||
|
||||
h, m, s = st.split (":")
|
||||
secs, subsecs = s.split (".")
|
||||
|
||||
return (long ((int (h) * 60**2 + int (m) * 60) * SECOND) +
|
||||
long (secs) * SECOND + long (subsecs))
|
||||
|
||||
class DebugLevel (int):
|
||||
|
||||
__names = ["NONE", "ERROR", "WARNING", "INFO", "DEBUG", "LOG"]
|
||||
__instances = {}
|
||||
|
||||
def __new__ (cls, level):
|
||||
|
||||
try:
|
||||
level_int = int (level)
|
||||
except (ValueError, TypeError,):
|
||||
try:
|
||||
level_int = cls.__names.index (level.upper ())
|
||||
except ValueError:
|
||||
raise ValueError ("no debug level named %r" % (level,))
|
||||
if level_int in cls.__instances:
|
||||
return cls.__instances[level_int]
|
||||
else:
|
||||
new_instance = int.__new__ (cls, level_int)
|
||||
new_instance.name = cls.__names[level_int]
|
||||
cls.__instances[level_int] = new_instance
|
||||
return new_instance
|
||||
|
||||
def __repr__ (self):
|
||||
|
||||
return "<%s %s (%i)>" % (type (self).__name__, self.__names[self], self,)
|
||||
|
||||
def higher_level (self):
|
||||
|
||||
if self == len (self.__names) - 1:
|
||||
raise ValueError ("already the highest debug level")
|
||||
|
||||
return DebugLevel (self + 1)
|
||||
|
||||
def lower_level (self):
|
||||
|
||||
if self == 0:
|
||||
raise ValueError ("already the lowest debug level")
|
||||
|
||||
return DebugLevel (self - 1)
|
||||
|
||||
DebugLevelNone = DebugLevel ("NONE")
|
||||
DebugLevelError = DebugLevel ("ERROR")
|
||||
DebugLevelWarning = DebugLevel ("WARNING")
|
||||
DebugLevelInfo = DebugLevel ("INFO")
|
||||
DebugLevelDebug = DebugLevel ("DEBUG")
|
||||
DebugLevelLog = DebugLevel ("LOG")
|
||||
|
||||
# For stripping color codes:
|
||||
_escape = re.compile ("\x1b\\[[0-9;]*m")
|
||||
def strip_escape (s):
|
||||
|
||||
return _escape.sub ("", s)
|
||||
|
||||
def default_log_line_regex_ ():
|
||||
|
||||
# "DEBUG "
|
||||
LEVEL = "([A-Z]+) +"
|
||||
# "0x8165430 "
|
||||
THREAD = r"(0x[0-9a-f]+) +" #r"\((0x[0-9a-f]+) - "
|
||||
# "0:00:00.777913000 "
|
||||
#TIME = r"([0-9]+:[0-9][0-9]:[0-9][0-9]\.[0-9]+) +"
|
||||
TIME = " +" # Only eating whitespace before PID away, we parse timestamps
|
||||
# without regex.
|
||||
CATEGORY = "([A-Za-z_-]+) +" # "GST_REFCOUNTING ", "flacdec "
|
||||
# " 3089 "
|
||||
PID = r"([0-9]+) +"
|
||||
FILENAME = r"([^:]+):"
|
||||
LINE = r"([0-9]+):"
|
||||
FUNCTION = "([A-Za-z0-9_]+):"
|
||||
# FIXME: When non-g(st)object stuff is logged with *_OBJECT (like
|
||||
# buffers!), the address is printed *without* <> brackets!
|
||||
OBJECT = "(?:<([^>]+)>)?"
|
||||
MESSAGE = " (.+)"
|
||||
|
||||
expressions = [TIME, PID, THREAD, LEVEL, CATEGORY, 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):
|
||||
|
||||
self.consumers = []
|
||||
|
||||
def have_load_started (self):
|
||||
|
||||
for consumer in self.consumers:
|
||||
consumer.handle_load_started ()
|
||||
|
||||
def have_load_finished (self):
|
||||
|
||||
for consumer in self.consumers:
|
||||
consumer.handle_load_finished ()
|
||||
|
||||
class LineCache (Producer):
|
||||
|
||||
_lines_per_iteration = 1000
|
||||
|
||||
def __init__ (self, fileobj, dispatcher):
|
||||
|
||||
Producer.__init__ (self)
|
||||
|
||||
self.logger = logging.getLogger ("linecache")
|
||||
|
||||
self.offsets = []
|
||||
self.dispatcher = dispatcher
|
||||
|
||||
import mmap
|
||||
self.__fileobj = mmap.mmap (fileobj.fileno (), 0, prot = mmap.PROT_READ)
|
||||
|
||||
self.__fileobj.seek (0, 2)
|
||||
self.__file_size = self.__fileobj.tell ()
|
||||
self.__fileobj.seek (0)
|
||||
|
||||
def start_loading (self):
|
||||
|
||||
self.logger.debug ("dispatching load process")
|
||||
self.have_load_started ()
|
||||
self.dispatcher (self.__process ())
|
||||
|
||||
def get_progress (self):
|
||||
|
||||
return float (self.__fileobj.tell ()) / self.__file_size
|
||||
|
||||
def __process (self):
|
||||
|
||||
offsets = self.offsets
|
||||
readline = self.__fileobj.readline
|
||||
tell = self.__fileobj.tell
|
||||
|
||||
self.__fileobj.seek (0)
|
||||
limit = self._lines_per_iteration
|
||||
i = 0
|
||||
while True:
|
||||
offset = tell ()
|
||||
line = readline ()
|
||||
if not line:
|
||||
break
|
||||
if not line.strip ():
|
||||
# Ignore empty lines, especially the one established by the
|
||||
# final newline at the end:
|
||||
continue
|
||||
# FIXME: We need to handle foreign lines separately!
|
||||
if line[1] != ":" or line[4] != ":" or line[7] != ".":
|
||||
# No timestamp at start, ignore line:
|
||||
continue
|
||||
offsets.append (offset)
|
||||
i += 1
|
||||
if i == limit:
|
||||
yield True
|
||||
|
||||
self.have_load_finished ()
|
||||
yield False
|
||||
|
||||
class LogFile (Producer):
|
||||
|
||||
def __init__ (self, filename, dispatcher):
|
||||
|
||||
Producer.__init__ (self)
|
||||
|
||||
self.logger = logging.getLogger ("logfile")
|
||||
|
||||
self.fileobj = file (filename, "rb")
|
||||
self.line_cache = LineCache (self.fileobj, dispatcher)
|
||||
self.line_cache.consumers.append (self)
|
||||
|
||||
def start_loading (self):
|
||||
|
||||
self.logger.debug ("starting load")
|
||||
self.line_cache.start_loading ()
|
||||
|
||||
def get_load_progress (self):
|
||||
|
||||
return self.line_cache.get_progress ()
|
||||
|
||||
def handle_load_started (self):
|
||||
|
||||
# Chain up to our consumers:
|
||||
self.have_load_started ()
|
||||
|
||||
def handle_load_finished (self):
|
||||
|
||||
# Chain up to our consumers:
|
||||
self.have_load_finished ()
|
||||
|
1196
debug-viewer/GstDebugViewer/GUI.py
Executable file
1196
debug-viewer/GstDebugViewer/GUI.py
Executable file
File diff suppressed because it is too large
Load diff
75
debug-viewer/GstDebugViewer/Main.py
Normal file
75
debug-viewer/GstDebugViewer/Main.py
Normal file
|
@ -0,0 +1,75 @@
|
|||
# -*- coding: utf-8; mode: python; -*-
|
||||
#
|
||||
# GStreamer Debug Viewer
|
||||
#
|
||||
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""GStreamer debug viewer main module"""
|
||||
|
||||
import sys
|
||||
from gettext import gettext as _, ngettext
|
||||
|
||||
import GstDebugViewer.Common.Main
|
||||
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):
|
||||
|
||||
Common.Main.LogOptionParser.__init__ (self, options)
|
||||
|
||||
options["main"] = None
|
||||
|
||||
self.add_option ("version", None, _("Display version and exit"))
|
||||
|
||||
def get_parameter_string (self):
|
||||
|
||||
return _("- Display and analyze debug log files")
|
||||
|
||||
def handle_parse_complete (self):
|
||||
|
||||
try:
|
||||
version = self.options["version"]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
main_version ()
|
||||
sys.exit (0)
|
||||
|
||||
if self.options["main"] is None:
|
||||
import GUI
|
||||
self.options["main"] = GUI.main
|
||||
|
||||
def main ():
|
||||
|
||||
options = {}
|
||||
parser = OptionParser (options)
|
||||
|
||||
Common.Main.main (option_parser = parser,
|
||||
gettext_domain = GETTEXT_DOMAIN,
|
||||
paths = Paths)
|
42
debug-viewer/GstDebugViewer/Plugins/ColorizeRows.py
Normal file
42
debug-viewer/GstDebugViewer/Plugins/ColorizeRows.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
from GstDebugViewer.Plugins import FeatureBase, PluginBase
|
||||
|
||||
class ColorizeLevels (FeatureBase):
|
||||
|
||||
def attach (self, window):
|
||||
|
||||
pass
|
||||
|
||||
def detach (self, window):
|
||||
|
||||
pass
|
||||
|
||||
class LevelColorSentinel (object):
|
||||
|
||||
def processor (self, proc):
|
||||
|
||||
for row in proc:
|
||||
|
||||
yield None
|
||||
|
||||
class ColorizeCategories (FeatureBase):
|
||||
|
||||
def attach (self, window):
|
||||
|
||||
pass
|
||||
|
||||
def detach (self, window):
|
||||
|
||||
pass
|
||||
|
||||
class CategoryColorSentinel (object):
|
||||
|
||||
def processor (self):
|
||||
|
||||
pass
|
||||
|
||||
class Plugin (PluginBase):
|
||||
|
||||
features = [ColorizeLevels, ColorizeCategories]
|
||||
|
||||
|
322
debug-viewer/GstDebugViewer/Plugins/LineFrequency.py
Normal file
322
debug-viewer/GstDebugViewer/Plugins/LineFrequency.py
Normal file
|
@ -0,0 +1,322 @@
|
|||
|
||||
import logging
|
||||
|
||||
from GstDebugViewer.Plugins import *
|
||||
|
||||
import cairo
|
||||
import gtk
|
||||
|
||||
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):
|
||||
|
||||
self.model = model
|
||||
|
||||
def _search_ts (self, target_ts, first_index, last_index):
|
||||
|
||||
model_get = self.model.get
|
||||
model_iter_nth_child = self.model.iter_nth_child
|
||||
col_id = self.model.COL_TIME
|
||||
|
||||
while True:
|
||||
middle = (last_index - first_index) // 2 + first_index
|
||||
if middle == first_index:
|
||||
return last_index
|
||||
ts = model_get (model_iter_nth_child (None, middle), col_id)[0]
|
||||
if ts < target_ts:
|
||||
first_index = middle + 1
|
||||
elif ts > target_ts:
|
||||
last_index = middle - 1
|
||||
else:
|
||||
return middle
|
||||
|
||||
def run_for (self, n):
|
||||
|
||||
if n == 0:
|
||||
raise ValueError ("illegal value for n")
|
||||
|
||||
model = self.model
|
||||
result = []
|
||||
|
||||
last_ts = None
|
||||
for row in iter_model_reversed (self.model):
|
||||
last_ts = row[model.COL_TIME]
|
||||
if last_ts:
|
||||
last_index = row.path[0]
|
||||
break
|
||||
|
||||
if last_ts is None:
|
||||
return result
|
||||
|
||||
step = int (float (last_ts) / float (n))
|
||||
|
||||
first_index = 0
|
||||
target_ts = step
|
||||
old_found = 0
|
||||
while target_ts < last_ts:
|
||||
found = self._search_ts (target_ts, first_index, last_index)
|
||||
result.append (found - old_found)
|
||||
old_found = found
|
||||
first_index = found
|
||||
target_ts += step
|
||||
|
||||
## count = 0
|
||||
## limit = step
|
||||
## for row in self.model:
|
||||
## ts = row[model.COL_TIME]
|
||||
## if ts is None:
|
||||
## continue
|
||||
## if ts > limit:
|
||||
## limit += step
|
||||
## result.append (count)
|
||||
## count = 0
|
||||
## count += 1
|
||||
|
||||
return (step, result,)
|
||||
|
||||
class LineFrequencyWidget (gtk.DrawingArea):
|
||||
|
||||
__gtype_name__ = "LineFrequencyWidget"
|
||||
|
||||
def __init__ (self, sentinel = None):
|
||||
|
||||
gtk.DrawingArea.__init__ (self)
|
||||
|
||||
self.logger = logging.getLogger ("ui.density-widget")
|
||||
|
||||
self.sentinel = sentinel
|
||||
self.sentinel_step = None
|
||||
self.sentinel_data = None
|
||||
self.__configure_id = None
|
||||
self.connect ("expose-event", self.__handle_expose_event)
|
||||
self.connect ("configure-event", self.__handle_configure_event)
|
||||
self.connect ("size-request", self.__handle_size_request)
|
||||
|
||||
def set_sentinel (self, sentinel):
|
||||
|
||||
self.sentinel = sentinel
|
||||
self.__redraw ()
|
||||
|
||||
def __redraw (self):
|
||||
|
||||
if not self.props.visible:
|
||||
return
|
||||
|
||||
x, y, w, h = self.get_allocation ()
|
||||
self.offscreen = gtk.gdk.Pixmap (self.window, w, h, -1)
|
||||
|
||||
self.__draw (self.offscreen)
|
||||
|
||||
self.__update ()
|
||||
|
||||
def __update (self):
|
||||
|
||||
if not self.props.visible:
|
||||
return
|
||||
|
||||
gc = gtk.gdk.GC (self.window)
|
||||
self.window.draw_drawable (gc, self.offscreen, 0, 0, 0, 0, -1, -1)
|
||||
|
||||
def update_position (self, start_ts, end_ts):
|
||||
|
||||
self.__update ()
|
||||
|
||||
position1 = int (float (start_ts) / self.sentinel_step)
|
||||
position2 = int (float (end_ts) / self.sentinel_step)
|
||||
|
||||
ctx = self.window.cairo_create ()
|
||||
x, y, w, h = self.get_allocation ()
|
||||
|
||||
line_width = position2 - position1
|
||||
ctx.set_source_rgba (1., 0., 0., .5)
|
||||
if line_width <= 1:
|
||||
ctx.set_line_width (1.)
|
||||
ctx.move_to (position1 + .5, 0)
|
||||
ctx.line_to (position1 + .5, h)
|
||||
ctx.stroke ()
|
||||
else:
|
||||
ctx.rectangle (position1, 0, line_width, h)
|
||||
ctx.fill ()
|
||||
|
||||
def __draw (self, drawable):
|
||||
|
||||
ctx = drawable.cairo_create ()
|
||||
x, y, w, h = self.get_allocation ()
|
||||
ctx.set_line_width (0.)
|
||||
ctx.rectangle (0, 0, w, h)
|
||||
ctx.set_source_rgb (1., 1., 1.)
|
||||
ctx.fill ()
|
||||
ctx.new_path ()
|
||||
|
||||
if self.sentinel_data is None and self.sentinel:
|
||||
if w > 15:
|
||||
self.logger.debug ("running sentinel for width %i", w)
|
||||
self.sentinel_step, self.sentinel_data = self.sentinel.run_for (w)
|
||||
else:
|
||||
return
|
||||
|
||||
if self.sentinel_data is None:
|
||||
self.logger.debug ("not redrawing: no sentinel set")
|
||||
return
|
||||
|
||||
from operator import add
|
||||
maximum = max (self.sentinel_data)
|
||||
heights = [h * float (d) / maximum for d in self.sentinel_data]
|
||||
ctx.move_to (0, h)
|
||||
ctx.set_source_rgb (0., 0., 0.)
|
||||
for i in range (len (heights)):
|
||||
ctx.line_to (i - .5, h - heights[i] + .5)
|
||||
#ctx.rectangle (i - .5, h - heights[i] + .5, i + 1, h)
|
||||
|
||||
ctx.line_to (i, h)
|
||||
ctx.close_path ()
|
||||
|
||||
ctx.fill ()
|
||||
|
||||
def __handle_expose_event (self, self_, event):
|
||||
|
||||
self.__redraw ()
|
||||
return True
|
||||
|
||||
def __handle_configure_event (self, self_, event):
|
||||
|
||||
if event.width < 16:
|
||||
return
|
||||
|
||||
if self.sentinel:
|
||||
self.sentinel_step, self.sentinel_data = self.sentinel.run_for (event.width)
|
||||
|
||||
# FIXME: Is this done automatically?
|
||||
self.queue_draw ()
|
||||
return False
|
||||
|
||||
def __handle_size_request (self, self_, req):
|
||||
|
||||
# FIXME:
|
||||
req.height = 64
|
||||
|
||||
class LineFrequencyFeature (FeatureBase):
|
||||
|
||||
state_section_name = "line-frequency-display"
|
||||
|
||||
def __init__ (self):
|
||||
|
||||
self.action_group = gtk.ActionGroup ("LineFrequencyActions")
|
||||
self.action_group.add_toggle_actions ([("show-line-frequency",
|
||||
None, _("Line _Density"))])
|
||||
|
||||
def attach (self, window):
|
||||
|
||||
self.log_model = window.log_model
|
||||
self.log_view = window.log_view
|
||||
|
||||
ui = window.ui_manager
|
||||
|
||||
ui.insert_action_group (self.action_group, 0)
|
||||
|
||||
self.merge_id = ui.new_merge_id ()
|
||||
ui.add_ui (self.merge_id, "/menubar/ViewMenu/ViewMenuAdditions",
|
||||
"ViewLineFrequency", "show-line-frequency",
|
||||
gtk.UI_MANAGER_MENUITEM, False)
|
||||
|
||||
box = window.get_top_attach_point ()
|
||||
|
||||
self.density_display = LineFrequencyWidget ()
|
||||
self.density_display.add_events (gtk.gdk.ALL_EVENTS_MASK) # FIXME
|
||||
self.density_display.connect ("button-press-event", self.handle_density_button_press_event)
|
||||
self.density_display.connect ("motion-notify-event", self.handle_density_motion_notify_event)
|
||||
box.pack_start (self.density_display, False, False, 0)
|
||||
self.density_display.hide ()
|
||||
|
||||
window.widgets.log_view_scrolled_window.props.vadjustment.connect ("value-changed",
|
||||
self.handle_log_view_adjustment_value_changed)
|
||||
|
||||
handler = self.handle_show_action_toggled
|
||||
self.action_group.get_action ("show-line-frequency").connect ("toggled", handler)
|
||||
|
||||
window.sentinels.append (self.sentinel_process)
|
||||
|
||||
def detach (self, window):
|
||||
|
||||
window.sentinels.remove (self.sentinel_process)
|
||||
|
||||
window.ui_manager.remove_ui (self.merge_id)
|
||||
self.merge_id = None
|
||||
|
||||
# FIXME: Remove action group from ui manager!
|
||||
|
||||
self.density_display.destroy ()
|
||||
self.density_display = None
|
||||
|
||||
def sentinel_process (self):
|
||||
|
||||
if self.action_group.get_action ("show-line-frequency").props.active:
|
||||
sentinel = LineDensitySentinel (self.log_model)
|
||||
self.density_display.set_sentinel (sentinel)
|
||||
|
||||
def handle_log_view_adjustment_value_changed (self, adj):
|
||||
|
||||
# FIXME: If not visible, disconnect this handler!
|
||||
if not self.density_display.props.visible:
|
||||
return
|
||||
|
||||
start_path, end_path = self.log_view.get_visible_range ()
|
||||
ts1 = self.log_model.get (self.log_model.get_iter (start_path),
|
||||
self.log_model.COL_TIME)[0]
|
||||
ts2 = self.log_model.get (self.log_model.get_iter (end_path),
|
||||
self.log_model.COL_TIME)[0]
|
||||
self.density_display.update_position (ts1, ts2)
|
||||
|
||||
def handle_show_action_toggled (self, action):
|
||||
|
||||
show = action.props.active
|
||||
|
||||
if show:
|
||||
self.density_display.show ()
|
||||
if self.density_display.sentinel is None:
|
||||
sentinel = LineFrequencySentinel (self.log_model)
|
||||
self.density_display.set_sentinel (sentinel)
|
||||
else:
|
||||
self.density_display.hide ()
|
||||
|
||||
def handle_density_button_press_event (self, widget, event):
|
||||
|
||||
if event.button != 1:
|
||||
return True
|
||||
|
||||
pos = int (event.x)
|
||||
self.goto_density (pos)
|
||||
return False
|
||||
|
||||
def handle_density_motion_notify_event (self, widget, event):
|
||||
|
||||
if not event.state & gtk.gdk.BUTTON1_MASK:
|
||||
return True
|
||||
|
||||
pos = int (event.x)
|
||||
self.goto_density (pos)
|
||||
return False
|
||||
|
||||
def goto_density (self, pos):
|
||||
|
||||
data = self.density_display.sentinel_data
|
||||
if not data:
|
||||
return True
|
||||
count = 0
|
||||
for i in range (pos):
|
||||
count += data[i]
|
||||
|
||||
row = self.log_model[count]
|
||||
self.log_view.scroll_to_cell ((count,), use_align = True, row_align = .5)
|
||||
|
||||
return False
|
||||
|
||||
class Plugin (PluginBase):
|
||||
|
||||
features = [LineFrequencyFeature]
|
42
debug-viewer/GstDebugViewer/Plugins/__init__.py
Normal file
42
debug-viewer/GstDebugViewer/Plugins/__init__.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
__all__ = ["_", "FeatureBase", "PluginBase"]
|
||||
|
||||
import os.path
|
||||
from gettext import gettext as _
|
||||
|
||||
def load (paths = ()):
|
||||
|
||||
for path in paths:
|
||||
for plugin_module in _load_plugins (path):
|
||||
yield plugin_module.Plugin
|
||||
|
||||
def _load_plugins (path):
|
||||
|
||||
import imp, glob
|
||||
|
||||
files = glob.glob (os.path.join (path, "*.py"))
|
||||
|
||||
for filename in files:
|
||||
|
||||
name = os.path.basename (os.path.splitext (filename)[0])
|
||||
if name == "__init__":
|
||||
continue
|
||||
fp, pathname, description = imp.find_module (name, [path])
|
||||
module = imp.load_module (name, fp, pathname, description)
|
||||
yield module
|
||||
|
||||
class FeatureBase (object):
|
||||
|
||||
state_section_name = None
|
||||
|
||||
def register_lazy_sentinel (self, sentinel):
|
||||
|
||||
pass
|
||||
|
||||
class PluginBase (object):
|
||||
|
||||
features = ()
|
||||
|
||||
def __init__ (self):
|
||||
|
||||
pass
|
24
debug-viewer/GstDebugViewer/__init__.py
Normal file
24
debug-viewer/GstDebugViewer/__init__.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
# -*- coding: utf-8; mode: python; -*-
|
||||
#
|
||||
# GStreamer Debug Viewer
|
||||
#
|
||||
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
version = "0.1"
|
||||
|
||||
__version__ = version
|
||||
|
||||
from GstDebugViewer.Main import Paths, main as run
|
502
debug-viewer/data/gst-debug-viewer.glade
Normal file
502
debug-viewer/data/gst-debug-viewer.glade
Normal file
|
@ -0,0 +1,502 @@
|
|||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||
|
||||
<glade-interface>
|
||||
<requires lib="gnome"/>
|
||||
|
||||
<widget class="GtkWindow" id="main_window">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">GStreamer Debug Viewer</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="default_width">640</property>
|
||||
<property name="default_height">480</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<signal name="destroy" handler="handle_main_window_destroy" last_modification_time="Thu, 05 Oct 2006 20:05:35 GMT"/>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox_main">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="log_view_scrolled_window">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="log_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">True</property>
|
||||
<property name="rules_hint">True</property>
|
||||
<property name="reorderable">True</property>
|
||||
<property name="enable_search">True</property>
|
||||
<property name="fixed_height_mode">False</property>
|
||||
<property name="hover_selection">False</property>
|
||||
<property name="hover_expand">False</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkAboutDialog" id="about_dialog">
|
||||
<property name="border_width">5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="name" translatable="yes">GStreamer Debug Viewer</property>
|
||||
<property name="copyright" translatable="yes">Copyright © 2007 René Stadler</property>
|
||||
<property name="comments" translatable="yes">View and analyze GStreamer debug files</property>
|
||||
<property name="license"> GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
</property>
|
||||
<property name="wrap_license">False</property>
|
||||
<property name="authors">René Stadler <mail@renestadler.de></property>
|
||||
<property name="translator_credits" translatable="yes" comments="TRANSLATORS: Replace this string with your names, one name per line.">translator-credits</property>
|
||||
<property name="logo">gst-debug-viewer.png</property>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkDialog" id="progress_dialog">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Loading log...</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<property name="has_separator">False</property>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="button2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-6</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox3">
|
||||
<property name="border_width">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkProgressBar" id="progress_bar">
|
||||
<property name="width_request">250</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
|
||||
<property name="fraction">0</property>
|
||||
<property name="pulse_step">0.10000000149</property>
|
||||
<property name="text" translatable="yes">Loading file</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">12</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
502
debug-viewer/data/gst-debug-viewer.glade.bak
Normal file
502
debug-viewer/data/gst-debug-viewer.glade.bak
Normal file
|
@ -0,0 +1,502 @@
|
|||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||
|
||||
<glade-interface>
|
||||
<requires lib="gnome"/>
|
||||
|
||||
<widget class="GtkWindow" id="main_window">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">GStreamer Debug Viewer</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="default_width">640</property>
|
||||
<property name="default_height">480</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<signal name="destroy" handler="handle_main_window_destroy" last_modification_time="Thu, 05 Oct 2006 20:05:35 GMT"/>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox_main">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="log_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">True</property>
|
||||
<property name="rules_hint">True</property>
|
||||
<property name="reorderable">True</property>
|
||||
<property name="enable_search">True</property>
|
||||
<property name="fixed_height_mode">False</property>
|
||||
<property name="hover_selection">False</property>
|
||||
<property name="hover_expand">False</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkAboutDialog" id="about_dialog">
|
||||
<property name="border_width">5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="name" translatable="yes">GStreamer Debug Viewer</property>
|
||||
<property name="copyright" translatable="yes">Copyright © 2007 René Stadler</property>
|
||||
<property name="comments" translatable="yes">View and analyze GStreamer debug files</property>
|
||||
<property name="license"> GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
</property>
|
||||
<property name="wrap_license">False</property>
|
||||
<property name="authors">René Stadler <mail@renestadler.de></property>
|
||||
<property name="translator_credits" translatable="yes" comments="TRANSLATORS: Replace this string with your names, one name per line.">translator-credits</property>
|
||||
<property name="logo">gst-debug-viewer.png</property>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkDialog" id="progress_dialog">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Loading log...</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<property name="has_separator">False</property>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="button2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-6</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox3">
|
||||
<property name="border_width">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkProgressBar" id="progress_bar">
|
||||
<property name="width_request">250</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
|
||||
<property name="fraction">0</property>
|
||||
<property name="pulse_step">0.10000000149</property>
|
||||
<property name="text" translatable="yes">Loading file</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">12</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
7
debug-viewer/data/gst-debug-viewer.gladep
Normal file
7
debug-viewer/data/gst-debug-viewer.gladep
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
|
||||
|
||||
<glade-project>
|
||||
<name></name>
|
||||
<program_name></program_name>
|
||||
</glade-project>
|
BIN
debug-viewer/data/gst-debug-viewer.png
Normal file
BIN
debug-viewer/data/gst-debug-viewer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
32
debug-viewer/data/gst-debug-viewer.ui
Normal file
32
debug-viewer/data/gst-debug-viewer.ui
Normal file
|
@ -0,0 +1,32 @@
|
|||
<!-- -*- mode: xml; -*- -->
|
||||
<ui>
|
||||
<menubar>
|
||||
<menu name="FileMenu" action="FileMenuAction">
|
||||
<menuitem name="FileNewWindow" action="new-window"/>
|
||||
<menuitem name="FileOpen" action="open-file"/>
|
||||
<placeholder name="FileMenuAdditions"/>
|
||||
<separator/>
|
||||
<menuitem name="FileCloseWindow" action="close-window"/>
|
||||
</menu>
|
||||
<menu name="ViewMenu" action="ViewMenuAction">
|
||||
<menu name="ViewColumnsMenu" action="ViewColumnsMenuAction">
|
||||
<menuitem name="ViewColumnsTime" action="show-time-column"/>
|
||||
<menuitem name="ViewColumnsLevel" action="show-level-column"/>
|
||||
<menuitem name="ViewColumnsThread" action="show-thread-column"/>
|
||||
<menuitem name="ViewColumnsCategory" action="show-category-column"/>
|
||||
<menuitem name="ViewColumnsFunction" action="show-function-column"/>
|
||||
<menuitem name="ViewColumnsObject" action="show-object-column"/>
|
||||
<menuitem name="ViewColumnsMessage" action="show-message-column"/>
|
||||
</menu>
|
||||
<placeholder name="ViewMenuAdditions"/>
|
||||
<!--<menuitem name="ViewLineDensity" action="show-line-density"/>-->
|
||||
<separator/>
|
||||
<menuitem name="ViewContextMenuCopyMessage" action="edit-copy-message"/>
|
||||
<menuitem name="ViewContextMenuCopyLine" action="edit-copy-line"/>
|
||||
</menu>
|
||||
<menu name="HelpMenu" action="HelpMenuAction">
|
||||
<placeholder name="HelpMenuAdditions"/>
|
||||
<menuitem name="HelpInfo" action="show-about"/>
|
||||
</menu>
|
||||
</menubar>
|
||||
</ui>
|
9
debug-viewer/gst-debug-viewer.desktop
Normal file
9
debug-viewer/gst-debug-viewer.desktop
Normal file
|
@ -0,0 +1,9 @@
|
|||
[Desktop Entry]
|
||||
Name=GStreamer Debug Viewer
|
||||
Comment=Examine GStreamer debug log information
|
||||
StartupNotify=true
|
||||
Exec=python /home/cymacs/src/gst-debug-viewer/gst-debug-viewer.py
|
||||
Icon=/home/cymacs/src/gst-debug-viewer/gst-debug-viewer.png
|
||||
Type=Application
|
||||
Categories=GNOME;Development
|
||||
|
68
debug-viewer/gst-debug-viewer.py
Executable file
68
debug-viewer/gst-debug-viewer.py
Executable file
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8; mode: python; -*-
|
||||
#
|
||||
# GStreamer Debug Viewer
|
||||
#
|
||||
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""GStreamer Debug Viewer program invocation."""
|
||||
|
||||
def main ():
|
||||
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
def substituted (s):
|
||||
if s.startswith ("$") and s.endswith ("$"):
|
||||
return None
|
||||
else:
|
||||
return s
|
||||
|
||||
# These "$"-enclosed strings are substituted at install time by a custom
|
||||
# distutils extension (see setup.py). If you don't see any dollar signs at
|
||||
# all, you are looking at an installed version of this file.
|
||||
data_dir = substituted ("$DATADIR$")
|
||||
lib_dir = substituted ("$LIBDIR$")
|
||||
|
||||
if data_dir:
|
||||
installed = True
|
||||
else:
|
||||
# Substitution has not been run, we are running uninstalled:
|
||||
lib_dir = os.path.dirname (os.path.abspath (sys.argv[0]))
|
||||
installed = False
|
||||
|
||||
if lib_dir:
|
||||
if not os.path.normpath (lib_dir) in [os.path.normpath (p)
|
||||
for p in sys.path]:
|
||||
sys.path.insert (0, lib_dir)
|
||||
|
||||
try:
|
||||
import GstDebugViewer
|
||||
except ImportError, exc:
|
||||
print >> sys.stderr, str (exc)
|
||||
sys.exit (1)
|
||||
else:
|
||||
if installed:
|
||||
GstDebugViewer.Paths.setup_installed (data_dir)
|
||||
else:
|
||||
# Assume that we reside inside the source dist.
|
||||
source_dir = os.path.dirname (os.path.abspath (sys.argv[0]))
|
||||
GstDebugViewer.Paths.setup_uninstalled (source_dir)
|
||||
|
||||
GstDebugViewer.run ()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main ()
|
BIN
debug-viewer/pixmaps/gst-debug-viewer.png
Normal file
BIN
debug-viewer/pixmaps/gst-debug-viewer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
Loading…
Reference in a new issue