tomboy r2233 - in trunk: . Tomboy



Author: sharm
Date: Mon Oct 20 07:20:30 2008
New Revision: 2233
URL: http://svn.gnome.org/viewvc/tomboy?rev=2233&view=rev

Log:
Fixes for bug #556136: Add single-instance detection and some support for
accessing the RemoteControl over .NET remoting (since we have no D-BUS
daemon on Windows or Mac).

* Tomboy/RemoteControlProxy: For WIN32, use a mutex to enforce a single
  instance of Tomboy, and register a RemoteControlWrapper over IPC for use
  via .NET remoting.

* Makefile.am:
* Tomboy/Tomboy.cs:
* Tomboy/RemoteControl.cs:
* Tomboy/IRemoteControl.cs: Extract interface from RemoteControl.

* Tomboy/RemoteControlWrapper.cs: Implementation of IRemoteControl that
  wraps a RemoteControl instance's method calls with Gtk.Application.Invoke.
  Unfortunately these calls are not processed by the GTK+ event loop until
  some interaction with GTK+ occurs, so behavior can seem unpredictable.
  Throws NotImplemented for everything but DisplaySearch and Version.

* Tomboy.csproj: Include new and existing RemoteControl stuff.

Added:
   trunk/Tomboy/IRemoteControl.cs   (contents, props changed)
   trunk/Tomboy/RemoteControlWrapper.cs   (contents, props changed)
Modified:
   trunk/ChangeLog
   trunk/Tomboy.csproj
   trunk/Tomboy/Makefile.am
   trunk/Tomboy/RemoteControl.cs
   trunk/Tomboy/RemoteControlProxy.cs
   trunk/Tomboy/Tomboy.cs

Modified: trunk/Tomboy.csproj
==============================================================================
--- trunk/Tomboy.csproj	(original)
+++ trunk/Tomboy.csproj	Mon Oct 20 07:20:30 2008
@@ -101,6 +101,7 @@
     <Reference Include="System.Data" />
     <Reference Include="System.Drawing" />
     <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Runtime.Remoting" />
     <Reference Include="System.Xml" />
     <Reference Include="glib-sharp, Version=2.10.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
     <Reference Include="System" />
@@ -111,8 +112,8 @@
     <Compile Include="Tomboy\ActionManager.cs" />
     <Compile Include="Tomboy\Contrast.cs" />
     <Compile Include="Tomboy\Defines.WIN32.cs" />
+    <Compile Include="Tomboy\IRemoteControl.cs" />
     <Compile Include="Tomboy\Logger.cs" />
-    <Compile Include="Tomboy\MacFactory.cs" />
     <Compile Include="Tomboy\ManagedWinapi.EventDispatchingNativeWindow.cs" />
     <Compile Include="Tomboy\ManagedWinapi.Hotkey.cs">
       <SubType>Component</SubType>
@@ -124,6 +125,9 @@
     <Compile Include="Tomboy\NoteWindow.cs" />
     <Compile Include="Tomboy\Preferences.cs" />
     <Compile Include="Tomboy\RecentChanges.cs" />
+    <Compile Include="Tomboy\RemoteControl.cs" />
+    <Compile Include="Tomboy\RemoteControlProxy.cs" />
+    <Compile Include="Tomboy\RemoteControlWrapper.cs" />
     <Compile Include="Tomboy\Tomboy.cs" />
     <Compile Include="Tomboy\Tray.cs" />
     <Compile Include="Tomboy\Trie.cs" />
@@ -297,4 +301,4 @@
 copy "$(ProjectDir)Tomboy\Tomboy.addin.xml" "$(ProjectDir)"
 copy "$(ProjectDir)data\UIManagerLayout.xml" "$(ProjectDir)"</PostBuildEvent>
   </PropertyGroup>
-</Project>
\ No newline at end of file
+</Project>

Added: trunk/Tomboy/IRemoteControl.cs
==============================================================================
--- (empty file)
+++ trunk/Tomboy/IRemoteControl.cs	Mon Oct 20 07:20:30 2008
@@ -0,0 +1,38 @@
+ïusing System;
+
+namespace Tomboy
+{
+	public interface IRemoteControl
+	{
+		bool AddTagToNote (string uri, string tag_name);
+		string CreateNamedNote (string linked_title);
+		string CreateNote ();
+		bool DeleteNote (string uri);
+		bool DisplayNote (string uri);
+		bool DisplayNoteWithSearch (string uri, string search);
+		void DisplaySearch ();
+		void DisplaySearchWithText (string search_text);
+		string FindNote (string linked_title);
+		string FindStartHereNote ();
+		string [] GetAllNotesWithTag (string tag_name);
+		long GetNoteChangeDate (string uri);
+		string GetNoteCompleteXml (string uri);
+		string GetNoteContents (string uri);
+		string GetNoteContentsXml (string uri);
+		long GetNoteCreateDate (string uri);
+		string GetNoteTitle (string uri);
+		string [] GetTagsForNote (string uri);
+		bool HideNote (string uri);
+		string [] ListAllNotes ();
+		event RemoteAddedHandler NoteAdded;
+		event RemoteDeletedHandler NoteDeleted;
+		bool NoteExists (string uri);
+		event RemoteSavedHandler NoteSaved;
+		bool RemoveTagFromNote (string uri, string tag_name);
+		string [] SearchNotes (string query, bool case_sensitive);
+		bool SetNoteCompleteXml (string uri, string xml_contents);
+		bool SetNoteContents (string uri, string text_contents);
+		bool SetNoteContentsXml (string uri, string xml_contents);
+		string Version ();
+	}
+}

Modified: trunk/Tomboy/Makefile.am
==============================================================================
--- trunk/Tomboy/Makefile.am	(original)
+++ trunk/Tomboy/Makefile.am	Mon Oct 20 07:20:30 2008
@@ -9,6 +9,7 @@
 if ENABLE_DBUS
 DBUS_CSFLAGS = -define:ENABLE_DBUS
 DBUS_CSFILES = 				\
+	$(srcdir)/IRemoteControl.cs	\
 	$(srcdir)/RemoteControl.cs	\
 	$(srcdir)/RemoteControlProxy.cs
 endif

Modified: trunk/Tomboy/RemoteControl.cs
==============================================================================
--- trunk/Tomboy/RemoteControl.cs	(original)
+++ trunk/Tomboy/RemoteControl.cs	Mon Oct 20 07:20:30 2008
@@ -2,18 +2,20 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
-
+#if !WIN32
 using NDesk.DBus;
 using org.freedesktop.DBus;
+#endif
 
 namespace Tomboy
 {
 	public delegate void RemoteDeletedHandler (string uri, string title);
 	public delegate void RemoteAddedHandler (string uri);
 	public delegate void RemoteSavedHandler (string uri);
-
+#if !WIN32
 	[Interface ("org.gnome.Tomboy.RemoteControl")]
-	public class RemoteControl : MarshalByRefObject
+#endif
+	public class RemoteControl : MarshalByRefObject, IRemoteControl
 	{
 		private NoteManager note_manager;
 

Modified: trunk/Tomboy/RemoteControlProxy.cs
==============================================================================
--- trunk/Tomboy/RemoteControlProxy.cs	(original)
+++ trunk/Tomboy/RemoteControlProxy.cs	Mon Oct 20 07:20:30 2008
@@ -1,14 +1,34 @@
 using System;
+#if !WIN32
 using NDesk.DBus;
 using org.freedesktop.DBus;
+#else
+using System.Runtime.Remoting;
+using System.Runtime.Remoting.Activation;
+using System.Runtime.Remoting.Channels;
+using System.Runtime.Remoting.Channels.Ipc;
+using System.Threading;
+#endif
 
 namespace Tomboy
 {
 	public static class RemoteControlProxy {
+#if !WIN32
 		private const string Path = "/org/gnome/Tomboy/RemoteControl";
 		private const string Namespace = "org.gnome.Tomboy";
+#else
+		private static Mutex mutex;
+		private static IpcChannel IpcChannel;
+		private const string MutexName = "{9EF7D32D-3392-4940-8A28-1320A7BD42AB}";
+		private const string ServerName = "TomboyServer";
+		private const string ClientName = "TomboyClient";
+		private const string WrapperName = "TomboyRemoteControlWrapper";
+		private static string ServiceUrl =
+			string.Format ("ipc://{0}/{1}", ServerName, WrapperName);
+#endif
 
-		public static RemoteControl GetInstance () {
+		public static IRemoteControl GetInstance () {
+#if !WIN32
 			BusG.Init ();
 
 			if (! Bus.Session.NameHasOwner (Namespace))
@@ -16,9 +36,18 @@
 
 			return Bus.Session.GetObject<RemoteControl> (Namespace,
 			                new ObjectPath (Path));
+#else
+			RemoteControlWrapper remote = (RemoteControlWrapper) Activator.GetObject (
+				typeof (RemoteControlWrapper),
+				ServiceUrl);
+
+			return remote;
+#endif
 		}
 
-		public static RemoteControl Register (NoteManager manager) {
+		public static RemoteControl Register (NoteManager manager)
+		{
+#if !WIN32
 			BusG.Init ();
 
 			RemoteControl remote_control = new RemoteControl (manager);
@@ -31,6 +60,47 @@
 				return null;
 
 			return remote_control;
+#else
+			// Use a mutex to provide single-instance detection
+			bool isNew;
+			mutex = new Mutex (true, MutexName, out isNew);
+
+			if (isNew) {
+				// Register an IPC channel for .NET remoting
+				// access to our Remote Control
+				IpcChannel = new IpcChannel (ServerName);
+				ChannelServices.RegisterChannel (IpcChannel, false);
+				RemotingConfiguration.RegisterWellKnownServiceType (
+					typeof (RemoteControlWrapper),
+					WrapperName,
+					WellKnownObjectMode.Singleton);
+
+				// The actual Remote Control has many methods
+				// that need to be called in the GTK+ mainloop,
+				// which will not happen when the method calls
+				// come from a .NET remoting client. So we wrap
+				// the Remote Control in a class that implements
+				// the same interface, but wraps most method
+				// calls in Gtk.Application.Invoke.
+				//
+				// Note that only one RemoteControl is ever
+				// created, and that it is stored statically
+				// in the RemoteControlWrapper.
+				RemoteControl realRemote = new RemoteControl (manager);
+				RemoteControlWrapper.Initialize (realRemote);
+
+				RemoteControlWrapper remoteWrapper = (RemoteControlWrapper) Activator.GetObject (
+					typeof (RemoteControlWrapper),
+					ServiceUrl);
+				return realRemote;
+			} else {
+				// If Tomboy is already running, register a
+				// client IPC channel.
+				IpcChannel = new IpcChannel (ClientName);
+				ChannelServices.RegisterChannel (IpcChannel, false);
+				return null;
+			}
+#endif
 		}
 	}
 }

Added: trunk/Tomboy/RemoteControlWrapper.cs
==============================================================================
--- (empty file)
+++ trunk/Tomboy/RemoteControlWrapper.cs	Mon Oct 20 07:20:30 2008
@@ -0,0 +1,171 @@
+ïusing System;
+
+namespace Tomboy
+{
+	/// <summary>
+	/// Wrap the RemoteControl class methods in Gtk.Application.Invoke.
+	/// </summary>
+	public class RemoteControlWrapper : MarshalByRefObject, IRemoteControl
+	{
+		#region Static Members
+
+		// Store the RemoteControl instance statically because:
+		//	1. We only want one anyway.
+		//	2. Otherwise .NET remoting will want to start
+		//	   serializing RemoteControl, NoteManager, etc.
+		private static RemoteControl remote;
+		public static void Initialize (RemoteControl remote)
+		{
+			RemoteControlWrapper.remote = remote;
+		}
+
+		#endregion
+
+		#region IRemoteControl Members
+
+		public bool AddTagToNote (string uri, string tag_name)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string CreateNamedNote (string linked_title)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string CreateNote ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		public bool DeleteNote (string uri)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public bool DisplayNote (string uri)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public bool DisplayNoteWithSearch (string uri, string search)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void DisplaySearch ()
+		{
+			Gtk.Application.Invoke (delegate {
+				remote.DisplaySearch ();
+			});
+		}
+
+		public void DisplaySearchWithText (string search_text)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string FindNote (string linked_title)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string FindStartHereNote ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string [] GetAllNotesWithTag (string tag_name)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public long GetNoteChangeDate (string uri)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string GetNoteCompleteXml (string uri)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string GetNoteContents (string uri)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string GetNoteContentsXml (string uri)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public long GetNoteCreateDate (string uri)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string GetNoteTitle (string uri)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string [] GetTagsForNote (string uri)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public bool HideNote (string uri)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string [] ListAllNotes ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		public event RemoteAddedHandler NoteAdded;
+
+		public event RemoteDeletedHandler NoteDeleted;
+
+		public bool NoteExists (string uri)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public event RemoteSavedHandler NoteSaved;
+
+		public bool RemoveTagFromNote (string uri, string tag_name)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string [] SearchNotes (string query, bool case_sensitive)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public bool SetNoteCompleteXml (string uri, string xml_contents)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public bool SetNoteContents (string uri, string text_contents)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public bool SetNoteContentsXml (string uri, string xml_contents)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public string Version ()
+		{
+			return remote.Version ();
+		}
+
+		#endregion
+	}
+}

Modified: trunk/Tomboy/Tomboy.cs
==============================================================================
--- trunk/Tomboy/Tomboy.cs	(original)
+++ trunk/Tomboy/Tomboy.cs	Mon Oct 20 07:20:30 2008
@@ -23,7 +23,7 @@
 		static bool is_panel_applet = false;
 		static PreferencesDialog prefs_dlg;
 		static SyncDialog sync_dlg;
-#if ENABLE_DBUS
+#if ENABLE_DBUS || WIN32
 		static RemoteControl remote_control;
 #endif
 		static Gtk.IconTheme icon_theme = null;
@@ -35,13 +35,13 @@
 
 			TomboyCommandLine cmd_line = new TomboyCommandLine (args);
 
-#if ENABLE_DBUS // Run command-line earlier with DBus enabled
+#if ENABLE_DBUS || WIN32 // Run command-line earlier with DBus enabled
 			if (cmd_line.NeedsExecute) {
 				// Execute args at an existing tomboy instance...
 				cmd_line.Execute ();
 				return;
 			}
-#endif // ENABLE_DBUS
+#endif // ENABLE_DBUS || WIN32
 
 			Initialize ("tomboy", "Tomboy", "tomboy", args);
 
@@ -69,7 +69,7 @@
 				addin.Initialize ();
 			}
 
-#if !ENABLE_DBUS
+#if !ENABLE_DBUS && !WIN32
 			if (cmd_line.NeedsExecute) {
 				cmd_line.Execute ();
 			}
@@ -149,7 +149,7 @@
 
 		static void RegisterRemoteControl (NoteManager manager)
 		{
-#if ENABLE_DBUS
+#if ENABLE_DBUS || WIN32
 			try {
 				remote_control = RemoteControlProxy.Register (manager);
 				if (remote_control != null) {
@@ -158,7 +158,7 @@
 					// If Tomboy is already running, open the search window
 					// so the user gets some sort of feedback when they
 					// attempt to run Tomboy again.
-					RemoteControl remote = null;
+					IRemoteControl remote = null;
 					try {
 						remote = RemoteControlProxy.GetInstance ();
 						remote.DisplaySearch ();
@@ -430,7 +430,7 @@
 			                "  --search [text]\t\tOpen the search all notes window with " +
 			                "the search text.\n");
 
-#if ENABLE_DBUS
+#if ENABLE_DBUS || WIN32
 			usage +=
 			        Catalog.GetString (
 			                "  --new-note\t\t\tCreate and display a new note.\n" +
@@ -449,7 +449,7 @@
 //     "  --check-plugin-unloading\tCheck if plugins are " +
 //     "unloaded properly.\n");
 
-#if !ENABLE_DBUS
+#if !ENABLE_DBUS && !WIN32
 			usage += Catalog.GetString ("D-BUS remote control disabled.\n");
 #endif
 
@@ -467,7 +467,7 @@
 				bool quit = false;
 
 				switch (args [idx]) {
-#if ENABLE_DBUS
+#if ENABLE_DBUS || WIN32
 				case "--new-note":
 					// Get optional name for new note...
 					if (idx + 1 < args.Length
@@ -535,7 +535,7 @@
 					Console.WriteLine (unknown_opt, args [idx]);
 					quit = true;
 					break;
-#endif // ENABLE_DBUS
+#endif // ENABLE_DBUS || WIN32
 
 				case "--panel-applet":
 					panel_applet = true;
@@ -602,8 +602,8 @@
 
 		public void Execute ()
 		{
-#if ENABLE_DBUS
-			RemoteControl remote = null;
+#if ENABLE_DBUS || WIN32
+			IRemoteControl remote = null;
 			try {
 				remote = RemoteControlProxy.GetInstance ();
 			} catch (Exception e) {
@@ -707,7 +707,7 @@
 
 				recent_changes.Present ();
 			}
-#endif // ENABLE_DBUS
+#endif // ENABLE_DBUS || WIN32
 		}
 	}
 }



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