[RFC][PATCH] Add --auto-close command line option



Hello,

The attached patch implements an auto-close option for
meld, to eventually use for automated testing purposes.

I intend to automate VC plugin testing, for a start and
this work is the first step in that direction.

It does open diffs specified on command-line, and then
afterwards close each diff view, being a filediff, a vcview,
and then finally closes meld itself. The --auto-compare
command line option still works and is complementary
to --auto-close.

This is an RFC, because I had to do some ugly things,
and I still don't fully understand why, for example the
scheduler dance in meldapp.cpp...

- Don't look at the misc.py part of it, it's current hacking
and not part of that RFC, it will probably come in a future
round of features.

- Use knowledge of vcview, diffview, meldapp internals in
gnomeglade.Component, maybe I should have added
a get_scheduler() API...

- Change the way MeldApp connects its scheduler
"runnable" callback, and then specifically have to
wake it manually by adding a dummy task.
See lines 935 & 937 of meldapp.py after patching.
Try with add_task(lambda: None) commented and
watch meld --auto-compare not working any more.

- I added auto-close delay capability, during patch
development, but it's not used in the current
incarnation, should I remove it, or allow it to be
specified with another command line option ?

Could you please tell me if you think of better ways
to do the same. In fact any comment would be
appreciated on the patch. Any ideas of additional
features.

-- 
Vincent Legoll
Index: misc.py
===================================================================
--- misc.py	(révision 1255)
+++ misc.py	(copie de travail)
@@ -37,7 +37,18 @@
         return ((whitespace_re.search(s) == None) and s or ('"%s"' % s))
     return " ".join( [ quote(x) for x in command ] )
 
-def run_dialog( text, parent=None, messagetype=gtk.MESSAGE_WARNING, buttonstype=gtk.BUTTONS_OK, extrabuttons=()):
+global_debug_mode = False
+def run_dialog(text, parent=None, messagetype=gtk.MESSAGE_WARNING, buttonstype=gtk.BUTTONS_OK, extrabuttons=()):
+    if global_debug_mode:
+        return run_dialog_stdio(text, parent, messagetype, buttonstype, extrabuttons)
+    else:
+        return run_dialog_gui(text, parent, messagetype, buttonstype, extrabuttons)
+
+def run_dialog_stdio(text, parent=None, messagetype=gtk.MESSAGE_WARNING, buttonstype=gtk.BUTTONS_OK, extrabuttons=()):
+    print text
+    return gtk.RESPONSE_OK
+
+def run_dialog_gui(text, parent=None, messagetype=gtk.MESSAGE_WARNING, buttonstype=gtk.BUTTONS_OK, extrabuttons=()):
     """Run a dialog with text 'text'.
        Extra buttons are passed as tuples of (button label, response id).
     """
Index: gnomeglade.py
===================================================================
--- gnomeglade.py	(révision 1255)
+++ gnomeglade.py	(copie de travail)
@@ -21,6 +21,7 @@
 import gtk.glade
 import historyentry
 import re
+import time
 
 class Component(object):
     """Base class for all glade objects.
@@ -46,7 +47,24 @@
         self.xml.signal_autoconnect(self)
         self.widget = getattr(self, root)
         self.widget.set_data("pyobject", self)
+        self.autoclose_delay = 0
 
+    def set_autoclose_handler(self, autoclose_delay=0):
+        # FIXME: we don't "know" we have a scheduler
+        assert hasattr(self, 'scheduler')
+        self.autoclose_delay = autoclose_delay
+        self.scheduler.add_task(self.autoclose_handler().next)
+
+    def on_autoclose(self):
+        self.widget.destroy()
+        
+    def autoclose_handler(self):
+        yield "Auto-closing..."
+        if self.autoclose_delay > 0:
+            time.sleep(self.autoclose_delay)
+        self.on_autoclose()
+        yield False
+
     def __getattr__(self, key):
         """Allow glade widgets to be accessed as self.widgetname.
         """
Index: meldapp.py
===================================================================
--- meldapp.py	(révision 1255)
+++ meldapp.py	(copie de travail)
@@ -574,11 +574,13 @@
         self.prefs.notify_add(self.on_preference_changed)
         self.idle_hooked = 0
         self.scheduler = task.LifoScheduler()
-        self.scheduler.connect("runnable", self.on_scheduler_runnable )
         self.widget.set_default_size(self.prefs.window_size_x, self.prefs.window_size_y)
         self.ui.ensure_update()
         self.widget.show()
 
+    def on_autoclose(self):
+        gtk.main_quit()
+        
     def on_widget_drag_data_received(self, wid, context, x, y, selection_data, info, time):
         if len(selection_data.get_uris()) != 0:
             paths = [gnomevfs.get_local_path_from_uri(u) for u in selection_data.get_uris()]
@@ -856,9 +858,12 @@
                     parent = self,
                     buttonstype = gtk.BUTTONS_OK)
         elif 1 in aredirs:
-            return self.append_dirdiff(paths, auto_compare)
+            ret = self.append_dirdiff(paths, auto_compare)
         else:
-            return self.append_filediff(paths)
+            ret = self.append_filediff(paths)
+        if self.autoclose:
+            ret.set_autoclose_handler()
+        return ret
 
     def append_vcview(self, locations, auto_compare=False):
         assert len(locations) in (1,)
@@ -868,6 +873,8 @@
         doc.set_location(location)
         if auto_compare:
             doc.on_button_diff_clicked(None)
+        if self.autoclose:
+            doc.set_autoclose_handler()
         return doc
 
     #
@@ -907,6 +914,7 @@
             version="%prog "+version)
         parser.add_option("-L", "--label", action="append", default=[], help=_("Set label to use instead of file name"))
         parser.add_option("-a", "--auto-compare", action="store_true", default=False, help=_("Automatically compare all differing files on startup"))
+        parser.add_option("-o", "--auto-close", action="store_true", default=False, help=_("Automatically close application after startup. Used for automated testing."))
         parser.add_option("-u", "--unified", action="store_true", help=_("Ignored for compatibility"))
         parser.add_option("-c", "--context", action="store_true", help=_("Ignored for compatibility"))
         parser.add_option("-e", "--ed", action="store_true", help=_("Ignored for compatibility"))
@@ -919,7 +927,15 @@
             if len(files) not in (1, 2, 3):
                 self.usage(_("Invalid number of arguments supplied for --diff."))
             self.append_diff(files)
+        self.autoclose = options.auto_close
+        if options.auto_close:
+            self.set_autoclose_handler()
+            misc.global_debug_mode = True
         tab = self.open_paths(args, options.auto_compare)
+        # We should not start the LifoScheduler before having at least scheduled real-work
+        self.scheduler.connect("runnable", self.on_scheduler_runnable)
+        # FIXME: this is needed to wake the scheduler
+        self.scheduler.add_task(lambda: None)
         if tab:
             tab.set_labels( options.label )
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]