diff --git a/sflphone-gtk/src/configurationmanager-glue.h b/sflphone-gtk/src/configurationmanager-glue.h
index b637a86310fb28b8f8115ebc4a964b0f070442ea..565dec6f1fca13b700af10b28194e72148ad4c86 100644
--- a/sflphone-gtk/src/configurationmanager-glue.h
+++ b/sflphone-gtk/src/configurationmanager-glue.h
@@ -541,6 +541,81 @@ static
 inline
 #endif
 gboolean
+org_sflphone_SFLphone_ConfigurationManager_get_ringtone_choice (DBusGProxy *proxy, char ** OUT_tone, GError **error)
+
+{
+  return dbus_g_proxy_call (proxy, "getRingtoneChoice", error, G_TYPE_INVALID, G_TYPE_STRING, OUT_tone, G_TYPE_INVALID);
+}
+
+typedef void (*org_sflphone_SFLphone_ConfigurationManager_get_ringtone_choice_reply) (DBusGProxy *proxy, char * OUT_tone, GError *error, gpointer userdata);
+
+static void
+org_sflphone_SFLphone_ConfigurationManager_get_ringtone_choice_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
+{
+  DBusGAsyncData *data = (DBusGAsyncData*) user_data;
+  GError *error = NULL;
+  char * OUT_tone;
+  dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRING, &OUT_tone, G_TYPE_INVALID);
+  (*(org_sflphone_SFLphone_ConfigurationManager_get_ringtone_choice_reply)data->cb) (proxy, OUT_tone, error, data->userdata);
+  return;
+}
+
+static
+#ifdef G_HAVE_INLINE
+inline
+#endif
+DBusGProxyCall*
+org_sflphone_SFLphone_ConfigurationManager_get_ringtone_choice_async (DBusGProxy *proxy, org_sflphone_SFLphone_ConfigurationManager_get_ringtone_choice_reply callback, gpointer userdata)
+
+{
+  DBusGAsyncData *stuff;
+  stuff = g_new (DBusGAsyncData, 1);
+  stuff->cb = G_CALLBACK (callback);
+  stuff->userdata = userdata;
+  return dbus_g_proxy_begin_call (proxy, "getRingtoneChoice", org_sflphone_SFLphone_ConfigurationManager_get_ringtone_choice_async_callback, stuff, g_free, G_TYPE_INVALID);
+}
+static
+#ifdef G_HAVE_INLINE
+inline
+#endif
+gboolean
+org_sflphone_SFLphone_ConfigurationManager_set_ringtone_choice (DBusGProxy *proxy, const char * IN_tone, GError **error)
+
+{
+  return dbus_g_proxy_call (proxy, "setRingtoneChoice", error, G_TYPE_STRING, IN_tone, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+typedef void (*org_sflphone_SFLphone_ConfigurationManager_set_ringtone_choice_reply) (DBusGProxy *proxy, GError *error, gpointer userdata);
+
+static void
+org_sflphone_SFLphone_ConfigurationManager_set_ringtone_choice_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
+{
+  DBusGAsyncData *data = (DBusGAsyncData*) user_data;
+  GError *error = NULL;
+  dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID);
+  (*(org_sflphone_SFLphone_ConfigurationManager_set_ringtone_choice_reply)data->cb) (proxy, error, data->userdata);
+  return;
+}
+
+static
+#ifdef G_HAVE_INLINE
+inline
+#endif
+DBusGProxyCall*
+org_sflphone_SFLphone_ConfigurationManager_set_ringtone_choice_async (DBusGProxy *proxy, const char * IN_tone, org_sflphone_SFLphone_ConfigurationManager_set_ringtone_choice_reply callback, gpointer userdata)
+
+{
+  DBusGAsyncData *stuff;
+  stuff = g_new (DBusGAsyncData, 1);
+  stuff->cb = G_CALLBACK (callback);
+  stuff->userdata = userdata;
+  return dbus_g_proxy_begin_call (proxy, "setRingtoneChoice", org_sflphone_SFLphone_ConfigurationManager_set_ringtone_choice_async_callback, stuff, g_free, G_TYPE_STRING, IN_tone, G_TYPE_INVALID);
+}
+static
+#ifdef G_HAVE_INLINE
+inline
+#endif
+gboolean
 org_sflphone_SFLphone_ConfigurationManager_get_codec_list (DBusGProxy *proxy, char *** OUT_list, GError **error)
 
 {
diff --git a/sflphone-gtk/src/configwindow.c b/sflphone-gtk/src/configwindow.c
index f59e61f171880d4c1bfea7ceb8d6160090e4c4ac..e0d052d570c719960673b50f091a8294da60e143 100644
--- a/sflphone-gtk/src/configwindow.c
+++ b/sflphone-gtk/src/configwindow.c
@@ -495,6 +495,21 @@ ringtone_enabled( void )
 {
   dbus_ringtone_enabled();  
 }
+
+void
+ringtone_changed( GtkFileChooser *chooser , GtkLabel *label)
+{
+  gchar* tone = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( chooser ));
+  g_print("tonepath = %s\n" , tone );
+  dbus_set_ringtone_choice( tone );
+}
+
+gchar*
+get_ringtone_choice( void )
+{
+  return dbus_get_ringtone_choice();
+}
+
 /**
  * Call back when the user click on an account in the list
  */
@@ -952,6 +967,7 @@ create_audio_tab ()
 	GtkWidget *codecLabel;
 	GtkWidget *codecBox;
 	GtkWidget *enableTone;
+	GtkWidget *fileChooser;
 	
 	GtkWidget *titleLabel;
 	GtkWidget *comboBox;
@@ -1102,6 +1118,12 @@ create_audio_tab ()
 	gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(enableTone), dbus_is_ringtone_enabled() );
 	gtk_box_pack_start( GTK_BOX(box) , enableTone , TRUE , TRUE , 1);
 	g_signal_connect(G_OBJECT( enableTone) , "clicked" , G_CALLBACK( ringtone_enabled ) , NULL);
+    // file chooser button
+	fileChooser = gtk_file_chooser_button_new("Choose a ringtone", GTK_FILE_CHOOSER_ACTION_OPEN);
+	gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER( fileChooser) , g_get_home_dir());	
+	gtk_file_chooser_set_filename(GTK_FILE_CHOOSER( fileChooser) , get_ringtone_choice());	
+	g_signal_connect( G_OBJECT( fileChooser ) , "selection_changed" , G_CALLBACK( ringtone_changed ) , NULL );
+	gtk_box_pack_start( GTK_BOX(box) , fileChooser , TRUE , TRUE , 1);
 
 	// Show all
 	gtk_widget_show_all(ret);
diff --git a/sflphone-gtk/src/dbus.c b/sflphone-gtk/src/dbus.c
index 6f4389b9811a3577307df909a8f99f7d85a4d501..68c226137728cbb2d70415fdf122bab1ebb26c1d 100644
--- a/sflphone-gtk/src/dbus.c
+++ b/sflphone-gtk/src/dbus.c
@@ -1027,6 +1027,43 @@ dbus_get_current_audio_output_plugin()
 	return plugin;
 }
 
+
+gchar*
+dbus_get_ringtone_choice()
+{
+	gchar* tone;
+	GError* error = NULL;
+	org_sflphone_SFLphone_ConfigurationManager_get_ringtone_choice(
+			configurationManagerProxy,
+			&tone,
+			&error);
+	g_print("After");
+	if(error)
+	{
+		g_error_free(error);
+	}
+	else
+		g_print("DBus called get_ringtone_choice() on ConfigurationManager\n");
+	return tone;
+}
+
+void
+dbus_set_ringtone_choice( const gchar* tone )
+{
+	GError* error = NULL;
+	org_sflphone_SFLphone_ConfigurationManager_set_ringtone_choice(
+			configurationManagerProxy,
+			tone,
+			&error);
+	g_print("After");
+	if(error)
+	{
+		g_error_free(error);
+	}
+	else
+		g_print("DBus called set_ringtone_choice() on ConfigurationManager\n");
+}
+
 int
 dbus_is_ringtone_enabled()
 {
diff --git a/sflphone-gtk/src/dbus.h b/sflphone-gtk/src/dbus.h
index 03a5c2f8cb69dde0c7a074fa14cfff4cb6b70c4d..137f3a256d79f62076c5bc032f1ef5d1890c2e2f 100644
--- a/sflphone-gtk/src/dbus.h
+++ b/sflphone-gtk/src/dbus.h
@@ -75,6 +75,8 @@ int dbus_get_audio_device_index(const gchar* name);
 gchar* dbus_get_current_audio_output_plugin();
 int dbus_is_iax2_enabled( void );
 int dbus_is_ringtone_enabled( void );
+gchar* dbus_get_ringtone_choice( void );
+void dbus_set_ringtone_choice( const gchar* tone );
 
 /* Instance */
 void dbus_register( int pid, gchar * name);
diff --git a/src/dbus/configurationmanager-glue.h b/src/dbus/configurationmanager-glue.h
index 59e12b3505f03f31ad21c60aded86ebf556be9b9..811dac37ad8eecb75e0f11e175404d372834fa8d 100644
--- a/src/dbus/configurationmanager-glue.h
+++ b/src/dbus/configurationmanager-glue.h
@@ -34,6 +34,8 @@ public:
         register_method(ConfigurationManager, getRecordDeviceList, _getRecordDeviceList_stub);
         register_method(ConfigurationManager, isRingtoneEnabled, _isRingtoneEnabled_stub);
         register_method(ConfigurationManager, ringtoneEnabled, _ringtoneEnabled_stub);
+        register_method(ConfigurationManager, getRingtoneChoice, _getRingtoneChoice_stub);
+        register_method(ConfigurationManager, setRingtoneChoice, _setRingtoneChoice_stub);
         register_method(ConfigurationManager, getCodecList, _getCodecList_stub);
         register_method(ConfigurationManager, getCodecDetails, _getCodecDetails_stub);
         register_method(ConfigurationManager, getActiveCodecList, _getActiveCodecList_stub);
@@ -125,6 +127,16 @@ public:
         {
             { 0, 0, 0 }
         };
+        static ::DBus::IntrospectedArgument getRingtoneChoice_args[] = 
+        {
+            { "tone", "s", false },
+            { 0, 0, 0 }
+        };
+        static ::DBus::IntrospectedArgument setRingtoneChoice_args[] = 
+        {
+            { "tone", "s", true },
+            { 0, 0, 0 }
+        };
         static ::DBus::IntrospectedArgument getCodecList_args[] = 
         {
             { "list", "as", false },
@@ -232,6 +244,8 @@ public:
             { "getRecordDeviceList", getRecordDeviceList_args },
             { "isRingtoneEnabled", isRingtoneEnabled_args },
             { "ringtoneEnabled", ringtoneEnabled_args },
+            { "getRingtoneChoice", getRingtoneChoice_args },
+            { "setRingtoneChoice", setRingtoneChoice_args },
             { "getCodecList", getCodecList_args },
             { "getCodecDetails", getCodecDetails_args },
             { "getActiveCodecList", getActiveCodecList_args },
@@ -295,6 +309,8 @@ public:
     virtual std::vector< ::DBus::String > getRecordDeviceList(  ) = 0;
     virtual ::DBus::Int32 isRingtoneEnabled(  ) = 0;
     virtual void ringtoneEnabled(  ) = 0;
+    virtual ::DBus::String getRingtoneChoice(  ) = 0;
+    virtual void setRingtoneChoice( const ::DBus::String& tone ) = 0;
     virtual std::vector< ::DBus::String > getCodecList(  ) = 0;
     virtual std::vector< ::DBus::String > getCodecDetails( const ::DBus::Int32& payload ) = 0;
     virtual std::vector< ::DBus::String > getActiveCodecList(  ) = 0;
@@ -469,6 +485,25 @@ private:
         ::DBus::ReturnMessage reply(call);
         return reply;
     }
+    ::DBus::Message _getRingtoneChoice_stub( const ::DBus::CallMessage& call )
+    {
+        ::DBus::MessageIter ri = call.reader();
+
+        ::DBus::String argout1 = getRingtoneChoice();
+        ::DBus::ReturnMessage reply(call);
+        ::DBus::MessageIter wi = reply.writer();
+        wi << argout1;
+        return reply;
+    }
+    ::DBus::Message _setRingtoneChoice_stub( const ::DBus::CallMessage& call )
+    {
+        ::DBus::MessageIter ri = call.reader();
+
+        ::DBus::String argin1; ri >> argin1;
+        setRingtoneChoice(argin1);
+        ::DBus::ReturnMessage reply(call);
+        return reply;
+    }
     ::DBus::Message _getCodecList_stub( const ::DBus::CallMessage& call )
     {
         ::DBus::MessageIter ri = call.reader();
diff --git a/src/dbus/configurationmanager-introspec.xml b/src/dbus/configurationmanager-introspec.xml
index 581b48d2196c190f1abce93a36ac314d2251e2f3..2ea00b91c3bd673135c732a400b1e97414d5aa49 100644
--- a/src/dbus/configurationmanager-introspec.xml
+++ b/src/dbus/configurationmanager-introspec.xml
@@ -63,6 +63,15 @@
 
     <method name="ringtoneEnabled">
     </method>
+
+    <method name="getRingtoneChoice">
+      <arg type="s" name="tone" direction="out"/>
+    </method>
+
+    <method name="setRingtoneChoice">
+      <arg type="s" name="tone" direction="in"/>
+    </method>
+
    <!--      ///////////////////////               -->
    
    <!-- Codecs-related methods -->
diff --git a/src/dbus/configurationmanager.cpp b/src/dbus/configurationmanager.cpp
index e97ec0e41a09cea845a9d7f00ddc31bcaf40fa3f..b974f9b84d6280924c03fdb9308d8d1e2c335024 100644
--- a/src/dbus/configurationmanager.cpp
+++ b/src/dbus/configurationmanager.cpp
@@ -248,3 +248,16 @@ ConfigurationManager::isRingtoneEnabled( void )
 {
   return Manager::instance().isRingtoneEnabled(  ); 
 }
+
+::DBus::String
+ConfigurationManager::getRingtoneChoice( void )
+{
+  return Manager::instance().getRingtoneChoice(  ); 
+}
+
+void
+ConfigurationManager::setRingtoneChoice( const ::DBus::String& tone )
+{
+  Manager::instance().setRingtoneChoice( tone ); 
+}
+
diff --git a/src/dbus/configurationmanager.h b/src/dbus/configurationmanager.h
index 5089e6e0a50d688350d733a874175263f23ce170..5cba2dcfbc049aa540e609b682b66589c76665a4 100644
--- a/src/dbus/configurationmanager.h
+++ b/src/dbus/configurationmanager.h
@@ -74,6 +74,8 @@ public:
     ::DBus::Int32 isIax2Enabled( void );
     ::DBus::Int32 isRingtoneEnabled( void );
     void ringtoneEnabled( void );
+    ::DBus::String getRingtoneChoice( void );
+    void setRingtoneChoice( const ::DBus::String& tone );
 };
 
 
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index 405cd2197c3f9b7da206553e4c4438fb6726a49c..022b19e2dd851f6451507706b27cc4fd4fde60ff 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -1375,6 +1375,33 @@ ManagerImpl::ringtoneEnabled( void )
   ( getConfigInt( PREFERENCES , CONFIG_RINGTONE ) == RINGTONE_ENABLED )? setConfig(PREFERENCES , CONFIG_RINGTONE , NO_STR ) : setConfig( PREFERENCES , CONFIG_RINGTONE , YES_STR );
 }
 
+std::string
+ManagerImpl::getRingtoneChoice( void )
+{
+  // we need the absolute path
+  std::string tone_name = getConfigString( AUDIO , RING_CHOICE );
+  std::string tone_path ;
+  if( tone_name.find( DIR_SEPARATOR_CH ) == std::string::npos )
+  {
+    // check in ringtone directory ($(PREFIX)/share/sflphone/ringtones)
+    tone_path = std::string(PROGSHAREDIR) + DIR_SEPARATOR_STR + RINGDIR + DIR_SEPARATOR_STR + tone_name ; 
+  }
+  else
+  {
+    // the absolute has been saved; do nothing
+    tone_path = tone_name ;
+  }   
+  _debug("%s\n", tone_path.c_str());
+  return tone_path;
+}
+
+void
+ManagerImpl::setRingtoneChoice( const std::string& tone )
+{
+  // we save the absolute path 
+  setConfig( AUDIO , RING_CHOICE , tone ); 
+}
+
   int
 ManagerImpl::getAudioDeviceIndex(const std::string name)
 {
diff --git a/src/managerimpl.h b/src/managerimpl.h
index 7a983bbe032f3a2e956872b8b9e9c34ab3c5d0f4..d10e28e407917034be9b48d140ccb7372f51a1da 100644
--- a/src/managerimpl.h
+++ b/src/managerimpl.h
@@ -344,6 +344,8 @@ public:
   int isIax2Enabled( void ); 
   int isRingtoneEnabled( void ); 
   void ringtoneEnabled( void ); 
+  std::string getRingtoneChoice( void );
+  void setRingtoneChoice( const std::string& );
   /**
    * Inverse of serialize
    */