diff --git a/Tomboy/Addins/FileSystemSyncService/FileSystemSyncServiceAddin.cs b/Tomboy/Addins/FileSystemSyncService/FileSystemSyncServiceAddin.cs
index b29a441..c0e0402 100644
--- a/Tomboy/Addins/FileSystemSyncService/FileSystemSyncServiceAddin.cs
+++ b/Tomboy/Addins/FileSystemSyncService/FileSystemSyncServiceAddin.cs
@@ -79,7 +79,7 @@ namespace Tomboy.Sync
 		/// not automatically be saved by a GConf Property Editor.  Preferences
 		/// should be saved when SaveConfiguration () is called.
 		/// </summary>
-		public override Gtk.Widget CreatePreferencesControl ()
+		public override Gtk.Widget CreatePreferencesControl (EventHandler requiredPrefChanged)
 		{
 			Gtk.Table table = new Gtk.Table (1, 2, false);
 			table.RowSpacing = 5;
@@ -99,6 +99,7 @@ namespace Tomboy.Sync
 
 			pathButton = new FileChooserButton (Catalog.GetString ("Select Synchronization Folder..."),
 			                                    FileChooserAction.SelectFolder);
+			pathButton.CurrentFolderChanged += requiredPrefChanged;
 			l.MnemonicWidget = pathButton;
 			pathButton.SetFilename (syncPath);
 
diff --git a/Tomboy/Addins/SshSyncService/SshSyncServiceAddin.cs b/Tomboy/Addins/SshSyncService/SshSyncServiceAddin.cs
index 4cde08b..61f4e9d 100644
--- a/Tomboy/Addins/SshSyncService/SshSyncServiceAddin.cs
+++ b/Tomboy/Addins/SshSyncService/SshSyncServiceAddin.cs
@@ -23,7 +23,7 @@ namespace Tomboy.Sync
 		/// not automatically be saved by a GConf Property Editor.  Preferences
 		/// should be saved when SaveConfiguration () is called.
 		/// </summary>
-		public override Gtk.Widget CreatePreferencesControl ()
+		public override Gtk.Widget CreatePreferencesControl (EventHandler requiredPrefChanged)
 		{
 			Gtk.Table table = new Gtk.Table (3, 2, false);
 			table.RowSpacing = 5;
@@ -44,6 +44,7 @@ namespace Tomboy.Sync
 
 			serverEntry = new Entry ();
 			serverEntry.Text = server;
+			serverEntry.Changed += requiredPrefChanged;
 			AddRow (table, serverEntry, Catalog.GetString ("Se_rver:"), 0);
 
 			usernameEntry = new Entry ();
@@ -119,6 +120,18 @@ namespace Tomboy.Sync
 				return GetConfigSettings (out server, out folder, out username, out port);
 			}
 		}
+		
+		/// <summary>
+		/// Returns true if required widget settings are non-empty
+		/// </summary>
+		public override bool IsSettingsValid
+		{
+			get {
+				string server, folder, username;
+				int port;
+				return GetPrefWidgetSettings (out server, out folder, out username, out port);
+			}
+		}
 
 		/// <summary>
 		/// The name that will be shown in the preferences to distinguish
@@ -187,6 +200,7 @@ namespace Tomboy.Sync
 		/// <summary>
 		/// Get config settings
 		/// </summary>
+		/// <returns>true if saved settings are valid</returns>
 		private bool GetConfigSettings (out string server, out string folder, out string username, out int port)
 		{
 			server = Preferences.Get ("/apps/tomboy/sync_sshfs_server") as String;
@@ -200,7 +214,6 @@ namespace Tomboy.Sync
 			return !string.IsNullOrEmpty (server) && !string.IsNullOrEmpty (username);
 		}
 
-
 		/// <summary>
 		/// Get config settings
 		/// </summary>
diff --git a/Tomboy/Addins/WebDavSyncService/WebDavSyncServiceAddin.cs b/Tomboy/Addins/WebDavSyncService/WebDavSyncServiceAddin.cs
index 307354c..b03ad57 100644
--- a/Tomboy/Addins/WebDavSyncService/WebDavSyncServiceAddin.cs
+++ b/Tomboy/Addins/WebDavSyncService/WebDavSyncServiceAddin.cs
@@ -33,7 +33,7 @@ namespace Tomboy.Sync
 		/// not automatically be saved by a GConf Property Editor.  Preferences
 		/// should be saved when SaveConfiguration () is called.
 		/// </summary>
-		public override Gtk.Widget CreatePreferencesControl ()
+		public override Gtk.Widget CreatePreferencesControl (EventHandler requiredPrefChanged)
 		{
 			Gtk.Table table = new Gtk.Table (3, 2, false);
 			table.RowSpacing = 5;
@@ -52,15 +52,18 @@ namespace Tomboy.Sync
 
 			urlEntry = new Entry ();
 			urlEntry.Text = url;
+			urlEntry.Changed += requiredPrefChanged;
 			AddRow (table, urlEntry, Catalog.GetString ("_URL:"), 0);
 
 			usernameEntry = new Entry ();
 			usernameEntry.Text = username;
+			usernameEntry.Changed += requiredPrefChanged;
 			AddRow (table, usernameEntry, Catalog.GetString ("User_name:"), 1);
 
 			passwordEntry = new Entry ();
 			passwordEntry.Text = password;
 			passwordEntry.Visibility = false;
+			passwordEntry.Changed += requiredPrefChanged;
 			AddRow (table, passwordEntry, Catalog.GetString ("_Password:"), 2);
 
 			table.ShowAll ();
@@ -108,6 +111,17 @@ namespace Tomboy.Sync
 				return GetConfigSettings (out url, out username, out password);
 			}
 		}
+		
+		/// <summary>
+		/// Returns true if required settings are non-empty in the preferences widget
+		/// </summary>
+		public override bool IsSettingsValid
+		{
+			get {
+				string url, username, password;
+				return GetPrefWidgetSettings (out url, out username, out password);
+			}
+		}
 
 		/// <summary>
 		/// The name that will be shown in the preferences to distinguish
diff --git a/Tomboy/Addins/WebSyncService/WebSyncPreferencesWidget.cs b/Tomboy/Addins/WebSyncService/WebSyncPreferencesWidget.cs
index 01536ae..5aecddf 100644
--- a/Tomboy/Addins/WebSyncService/WebSyncPreferencesWidget.cs
+++ b/Tomboy/Addins/WebSyncService/WebSyncPreferencesWidget.cs
@@ -46,7 +46,7 @@ namespace Tomboy.WebSync
 		private const string callbackHtmlTemplate =
 			@"<html><head><title>{0}</title></head><body><div><h1>{0}</h1>{1}</div></body></html>";
 		
-		public WebSyncPreferencesWidget (Api.OAuth oauth, string server) : base (false, 5)
+		public WebSyncPreferencesWidget (Api.OAuth oauth, string server, EventHandler requiredPrefChanged) : base (false, 5)
 		{
 			this.oauth = oauth;
 			
@@ -73,6 +73,7 @@ namespace Tomboy.WebSync
 			serverEntry.Changed += delegate {
 				Auth = null;
 			};
+			serverEntry.Changed += requiredPrefChanged;
 
 			Add (authButton);
 
diff --git a/Tomboy/Addins/WebSyncService/WebSyncServiceAddin.cs b/Tomboy/Addins/WebSyncService/WebSyncServiceAddin.cs
index 366c2dd..f04f6ae 100644
--- a/Tomboy/Addins/WebSyncService/WebSyncServiceAddin.cs
+++ b/Tomboy/Addins/WebSyncService/WebSyncServiceAddin.cs
@@ -75,10 +75,14 @@ namespace Tomboy.WebSync
 			get {
 				string serverPref;
 				Api.OAuth oauth;
-				GetConfigSettings (out oauth, out serverPref);
-				return !string.IsNullOrEmpty (serverPref) &&
-					oauth != null &&
-					oauth.IsAccessToken;
+				return GetConfigSettings (out oauth, out serverPref);
+			}
+		}
+		
+		public override bool IsSettingsValid
+		{
+			get {
+				return prefsWidget != null && !String.IsNullOrEmpty(prefsWidget.Server);
 			}
 		}
 
@@ -88,12 +92,12 @@ namespace Tomboy.WebSync
 			}
 		}
 
-		public override Gtk.Widget CreatePreferencesControl ()
+		public override Gtk.Widget CreatePreferencesControl (EventHandler requiredPrefChanged)
 		{
 			string serverPref;
 			Api.OAuth oauth;
 			GetConfigSettings (out oauth, out serverPref);
-			prefsWidget = new WebSyncPreferencesWidget (oauth, serverPref);
+			prefsWidget = new WebSyncPreferencesWidget (oauth, serverPref, requiredPrefChanged);
 			return prefsWidget;
 		}
 
@@ -148,7 +152,7 @@ namespace Tomboy.WebSync
 
 		#region Private Members
 
-		private void GetConfigSettings (out Api.OAuth oauthConfig, out string serverPref)
+		private bool GetConfigSettings (out Api.OAuth oauthConfig, out string serverPref)
 		{
 			serverPref = (string)
 				Preferences.Get (serverUrlPrefPath);
@@ -177,6 +181,9 @@ namespace Tomboy.WebSync
 			//       case of weird circumstances?
 			oauthConfig.IsAccessToken =
 				!String.IsNullOrEmpty (oauthConfig.Token);
+			
+			return !string.IsNullOrEmpty (serverPref)
+				&& oauthConfig.IsAccessToken;
 		}
 
 		private void SaveConfigSettings (Api.OAuth oauthConfig, string serverPref)
diff --git a/Tomboy/PreferencesDialog.cs b/Tomboy/PreferencesDialog.cs
index 403e013..31bec24 100644
--- a/Tomboy/PreferencesDialog.cs
+++ b/Tomboy/PreferencesDialog.cs
@@ -481,7 +481,7 @@ namespace Tomboy
 				selectedSyncAddin = syncAddinStore.GetValue (active_iter, 0) as SyncServiceAddin;
 
 			if (selectedSyncAddin != null)
-				syncAddinPrefsWidget = selectedSyncAddin.CreatePreferencesControl ();
+				syncAddinPrefsWidget = selectedSyncAddin.CreatePreferencesControl (OnSyncAddinPrefsChanged);
 			if (syncAddinPrefsWidget == null) {
 				Gtk.Label l = new Gtk.Label (Catalog.GetString ("Not configurable"));
 				l.Yalign = 0.5f;
@@ -1108,7 +1108,7 @@ namespace Tomboy
 				        syncAddinStore.GetValue (iter, 0) as SyncServiceAddin;
 				if (newAddin != null) {
 					selectedSyncAddin = newAddin;
-					syncAddinPrefsWidget = selectedSyncAddin.CreatePreferencesControl ();
+					syncAddinPrefsWidget = selectedSyncAddin.CreatePreferencesControl (OnSyncAddinPrefsChanged);
 					if (syncAddinPrefsWidget == null) {
 						Gtk.Label l = new Gtk.Label (Catalog.GetString ("Not configurable"));
 						l.Yalign = 0.5f;
@@ -1120,7 +1120,7 @@ namespace Tomboy
 					syncAddinPrefsContainer.PackStart (syncAddinPrefsWidget, false, false, 0);
 
 					resetSyncAddinButton.Sensitive = false;
-					saveSyncAddinButton.Sensitive = true;
+					saveSyncAddinButton.Sensitive = false;
 				}
 			} else {
 				selectedSyncAddin = null;
@@ -1285,6 +1285,13 @@ namespace Tomboy
 				dialog.Destroy ();
 			}
 		}
+		
+		void OnSyncAddinPrefsChanged (object sender, EventArgs args)
+		{
+			// Enable/disable the save button based on required fields
+			if (selectedSyncAddin != null)
+				saveSyncAddinButton.Sensitive = selectedSyncAddin.IsSettingsValid;
+		}
 
 		void OpenTemplateButtonClicked (object sender, EventArgs args)
 		{
diff --git a/Tomboy/Synchronization/SyncServiceAddin.cs b/Tomboy/Synchronization/SyncServiceAddin.cs
index 3377877..dc927c3 100644
--- a/Tomboy/Synchronization/SyncServiceAddin.cs
+++ b/Tomboy/Synchronization/SyncServiceAddin.cs
@@ -23,9 +23,11 @@ namespace Tomboy.Sync
 		/// Creates a Gtk.Widget that's used to configure the service.  This
 		/// will be used in the Synchronization Preferences.  Preferences should
 		/// not automatically be saved by a GConf Property Editor.  Preferences
-		/// should be saved when SaveConfiguration () is called.
+		/// should be saved when SaveConfiguration () is called. requiredPrefChanged
+		/// should be called when a required setting is changed.
 		/// </summary>
-		public abstract Gtk.Widget CreatePreferencesControl ();
+		/// <param name="requiredPrefChanged">Delegate to be called when a required preference is changed</param>
+		public abstract Gtk.Widget CreatePreferencesControl (EventHandler requiredPrefChanged);
 
 		/// <summary>
 		/// The Addin should verify and check the connection to the service
@@ -46,6 +48,15 @@ namespace Tomboy.Sync
 		{
 			get;
 		}
+		
+		/// <summary>
+		/// Returns true if required settings are valid in the widget
+		/// (Required setings are non-empty)
+		/// </summary>
+		public virtual bool IsSettingsValid
+		{
+			get { return true; }
+		}
 
 		/// <summary>
 		/// The name that will be shown in the preferences to distinguish
