Continued data model docs.
[doldaconnect.git] / config / dolconf.c
index 663e235..a637909 100644 (file)
 #include <signal.h>
 #include <errno.h>
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
 #include <locale.h>
 #include <libintl.h>
 #include <pwd.h>
 #include <stdarg.h>
 #include <arpa/inet.h>
+#include <doldaconnect/uilib.h>
+#include <doldaconnect/uimisc.h>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -52,7 +55,7 @@ struct cfvar {
 char *cfname;
 GtkWindow *rootwnd = NULL;
 GtkListStore *shares;
-int state;
+int state, dirty = 1;
 int ignoreclose = 0;
 
 void astcancel(GtkWidget *widget, gpointer uudata);
@@ -67,8 +70,9 @@ void cb_cfw_mode_act_toggled(GtkWidget *widget, gpointer uudata);
 void cb_cfw_orport_toggled(GtkWidget *widget, gpointer uudata);
 void cb_cfw_oraddr_toggled(GtkWidget *widget, gpointer uudata);
 void cb_cfw_uinet_toggled(GtkWidget *widget, gpointer uudata);
-void cb_cfw_save_clicked(GtkWidget *widget, gpointer uudata);
-void cb_cfw_quit_clicked(GtkWidget *widget, gpointer uudata);
+void cb_cfw_save_activate(GtkWidget *widget, gpointer uudata);
+void cb_cfw_hup_activate(GtkWidget *widget, gpointer uudata);
+void cb_cfw_quit_activate(GtkWidget *widget, gpointer uudata);
 void cb_cfw_shareadd_clicked(GtkWidget *widget, gpointer uudata);
 void cb_cfw_sharerem_clicked(GtkWidget *widget, gpointer uudata);
 
@@ -190,8 +194,11 @@ void setcfvar(char *name, const char *val)
     struct cfvar *v;
     
     v = findcfvar(name);
+    if(!strcmp(v->val, val))
+       return;
     free(v->val);
     v->val = sstrdup(val);
+    dirty = 1;
 }
 
 int msgbox(int type, int buttons, char *format, ...)
@@ -353,6 +360,7 @@ int readconfig(void)
     if(val != NULL)
        free(val);
     fclose(cf);
+    dirty = 0;
     return(rv);
 }
 
@@ -403,6 +411,7 @@ void writeconfig(void)
        } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(shares), &iter));
     }
     fclose(cf);
+    dirty = 0;
 }
 
 void fillcfw(void)
@@ -456,11 +465,16 @@ void ast2conf(void)
 void cfw2conf(void)
 {
     struct cfvar *var;
+    const char *val;
     
     for(var = config; var->name != NULL; var++) {
        if(var->cfww != NULL) {
+           val = gtk_entry_get_text(GTK_ENTRY(*(var->cfww)));
+           if(!strcmp(var->val, val))
+               continue;
            free(var->val);
-           var->val = sstrdup(gtk_entry_get_text(GTK_ENTRY(*(var->cfww))));
+           var->val = sstrdup(val);
+           dirty = 1;
        }
     }
     if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cfw_mode_act))) {
@@ -487,6 +501,23 @@ void cfw2conf(void)
     }
 }
 
+struct cfvar *cfwvalid(void)
+{
+    struct cfvar *cv;
+    
+    for(cv = config; cv->name != NULL; cv++) {
+       if((cv->vld != NULL) && !cv->vld->check(cv->val)) {
+           if(cv->rname) {
+               return(cv);
+           } else {
+               msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Internal error (Auto-generated variable %s has an invalid value \"%s\")"), cv->name, cv->val);
+               abort();
+           }
+       }
+    }
+    return(NULL);
+}
+
 void astcancel(GtkWidget *widget, gpointer uudata)
 {
     if(ignoreclose)
@@ -688,26 +719,48 @@ void cb_cfw_uinet_toggled(GtkWidget *widget, gpointer uudata)
     gtk_widget_set_sensitive(GTK_WIDGET(cfw_uibox), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
 }
 
-void cb_cfw_save_clicked(GtkWidget *widget, gpointer uudata)
+void cb_cfw_hup_activate(GtkWidget *widget, gpointer uudata)
+{
+    int tag;
+    struct dc_response *resp;
+    
+    if(dc_connectsync2(dc_srv_local, DC_LATEST) < 0) {
+       msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not connect to server"));
+       return;
+    }
+    if(dc_login(NULL, 1, dc_convnone, NULL) != DC_LOGIN_ERR_SUCCESS) {
+       dc_disconnect();
+       msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not connect to server"));
+       return;
+    }
+    tag = dc_queuecmd(NULL, NULL, L"hup", NULL);
+    if((resp = dc_gettaggedrespsync(tag)) != NULL) {
+       if(resp->code != 200)
+           msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not connect to server"));
+       dc_freeresp(resp);
+    }
+    dc_disconnect();
+}
+
+void cb_cfw_save_activate(GtkWidget *widget, gpointer uudata)
 {
     struct cfvar *cv;
     
-    for(cv = config; cv->name != NULL; cv++) {
-       if((cv->vld != NULL) && !cv->vld->check(cv->val)) {
-           if(cv->rname) {
-               msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, cv->vld->invmsg, cv->rname);
-           } else {
-               msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Internal error (Auto-generated variable %s has an invalid value \"%s\")"), cv->name, cv->val);
-           }
-           return;
-       }
+    if((cv = cfwvalid()) != NULL) {
+       msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, cv->vld->invmsg, cv->rname);
+       return;
     }
     cfw2conf();
     writeconfig();
 }
 
-void cb_cfw_quit_clicked(GtkWidget *widget, gpointer uudata)
+void cb_cfw_quit_activate(GtkWidget *widget, gpointer uudata)
 {
+    cfw2conf();
+    if(dirty) {
+       if(msgbox(GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("There are unsaved changes. Do you wish to discard the changes and exit anyway?")) == GTK_RESPONSE_NO)
+           return;
+    }
     gtk_main_quit();
     state = -1;
 }
@@ -721,6 +774,7 @@ int main(int argc, char **argv)
     bindtextdomain(PACKAGE, LOCALEDIR);
     textdomain(PACKAGE);
     prepstatic();
+    dc_init();
     
     gtk_init(&argc, &argv);
     state = -1;
@@ -731,10 +785,16 @@ int main(int argc, char **argv)
            break;
        case 'w':
            state = 0;
+           break;
        case 'h':
+           printf("usage: dolconf [-haw]\n");
+           printf("\t-h\tDisplay this help message\n");
+           printf("\t-a\tGo directly to the assistant\n");
+           printf("\t-w\tGo directly to the standard window\n");
+           exit(0);
        default:
-           fprintf((c == 'h')?stdout:stderr, "usage: dolconf [-haw]\n");
-           break;
+           fprintf(stderr, "usage: dolconf [-haw]\n");
+           exit(1);
        }
     }
     
@@ -757,11 +817,15 @@ int main(int argc, char **argv)
     }
     
     ex = !access(cfname, F_OK);
-    if(!ex && (state == -1)) {
-       if(msgbox(GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("It appears that you have not run this setup program before. Would you like to run the first-time setup assistant?")) == GTK_RESPONSE_YES)
-           state = 1;
-       else
+    if(state == -1) {
+       if(!ex) {
+           if(msgbox(GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("It appears that you have not run this setup program before. Would you like to run the first-time setup assistant?")) == GTK_RESPONSE_YES)
+               state = 1;
+           else
+               state = 0;
+       } else {
            state = 0;
+       }
     }
     
     if(ex && (state == 0)) {