chiark / gitweb /
Merge from disorder.userman
[disorder] / disobedience / login.c
index 729597bac7658cee22d14ffa88b9da481007ca0c..18afce461642b353c49cc6fc6a9bfe06ddd0ca44 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder
- * Copyright (C) 2007 Richard Kettlewell
+ * Copyright (C) 2007, 2008 Richard Kettlewell
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  */
 /** @file disobedience/login.c
  * @brief Login box for Disobedience
+ *
+ * As of 2.1 we have only two buttons: Login and Cancel.
+ *
+ * If you hit Login then a login is attempted.  If it works the window
+ * disappears and the settings are saved, otherwise they are NOT saved and the
+ * window remains.
+ *
+ * It you hit Cancel then the window disappears without saving anything.
  */
 
 #include "disobedience.h"
 #include "split.h"
 #include "filepart.h"
+#include "client.h"
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <unistd.h>
 
 /** @brief One field in the login window */
 struct login_window_item {
@@ -50,7 +60,7 @@ struct login_window_item {
 #define LWI_HIDDEN 0x0001
 
 /** @brief Current login window */
-static GtkWidget *login_window;
+GtkWidget *login_window;
 
 /** @brief Set connection defaults */
 static void default_connect(void) {
@@ -65,7 +75,7 @@ static void default_connect(void) {
 static const char *get_hostname(void) { return config->connect.s[0]; }
 static const char *get_service(void) { return config->connect.s[1]; }
 static const char *get_username(void) { return config->username; }
-static const char *get_password(void) { return config->password; }
+static const char *get_password(void) { return config->password ? config->password : ""; }
 
 static void set_hostname(const char *s) { config->connect.s[0] = (char *)s; }
 static void set_service(const char *s) { config->connect.s[1] = (char *)s; }
@@ -83,32 +93,26 @@ static const struct login_window_item lwis[] = {
 
 static GtkWidget *lwi_entry[NLWIS];
 
-static void update_config(void) {
+static void login_update_config(void) {
   size_t n;
 
   for(n = 0; n < NLWIS; ++n)
-    lwis[n].set(gtk_entry_get_text(GTK_ENTRY(lwi_entry[n])));
+    lwis[n].set(xstrdup(gtk_entry_get_text(GTK_ENTRY(lwi_entry[n]))));
 }
 
-static void login_ok(GtkButton attribute((unused)) *button,
-                     gpointer attribute((unused)) userdata) {
-  update_config();
-  reset();
-}
-
-static void login_save(GtkButton attribute((unused)) *button,
-                       gpointer attribute((unused)) userdata) {
+/** @brief Save current login details */
+static void login_save_config(void) {
   char *path = config_userconf(0, 0), *tmp;
   FILE *fp;
 
-  update_config();
   byte_xasprintf(&tmp, "%s.tmp", path);
   /* Make sure the directory exists; don't care if it already exists. */
   mkdir(d_dirname(tmp), 02700);
   /* Write out the file */
   if(!(fp = fopen(tmp, "w"))) {
-    fpopup_error("error opening %s: %s", tmp, strerror(errno));
-    return;
+    fpopup_msg(GTK_MESSAGE_ERROR, "error opening %s: %s",
+               tmp, strerror(errno));
+    goto done;
   }
   if(fprintf(fp, "username %s\n"
              "password %s\n"
@@ -117,42 +121,67 @@ static void login_save(GtkButton attribute((unused)) *button,
              quoteutf8(config->password),
              quoteutf8(config->connect.s[0]),
              quoteutf8(config->connect.s[1])) < 0) {
-    fpopup_error("error writing to %s: %s", tmp, strerror(errno));
+    fpopup_msg(GTK_MESSAGE_ERROR, "error writing to %s: %s",
+               tmp, strerror(errno));
     fclose(fp);
-    return;
+    goto done;
   }
   if(fclose(fp) < 0) {
-    fpopup_error("error closing %s: %s", tmp, strerror(errno));
-    return;
+    fpopup_msg(GTK_MESSAGE_ERROR, "error closing %s: %s",
+               tmp, strerror(errno));
+    goto done;
   }
   /* Rename into place */
   if(rename(tmp, path) < 0) {
-    fpopup_error("error renaming %s: %s", tmp, strerror(errno));
-    return;
+    fpopup_msg(GTK_MESSAGE_ERROR, "error renaming %s: %s",
+               tmp, strerror(errno));
+    goto done;
   }
+done:
+  ;
 }
 
+/** @brief User pressed OK in login window */
+static void login_ok(GtkButton attribute((unused)) *button,
+                     gpointer attribute((unused)) userdata) {
+  disorder_client *c;
+  
+  /* Copy the new config into @ref config */
+  login_update_config();
+  /* Attempt a login with the new details */
+  c = disorder_new(0);
+  if(!disorder_connect(c)) {
+    /* Success; save the config and start using it */
+    login_save_config();
+    reset();
+    /* Pop down login window */
+    gtk_widget_destroy(login_window);
+  } else {
+    /* Failed to connect - report the error */
+    popup_msg(GTK_MESSAGE_ERROR, disorder_last(c));
+  }
+  disorder_close(c);                    /* no use for this any more */
+}
+
+/** @brief User pressed cancel in the login window */
 static void login_cancel(GtkButton attribute((unused)) *button,
                          gpointer attribute((unused)) userdata) {
   gtk_widget_destroy(login_window);
 }
 
 /* Buttons that appear at the bottom of the window */
-static const struct button buttons[] = {
+static struct button buttons[] = {
   {
-    GTK_STOCK_OK,
+    "Login",
     login_ok,
-    "Login with these settings",
-  },
-  {
-    GTK_STOCK_SAVE,
-    login_save,
-    "Save these settings",
+    "(Re-)connect using these settings",
+    0
   },
   {
-    GTK_STOCK_CANCEL,
+    GTK_STOCK_CLOSE,
     login_cancel,
-    "Discard all changes and close window"
+    "Discard changes and close window",
+    0
   },
 };
 
@@ -171,13 +200,16 @@ void login_box(void) {
   default_connect();
   /* Create a new login window */
   login_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  gtk_widget_set_style(login_window, tool_style);
   g_signal_connect(login_window, "destroy",
                   G_CALLBACK(gtk_widget_destroyed), &login_window);
   gtk_window_set_title(GTK_WINDOW(login_window), "Login Details");
   /* Construct the form */
   table = gtk_table_new(NLWIS + 1/*rows*/, 2/*columns*/, FALSE/*homogenous*/);
+  gtk_widget_set_style(table, tool_style);
   for(n = 0; n < NLWIS; ++n) {
     label = gtk_label_new(lwis[n].description);
+    gtk_widget_set_style(label, tool_style);
     gtk_misc_set_alignment(GTK_MISC(label), 1/*right*/, 0/*bottom*/);
     gtk_table_attach(GTK_TABLE(table), label,
                     0, 1,              /* left/right_attach */
@@ -185,6 +217,7 @@ void login_box(void) {
                     GTK_FILL, 0,       /* x/yoptions */
                     1, 1);             /* x/ypadding */
     entry = gtk_entry_new();
+    gtk_widget_set_style(entry, tool_style);
     gtk_entry_set_visibility(GTK_ENTRY(entry),
                              lwis[n].flags & LWI_HIDDEN ? FALSE : TRUE);
     gtk_entry_set_text(GTK_ENTRY(entry), lwis[n].get());
@@ -201,7 +234,9 @@ void login_box(void) {
                      TRUE/*expand*/, TRUE/*fill*/, 1/*padding*/);
   gtk_box_pack_start(GTK_BOX(vbox), buttonbox,
                      FALSE/*expand*/, FALSE/*fill*/, 1/*padding*/);
-  gtk_container_add(GTK_CONTAINER(login_window), vbox);
+  gtk_container_add(GTK_CONTAINER(login_window), frame_widget(vbox, NULL));
+  gtk_window_set_transient_for(GTK_WINDOW(login_window),
+                               GTK_WINDOW(toplevel));
   gtk_widget_show_all(login_window);
 }