irex-account.c

Go to the documentation of this file.
00001 /*
00002  * File Name: irex-account.c
00003  */
00004 
00005 /*
00006  * This file is part of settings.
00007  *
00008  * settings is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation, either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * settings is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00020  */
00021 
00022 /**
00023  * Copyright (C) 2008 iRex Technologies B.V.
00024  * All rights reserved.
00025  */
00026 
00027 //----------------------------------------------------------------------------
00028 // Include Files
00029 //----------------------------------------------------------------------------
00030 
00031 #include <unistd.h>
00032 #include <stdio.h>
00033 
00034 #include <gtk/gtk.h>
00035 #include <gdk/gdk.h>
00036 #include <glib.h>
00037 
00038 #include <libergtk/ergtk.h>
00039 #include <liberkeyb/ergtk-keyb.h>
00040 
00041 #include "i18n.h"
00042 #include "log.h"
00043 #include "ipc.h"
00044 #include "settings.h"
00045 #include "settings_utils.h"
00046 #include "settings_style.h"
00047 #include "irex-account.h"
00048 
00049 
00050 //----------------------------------------------------------------------------
00051 // Type Declarations
00052 //----------------------------------------------------------------------------
00053 
00054 
00055 //----------------------------------------------------------------------------
00056 // Global Constants
00057 //----------------------------------------------------------------------------
00058 
00059 const int ENTRY_LABEL_WIDTH                     = 180;
00060 const int ENTRY_EMAIL_WIDTH                     = 350;
00061 const int ENTRY_PASSWD_WIDTH                    = 250;
00062 const int ENTRY_PASSWD_LENGTH_LIMITATION        = 64 ;
00063 
00064 static const int        TITLE_HEIGHT                =  44;  // total height of titlebar
00065 static const int        TITLE_V_PADDING             =  10;  // vertical padding around title
00066 static const int        TITLE_SPACING               =  20;  // space between path and number of items in title
00067 
00068 
00069 //----------------------------------------------------------------------------
00070 // Static Variables
00071 //----------------------------------------------------------------------------
00072 
00073 static GtkWidget* g_myirex_window = NULL ; 
00074 static GtkWidget* g_entry_email    = NULL;
00075 static GtkWidget* g_entry_passwd   = NULL;
00076 static char   g_email[128]  = { 0 };
00077 static char   g_passwd[128] = { 0 };
00078 
00079 
00080 //============================================================================
00081 // Local Function Definitions
00082 //============================================================================
00083 
00084 static void   init_widgets_with_settings();
00085 static gchar* fix_base64_missing_equals(gchar* input);
00086 static gchar* cut_base64_existing_equals(gchar* input);
00087 static void   on_listview_row_activated(GtkTreeView       *view,
00088                                         GtkTreePath       *path,
00089                                         GtkTreeViewColumn *column,
00090                                         gpointer          user_data);
00091 static void   on_listview_navigate_cursor(erGtkListView         *er_listview,
00092                                           erGtkListViewKeyPress keycode,
00093                                           gpointer              user_data);
00094 static gboolean on_focus_in( GtkWidget* widget, gpointer data );
00095 static gboolean on_focus_out( GtkWidget* widget, gpointer data );
00096 static gboolean on_save_button_clicked(GtkWidget* widget, gpointer data);
00097 static void   run_dialog(GtkMessageType type, const gchar *msg);
00098 
00099 
00100 //============================================================================
00101 // Functions Implementation
00102 //============================================================================
00103 
00104 GtkWidget* create_account_window(GtkWidget* parent)
00105 {
00106     // create the top level window 
00107     GtkWidget* top_window = parent;
00108     gtk_window_maximize(GTK_WINDOW(top_window));
00109     gtk_window_set_resizable(GTK_WINDOW(top_window), FALSE);
00110     gtk_container_set_border_width(GTK_CONTAINER(top_window),WINDOW_BORDER_PADDING  );
00111     gtk_window_set_modal(GTK_WINDOW(top_window), TRUE);
00112 
00113     // vboxtop in top level window
00114     GtkWidget* vboxtop = gtk_vbox_new(FALSE, 3);
00115     gtk_container_add(GTK_CONTAINER(top_window), vboxtop);   
00116 
00117     // add title (header) in vboxtop
00118     create_title(GTK_VBOX(vboxtop), _("Settings"), _("MYIREX Account"));
00119 
00120     // add back/exit bar below title (header) in vboxtop
00121     GtkWidget* view = create_settingsview();
00122     gtk_box_pack_start(GTK_BOX(vboxtop), view, FALSE, FALSE,0 ); 
00123     g_signal_connect(view, "row-activated",   G_CALLBACK(on_listview_row_activated),   NULL);
00124     g_signal_connect(view, "navigate-cursor", G_CALLBACK(on_listview_navigate_cursor), NULL );
00125     g_signal_connect(view, "focus-in-event", G_CALLBACK(on_focus_in), NULL );
00126     g_signal_connect(view, "focus-out-event", G_CALLBACK(on_focus_out), NULL );
00127 
00128     // add alignment for frame below back/exit bar in vboxtop
00129     GtkWidget* top_frame_alignment = gtk_alignment_new(0.0, 0.0, 1.0, 0.0 );
00130     gtk_box_pack_start(GTK_BOX(vboxtop), top_frame_alignment, FALSE, FALSE, 0);
00131 
00132     // add frame in top_frame_alignment
00133     GtkWidget* top_frame  = gtk_frame_new(NULL);
00134     gtk_widget_set_name(top_frame, "irex-margins-frame");
00135     gtk_container_add(GTK_CONTAINER(top_frame_alignment), top_frame);
00136     gtk_container_set_border_width(GTK_CONTAINER(top_frame), 3  );
00137 
00138     // Alignment.
00139     GtkWidget* alignment = gtk_alignment_new(0, 0, 1.0, 1.0);
00140     gtk_container_add(GTK_CONTAINER(top_frame), alignment);
00141     gtk_alignment_set_padding(GTK_ALIGNMENT(alignment),
00142                               WINDOW_TOP_ALT_PADDING,
00143                               WINDOW_BOTTOM_PADDING,
00144                               WINDOW_H_PADDING,
00145                               WINDOW_H_PADDING);
00146    
00147     // add  vbox in top frame 
00148     GtkWidget* vbox = gtk_vbox_new(FALSE, SMALL_SPACING);
00149     gtk_container_add(GTK_CONTAINER(alignment), vbox);
00150 
00151     // The label ("MyiRex Account Information").
00152     GtkWidget* label = gtk_label_new(_("MYIREX Account Information"));
00153     gtk_widget_set_name(label, "irex-normal-text");
00154     gtk_widget_set_size_request(label, -1, -1);
00155     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
00156     gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
00157 
00158     // the second label
00159     label = gtk_label_new(_("A MYIREX account is used to deliver newspaper "
00160                             "and periodical subscriptions directly to your device."
00161                             ));
00162     gtk_widget_set_name(label, "irex-sans-small-grey-italic");
00163     gtk_widget_set_size_request(label, SETTINGS_LABEL_MAX_WIDTH - 15 , -1);
00164     gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
00165     gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
00166     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
00167     gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
00168 
00169     // hbox with username/email
00170     GtkWidget* hbox = gtk_hbox_new(FALSE,0);
00171     gtk_box_pack_start(GTK_BOX(vbox),hbox , FALSE, FALSE, SMALL_SPACING);
00172 
00173     // the label "email"
00174     label = gtk_label_new(_("Email"));
00175     gtk_widget_set_name(label, "irex-normal-text");
00176     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
00177     gtk_widget_set_size_request(label, ENTRY_LABEL_WIDTH, -1);
00178     gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);  
00179     
00180     // the text entry for the email
00181     g_entry_email = ergtk_entry_new();
00182     gtk_widget_set_size_request(g_entry_email,ENTRY_EMAIL_WIDTH, -1);
00183     gtk_box_pack_start(GTK_BOX(hbox), g_entry_email, TRUE, TRUE, SMALL_SPACING);
00184     g_object_set(G_OBJECT(g_entry_email), "im-context-inhibit", TRUE, NULL);
00185      
00186     // second hbox for password
00187     hbox = gtk_hbox_new(FALSE,0);
00188     gtk_box_pack_start(GTK_BOX(vbox),hbox , FALSE, FALSE, SMALL_SPACING);
00189 
00190     // the label "password"
00191     label = gtk_label_new(_("Password"));
00192     gtk_widget_set_name(label, "irex-normal-text");
00193     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
00194     gtk_widget_set_size_request(label, ENTRY_LABEL_WIDTH, -1);
00195     gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);  
00196     
00197     // the text entry for the password
00198     g_entry_passwd = ergtk_entry_new();
00199     gtk_entry_set_visibility(GTK_ENTRY(g_entry_passwd),FALSE);
00200     gtk_entry_set_max_length(GTK_ENTRY(g_entry_passwd),ENTRY_PASSWD_LENGTH_LIMITATION);
00201     gtk_widget_set_size_request(g_entry_passwd,ENTRY_PASSWD_WIDTH, -1);
00202     gtk_box_pack_start(GTK_BOX(hbox), g_entry_passwd, TRUE, TRUE, SMALL_SPACING);
00203     g_object_set(G_OBJECT(g_entry_passwd), "im-context-inhibit", TRUE, NULL);
00204 
00205     // hbuttonbox for the save button
00206     GtkWidget* hbuttonbox = gtk_hbutton_box_new();
00207     gtk_box_set_spacing(GTK_BOX(hbuttonbox), 15);
00208     gtk_hbutton_box_set_layout_default(GTK_BUTTONBOX_END);
00209     gtk_box_pack_start(GTK_BOX(vbox), hbuttonbox, FALSE, FALSE, 0);
00210     // the save button
00211     GtkWidget* save_button = gtk_button_new_with_label( _("Save") );
00212     gtk_container_add(GTK_CONTAINER(hbuttonbox),save_button);
00213     g_signal_connect(G_OBJECT(save_button), "clicked", G_CALLBACK(on_save_button_clicked), NULL);
00214 
00215     // Add separator here.
00216     GtkWidget* separator = create_separator_widgets();
00217     gtk_widget_set_name(separator, "irex-separator-invisible");
00218     gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 0);
00219 
00220     // label "To create ..."
00221     label = gtk_label_new(NULL);
00222     gtk_label_set_markup(GTK_LABEL(label), _("To create a MYIREX account, use a computer with internet "
00223       "connection and go to <b>www.irexreader.com/setup</b> for directions."));
00224     gtk_widget_set_name(label, "irex-sans-small-grey-italic");
00225     gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
00226     gtk_widget_set_size_request(label, SETTINGS_LABEL_MAX_WIDTH, -1);
00227     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 1.0);
00228     gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 10);
00229     
00230     //  separator here.
00231     separator = create_separator_widgets();
00232     gtk_widget_set_name(separator, "irex-separator-invisible");
00233     gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 0);
00234     
00235     // alignment for the keyboard (prevent ugly scaled buttons)
00236     GtkWidget* keyb_align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
00237     gtk_box_pack_start(GTK_BOX(vbox), keyb_align, FALSE, FALSE, 0 );
00238    
00239     // keyboard in keyb_align
00240     GtkWidget* keyboard = ergtk_keyb_new();
00241     gtk_container_add(GTK_CONTAINER(keyb_align), keyboard );
00242 
00243     // Update widget with current settings.
00244     init_widgets_with_settings();
00245    
00246     g_myirex_window = top_window;
00247 
00248     gtk_widget_grab_focus(view);
00249 
00250     gtk_widget_show_all(top_window);
00251 
00252     return top_window;
00253 }
00254 
00255 void load_account_settings()
00256 {
00257     gchar* email_gconf  = (gchar*)get_value_string(GCONF_DOWNLOAD_ACCOUNT_EMAIL);
00258     gchar* password_gconf = (gchar*)get_value_string(GCONF_DOWNLOAD_ACCOUNT_PASSWD);
00259 
00260     if (!email_gconf || !password_gconf)
00261     {
00262         ERRORPRINTF("Error reading settings from gconf");
00263         _exit(1);
00264     }
00265 
00266     strncpy(g_email, email_gconf, sizeof(g_email));
00267     g_email[sizeof(g_email)-1] = '\0';
00268     
00269     if (strcmp(password_gconf, "") != 0)
00270     {
00271         gchar* password_fixed = fix_base64_missing_equals(password_gconf);
00272         gsize len = 0;
00273         guchar* password = g_base64_decode(password_fixed, &len);
00274         g_free(password_fixed);
00275         strncpy(g_passwd, (gchar*)password, sizeof(g_passwd));
00276     }
00277     else
00278     {
00279         strncpy(g_passwd, password_gconf,  sizeof(g_passwd));
00280     }
00281     g_passwd[sizeof(g_passwd)-1] = '\0';
00282 
00283     g_free(email_gconf);
00284     g_free(password_gconf);
00285 }
00286 
00287 
00288 void save_account_settings()
00289 {
00290     const gchar* email = gtk_entry_get_text(GTK_ENTRY(g_entry_email));
00291     const gchar* passwd = gtk_entry_get_text(GTK_ENTRY(g_entry_passwd));
00292     if (email != NULL)
00293     {
00294       set_value_string(GCONF_DOWNLOAD_ACCOUNT_EMAIL, email);
00295 
00296         if (passwd != NULL)
00297         {
00298             if (strcmp(passwd, "") == 0)
00299             {
00300                 set_value_string(GCONF_DOWNLOAD_ACCOUNT_PASSWD, passwd);
00301             }
00302             else
00303             {
00304                 gsize len = strlen(passwd);  
00305                 gchar* passwd_encode = g_base64_encode((const guchar*)passwd, len); 
00306                 gchar* passwd_cut = cut_base64_existing_equals(passwd_encode);
00307                 set_value_string(GCONF_DOWNLOAD_ACCOUNT_PASSWD, passwd_cut);
00308                 g_free(passwd_encode);
00309                 g_free(passwd_cut);
00310                 
00311                 run_dialog(GTK_MESSAGE_INFO, _("Your MYIREX account has been saved"));
00312             }
00313         }
00314     }
00315 }
00316 
00317 
00318 //============================================================================
00319 // Local Functions Implementation
00320 //============================================================================
00321 
00322 static gchar* fix_base64_missing_equals(gchar* input)
00323 {
00324     int len = strlen(input);
00325     gchar* password_fixed = g_strndup(input, len+2);
00326 
00327     switch (len % 4) 
00328     {
00329       case 0:
00330           break;
00331       case 1:
00332           ERRORPRINTF("corrupted base64 string '%s'", input);
00333           break;
00334       case 2:
00335           password_fixed[len+1] = '=';
00336       case 3:
00337           password_fixed[len] = '=';
00338           password_fixed[len+2] = 0;
00339           break;
00340     }
00341     return password_fixed;
00342 }
00343 
00344 static gchar* cut_base64_existing_equals(gchar* input)
00345 {
00346     if (input == NULL) { return NULL; }
00347     int len = strlen(input);
00348     gchar* password_cut = g_strndup(input, len);
00349     int i;
00350     for(i = len -1; i >= 0; i--)
00351     {
00352       if (password_cut[i] != '=') { break ; }
00353       password_cut[i] = 0;
00354     }
00355     //it means more than 2 "=' need to be cut
00356     if (i < len - 3)
00357     {
00358       ERRORPRINTF("corrupted base64 string '%s'", input);
00359       g_free(password_cut);
00360       return NULL;
00361     } 
00362     return password_cut;
00363    
00364 }
00365 
00366 
00367 void     init_widgets_with_settings()
00368 {
00369   gtk_entry_set_text(GTK_ENTRY(g_entry_email),(const gchar*) g_email);  
00370   gtk_entry_set_text(GTK_ENTRY(g_entry_passwd),(const gchar*) g_passwd);   
00371   return;
00372 }
00373 
00374 static gboolean on_focus_in(GtkWidget* widget, gpointer data )
00375 {
00376     g_assert(widget != NULL ) ;
00377     ergtk_list_view_set_cursor( ERGTK_LIST_VIEW(widget), 0); // row = 0;
00378     return FALSE;
00379 }
00380 
00381 static gboolean on_focus_out(GtkWidget* widget, gpointer data )
00382 {
00383     g_assert(widget != NULL ) ;
00384     GtkTreeSelection* my_selection = gtk_tree_view_get_selection((GtkTreeView*) widget);
00385     g_assert( my_selection != NULL ) ;
00386     gtk_tree_selection_unselect_all(my_selection);
00387     return FALSE;
00388 }
00389 
00390 static void on_listview_row_activated ( GtkTreeView       *view,
00391                                         GtkTreePath       *path,
00392                                         GtkTreeViewColumn *column,
00393                                         gpointer          user_data )
00394 {
00395     main_quit();
00396 }
00397 
00398 static void on_listview_navigate_cursor ( erGtkListView         *er_listview,
00399         erGtkListViewKeyPress keycode,
00400         gpointer              user_data )
00401 {
00402    GtkTreeSelection* my_selection = gtk_tree_view_get_selection((GtkTreeView*) er_listview);
00403    g_assert(my_selection != NULL ) ;
00404 
00405     // determine new cursor position
00406     switch (keycode)
00407     {
00408         case ERGTK_LIST_VIEW_PRESS_SHORT_UP:
00409         case ERGTK_LIST_VIEW_PRESS_LONG_UP:
00410             break;
00411         case ERGTK_LIST_VIEW_PRESS_SHORT_DOWN:
00412         case ERGTK_LIST_VIEW_PRESS_LONG_DOWN:
00413             gtk_widget_grab_focus(GTK_WIDGET(g_entry_email));
00414             // this works because we only have one row
00415             gtk_tree_selection_unselect_all(my_selection);
00416             break;
00417         default:
00418             LOGPRINTF("illegal erGtkListViewKeyPress [%d]\n", keycode);
00419             ;  // ignore
00420             break;
00421     }
00422 
00423 }
00424 
00425 static gboolean on_save_button_clicked(GtkWidget* widget, gpointer data)
00426 {
00427     save_account_settings(); 
00428     return FALSE;
00429 }
00430 
00431 static void run_dialog (GtkMessageType type, const gchar *msg)
00432 {
00433     LOGPRINTF("entry: msg [%s]\n", msg);
00434 
00435     GtkWidget *dialog = gtk_message_dialog_new(
00436             GTK_WINDOW(g_myirex_window),
00437             GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
00438             type,
00439             GTK_BUTTONS_OK,
00440             msg );
00441     gtk_window_set_deletable( GTK_WINDOW(dialog), FALSE );
00442     ipc_menu_block();
00443     gtk_dialog_run( GTK_DIALOG(dialog) );
00444     ipc_menu_unblock();
00445     gtk_widget_destroy( dialog );
00446 }
Generated by  doxygen 1.6.2-20100208