Index: meldapp.py
===================================================================
--- meldapp.py	(revision 1347)
+++ meldapp.py	(working copy)
@@ -38,6 +38,21 @@
 import task
 import vc
 
+# optional
+# dbus
+dbus_available = False
+try:
+    import dbus
+    import dbus.service
+    if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
+        import dbus.glib
+        dbus_available = True
+    else:
+        # No dbus support 
+        pass
+except ImportError:
+    print "No dbus support."
+
 from sourceviewer import srcviewer
 
 version = "1.2.1-svn"
@@ -45,6 +60,21 @@
 # magic developer switch, changes some behaviour
 developer = 0
 
+###
+# OptParse Override
+###
+
+class MeldOptionParser(optparse.OptionParser):
+    def exit(self, status=0, msg=None):
+        if msg:
+            sys.stderr.write(msg)
+            
+    def error(self, msg):
+        self.print_usage(sys.stderr)
+        self.exit(2, "%s: error: %s\n" % (self.get_prog_name(), msg))
+        raise
+    
+        
 ################################################################################
 #
 # NewDocDialog
@@ -903,7 +933,8 @@
         return "\n" + "\n".join( ["%prog " + pad_args_fmt % u for u in usages] )
 
     def parse_args(self, rawargs):
-        parser = optparse.OptionParser(
+#        parser = optparse.OptionParser(
+        parser = MeldOptionParser(
             option_class=misc.MeldOption,
             usage=self.usage_msg(),
             description=_("Meld is a file and directory comparison tool."),
@@ -919,17 +950,22 @@
         parser.add_option("", "--diff", action="diff_files", dest='diff',
                           default=[],
                           help=_("Creates a diff tab for up to 3 supplied files or directories."))
-        options, args = parser.parse_args(rawargs)
-        for files in options.diff:
-            if len(files) not in (1, 2, 3):
-                self.usage(_("Invalid number of arguments supplied for --diff."))
-            self.append_diff(files)
-        if len(args) not in (0, 1, 2, 3):
-            self.usage(_("Wrong number of arguments (Got %i)") % len(args))
-        else:
-            tab = self.open_paths(args, options.auto_compare)
-            if tab:
-                tab.set_labels(options.label)
+        try:
+            options, args = parser.parse_args(rawargs)        
+            for files in options.diff:
+                if len(files) not in (1, 2, 3):
+                    parser.error(_("Invalid number of arguments supplied for --diff."))
+                self.append_diff(files)
+            if len(args) not in (0, 1, 2, 3):
+                parser.error(_("Wrong number of arguments (Got %i)") % len(args))
+            return (options, args)
+        except Exception:
+            raise
+    
+    def open_tab(self, args, auto_compare, label):
+        tab = self.open_paths(args, auto_compare)
+        if tab:
+            tab.set_labels(label)
 
     def _single_file_open(self, path):
         doc = vcview.VcView(self.prefs)
@@ -954,9 +990,50 @@
             tab = self.append_diff(paths, auto_compare)
         return tab
 
-
 ################################################################################
 #
+# DbusHandler
+#
+################################################################################
+class DBusProvider(dbus.service.Object):
+    def __init__(self, bus_name, app, object_path='/net/sf/meld'):
+        dbus.service.Object.__init__(self, bus_name, object_path)
+        self.app = app
+        
+    @dbus.service.method('net.sf.meld')
+    def diff(self, args):
+        try:
+            options, args = self.app.parse_args(args)
+        except:
+            return
+        self.app.open_tab(args, 
+                          options.auto_compare, 
+                          options.label)
+        
+class DBusUser:
+    def running_already(self):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('org.freedesktop.DBus',
+                               '/org/freedesktop/DBus')
+        iface = dbus.Interface(proxy, 'org.freedesktop.DBus')
+        names = iface.ListNames()
+        if 'net.sf.meld' in names:
+            return True
+        return False        
+    
+    def register(self, app):
+        bus = dbus.SessionBus()
+        bus_name = dbus.service.BusName('net.sf.meld', bus=bus)
+        self.remote_instance = DBusProvider(bus_name, app)
+        
+    def remote_diff(self, args):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('net.sf.meld', '/net/sf/meld')
+        iface = dbus.Interface(proxy, 'net.sf.meld')
+        return iface.diff(args)
+        
+################################################################################
+#
 # Main
 #
 ################################################################################
@@ -972,6 +1049,24 @@
     sys.stdout = Unbuffered(sys.stdout)
 
     gtk.icon_theme_get_default().append_search_path(paths.share_dir("glade2/pixmaps/"))
+    
+    # check for previously running instance
+    
+    dbus_user = DBusUser()
+    running = False
+    if dbus_available:
+        running = dbus_user.running_already()
+        if running:
+            dbus_user.remote_diff(sys.argv[1:])
+            return
+    
     app = MeldApp()
-    app.parse_args(sys.argv[1:])
+    if dbus_available and not running:
+        dbus_user.register(app)
+    try:
+        options, args = app.parse_args(sys.argv[1:])
+    except:
+        sys.exit(2)
+    app.open_tab(args, options.auto_compare, options.label)
+
     gtk.main()
