[gthumb] allow to choose another account if authentication fails



commit c3fee28e425f81c8b7e0f94dd3906ce6360900d3
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sat Apr 10 01:19:39 2010 +0200

    allow to choose another account if authentication fails

 .../facebook/data/ui/facebook-account-chooser.ui   |   13 +--
 .../facebook/facebook-account-chooser-dialog.c     |   90 +++++++++++++-
 .../facebook/facebook-account-manager-dialog.c     |    5 +-
 extensions/facebook/facebook-authentication.c      |  130 +++++++++++++-------
 extensions/facebook/facebook-connection.c          |   22 ++--
 .../flicker/data/ui/flicker-account-chooser.ui     |   13 +--
 extensions/flicker/flickr-account-chooser-dialog.c |   88 +++++++++++++-
 extensions/flicker/flickr-authentication.c         |  128 +++++++++++++------
 8 files changed, 370 insertions(+), 119 deletions(-)
---
diff --git a/extensions/facebook/data/ui/facebook-account-chooser.ui b/extensions/facebook/data/ui/facebook-account-chooser.ui
index 54abe69..924669d 100644
--- a/extensions/facebook/data/ui/facebook-account-chooser.ui
+++ b/extensions/facebook/data/ui/facebook-account-chooser.ui
@@ -1,11 +1,10 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-naming-policy project-wide -->
   <object class="GtkVBox" id="account_chooser">
     <property name="visible">True</property>
     <property name="border_width">5</property>
-    <property name="orientation">vertical</property>
     <property name="spacing">6</property>
     <child>
       <object class="GtkHBox" id="hbox3">
@@ -28,12 +27,6 @@
             <property name="width_request">300</property>
             <property name="visible">True</property>
             <property name="model">account_liststore</property>
-            <child>
-              <object class="GtkCellRendererText" id="cellrenderertext1"/>
-              <attributes>
-                <attribute name="text">1</attribute>
-              </attributes>
-            </child>
           </object>
           <packing>
             <property name="position">1</property>
@@ -51,6 +44,10 @@
       <column type="GObject"/>
       <!-- column-name name -->
       <column type="gchararray"/>
+      <!-- column-name separator -->
+      <column type="gboolean"/>
+      <!-- column-name icon_name -->
+      <column type="gchararray"/>
     </columns>
   </object>
 </interface>
diff --git a/extensions/facebook/facebook-account-chooser-dialog.c b/extensions/facebook/facebook-account-chooser-dialog.c
index 9597a7c..3fb8bff 100644
--- a/extensions/facebook/facebook-account-chooser-dialog.c
+++ b/extensions/facebook/facebook-account-chooser-dialog.c
@@ -29,7 +29,9 @@
 
 enum {
 	ACCOUNT_DATA_COLUMN,
-	ACCOUNT_NAME_COLUMN
+	ACCOUNT_NAME_COLUMN,
+	ACCOUNT_SEPARATOR_COLUMN,
+	ACCOUNT_ICON_COLUMN
 };
 
 
@@ -68,12 +70,51 @@ facebook_account_chooser_dialog_class_init (FacebookAccountChooserDialogClass *k
 
 
 static void
+account_combobox_changed_cb (GtkComboBox *combobox,
+			     gpointer     user_data)
+{
+	FacebookAccountChooserDialog *self = user_data;
+	GtkTreeIter                   iter;
+	FacebookAccount              *account;
+
+	if (! gtk_combo_box_get_active_iter (combobox, &iter))
+		return;
+
+	gtk_tree_model_get (GTK_TREE_MODEL (GET_WIDGET ("account_liststore")), &iter,
+			    ACCOUNT_DATA_COLUMN, &account,
+			    -1);
+
+	if (account == NULL)
+		gtk_dialog_response (GTK_DIALOG (self), FACEBOOK_ACCOUNT_CHOOSER_RESPONSE_NEW);
+
+	_g_object_unref (account);
+}
+
+
+static gboolean
+row_separator_func (GtkTreeModel *model,
+		    GtkTreeIter  *iter,
+		    gpointer      user_data)
+{
+	FacebookAccountChooserDialog *self = user_data;
+	gboolean                      is_separator;
+
+	gtk_tree_model_get (GTK_TREE_MODEL (GET_WIDGET ("account_liststore")),
+			    iter,
+			    ACCOUNT_SEPARATOR_COLUMN, &is_separator,
+			    -1);
+
+	return is_separator;
+}
+
+
+static void
 facebook_account_chooser_dialog_init (FacebookAccountChooserDialog *self)
 {
 	GtkWidget *content;
 
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, FACEBOOK_TYPE_ACCOUNT_CHOOSER_DIALOG, FacebookAccountChooserDialogPrivate);
-	self->priv->builder = _gtk_builder_new_from_file ("flicker-account-chooser.ui", "flicker");
+	self->priv->builder = _gtk_builder_new_from_file ("facebook-account-chooser.ui", "facebook");
 
 	gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
 	gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE);
@@ -84,9 +125,33 @@ facebook_account_chooser_dialog_init (FacebookAccountChooserDialog *self)
 	gtk_container_set_border_width (GTK_CONTAINER (content), 5);
 	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), content, TRUE, TRUE, 0);
 
-	gtk_dialog_add_button (GTK_DIALOG (self),
-			       GTK_STOCK_NEW,
-			       FACEBOOK_ACCOUNT_CHOOSER_RESPONSE_NEW);
+	{
+		GtkCellLayout   *cell_layout;
+		GtkCellRenderer *renderer;
+
+		cell_layout = GTK_CELL_LAYOUT (GET_WIDGET ("account_combobox"));
+
+		renderer = gtk_cell_renderer_pixbuf_new ();
+		gtk_cell_layout_pack_start (cell_layout, renderer, FALSE);
+		gtk_cell_layout_set_attributes (cell_layout, renderer,
+						"icon-name", ACCOUNT_ICON_COLUMN,
+						NULL);
+
+		renderer = gtk_cell_renderer_text_new ();
+		gtk_cell_layout_pack_start (cell_layout, renderer, TRUE);
+		gtk_cell_layout_set_attributes (cell_layout, renderer,
+						"text", ACCOUNT_NAME_COLUMN,
+						NULL);
+	}
+	gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (GET_WIDGET ("account_combobox")),
+					      row_separator_func,
+					      self,
+					      NULL);
+	g_signal_connect (GET_WIDGET ("account_combobox"),
+			  "changed",
+			  G_CALLBACK (account_combobox_changed_cb),
+			  self);
+
 	gtk_dialog_add_button (GTK_DIALOG (self),
 			       GTK_STOCK_CANCEL,
 			       GTK_RESPONSE_CANCEL);
@@ -147,9 +212,24 @@ facebook_account_chooser_dialog_construct (FacebookAccountChooserDialog *self,
 		gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter,
 				    ACCOUNT_DATA_COLUMN, account,
 				    ACCOUNT_NAME_COLUMN, account->username,
+				    ACCOUNT_SEPARATOR_COLUMN, FALSE,
+				    ACCOUNT_ICON_COLUMN, "dialog-password",
 				    -1);
 	}
 
+	gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter);
+	gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter,
+			    ACCOUNT_SEPARATOR_COLUMN, TRUE,
+			    -1);
+
+	gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter);
+	gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter,
+			    ACCOUNT_DATA_COLUMN, NULL,
+			    ACCOUNT_NAME_COLUMN, _("New authentication..."),
+			    ACCOUNT_SEPARATOR_COLUMN, FALSE,
+			    ACCOUNT_ICON_COLUMN, GTK_STOCK_NEW,
+			    -1);
+
 	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("account_combobox")), active);
 }
 
diff --git a/extensions/facebook/facebook-account-manager-dialog.c b/extensions/facebook/facebook-account-manager-dialog.c
index 3afd680..8b502d2 100644
--- a/extensions/facebook/facebook-account-manager-dialog.c
+++ b/extensions/facebook/facebook-account-manager-dialog.c
@@ -128,7 +128,7 @@ facebook_account_manager_dialog_init (FacebookAccountManagerDialog *self)
 	GtkWidget *content;
 
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, FACEBOOK_TYPE_ACCOUNT_MANAGER_DIALOG, FacebookAccountManagerDialogPrivate);
-	self->priv->builder = _gtk_builder_new_from_file ("flicker-account-manager.ui", "flicker");
+	self->priv->builder = _gtk_builder_new_from_file ("facebook-account-manager.ui", "facebook");
 
 	gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
 	gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE);
@@ -140,6 +140,9 @@ facebook_account_manager_dialog_init (FacebookAccountManagerDialog *self)
 	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), content, TRUE, TRUE, 0);
 
 	gtk_dialog_add_button (GTK_DIALOG (self),
+			       GTK_STOCK_NEW,
+			       FACEBOOK_ACCOUNT_MANAGER_RESPONSE_NEW);
+	gtk_dialog_add_button (GTK_DIALOG (self),
 			       GTK_STOCK_CANCEL,
 			       GTK_RESPONSE_CANCEL);
 	gtk_dialog_add_button (GTK_DIALOG (self),
diff --git a/extensions/facebook/facebook-authentication.c b/extensions/facebook/facebook-authentication.c
index d8a11a3..7aab518 100644
--- a/extensions/facebook/facebook-authentication.c
+++ b/extensions/facebook/facebook-authentication.c
@@ -33,6 +33,7 @@
 
 
 #define SECRET_SEPARATOR ("::")
+#define FACEBOOK_AUTHENTICATION_RESPONSE_CHOOSE_ACCOUNT 2
 
 
 /* Signals */
@@ -178,6 +179,61 @@ facebook_authentication_new (FacebookConnection *conn,
 }
 
 
+static void show_choose_account_dialog (FacebookAuthentication *self);
+
+
+static void
+authentication_error_dialog_response_cb (GtkDialog *dialog,
+					 int        response_id,
+					 gpointer   user_data)
+{
+	FacebookAuthentication *self = user_data;
+
+	switch (response_id) {
+	case GTK_RESPONSE_DELETE_EVENT:
+	case GTK_RESPONSE_CANCEL:
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		gtk_widget_destroy (self->priv->dialog);
+		break;
+
+	case FACEBOOK_AUTHENTICATION_RESPONSE_CHOOSE_ACCOUNT:
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		show_choose_account_dialog (self);
+		break;
+
+	default:
+		break;
+	}
+}
+
+
+static void
+show_authentication_error_dialog (FacebookAuthentication  *self,
+				  GError                 **error)
+{
+	GtkWidget *dialog;
+
+	if (self->priv->conn != NULL)
+		gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
+
+	dialog = _gtk_message_dialog_new (GTK_WINDOW (self->priv->browser),
+			             GTK_DIALOG_MODAL,
+				     GTK_STOCK_DIALOG_ERROR,
+				     _("Could not connect to the server"),
+				     (*error)->message,
+				     _("Choose _Account..."), FACEBOOK_AUTHENTICATION_RESPONSE_CHOOSE_ACCOUNT,
+				     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+				     NULL);
+	g_signal_connect (dialog,
+			  "response",
+			  G_CALLBACK (authentication_error_dialog_response_cb),
+			  self);
+	gtk_widget_show (dialog);
+
+	g_clear_error (error);
+}
+
+
 /* -- facebook_authentication_auto_connect -- */
 
 
@@ -192,10 +248,7 @@ get_user_info_ready_cb (GObject      *source_object,
 
 	user = facebook_service_get_user_info_finish (FACEBOOK_SERVICE (source_object), res, &error);
 	if (error != NULL) {
-		if (self->priv->conn != NULL)
-			gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
-		_gtk_error_dialog_from_gerror_run (GTK_WINDOW (self->priv->browser), _("Could not connect to the server"), &error);
-		gtk_widget_destroy (self->priv->dialog);
+		show_authentication_error_dialog (self, &error);
 		return;
 	}
 
@@ -222,10 +275,7 @@ get_logged_in_user_ready_cb (GObject      *source_object,
 
 	uid = facebook_service_get_logged_in_user_finish (FACEBOOK_SERVICE (source_object), res, &error);
 	if (error != NULL) {
-		if (self->priv->conn != NULL)
-			gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
-		_gtk_error_dialog_from_gerror_run (GTK_WINDOW (self->priv->browser), _("Could not connect to the server"), &error);
-		gtk_widget_destroy (self->priv->dialog);
+		show_authentication_error_dialog (self, &error);
 		return;
 	}
 
@@ -363,10 +413,7 @@ get_session_ready_cb (GObject      *source_object,
 	FacebookAccount        *account;
 
 	if (! facebook_connection_get_session_finish (FACEBOOK_CONNECTION (source_object), res, &error)) {
-		if (self->priv->conn != NULL)
-			gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
-		_gtk_error_dialog_from_gerror_run (GTK_WINDOW (self->priv->browser), _("Could not connect to the server"), &error);
-		gtk_widget_destroy (self->priv->dialog);
+		show_authentication_error_dialog (self, &error);
 		return;
 	}
 
@@ -500,12 +547,8 @@ ask_authorization_messagedialog_response_cb (GtkDialog *dialog,
 			if (gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (dialog)), url, 0, &error)) {
 				complete_authorization (self);
 			}
-			else {
-				if (self->priv->conn != NULL)
-					gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
-				_gtk_error_dialog_from_gerror_run (GTK_WINDOW (self->priv->browser), _("Could not connect to the server"), &error);
-				gtk_widget_destroy (self->priv->dialog);
-			}
+			else
+				show_authentication_error_dialog (self, &error);
 
 			g_free (url);
 		}
@@ -556,17 +599,12 @@ create_token_ready_cb (GObject      *source_object,
 		       gpointer      user_data)
 {
 	FacebookAuthentication *self = user_data;
-	GError               *error = NULL;
-
-	if (! facebook_connection_create_token_finish (FACEBOOK_CONNECTION (source_object), res, &error)) {
-		if (self->priv->conn != NULL)
-			gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
-		_gtk_error_dialog_from_gerror_run (GTK_WINDOW (self->priv->browser), _("Could not connect to the server"), &error);
-		gtk_widget_destroy (self->priv->dialog);
-		return;
-	}
+	GError                 *error = NULL;
 
-	ask_authorization (self);
+	if (! facebook_connection_create_token_finish (FACEBOOK_CONNECTION (source_object), res, &error))
+		show_authentication_error_dialog (self, &error);
+	else
+		ask_authorization (self);
 }
 
 
@@ -615,6 +653,25 @@ account_chooser_dialog_response_cb (GtkDialog *dialog,
 }
 
 
+static void
+show_choose_account_dialog (FacebookAuthentication *self)
+{
+	GtkWidget *dialog;
+
+	gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
+	dialog = facebook_account_chooser_dialog_new (self->priv->accounts, self->priv->account);
+	g_signal_connect (dialog,
+			  "response",
+			  G_CALLBACK (account_chooser_dialog_response_cb),
+			  self);
+
+	gtk_window_set_title (GTK_WINDOW (dialog), _("Choose Account"));
+	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (self->priv->browser));
+	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+	gtk_window_present (GTK_WINDOW (dialog));
+}
+
+
 void
 facebook_authentication_auto_connect (FacebookAuthentication *self)
 {
@@ -629,21 +686,8 @@ facebook_authentication_auto_connect (FacebookAuthentication *self)
 			self->priv->account = g_object_ref (self->priv->accounts->data);
 			connect_to_server (self);
 		}
-		else {
-			GtkWidget *dialog;
-
-			gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
-			dialog = facebook_account_chooser_dialog_new (self->priv->accounts, self->priv->account);
-			g_signal_connect (dialog,
-					  "response",
-					  G_CALLBACK (account_chooser_dialog_response_cb),
-					  self);
-
-			gtk_window_set_title (GTK_WINDOW (dialog), _("Choose Account"));
-			gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (self->priv->browser));
-			gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-			gtk_window_present (GTK_WINDOW (dialog));
-		}
+		else
+			show_choose_account_dialog (self);
 	}
 	else
 		start_authorization_process (self);
diff --git a/extensions/facebook/facebook-connection.c b/extensions/facebook/facebook-connection.c
index 1f57ec9..80439fe 100644
--- a/extensions/facebook/facebook-connection.c
+++ b/extensions/facebook/facebook-connection.c
@@ -28,7 +28,7 @@
 #include "facebook-user.h"
 
 
-#define DEBUG_FACEBOOK_CONNECTION 1
+#undef  DEBUG_FACEBOOK_CONNECTION
 #define GTHUMB_FACEBOOK_API_KEY "1536ca726857c69843423d0312b9b356"
 #define GTHUMB_FACEBOOK_SHARED_SECRET "8c0b99672a9bbc159ebec3c9a8240679"
 #define FACEBOOK_API_VERSION "1.0"
@@ -283,15 +283,6 @@ create_token_ready_cb (SoupSession *session,
 	DomDocument        *doc = NULL;
 	GError             *error = NULL;
 
-	g_free (self->priv->token);
-	g_free (self->priv->session_key);
-	g_free (self->priv->secret);
-	g_free (self->priv->user_id);
-	self->priv->token = NULL;
-	self->priv->session_key = NULL;
-	self->priv->secret = NULL;
-	self->priv->user_id = NULL;
-
 	body = soup_message_body_flatten (msg->response_body);
 	if (facebook_utils_parse_response (body, &doc, &error)) {
 		DomElement *root;
@@ -327,6 +318,15 @@ facebook_connection_create_token (FacebookConnection  *self,
 	GHashTable  *data_set;
 	SoupMessage *msg;
 
+	g_free (self->priv->token);
+	g_free (self->priv->session_key);
+	g_free (self->priv->secret);
+	g_free (self->priv->user_id);
+	self->priv->token = NULL;
+	self->priv->session_key = NULL;
+	self->priv->secret = NULL;
+	self->priv->user_id = NULL;
+
 	gth_task_progress (GTH_TASK (self), _("Connecting to the server"), NULL, TRUE, 0.0);
 
 	data_set = g_hash_table_new (g_str_hash, g_str_equal);
@@ -392,6 +392,8 @@ facebook_connection_get_login_link (FacebookConnection *self,
 	g_hash_table_insert (data_set, "api_key", GTHUMB_FACEBOOK_API_KEY);
 	g_hash_table_insert (data_set, "auth_token", self->priv->token);
 	g_hash_table_insert (data_set, "req_perms", get_access_type_name (access_type));
+	g_hash_table_insert (data_set, "connect_display", "page");
+	g_hash_table_insert (data_set, "fbconnect", "true");
 
 	link = g_string_new ("http://www.facebook.com/login.php?";);
 	keys = g_hash_table_get_keys (data_set);
diff --git a/extensions/flicker/data/ui/flicker-account-chooser.ui b/extensions/flicker/data/ui/flicker-account-chooser.ui
index 54abe69..924669d 100644
--- a/extensions/flicker/data/ui/flicker-account-chooser.ui
+++ b/extensions/flicker/data/ui/flicker-account-chooser.ui
@@ -1,11 +1,10 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-naming-policy project-wide -->
   <object class="GtkVBox" id="account_chooser">
     <property name="visible">True</property>
     <property name="border_width">5</property>
-    <property name="orientation">vertical</property>
     <property name="spacing">6</property>
     <child>
       <object class="GtkHBox" id="hbox3">
@@ -28,12 +27,6 @@
             <property name="width_request">300</property>
             <property name="visible">True</property>
             <property name="model">account_liststore</property>
-            <child>
-              <object class="GtkCellRendererText" id="cellrenderertext1"/>
-              <attributes>
-                <attribute name="text">1</attribute>
-              </attributes>
-            </child>
           </object>
           <packing>
             <property name="position">1</property>
@@ -51,6 +44,10 @@
       <column type="GObject"/>
       <!-- column-name name -->
       <column type="gchararray"/>
+      <!-- column-name separator -->
+      <column type="gboolean"/>
+      <!-- column-name icon_name -->
+      <column type="gchararray"/>
     </columns>
   </object>
 </interface>
diff --git a/extensions/flicker/flickr-account-chooser-dialog.c b/extensions/flicker/flickr-account-chooser-dialog.c
index fa48273..8f7deea 100644
--- a/extensions/flicker/flickr-account-chooser-dialog.c
+++ b/extensions/flicker/flickr-account-chooser-dialog.c
@@ -29,7 +29,9 @@
 
 enum {
 	ACCOUNT_DATA_COLUMN,
-	ACCOUNT_NAME_COLUMN
+	ACCOUNT_NAME_COLUMN,
+	ACCOUNT_SEPARATOR_COLUMN,
+	ACCOUNT_ICON_COLUMN
 };
 
 
@@ -68,6 +70,45 @@ flickr_account_chooser_dialog_class_init (FlickrAccountChooserDialogClass *klass
 
 
 static void
+account_combobox_changed_cb (GtkComboBox *combobox,
+			     gpointer     user_data)
+{
+	FlickrAccountChooserDialog *self = user_data;
+	GtkTreeIter                 iter;
+	FlickrAccount              *account;
+
+	if (! gtk_combo_box_get_active_iter (combobox, &iter))
+		return;
+
+	gtk_tree_model_get (GTK_TREE_MODEL (GET_WIDGET ("account_liststore")), &iter,
+			    ACCOUNT_DATA_COLUMN, &account,
+			    -1);
+
+	if (account == NULL)
+		gtk_dialog_response (GTK_DIALOG (self), FLICKR_ACCOUNT_CHOOSER_RESPONSE_NEW);
+
+	_g_object_unref (account);
+}
+
+
+static gboolean
+row_separator_func (GtkTreeModel *model,
+		    GtkTreeIter  *iter,
+		    gpointer      user_data)
+{
+	FlickrAccountChooserDialog *self = user_data;
+	gboolean                    is_separator;
+
+	gtk_tree_model_get (GTK_TREE_MODEL (GET_WIDGET ("account_liststore")),
+			    iter,
+			    ACCOUNT_SEPARATOR_COLUMN, &is_separator,
+			    -1);
+
+	return is_separator;
+}
+
+
+static void
 flickr_account_chooser_dialog_init (FlickrAccountChooserDialog *self)
 {
 	GtkWidget *content;
@@ -84,9 +125,33 @@ flickr_account_chooser_dialog_init (FlickrAccountChooserDialog *self)
 	gtk_container_set_border_width (GTK_CONTAINER (content), 5);
 	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), content, TRUE, TRUE, 0);
 
-	gtk_dialog_add_button (GTK_DIALOG (self),
-			       GTK_STOCK_NEW,
-			       FLICKR_ACCOUNT_CHOOSER_RESPONSE_NEW);
+	{
+		GtkCellLayout   *cell_layout;
+		GtkCellRenderer *renderer;
+
+		cell_layout = GTK_CELL_LAYOUT (GET_WIDGET ("account_combobox"));
+
+		renderer = gtk_cell_renderer_pixbuf_new ();
+		gtk_cell_layout_pack_start (cell_layout, renderer, FALSE);
+		gtk_cell_layout_set_attributes (cell_layout, renderer,
+						"icon-name", ACCOUNT_ICON_COLUMN,
+						NULL);
+
+		renderer = gtk_cell_renderer_text_new ();
+		gtk_cell_layout_pack_start (cell_layout, renderer, TRUE);
+		gtk_cell_layout_set_attributes (cell_layout, renderer,
+						"text", ACCOUNT_NAME_COLUMN,
+						NULL);
+	}
+	gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (GET_WIDGET ("account_combobox")),
+					      row_separator_func,
+					      self,
+					      NULL);
+	g_signal_connect (GET_WIDGET ("account_combobox"),
+			  "changed",
+			  G_CALLBACK (account_combobox_changed_cb),
+			  self);
+
 	gtk_dialog_add_button (GTK_DIALOG (self),
 			       GTK_STOCK_CANCEL,
 			       GTK_RESPONSE_CANCEL);
@@ -147,9 +212,24 @@ flickr_account_chooser_dialog_construct (FlickrAccountChooserDialog *self,
 		gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter,
 				    ACCOUNT_DATA_COLUMN, account,
 				    ACCOUNT_NAME_COLUMN, account->username,
+				    ACCOUNT_SEPARATOR_COLUMN, FALSE,
+				    ACCOUNT_ICON_COLUMN, "dialog-password",
 				    -1);
 	}
 
+	gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter);
+	gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter,
+			    ACCOUNT_SEPARATOR_COLUMN, TRUE,
+			    -1);
+
+	gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter);
+	gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter,
+			    ACCOUNT_DATA_COLUMN, NULL,
+			    ACCOUNT_NAME_COLUMN, _("New authentication..."),
+			    ACCOUNT_SEPARATOR_COLUMN, FALSE,
+			    ACCOUNT_ICON_COLUMN, GTK_STOCK_NEW,
+			    -1);
+
 	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("account_combobox")), active);
 }
 
diff --git a/extensions/flicker/flickr-authentication.c b/extensions/flicker/flickr-authentication.c
index 83037b4..90f6c30 100644
--- a/extensions/flicker/flickr-authentication.c
+++ b/extensions/flicker/flickr-authentication.c
@@ -32,6 +32,9 @@
 #include "flickr-service.h"
 
 
+#define FLICKR_AUTHENTICATION_RESPONSE_CHOOSE_ACCOUNT 2
+
+
 /* Signals */
 enum {
 	READY,
@@ -175,6 +178,61 @@ flickr_authentication_new (FlickrConnection *conn,
 }
 
 
+static void show_choose_account_dialog (FlickrAuthentication *self);
+
+
+static void
+authentication_error_dialog_response_cb (GtkDialog *dialog,
+					 int        response_id,
+					 gpointer   user_data)
+{
+	FlickrAuthentication *self = user_data;
+
+	switch (response_id) {
+	case GTK_RESPONSE_DELETE_EVENT:
+	case GTK_RESPONSE_CANCEL:
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		gtk_widget_destroy (self->priv->dialog);
+		break;
+
+	case FLICKR_AUTHENTICATION_RESPONSE_CHOOSE_ACCOUNT:
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		show_choose_account_dialog (self);
+		break;
+
+	default:
+		break;
+	}
+}
+
+
+static void
+show_authentication_error_dialog (FlickrAuthentication  *self,
+				  GError               **error)
+{
+	GtkWidget *dialog;
+
+	if (self->priv->conn != NULL)
+		gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
+
+	dialog = _gtk_message_dialog_new (GTK_WINDOW (self->priv->browser),
+			             GTK_DIALOG_MODAL,
+				     GTK_STOCK_DIALOG_ERROR,
+				     _("Could not connect to the server"),
+				     (*error)->message,
+				     _("Choose _Account..."), FLICKR_AUTHENTICATION_RESPONSE_CHOOSE_ACCOUNT,
+				     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+				     NULL);
+	g_signal_connect (dialog,
+			  "response",
+			  G_CALLBACK (authentication_error_dialog_response_cb),
+			  self);
+	gtk_widget_show (dialog);
+
+	g_clear_error (error);
+}
+
+
 /* -- flickr_authentication_auto_connect -- */
 
 
@@ -189,10 +247,7 @@ upload_status_ready_cb (GObject      *source_object,
 
 	user = flickr_service_get_upload_status_finish (FLICKR_SERVICE (source_object), res, &error);
 	if (error != NULL) {
-		if (self->priv->conn != NULL)
-			gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
-		_gtk_error_dialog_from_gerror_run (GTK_WINDOW (self->priv->browser), _("Could not connect to the server"), &error);
-		gtk_widget_destroy (self->priv->dialog);
+		show_authentication_error_dialog (self, &error);
 		return;
 	}
 	flickr_accounts_save_to_file (self->priv->accounts, self->priv->account);
@@ -302,10 +357,7 @@ connection_token_ready_cb (GObject      *source_object,
 	FlickrAccount        *account;
 
 	if (! flickr_connection_get_token_finish (FLICKR_CONNECTION (source_object), res, &error)) {
-		if (self->priv->conn != NULL)
-			gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
-		_gtk_error_dialog_from_gerror_run (GTK_WINDOW (self->priv->browser), _("Could not connect to the server"), &error);
-		gtk_widget_destroy (self->priv->dialog);
+		show_authentication_error_dialog (self, &error);
 		return;
 	}
 
@@ -428,15 +480,10 @@ ask_authorization_messagedialog_response_cb (GtkDialog *dialog,
 			gtk_widget_destroy (GTK_WIDGET (dialog));
 
 			url = flickr_connection_get_login_link (self->priv->conn, FLICKR_ACCESS_WRITE);
-			if (gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (dialog)), url, 0, &error)) {
+			if (gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (dialog)), url, 0, &error))
 				complete_authorization (self);
-			}
-			else {
-				if (self->priv->conn != NULL)
-					gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
-				_gtk_error_dialog_from_gerror_run (GTK_WINDOW (self->priv->browser), _("Could not connect to the server"), &error);
-				gtk_widget_destroy (self->priv->dialog);
-			}
+			else
+				show_authentication_error_dialog (self, &error);
 
 			g_free (url);
 		}
@@ -489,15 +536,10 @@ connection_frob_ready_cb (GObject      *source_object,
 	FlickrAuthentication *self = user_data;
 	GError               *error = NULL;
 
-	if (! flickr_connection_get_frob_finish (FLICKR_CONNECTION (source_object), res, &error)) {
-		if (self->priv->conn != NULL)
-			gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
-		_gtk_error_dialog_from_gerror_run (GTK_WINDOW (self->priv->browser), _("Could not connect to the server"), &error);
-		gtk_widget_destroy (self->priv->dialog);
-		return;
-	}
-
-	ask_authorization (self);
+	if (! flickr_connection_get_frob_finish (FLICKR_CONNECTION (source_object), res, &error))
+		show_authentication_error_dialog (self, &error);
+	else
+		ask_authorization (self);
 }
 
 
@@ -546,6 +588,25 @@ account_chooser_dialog_response_cb (GtkDialog *dialog,
 }
 
 
+static void
+show_choose_account_dialog (FlickrAuthentication *self)
+{
+	GtkWidget *dialog;
+
+	gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
+	dialog = flickr_account_chooser_dialog_new (self->priv->accounts, self->priv->account);
+	g_signal_connect (dialog,
+			  "response",
+			  G_CALLBACK (account_chooser_dialog_response_cb),
+			  self);
+
+	gtk_window_set_title (GTK_WINDOW (dialog), _("Choose Account"));
+	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (self->priv->browser));
+	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+	gtk_window_present (GTK_WINDOW (dialog));
+}
+
+
 void
 flickr_authentication_auto_connect (FlickrAuthentication *self)
 {
@@ -560,21 +621,8 @@ flickr_authentication_auto_connect (FlickrAuthentication *self)
 			self->priv->account = g_object_ref (self->priv->accounts->data);
 			connect_to_server (self);
 		}
-		else {
-			GtkWidget *dialog;
-
-			gth_task_dialog (GTH_TASK (self->priv->conn), TRUE);
-			dialog = flickr_account_chooser_dialog_new (self->priv->accounts, self->priv->account);
-			g_signal_connect (dialog,
-					  "response",
-					  G_CALLBACK (account_chooser_dialog_response_cb),
-					  self);
-
-			gtk_window_set_title (GTK_WINDOW (dialog), _("Choose Account"));
-			gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (self->priv->browser));
-			gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-			gtk_window_present (GTK_WINDOW (dialog));
-		}
+		else
+			show_choose_account_dialog (self);
 	}
 	else
 		start_authorization_process (self);



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