f-spot r4107 - in trunk: . extensions extensions/DBusService src src/UI.Dialog



Author: thomasvm
Date: Thu Jun 26 18:29:51 2008
New Revision: 4107
URL: http://svn.gnome.org/viewvc/f-spot?rev=4107&view=rev

Log:
Turn DBus api into a service extension

Added:
   trunk/extensions/DBusService/
   trunk/extensions/DBusService/DBusProxy.cs
   trunk/extensions/DBusService/DBusService.addin.xml
   trunk/extensions/DBusService/DBusService.cs
   trunk/extensions/DBusService/Makefile.am
Removed:
   trunk/src/DBusProxy.cs
Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/extensions/ChangeLog
   trunk/extensions/Makefile.am
   trunk/src/Core.cs
   trunk/src/Db.cs
   trunk/src/Makefile.am
   trunk/src/PhotoStore.cs
   trunk/src/Preferences.cs
   trunk/src/UI.Dialog/PreferenceDialog.cs
   trunk/src/f-spot.glade

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Thu Jun 26 18:29:51 2008
@@ -359,6 +359,7 @@
 extensions/Makefile
 extensions/BeagleService/Makefile
 extensions/CDExport/Makefile
+extensions/DBusService/Makefile
 extensions/DefaultExporters/Makefile
 extensions/FlickrExport/Makefile
 extensions/FlickrExport/FlickrNet/Makefile

Added: trunk/extensions/DBusService/DBusProxy.cs
==============================================================================
--- (empty file)
+++ trunk/extensions/DBusService/DBusProxy.cs	Thu Jun 26 18:29:51 2008
@@ -0,0 +1,447 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+using FSpot;
+using NDesk.DBus;
+
+namespace DBusService {
+	public delegate void RemoteUp();
+	public delegate void RemoteDown();
+
+	public class DBusException : Exception { 
+		public DBusException (string message)
+			: base (message)
+		{} 
+
+		public DBusException (string message, params object [] format_params)
+			: this (string.Format (message, format_params))
+		{}
+	}
+
+	public class DBusProxy {
+		public event RemoteUp RemoteUp; 
+		public event RemoteDown RemoteDown;
+
+		internal void OnRemoteUp () 
+		{
+			if (RemoteUp != null)
+			 	RemoteUp (); 
+		}
+
+		internal void OnRemoteDown () 
+		{
+			if (RemoteDown != null)
+			 	RemoteDown (); 
+		}
+	}
+
+	public class DBusProxyFactory {
+		private const string SERVICE_PATH = "org.gnome.FSpot";
+		private const string TAG_PROXY_PATH = "/org/gnome/FSpot/TagRemoteControl";
+		private const string PHOTO_PROXY_PATH = "/org/gnome/FSpot/PhotoRemoteControl";
+
+		private static TagProxy tag_remote;
+		private static PhotoProxy photo_remote;
+
+		public static void Load (Db db) 
+		{
+			tag_remote = new TagProxy (db.Tags);
+			Bus.Session.Register (SERVICE_PATH, new ObjectPath (TAG_PROXY_PATH), tag_remote);
+			tag_remote.OnRemoteUp ();
+
+			photo_remote = new PhotoProxy (db);
+			Bus.Session.Register (SERVICE_PATH, new ObjectPath (PHOTO_PROXY_PATH), photo_remote);
+			photo_remote.OnRemoteUp ();
+		} 
+
+		public static void EmitRemoteDown () 
+		{
+		 	tag_remote.OnRemoteDown ();
+			photo_remote.OnRemoteDown ();
+		}
+	 
+	}
+
+	[Interface ("org.gnome.FSpot.TagRemoteControl")]
+	public interface ITagRemoteControl {
+		// info, included for backward compatibility with times
+		// where this was embedded in f-spot core
+		bool IsReadOnly ();
+
+	 	// get all
+		string[] GetTagNames ();
+		uint[] GetTagIds ();
+
+		// get info for one tag
+		IDictionary<string, object> GetTagByName (string name);
+		IDictionary<string, object> GetTagById (int id);
+
+		event RemoteUp RemoteUp;
+		event RemoteDown RemoteDown;
+
+		// tag creators
+		int CreateTag (string name);
+		int CreateTagWithParent (string parent, string name);
+
+		// tag removers
+		bool RemoveTagByName (string name);
+		bool RemoveTagById (int id);
+	}
+
+	// Class exposing all photos on the dbus
+	public class TagProxy : DBusProxy, ITagRemoteControl {
+		protected TagStore tag_store;
+
+		public TagStore Store {
+			get { return tag_store; } 
+		}
+
+		internal TagProxy (TagStore store) 
+		{
+		 	tag_store = store;
+		}
+
+		#region Interface methods
+		public bool IsReadOnly () {
+			return false; 
+		}
+
+		public string[] GetTagNames () 
+		{
+		 	List<string> tags = new List<string> ();
+			AddTagNameToList (tags, tag_store.RootCategory);
+
+			return tags.ToArray ();
+		}
+
+		public uint[] GetTagIds () 
+		{
+		 	List<uint> tags = new List<uint> ();
+			AddTagIdToList (tags, tag_store.RootCategory);
+
+			return tags.ToArray ();
+		}
+
+		public IDictionary<string, object> GetTagByName (string name) 
+		{
+			Tag t = tag_store.GetTagByName (name);
+
+			if (t == null)
+			 	throw new DBusException ("Tag with name {0} does not exist.", name);
+
+			return CreateDictFromTag (t);
+		}
+
+		public IDictionary<string, object> GetTagById (int id) 
+		{
+			Tag t = tag_store.GetTagById (id);
+
+			if (t == null)
+			 	throw new DBusException ("Tag with id {0} does not exist.", id);
+
+			return CreateDictFromTag (t);
+		}
+
+		public int CreateTag (string name) 
+		{
+		 	return CreateTagPriv (null, name);
+		}
+
+		public int CreateTagWithParent (string parent, string name) 
+		{
+			Tag parent_tag = tag_store.GetTagByName (parent); 
+
+			if (!(parent_tag is Category))
+			 	parent_tag = null;
+
+		 	return CreateTagPriv (parent_tag as Category, name);
+		}
+
+		public bool RemoveTagByName (string name) 
+		{
+		 	Tag tag = tag_store.GetTagByName (name);
+
+			return RemoveTag (tag);
+		}
+
+		public bool RemoveTagById (int id) 
+		{
+			Tag tag = tag_store.GetTagById (id);
+			
+			return RemoveTag (tag); 
+		}	 
+
+		#endregion
+
+		#region Helper methods
+		private void AddTagNameToList (List<string> list, Tag tag) 
+		{
+			if (tag != tag_store.RootCategory)
+			 	list.Add (tag.Name);
+
+			if (tag is Category) {
+				foreach (Tag child in (tag as Category).Children)
+					AddTagNameToList (list, child);
+			}
+		}
+
+		private void AddTagIdToList (List<uint> list, Tag tag) 
+		{
+			if (tag != tag_store.RootCategory)
+				list.Add (tag.Id);
+
+			if (tag is Category) {
+				foreach (Tag child in (tag as Category).Children)
+					AddTagIdToList (list, child);
+			}
+		}
+
+		private IDictionary<string, object> CreateDictFromTag (Tag t) 
+		{
+			Dictionary<string, object> result = new Dictionary<string, object> ();
+
+			result.Add ("Id", t.Id);
+			result.Add ("Name", t.Name);
+			
+			StringBuilder builder = new StringBuilder ();
+
+			if (t is Category) {
+				foreach (Tag child in (t as Category).Children) {
+					if (builder.Length > 0)
+					 	builder.Append (",");
+
+					builder.Append (child.Name);
+				}
+			}
+			
+			result.Add ("Children", builder.ToString ());
+
+			return result;
+		}
+
+		private int CreateTagPriv (Category parent_tag, string name)
+		{
+			try {
+				Tag created = tag_store.CreateCategory (parent_tag, name);			
+				return (int)created.Id; 
+			}
+			catch {
+				throw new DBusException ("Failed to create tag."); 
+			}
+		}
+
+		private bool RemoveTag (Tag t) 
+		{
+			if (t == null)
+			 	return false;
+				
+			try {
+			 	// remove tags from photos first
+			 	Core.Database.Photos.Remove (new Tag [] { t });
+				// then remove tag
+				tag_store.Remove (t);
+				return true; 
+			} 
+			catch {
+				return false; 
+			}
+		}
+		#endregion
+	}
+
+
+ 	[Interface ("org.gnome.FSpot.PhotoRemoteControl")]
+	public interface IPhotoRemoteControl {
+		// info; included for backward compatibility
+		// with previous version where this was embedded in f-spot
+		bool IsReadOnly ();
+
+	 	// get all
+		uint[] GetPhotoIds ();
+
+		// import prepare
+		void PrepareRoll ();
+		void FinishRoll ();
+
+		// import 
+		int ImportPhoto (string path, bool copy, string []tags);
+
+		// photo properties
+		IDictionary<string, object> GetPhotoProperties (uint id); 
+		
+		// photo remove
+		void RemovePhoto (uint id);
+
+		// query
+		uint[] Query (string []tags);
+
+		// events
+		event RemoteUp RemoteUp;
+		event RemoteDown RemoteDown;
+	}
+
+	// Class exposing all photos on the dbus
+	public class PhotoProxy : DBusProxy, IPhotoRemoteControl {
+		protected Db db;
+		private Roll current_roll;
+
+		public Db Database {
+			get { return db; } 
+		}
+
+		internal PhotoProxy (Db db) 
+		{
+			this.db = db;
+		}
+
+		public bool IsReadOnly () 
+		{
+			return false;
+		}
+
+		public uint[] GetPhotoIds () 
+		{
+		 	List<uint> ids = new List<uint> ();
+
+			foreach (Photo p in QueryAll ())
+				ids.Add (p.Id);
+
+			return ids.ToArray ();
+		}
+
+		public IDictionary<string, object> GetPhotoProperties (uint id) 
+		{
+			Dictionary<string, object> dict = new Dictionary<string, object> ();
+
+			Photo p = db.Photos.Get (id) as Photo;
+
+			if (p == null)
+			 	throw new DBusException ("Photo with id {0} does not exist.", id);
+
+			dict.Add ("Uri", p.DefaultVersionUri.ToString());
+			dict.Add ("Id", p.Id);
+			dict.Add ("Name", p.Name);
+			dict.Add ("Description", p.Description ?? string.Empty);
+
+			StringBuilder builder = new StringBuilder ();
+
+			foreach (Tag t in p.Tags) {
+				if (builder.Length > 0)
+				 	builder.Append (",");
+
+				builder.AppendFormat (t.Name);
+			}
+
+			dict.Add ("Tags", builder.ToString ());
+
+			return dict;
+		}
+
+		public uint[] Query (string []tags) 
+		{
+			List<Tag> tag_list = GetTagsByNames (tags);
+
+			Photo []photos = db.Photos.Query (tag_list.ToArray ());
+
+			uint []ids = new uint[photos.Length];
+
+		 	for (int i = 0; i < ids.Length; i++)
+			 	ids[i] = photos[i].Id;
+
+			return ids;
+		}
+
+		protected Photo[] QueryAll () 
+		{
+			return db.Photos.Query ((Tag [])null);
+		}
+
+		protected List<Tag> GetTagsByNames (string []names) 
+		{
+			// add tags that exist in tag store
+			List<Tag> tag_list = new List<Tag> ();
+
+			foreach (string tag_name in names) {
+				Tag t = db.Tags.GetTagByName (tag_name);
+
+				if (t == null)
+				 	continue;
+
+				tag_list.Add (t);
+			} 
+
+			return tag_list;
+		}
+
+		public void PrepareRoll () 
+		{
+			if (current_roll != null)
+			 	return;
+
+			current_roll = db.Rolls.Create (); 
+		}
+
+		public void FinishRoll () 
+		{
+			current_roll = null; 
+		}
+
+		public int ImportPhoto (string path, bool copy, string []tags) 
+		{
+			if (current_roll == null)
+			 	throw new DBusException ("You must use PrepareRoll before you can import a photo.");
+
+			// add tags that exist in tag store
+			List<Tag> tag_list = GetTagsByNames (tags);
+
+			Gdk.Pixbuf pixbuf = null;
+			
+			// FIXME: this is more or less a copy of the file import backend code
+			// this should be streamlined
+			try {
+				string new_path = path;
+
+				if (copy)
+				 	new_path = FileImportBackend.ChooseLocation (path);
+
+				if (new_path != path)
+				 	System.IO.File.Copy (path, new_path);
+
+			 	Photo created = db.Photos.CreateOverDBus (new_path, path, current_roll.Id, out pixbuf);
+
+				try {
+					File.SetAttributes (new_path, File.GetAttributes (new_path) & ~FileAttributes.ReadOnly);
+					DateTime create = File.GetCreationTime (path);
+					File.SetCreationTime (new_path, create);
+					DateTime mod = File.GetLastWriteTime (path);
+					File.SetLastWriteTime (new_path, mod);
+				} catch (IOException) { 
+				 	// we don't want an exception here to be fatal.
+				}
+				
+				// attach tags we got
+				if (tag_list.Count > 0) {
+				 	created.AddTag (tag_list.ToArray ());
+					db.Photos.Commit (created);
+				}
+
+				return (int)created.Id;
+			// indicate failure
+			} catch {
+			 	throw new DBusException ("Failed to import the photo.");
+			}
+		}
+
+		public void RemovePhoto (uint id) 
+		{
+		 	Photo p = db.Photos.Get (id) as Photo;
+
+			if (p == null)
+			 	throw new DBusException ("Photo with id {0} does not exist.", id);
+
+			db.Photos.RemoveOverDBus (p);
+		} 
+ 	}
+}

Added: trunk/extensions/DBusService/DBusService.addin.xml
==============================================================================
--- (empty file)
+++ trunk/extensions/DBusService/DBusService.addin.xml	Thu Jun 26 18:29:51 2008
@@ -0,0 +1,17 @@
+<Addin namespace="FSpot"
+	id="DBusService"
+	version="0.4.4.0"
+	description="Expose F-Spot Photos over DBus"
+	author="Thomas Van Machelen"
+	url="http://f-spot.org/Extensions";
+	defaultEnabled="false"
+	category="Services">
+	<Dependencies>
+		<Addin id="Core" version="0.4.4.2"/>
+	</Dependencies>
+	<Extension path = "/FSpot/Services">
+		<Service class="DBusService.DBusService"/>
+	</Extension>
+</Addin>
+
+

Added: trunk/extensions/DBusService/DBusService.cs
==============================================================================
--- (empty file)
+++ trunk/extensions/DBusService/DBusService.cs	Thu Jun 26 18:29:51 2008
@@ -0,0 +1,41 @@
+/*
+ * DBusService.DBusService.cs
+ *
+ * Author(s):
+ *	Thomas Van Machelen <thomas vanmachelen gmail com>
+ *
+ * This is free software. See COPYING for details.
+ *
+ */
+
+using System;
+using FSpot;
+using FSpot.Extensions;
+using FSpot.Utils;
+
+namespace DBusService {
+	public class DBusService : IService
+	{
+		public bool Start ()
+		{
+			uint timer = Log.InformationTimerStart ("Starting DBusService");
+			try {
+				DBusProxyFactory.Load (Core.Database);
+			} catch {
+				Log.Warning ("unable init DBus service");
+			}
+			Log.DebugTimerPrint (timer, "DBusService startup took {0}");
+			return true;
+		}
+
+		public bool Stop ()
+		{
+			uint timer = Log.InformationTimerStart ("Stopping DBusService");
+
+			DBusProxyFactory.EmitRemoteDown ();
+
+			Log.DebugTimerPrint (timer, "DBusService stop took {0}");	
+			return true;
+		}
+	}
+}

Added: trunk/extensions/DBusService/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/extensions/DBusService/Makefile.am	Thu Jun 26 18:29:51 2008
@@ -0,0 +1,47 @@
+include $(top_srcdir)/Makefile.include
+
+PLUGIN_NAME = DBusService
+
+PLUGIN_MANIFEST = $(PLUGIN_NAME).addin.xml
+
+PLUGIN_ASSEMBLY = $(PLUGIN_NAME).dll
+
+PLUGIN_SOURCES =			\
+	$(srcdir)/DBusService.cs	\
+	$(srcdir)/DBusProxy.cs
+
+
+REFS =					\
+	-pkg:gtk-sharp-2.0		\
+	-r:../../src/f-spot.exe		\
+	-r:../../src/FSpot.Core.dll	\
+	-r:../../src/FSpot.Utils.dll	\
+	$(LINK_DBUS)
+
+PKGS =
+
+RESOURCES =				\
+	-resource:$(srcdir)/$(PLUGIN_MANIFEST)
+
+all: $(PLUGIN_ASSEMBLY)
+
+mpack: $(PLUGIN_ASSEMBLY)
+	mautil p $(PLUGIN_ASSEMBLY)
+
+$(PLUGIN_ASSEMBLY): $(PLUGIN_SOURCES) $(PLUGIN_MANIFEST)
+	$(CSC_LIB) -out:$@ $(CSC_DEFINES) $(PLUGIN_SOURCES) $(REFS) $(PKGS) $(ASSEMBLIES) $(RESOURCES)
+
+plugindir = $(pkglibdir)/extensions
+
+plugin_DATA =			\
+	$(PLUGIN_ASSEMBLY)
+
+EXTRA_DIST = 			\
+	$(PLUGIN_SOURCES)	\
+	$(PLUGIN_MANIFEST)	\
+	$(PLUGIN_NAME).glade
+
+CLEANFILES =			\
+	$(PLUGIN_ASSEMBLY)	\
+	$(PLUGIN_ASSEMBLY).mdb	\
+	*.mpack

Modified: trunk/extensions/Makefile.am
==============================================================================
--- trunk/extensions/Makefile.am	(original)
+++ trunk/extensions/Makefile.am	Thu Jun 26 18:29:51 2008
@@ -1,5 +1,6 @@
 SUBDIRS = 			\
 	BeagleService		\
+	DBusService		\
 	CDExport		\
 	GalleryExport		\
 	FlickrExport		\

Modified: trunk/src/Core.cs
==============================================================================
--- trunk/src/Core.cs	(original)
+++ trunk/src/Core.cs	Thu Jun 26 18:29:51 2008
@@ -269,8 +269,6 @@
 		{
 			toplevels.Remove (sender);
 			if (toplevels.Count == 0) {
-				if (db != null)
-					db.EmitDown ();
 				// FIXME
 				// Should use Application.Quit(), but for that to work we need to terminate the threads
 				// first too.

Modified: trunk/src/Db.cs
==============================================================================
--- trunk/src/Db.cs	(original)
+++ trunk/src/Db.cs	Thu Jun 26 18:29:51 2008
@@ -248,18 +248,12 @@
 		job_store = new JobStore (Database, new_db);
  		photo_store = new PhotoStore (Database, new_db);
 
-		FSpot.DBusProxyFactory.Load (this);
-		
 		Database.CommitTransaction ();
 
 		empty = new_db;
 		Log.DebugTimerPrint (timer, "Db Initialization took {0}");
 	}
 
-	public void EmitDown () {
-		FSpot.DBusProxyFactory.EmitRemoteDown ();
-	}
-
 	public bool Empty {
 		get {
 			return empty;

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Thu Jun 26 18:29:51 2008
@@ -85,7 +85,6 @@
 	$(srcdir)/Core/PhotoVersion.cs		\
 	$(srcdir)/DateCommands.cs		\
 	$(srcdir)/Db.cs				\
-	$(srcdir)/DBusProxy.cs			\
 	$(srcdir)/DependentListStore.cs		\
 	$(srcdir)/DirectoryAdaptor.cs		\
 	$(srcdir)/DirectoryCollection.cs	\

Modified: trunk/src/PhotoStore.cs
==============================================================================
--- trunk/src/PhotoStore.cs	(original)
+++ trunk/src/PhotoStore.cs	Thu Jun 26 18:29:51 2008
@@ -462,14 +462,14 @@
 	public event ItemsAddedHandler ItemsAddedOverDBus;
 	public event ItemsRemovedHandler ItemsRemovedOverDBus;
 
-	internal Photo CreateOverDBus (string new_path, string orig_path, uint roll_id, out Gdk.Pixbuf pixbuf)  {
+	public Photo CreateOverDBus (string new_path, string orig_path, uint roll_id, out Gdk.Pixbuf pixbuf)  {
 		Photo photo = Create (new_path, orig_path, roll_id, out pixbuf);
 		EmitAddedOverDBus (photo);
 
 		return photo;
 	}
 
-	internal void RemoveOverDBus (Photo photo) {
+	public void RemoveOverDBus (Photo photo) {
 	 	Remove (photo);
 		EmitRemovedOverDBus (photo);
 	}

Modified: trunk/src/Preferences.cs
==============================================================================
--- trunk/src/Preferences.cs	(original)
+++ trunk/src/Preferences.cs	Thu Jun 26 18:29:51 2008
@@ -57,8 +57,6 @@
 
 		public const string IMPORT_GUI_ROLL_HISTORY = "/apps/f-spot/import/gui_roll_history";
 
-		public const string DBUS_READ_ONLY = "/apps/f-spot/dbus/read_only";
-
 		public const string SCREENSAVER_TAG = "/apps/f-spot/screensaver/tag_id";
 
 		public const string STORAGE_PATH = "/apps/f-spot/import/storage_path";
@@ -138,8 +136,6 @@
 			case SHOW_DATES:
 			case SHOW_RATINGS:
 			case VIEWER_SHOW_FILENAMES:
-			case DBUS_READ_ONLY:
-				return true;
 			
 			case TAG_ICON_SIZE:
 				return (int) Tag.IconSize.Medium;

Modified: trunk/src/UI.Dialog/PreferenceDialog.cs
==============================================================================
--- trunk/src/UI.Dialog/PreferenceDialog.cs	(original)
+++ trunk/src/UI.Dialog/PreferenceDialog.cs	Thu Jun 26 18:29:51 2008
@@ -76,8 +76,6 @@
 				photosdir_chooser.SetCurrentFolder(Global.PhotoDirectory);
 				photosdir_chooser.Sensitive = false;
 			}
-			LoadPreference (Preferences.DBUS_READ_ONLY);
-
 #if FALSE
 			Gtk.CellRendererText name_cell = new Gtk.CellRendererText ();
 			Gtk.CellRendererText desc_cell = new Gtk.CellRendererText ();
@@ -251,14 +249,6 @@
 			Preferences.Set (Preferences.METADATA_EMBED_IN_IMAGE, metadata_check.Active);
 		}
 
-		void DBusReadOnlyToggled (object sender, System.EventArgs args)
-		{
-			Preferences.Set (Preferences.DBUS_READ_ONLY, !dbus_check.Active); 
-
-			DBusProxyFactory.EmitRemoteDown ();
-			DBusProxyFactory.Load (MainWindow.Toplevel.Database);
-		}
-
 		void HandlePhotosdirChanged (object sender, System.EventArgs args)
 		{
 			Preferences.Set (Preferences.STORAGE_PATH, photosdir_chooser.Filename);
@@ -308,9 +298,6 @@
 			case Preferences.STORAGE_PATH:
 				photosdir_chooser.SetCurrentFolder (Preferences.Get<string> (key));
 				break;
-			case Preferences.DBUS_READ_ONLY:
-				dbus_check.Active = !(Preferences.Get<bool> (key));
-				break;
 			case Preferences.GTK_RC:
 				themenone_radio.Active = (Preferences.Get<string> (key) == String.Empty);
 				themecustom_radio.Active = (Preferences.Get<string> (key) != String.Empty);

Modified: trunk/src/f-spot.glade
==============================================================================
--- trunk/src/f-spot.glade	(original)
+++ trunk/src/f-spot.glade	Thu Jun 26 18:29:51 2008
@@ -6446,74 +6446,6 @@
               </packing>
             </child>
             <child>
-              <widget class="GtkFrame" id="frame27">
-                <property name="visible">True</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">GTK_SHADOW_NONE</property>
-                <child>
-                  <widget class="GtkAlignment" id="alignment28">
-                    <property name="visible">True</property>
-                    <property name="left_padding">12</property>
-                    <child>
-                      <widget class="GtkVBox" id="vbox18">
-                        <property name="visible">True</property>
-                        <child>
-                          <widget class="GtkCheckButton" id="dbus_check">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="label" translatable="yes">Allow other programs to manipulate F-Spot</property>
-                            <property name="use_underline">True</property>
-                            <property name="response_id">0</property>
-                            <property name="draw_indicator">True</property>
-                            <signal name="toggled" handler="DBusReadOnlyToggled"/>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkLabel" id="label8">
-                            <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="xpad">12</property>
-                            <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Enable this option if you want to allow other programs to import or delete photos and tags over DBus.&lt;/i&gt;&lt;/small&gt;</property>
-                            <property name="use_markup">True</property>
-                            <property name="wrap">True</property>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="padding">12</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <placeholder/>
-                        </child>
-                        <child>
-                          <placeholder/>
-                        </child>
-                      </widget>
-                    </child>
-                  </widget>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label9">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">&lt;b&gt;Interoperability&lt;/b&gt;</property>
-                    <property name="use_markup">True</property>
-                  </widget>
-                  <packing>
-                    <property name="type">label_item</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">4</property>
-              </packing>
-            </child>
-            <child>
               <widget class="GtkFrame" id="frame9">
                 <property name="visible">True</property>
                 <property name="shadow_type">GTK_SHADOW_NONE</property>



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