[RFC][PATCH] Add --auto-close command line option
- From: Vincent Legoll <vincent legoll gmail com>
- To: meld-list <meld-list gnome org>
- Subject: [RFC][PATCH] Add --auto-close command line option
- Date: Thu, 12 Mar 2009 21:09:01 +0100
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]