[SCM] advene/master: New upstream version 3.1

oaubert-guest at users.alioth.debian.org oaubert-guest at users.alioth.debian.org
Thu Oct 12 20:45:52 UTC 2017


The following commit has been merged in the master branch:
commit d93ebe7a5ce216214db5d8e1c4e175acb0130e46
Author: Olivier Aubert <contact at olivieraubert.net>
Date:   Sun Jun 18 23:25:25 2017 +0200

    New upstream version 3.1

diff --git a/CHANGES.txt b/CHANGES.txt
index 105589b..a9c5e61 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,13 @@
+advene (3.1) unstable; urgency=medium
+
+  * Bug fixes.
+
+  * Timeline : improve zoom level setting
+
+  * OWL importer: adapt to new definition structure
+
+ -- Olivier Aubert <contact at olivieraubert.net>  Sun, 18 Jun 2017 23:21:19 +0200
+
 advene (3.0) unstable; urgency=medium
 
   * Upgrade libs to Gtk3 / Gstreamer 1.0
diff --git a/lib/advene/core/config.py b/lib/advene/core/config.py
index 6cfa0a0..bab0f41 100644
--- a/lib/advene/core/config.py
+++ b/lib/advene/core/config.py
@@ -492,7 +492,7 @@ class Config(object):
         """Check if the settings directory is present, and create it if necessary.
         """
         if not os.path.isdir(self.path['settings']):
-            os.mkdir(self.path['settings'])
+            os.makedirs(self.path['settings'])
             self.first_run=True
         else:
             self.first_run=False
@@ -773,7 +773,7 @@ class Config(object):
         dp=os.path.dirname(preffile)
         if not os.path.isdir(dp):
             try:
-                os.mkdir(dp)
+                os.makedirs(dp)
             except OSError, e:
                 logger.error("Error: %s", str(e))
                 return False
diff --git a/lib/advene/core/version.py b/lib/advene/core/version.py
index 4a01a09..b7e8ebe 100644
--- a/lib/advene/core/version.py
+++ b/lib/advene/core/version.py
@@ -19,6 +19,6 @@
 """Versioning information.
 """
 
-version='3.0'
-date='20170601'
+version='3.1'
+date='20170618'
 major,minor=[ long(s) for s in version.split('.') ]
diff --git a/lib/advene/gui/edit/transcribe.py b/lib/advene/gui/edit/transcribe.py
index e62989f..267b5d9 100644
--- a/lib/advene/gui/edit/transcribe.py
+++ b/lib/advene/gui/edit/transcribe.py
@@ -85,7 +85,6 @@ class TranscriptionEdit(AdhocView):
         self.contextual_actions = (
             (_("Save view"), self.save_view),
             (_("Save default options"), self.save_default_options),
-            (_("Export as static view"), lambda v, t: self.export_as_static_view()),
             )
 
         self.controller=controller
diff --git a/lib/advene/gui/plugins/kinect.py b/lib/advene/gui/plugins/kinect.py
index a8c8782..9fad853 100644
--- a/lib/advene/gui/plugins/kinect.py
+++ b/lib/advene/gui/plugins/kinect.py
@@ -44,8 +44,7 @@ class KinectController(AdhocView):
     def __init__(self, controller=None, uri=None, parameters=None):
         super(KinectController, self).__init__(controller=controller)
         self.close_on_package_load = False
-        self.contextual_actions = [
-            ]
+        self.contextual_actions = []
         self.controller = controller
         self.registered_rules = []
 
diff --git a/lib/advene/gui/plugins/shotvalidation.py b/lib/advene/gui/plugins/shotvalidation.py
index ef06e60..adf2b04 100644
--- a/lib/advene/gui/plugins/shotvalidation.py
+++ b/lib/advene/gui/plugins/shotvalidation.py
@@ -37,8 +37,7 @@ class ShotValidation(AdhocView):
     def __init__(self, controller=None, parameters=None, annotationtype=None):
         super(ShotValidation, self).__init__(controller=controller)
         self.close_on_package_load = True
-        self.contextual_actions = (
-            )
+        self.contextual_actions = ()
         self.controller=controller
         self._annotationtype=None
 
diff --git a/lib/advene/gui/plugins/videoplayer.py b/lib/advene/gui/plugins/videoplayer.py
index c26c49d..782edad 100644
--- a/lib/advene/gui/plugins/videoplayer.py
+++ b/lib/advene/gui/plugins/videoplayer.py
@@ -119,7 +119,7 @@ class VideoPlayer(AdhocView):
             arguments = [ ('offset', self.offset) ]
         return self.options, arguments
 
-    def select_file(self, button=None, *p):
+    def select_file(self, *p):
         mp=[ d for d in config.data.path['moviepath'].split(os.path.pathsep) if d != '_' ]
         if mp:
             default=mp[0]
diff --git a/lib/advene/gui/views/browser.py b/lib/advene/gui/views/browser.py
index e59c906..6b67f44 100755
--- a/lib/advene/gui/views/browser.py
+++ b/lib/advene/gui/views/browser.py
@@ -297,7 +297,7 @@ class Browser(AdhocView):
         self.current_value=element
 
     def display_result(self, *p):
-        """Display the results as annotations in a timeline.
+        """Display the results as annotations in a table
         """
         if not hasattr(self.current_value, '__iter__'):
             self.log(_("Result is not a list"))
diff --git a/lib/advene/gui/views/checker.py b/lib/advene/gui/views/checker.py
index bcdb800..60444d2 100644
--- a/lib/advene/gui/views/checker.py
+++ b/lib/advene/gui/views/checker.py
@@ -41,8 +41,7 @@ class CheckerView(AdhocView):
     def __init__ (self, controller=None, parameters=None):
         super(CheckerView, self).__init__(controller=controller)
         self.close_on_package_load = False
-        self.contextual_actions = (
-            )
+        self.contextual_actions = ()
         self.controller=controller
         self.options = {
             }
diff --git a/lib/advene/gui/views/editionhistory.py b/lib/advene/gui/views/editionhistory.py
index 0a3d54b..b6dbdeb 100644
--- a/lib/advene/gui/views/editionhistory.py
+++ b/lib/advene/gui/views/editionhistory.py
@@ -43,7 +43,7 @@ class EditionHistory(AdhocView):
     def __init__ (self, controller=None, **kw):
         super(EditionHistory, self).__init__(controller=controller)
         self.close_on_package_load = False
-        self.contextual_actions = ( )
+        self.contextual_actions = ()
 
         self.options={}
 
diff --git a/lib/advene/gui/views/finder.py b/lib/advene/gui/views/finder.py
index e144a79..4375f04 100644
--- a/lib/advene/gui/views/finder.py
+++ b/lib/advene/gui/views/finder.py
@@ -102,15 +102,15 @@ class DetailedTreeModel(object):
     def __init__(self, controller=None, package=None):
         self.childrencache = {}
         self.virtual={}
-        self.virtual['root'] = VirtualNode(_("Package"), package)
-        self.virtual['views']=VirtualNode(_("List of views"), package, viewableType='view-list')
-        self.virtual['static']=VirtualNode(_("Static views"), package, viewableType='view-list')
-        self.virtual['dynamic']=VirtualNode(_("Dynamic views"), package, viewableType='view-list')
-        self.virtual['admin']=VirtualNode(_("Admin views"), package, viewableType='view-list')
-        self.virtual['adhoc']=VirtualNode(_("Adhoc views"), package)
+        self.virtual['root']    = VirtualNode(_("Package"),       package)
+        self.virtual['views']   = VirtualNode(_("List of views"), package, viewableType='view-list')
+        self.virtual['static']  = VirtualNode(_("Static views"),  package, viewableType='view-list')
+        self.virtual['dynamic'] = VirtualNode(_("Dynamic views"), package, viewableType='view-list')
+        self.virtual['admin']   = VirtualNode(_("Admin views"),   package, viewableType='view-list')
+        self.virtual['adhoc']   = VirtualNode(_("Adhoc views"),   package)
 
     def nodeParent (self, node):
-        #print "nodeparent %s" % node
+        logger.warn("nodeparent %s", node)
         if isinstance (node, Annotation):
             parent = node.type
         elif isinstance (node, Relation):
@@ -146,7 +146,7 @@ class DetailedTreeModel(object):
         return parent
 
     def nodeChildren (self, node):
-        #print "nodechildren %s" % node
+        logger.warn("nodechildren %s %s", type(node), node)
         children = []
         if isinstance (node, Annotation):
             children = []
@@ -171,7 +171,7 @@ class DetailedTreeModel(object):
             children = []
         elif isinstance (node, Package):
             if not node in self.childrencache:
-                self.childrencache[node] = [node.schemas, self.virtual['views'], node.queries, node.resources ]
+                self.childrencache[node] = [node.schemas, self.virtual['views'], node.queries, node.resources or _("No resources") ]
             children = self.childrencache[node]
         elif isinstance (node, AbstractBundle):
             children = node
@@ -377,7 +377,7 @@ class ModelColumn(FinderColumn):
             store, it = selection.get_selected()
             if it is not None:
                 att = model.get_value (it, self.COLUMN_ELEMENT)
-        if att and self.callback:
+        if att is not None and self.callback:
             self.callback(self, att)
             return True
         return False
@@ -540,8 +540,11 @@ class ViewColumn(FinderColumn):
         t=helper.get_view_type(self.element)
         if t == 'static':
             c=self.controller.build_context()
-            url=c.evaluateValue('here/view/%s/absolute_url' % self.element.id)
-            self.controller.open_url(url)
+            try:
+                url=c.evaluateValue('here/view/%s/absolute_url' % self.element.id)
+                self.controller.open_url(url)
+            except:
+                logger.warn("Cannot open static view: error when trying to get its url", exc_info=True)
         elif t == 'dynamic':
             self.controller.activate_stbv(self.element)
         elif t == 'adhoc':
@@ -877,6 +880,7 @@ class Finder(AdhocView):
         return True
 
     def clicked_callback(self, columnbrowser, node):
+        logger.debug("clicked_callback %s %s %s", columnbrowser, node, columnbrowser.next)
         if columnbrowser is None:
             # We selected  the rootcolumn. Delete the next ones
             cb=self.rootcolumn.next
@@ -903,8 +907,8 @@ class Finder(AdhocView):
             if cb is not None:
                 cb.close()
             # Check if the column is still appropriate for the node
-            clazz=CLASS2COLUMN.get(type(node), ModelColumn)
-            if not isinstance(columnbrowser.next, clazz):
+            clazz=CLASS2COLUMN.get(type(node), None)
+            if clazz is None or not isinstance(columnbrowser.next, clazz):
                 # The column is not appropriate for the new node.
                 # Close it and reopen it.
                 columnbrowser.next.close()
diff --git a/lib/advene/gui/views/html.py b/lib/advene/gui/views/html.py
index 9b3144e..821b6d2 100644
--- a/lib/advene/gui/views/html.py
+++ b/lib/advene/gui/views/html.py
@@ -192,7 +192,7 @@ class HTMLView(AdhocView):
         def utbv_menu(*p):
             if self.controller and self.controller.gui:
                 m=self.controller.gui.build_utbv_menu(action=self.open_url)
-                m.popup(None, None, None, 0, Gtk.get_current_event_time())
+                m.popup_at_pointer()
             return True
 
         tb=Gtk.Toolbar()
diff --git a/lib/advene/gui/views/interactivequery.py b/lib/advene/gui/views/interactivequery.py
index 4183646..34a0366 100644
--- a/lib/advene/gui/views/interactivequery.py
+++ b/lib/advene/gui/views/interactivequery.py
@@ -23,6 +23,7 @@ Display the query results in a view (timeline, tree, etc).
 from gettext import gettext as _
 import pprint
 
+from gi.repository import Gdk
 from gi.repository import Gtk
 from gi.repository import Pango
 
diff --git a/lib/advene/gui/views/table.py b/lib/advene/gui/views/table.py
index fa9cb1d..8242640 100644
--- a/lib/advene/gui/views/table.py
+++ b/lib/advene/gui/views/table.py
@@ -273,7 +273,7 @@ class AnnotationTable(AdhocView):
             if not it:
                 return
             a = self.model.get_value (it, COLUMN_ELEMENT)
-            new_content = helper.title2content(text,
+            new_content = helper.title2content(text.decode('utf-8'),
                                                a.content,
                                                a.type.getMetaData(config.data.namespace, "representation"))
             if new_content is None:
@@ -556,8 +556,7 @@ class GenericTable(AdhocView):
     def __init__(self, controller=None, parameters=None, elements=None, source=None):
         super(GenericTable, self).__init__(controller=controller)
         self.close_on_package_load = False
-        self.contextual_actions = (
-            )
+        self.contextual_actions = ()
         self.controller=controller
         self.elements=elements
         self.source = source
diff --git a/lib/advene/gui/views/timeline.py b/lib/advene/gui/views/timeline.py
index a1f3e22..fb37f39 100755
--- a/lib/advene/gui/views/timeline.py
+++ b/lib/advene/gui/views/timeline.py
@@ -139,8 +139,8 @@ class TimeLine(AdhocView):
             (_("Refresh"), self.refresh),
             (_("Save view"), self.save_view),
             (_("Save default options"), self.save_default_options),
-            (_("Limit display to current area"), lambda i, b: self.limit_display()),
-            (_("Display whole movie"), lambda i, b: self.unlimit_display()),
+            (_("Limit display to current area"), self.limit_display),
+            (_("Display whole movie"), self.unlimit_display),
             )
         self.options = {
             'highlight': False,
@@ -162,7 +162,7 @@ class TimeLine(AdhocView):
         # Default position in ms.
         default_position=None
         default_zoom=1.0
-        pane_position=opt.get('pane-position', None)
+        inspector_width = opt.get('inspector-width', None)
         for n, v in arg:
             if n == 'annotation-type':
                 at=helper.get_id(self.controller.package.annotationTypes,
@@ -264,7 +264,7 @@ class TimeLine(AdhocView):
         # The same value in relative form
         self.fraction_adj = Gtk.Adjustment.new(value=1.0,
                                                lower=0.01,
-                                               upper=1.0,
+                                               upper=10.0,
                                                step_increment=.01,
                                                page_increment=.1,
                                                page_size=.1)
@@ -344,46 +344,66 @@ class TimeLine(AdhocView):
 
         # Set default parameters (zoom) and refresh the legend widget
         # on the first expose signal
-        def set_default_parameters(widget, event, zoom, pos, pane):
-            self.update_adjustment ()
-            self.adjustment.set_value(u2p(self.minimum, absolute=True))
-            self.fraction_adj.set_value(zoom)
-            if pos >= self.minimum and pos <= self.maximum:
-                self.adjustment.set_value(u2p(pos, absolute=True))
+        def set_default_parameters(widget, event, default_zoom, pos, inspector_width):
+            logger.debug("set_default_parameters default zoom: %f  pos: %d inspector_width: %d", default_zoom or 0, pos or 0, inspector_width or 0)
+
             # Set annotation inspector width, so that it does not auto-resize
-            if pane is None:
-                pane = self.widget.get_window().get_width() - 160
-            self.inspector_pane.set_position(pane)
+            if inspector_width is None:
+                inspector_width = 160
+            self.set_inspector_size(inspector_width)
+
             # Check if display is limited
             if self.minimum > 0 and self.maximum < self.controller.package.cached_duration:
                 self.limit_navtools.show()
+
+            self.update_adjustment ()
+            if pos >= self.minimum and pos <= self.maximum:
+                self.adjustment.set_value(u2p(pos, absolute=True))
+            else:
+                self.adjustment.set_value(u2p(self.minimum, absolute=True))
+
             if self.expose_signal:
                 self.widget.disconnect(self.expose_signal)
                 self.expose_signal = None
             self.update_model(from_init=True)
+            logger.debug("set zoom value default zoom: %f width: %d", default_zoom, self.layout.get_clip().width)
+            self.fraction_adj.set_value(default_zoom)
             return False
         # Convert values, that could be strings
         if default_position is not None:
             default_position=long(float(default_position))
-        if pane_position is not None:
-            pane_position=long(float(pane_position))
+        if inspector_width is not None:
+            inspector_width = long(float(inspector_width))
 
-        self.expose_signal=self.widget.connect('draw', set_default_parameters,
-                                               default_zoom, default_position, pane_position)
+        self.expose_signal=self.widget.connect_after('draw', set_default_parameters,
+                                                     default_zoom, default_position, inspector_width)
 
     def get_save_arguments(self):
         arguments = []
         if self.annotationtypes_selection:
-            arguments.append([ ('annotation-type', at.id) for at in self.annotationtypes_selection ])
+            arguments.extend([ ('annotation-type', at.id) for at in self.annotationtypes_selection ])
         if self.list:
-            arguments.append([ ('element', el.id) for el in self.list ])
+            arguments.extend([ ('element', el.id) for el in self.list ])
         arguments.append( ('minimum', self.minimum ) )
         arguments.append( ('maximum', self.maximum ) )
         arguments.append( ('position', self.pixel2unit(self.adjustment.get_value(), absolute=True) ) )
         arguments.append( ('zoom', self.fraction_adj.get_value()) )
-        self.options['pane-position']=self.inspector_pane.get_position()
+        self.options['inspector-width'] = self.get_inspector_size()
         return self.options, arguments
 
+    def get_inspector_size(self):
+        return self.inspector_pane.get_clip().width - self.inspector_pane.get_position()
+
+    def set_inspector_size(self, inspector_width):
+        width = self.inspector_pane.get_clip().width
+        if inspector_width > width - 100:
+            logger.debug("Too large inspector. Use a default value")
+            if width > 300:
+                inspector_width = 160
+            else:
+                inspector_width = 0
+        self.inspector_pane.set_position(width - inspector_width)
+
     def draw_background(self, layout, context):
         """Draw annotation type separating lines
         """
@@ -420,12 +440,15 @@ class TimeLine(AdhocView):
         for b1, b2, r in to_draw:
             if b1 is None or b2 is None:
                 continue
+            x_offset = self.layout.get_hadjustment().get_value()
+            y_offset = self.layout.get_vadjustment().get_value()
+
             r1 = b1.get_allocation()
             r2 = b2.get_allocation()
-            x_start = r1.x + 3 * r1.width / 4
-            y_start  = r1.y + r1.height / 4
-            x_end=r2.x + r2.width / 4
-            y_end=r2.y + 3 * r2.height / 4
+            x_start = (r1.x + 3 * r1.width / 4) - x_offset
+            y_start  = (r1.y + r1.height / 4) - y_offset
+            x_end=(r2.x + r2.width / 4) - x_offset
+            y_end=(r2.y + 3 * r2.height / 4) - y_offset
             context.set_source_rgb(0, 0, 0)
             context.set_line_width(1)
             context.move_to(x_start, y_start)
@@ -561,7 +584,7 @@ class TimeLine(AdhocView):
 
         if self.maximum != oldmax and self.layout.get_window() is not None:
             # Reset to display whole timeline
-            self.scale.set_value( (self.maximum - self.minimum) / float(self.layout.get_window().get_height()) )
+            self.scale.set_value( (self.maximum - self.minimum) / float(self.layout.get_clip().width or 100) )
 
     def update_model(self, package=None, partial_update=False, from_init=False):
         """Update the whole model.
@@ -608,8 +631,6 @@ class TimeLine(AdhocView):
         def finalize_callback():
             self.update_legend_widget(self.legend)
             self.legend.show_all()
-            if self.layout.get_window() is not None:
-                self.fraction_event(widget=None, forced_window_width=self.layout.get_window().get_width())
             self.update_lock.release()
 
         self.populate(finalize_callback)
@@ -1952,11 +1973,15 @@ class TimeLine(AdhocView):
         count = 10
         length = len(l)
 
-        #print '----------------------------------------- populate', length
-        #import traceback; traceback.print_stack()
         if l:
-            old_position = self.inspector_pane.get_position()
-            self.inspector_pane.set_position(2)
+            old_inspector_width = self.get_inspector_size()
+
+        def update_layout_size():
+            self.layout.set_size (u2p (self.maximum - self.minimum),
+                                  max(self.layer_position.values() or (0,))
+                                  + self.button_height + config.data.preferences['timeline']['interline-height'])
+            self.scale_layout.set_size(u2p (self.maximum - self.minimum), 40)
+
         def create_annotations(annotations, length):
             i = counter[0]
             if i < length:
@@ -1974,15 +1999,8 @@ class TimeLine(AdhocView):
                     self.quickview.set_text(_("Displaying done."))
                     self.locked_inspector = False
                 self.controller.gui.set_busy_cursor(False)
-                if old_position:
-                    self.inspector_pane.set_position(old_position)
-                else:
-                    # old_position was = 0, because its value was
-                    # obtained before the widget was realized. There
-                    # is a good chance that the value is now
-                    # available.
-                    if self.widget.get_window():
-                        self.inspector_pane.set_position(max((0, self.widget.get_window().get_width() - 160)))
+                self.set_inspector_size(old_inspector_width or 20)
+                update_layout_size()
                 if callback:
                     callback()
                 return False
@@ -1997,14 +2015,9 @@ class TimeLine(AdhocView):
             self.controller.gui.set_busy_cursor(True)
             GObject.idle_add(create_annotations, l, length)
         elif callback:
+            update_layout_size()
             callback()
 
-        self.layout.set_size (u2p (self.maximum - self.minimum),
-                              max(self.layer_position.values() or (0,))
-                              + self.button_height + config.data.preferences['timeline']['interline-height'])
-
-        self.scale_layout.set_size(u2p (self.maximum - self.minimum), 40)
-
     def draw_current_mark (self):
         u2p = self.unit2pixel
 
@@ -2647,12 +2660,10 @@ class TimeLine(AdhocView):
     def layout_resize_event(self, widget=None, event=None, *p):
         """Recompute fraction_adj value when the layout size changes
         """
-        parent = self.layout.get_window()
-        if not parent:
+        if not self.layout.get_window():
             return False
         if self.maximum != self.minimum:
-            fraction=self.scale.get_value() * float(parent.get_width()) / (self.maximum - self.minimum)
-            #print "Layout resize, reset fraction_adj to ", fraction, w
+            fraction=self.scale.get_value() * float(self.layout.get_clip().width) / (self.maximum - self.minimum)
             self.fraction_adj.set_value(fraction)
             self.zoom_combobox.get_child().set_text('%d%%' % long(100 * fraction))
         return False
@@ -2661,7 +2672,7 @@ class TimeLine(AdhocView):
         # Deactivate autoscroll...
         self.set_autoscroll_mode(0)
 
-        self.scale.set_value(1.3 * (end - begin) / self.layout.get_window().get_width())
+        self.scale.set_value(1.3 * (end - begin) / self.layout.get_clip().width or 100)
 
         # Center on annotation
         self.center_on_position( (begin + end) / 2 )
@@ -2700,20 +2711,20 @@ class TimeLine(AdhocView):
 
         fraction is > 0 and <= 1.
         """
-        parent = self.layout.get_window()
-        if not parent:
+        if not self.layout.get_window():
             return True
-        w = parent.get_width()
-        if forced_window_width != 0:
+        if forced_window_width > 0:
             w = forced_window_width
-
-        if w < 10:
+        else:
+            w = self.layout.get_clip().width
+        if w < 50:
             return True
 
         if self.minimum == self.maximum:
             return True
 
         fraction = self.fraction_adj.get_value()
+        logger.debug("fraction_event %f width %d forced %d", fraction, w, forced_window_width)
 
         v = (self.maximum - self.minimum) / float(w) * fraction
         # New width in pixel
@@ -2721,9 +2732,7 @@ class TimeLine(AdhocView):
             self.log(_("Cannot zoom more"))
             return True
 
-        # Is it worth redrawing the whole timeline ?
-        if abs(v - self.scale.get_value()) / float(self.scale.get_value()) > 0.01:
-            self.scale.set_value(v)
+        self.scale.set_value(v)
         self.zoom_combobox.get_child().set_text('%d%%' % long(100 * fraction))
 
         return True
@@ -3408,10 +3417,6 @@ class TimeLine(AdhocView):
         # Relation display toggle
         def handle_toggle(b, option):
             self.options[option]=b.get_active()
-            if option == 'display-all-relations':
-                region = self.layout.get_window().get_clip_region()
-                if region:
-                    self.layout.get_window().invalidate_region(region, True)
             return True
 
         self.display_relations_toggle=Gtk.ToggleToolButton(stock_id=Gtk.STOCK_REDO)
diff --git a/lib/advene/gui/views/viewbook.py b/lib/advene/gui/views/viewbook.py
index ba38029..10e794c 100644
--- a/lib/advene/gui/views/viewbook.py
+++ b/lib/advene/gui/views/viewbook.py
@@ -113,6 +113,10 @@ class ViewBook(AdhocView):
                 self.controller.gui.viewbook[d].add_view(v, name=v._label)
             return True
 
+        def handle_contextual_action(menuitem, action):
+            action()
+            return True
+
         def popup_menu(button, event, view):
             if event.button == 3:
                 menu = Gtk.Menu()
@@ -143,7 +147,7 @@ class ViewBook(AdhocView):
                 try:
                     for label, action in view.contextual_actions:
                         item = Gtk.MenuItem(label, use_underline=False)
-                        item.connect('activate', lambda w: action())
+                        item.connect('activate', handle_contextual_action, action)
                         menu.append(item)
                 except AttributeError:
                     pass
diff --git a/lib/advene/model/viewable.py b/lib/advene/model/viewable.py
index cad4c38..40076d8 100644
--- a/lib/advene/model/viewable.py
+++ b/lib/advene/model/viewable.py
@@ -155,7 +155,10 @@ class Viewable(object):
         context.setLocal('view', view)
         context.interpret(view_source, mimetype, result)
         context.popLocals ()
-        s=TypedUnicode(result.getvalue())
+        v = result.getvalue()
+        if isinstance(v, str):
+            v = v.decode('utf-8')
+        s=TypedUnicode(v)
         s.contenttype=view.getContent().getMimetype()
         return s
 
diff --git a/lib/advene/plugins/owl_import.py b/lib/advene/plugins/owl_import.py
index 3245de3..3659b93 100644
--- a/lib/advene/plugins/owl_import.py
+++ b/lib/advene/plugins/owl_import.py
@@ -27,12 +27,12 @@ import os
 import advene.core.config as config
 from advene.util.importer import GenericImporter
 try:
-    import ontospy
+    import rdflib
 except ImportError:
-    ontospy = None
+    rdflib = None
 
 def register(controller=None):
-    if ontospy is not None:
+    if rdflib is not None:
         controller.register_importer(OWLImporter)
     return True
 
@@ -51,38 +51,73 @@ class OWLImporter(GenericImporter):
     can_handle=staticmethod(can_handle)
 
     def process_file(self, filename, dest=None):
-        model = ontospy.Ontospy(filename)
+        graph = rdflib.Graph()
+        graph.parse(filename)
         p, at = self.init_package(filename=dest)
         p.setMetaData(config.data.namespace_prefix['dc'],
                       'description',
                       _("Converted from %s") % filename)
-        self.convert(self.iterator(model))
+        self.convert(self.iterator(graph))
         self.progress(1.0)
         return self.package
 
-    def iterator(self, model):
+    def iterator(self, graph):
         """Iterate through the loaded OWL.
-
-        Assumptions:
-        - there is a toplevel element (AnnotationConcept) in the model toplayer
-        - the first level of children defines schemas
-        - the leaf elements for each schema define annotation types
         """
+        AO = rdflib.Namespace('http://ada.filmontology.org/ontology/')
+        AR = rdflib.Namespace('http://ada.filmontology.org/resource/')
+        PREFIX = """PREFIX owl: <http://www.w3.org/2002/07/owl#>
+        PREFIX ar: <http://ada.filmontology.org/resource/>
+        PREFIX ao: <http://ada.filmontology.org/ontology/>
+        PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+        PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
+        """
+        def get_label(graph, subject, default=""):
+            """Return a label for the object.
+
+            Using preferably @en labels
+            """
+            labels = graph.preferredLabel(s, lang='en')
+            if labels:
+                # We have at least 1 @en label. Return it.
+                return labels[0][1]
+            else:
+                # No defined label. Use default
+                return default
+
+        def get_comment(graph, subject, default=""):
+            """Return the comment at en for the object.
+            """
+            results = list(graph.query(PREFIX + 'SELECT ?comment WHERE { <%s> rdfs:comment ?comment . FILTER langMatches( lang(?comment), "en" ) }' % unicode(subject)))
+            if results:
+                return unicode(results[0][0])
+            else:
+                return default
+
         progress=0.01
         self.progress(progress, "Starting conversion")
-        root = model.toplayer[0]
-        schemas = root.children()
-        incr=0.98/len(schemas)
+        RDF = rdflib.RDF
+        schemas = list(graph.subjects(RDF.type, AO.AnnotationLevel))
+        incr=0.98 / len(schemas)
         for s in schemas:
             progress += incr
             # Create the schema
-            schema = self.create_schema(s.qname.strip(':'), title=s.bestLabel(), description=s.bestDescription())
+            # FIXME: there is no label neither description at the moment.
+            schema_id = s.rpartition('/')[-1]
+            title = get_label(graph, s, schema_id)
+            description = get_comment(graph, s)
+            schema = self.create_schema(schema_id, title=title, description=description)
             if not self.progress(progress, "Creating schema %s" % schema.title):
                 break
-            for c in s.descendants():
-                if not c.children():
-                    # We consider only leaf nodes
-                    self.create_annotation_type(schema, c.qname.strip(':'), title=c.bestLabel(), description=c.bestDescription())
+            for atnode in graph.objects(s, AO.term('hasAnnotationType')):
+                at_id = atnode.rpartition('/')[-1]
+                label = get_label(graph, atnode, at_id)
+                description = get_comment(graph, atnode)
+                at = self.create_annotation_type(schema, at_id, title=label, description=description)
+                values = [ unicode(t[0])
+                           for t in graph.query(PREFIX + "SELECT ?label WHERE { <%s> ao:hasPredefinedValue ?x . ?x rdfs:label ?label . }" % unicode(atnode)) ]
+                if values:
+                    at.setMetaData(config.data.namespace, "completions", ",".join(values))
         self.progress(1.0)
         # Hack: we have an empty iterator (no annotations here), but
         # if the yield instruction is not present in the method code,
@@ -93,8 +128,8 @@ class OWLImporter(GenericImporter):
 
 if __name__ == "__main__":
     import sys
-    if ontospy is None:
-        print("Cannot import required ontospy module")
+    if rdflib is None:
+        print("Cannot import required rdflib module")
         sys.exit(1)
     if len(sys.argv) < 3:
         print "Should provide a file name and a package name"
diff --git a/lib/advene/util/helper.py b/lib/advene/util/helper.py
index f045a02..76dc14e 100755
--- a/lib/advene/util/helper.py
+++ b/lib/advene/util/helper.py
@@ -844,9 +844,11 @@ def title2content(new_title, original_content, representation):
     then we can convert the short representation back to the
     appropriate content.
 
+    new_title is expected to be unicode.
+
     @return the new content or None if the content could not be updated.
     """
-    new_title = unicode(new_title, 'utf-8')
+    assert(isinstance(new_title, unicode))
     r = None
     if representation is None or empty_representation.match(representation):
         r = new_title

-- 
advene packaging



More information about the pkg-multimedia-commits mailing list