power.c

Go to the documentation of this file.
00001 /*
00002  * File Name: power.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 // system include files, between < >
00032 
00033 #include <gtk/gtk.h>
00034 #include <gdk/gdk.h>
00035 
00036 #include <libergtk/ergtk.h>
00037 
00038 #include "i18n.h"
00039 #include "log.h"
00040 #include "settings.h"
00041 #include "settings_utils.h"
00042 #include "settings_style.h"
00043 #include "power.h"
00044 
00045 
00046 //----------------------------------------------------------------------------
00047 // Type Declarations
00048 //----------------------------------------------------------------------------
00049 
00050 typedef struct
00051 {
00052     gboolean standby_if_plugged;
00053     int minutes_standby;
00054 } PowerSettings;
00055 
00056 
00057 //----------------------------------------------------------------------------
00058 // Global Constants
00059 //----------------------------------------------------------------------------
00060 #define NUM_STANDBY_MODES   3
00061 #define NUM_STANDBY_TIMES   4 
00062 #define STANDBY_NEVER       (-1)
00063 
00064 
00065 //----------------------------------------------------------------------------
00066 // Static Variables
00067 //----------------------------------------------------------------------------
00068 
00069 static PowerSettings g_orig_power_settings;
00070 static PowerSettings g_cur_power_settings;
00071 
00072 static GtkWidget* g_power_settings_window               = NULL;
00073 static GtkWidget* g_plugged_radios[NUM_STANDBY_MODES]   = {NULL, NULL, NULL};
00074 static GtkWidget* g_standby_radios[NUM_STANDBY_TIMES]   = {NULL, NULL, NULL, NULL};
00075 
00076 static int        standby_times[NUM_STANDBY_TIMES]      = {15, 30, 45, 60}; // minutes
00077 
00078 
00079 //============================================================================
00080 // Local Function Definitions
00081 //============================================================================
00082 
00083 static GtkWidget* create_auto_shutdown_widgets  (GtkBox* parent);
00084 
00085 static void on_plugged_changed              (GtkWidget *widget, gpointer data);
00086 static void on_standby_changed              (GtkWidget *widget, gpointer data);
00087 
00088 static void greyout_radio_buttons           (GtkWidget** widget_list, 
00089                                              gboolean to_grey,
00090                                              int length );
00091 static gint read_radio_buttons              (GtkWidget** widget_list, int length);
00092 
00093 static void init_widgets_with_settings      (void);
00094 
00095 static void on_listview_row_activated       (GtkTreeView            *view,
00096                                              GtkTreePath            *path,
00097                                              GtkTreeViewColumn      *column,
00098                                              gpointer               user_data );
00099 
00100 static void on_listview_navigate_cursor     (erGtkListView          *er_listview,
00101                                              erGtkListViewKeyPress  keycode,
00102                                              gpointer               user_data );
00103 
00104 static gboolean on_focus_in                 (GtkWidget* widget, gpointer data );
00105 static gboolean on_focus_out                (GtkWidget* widget, gpointer data );
00106 
00107 
00108 //============================================================================
00109 // Functions Implementation
00110 //============================================================================
00111 
00112 void load_power_settings()
00113 {
00114     g_orig_power_settings.standby_if_plugged = get_value_bool(GCONF_STANDBY_IF_PLUGGED);
00115     g_orig_power_settings.minutes_standby    = get_value_int (GCONF_MIN_STANDBY);
00116 
00117     g_cur_power_settings = g_orig_power_settings;
00118     LOGPRINTF("Loading power settings, done.");
00119 }
00120 
00121 
00122 void save_power_settings()
00123 {
00124     if (g_cur_power_settings.standby_if_plugged != g_orig_power_settings.standby_if_plugged)
00125     {
00126         set_value_bool(GCONF_STANDBY_IF_PLUGGED, g_cur_power_settings.standby_if_plugged);
00127     }
00128 
00129     if (g_cur_power_settings.minutes_standby != g_orig_power_settings.minutes_standby)
00130     {
00131         set_value_int(GCONF_MIN_STANDBY, g_cur_power_settings.minutes_standby);
00132     }
00133 
00134     LOGPRINTF("Saving power settings, done.");
00135 }    
00136     
00137 
00138 GtkWidget* create_power_window(GtkWidget* parent)
00139 {
00140     // create top window
00141     GtkWidget* top_window = parent;
00142     gtk_window_maximize(GTK_WINDOW(top_window));
00143     gtk_window_set_resizable(GTK_WINDOW(top_window), FALSE);
00144     gtk_container_set_border_width(GTK_CONTAINER(top_window),WINDOW_BORDER_PADDING  );
00145     gtk_window_set_modal(GTK_WINDOW(top_window), TRUE);
00146 
00147     // top level vbox (vboxtop)
00148     GtkWidget* vboxtop = gtk_vbox_new(FALSE, 0);
00149     gtk_container_add(GTK_CONTAINER(top_window), vboxtop);
00150 
00151     // add header container the title and subtitle of this settings page
00152     create_title(GTK_VBOX(vboxtop), _("Settings"), _("Power Management"));
00153     
00154     // add the back/exit bar below the title 
00155     GtkWidget* view = create_settingsview();
00156     gtk_box_pack_start(GTK_BOX(vboxtop), view, FALSE, FALSE, 0); 
00157     g_signal_connect(view, "row-activated", G_CALLBACK(on_listview_row_activated), NULL ) ;
00158     g_signal_connect(view, "navigate-cursor", G_CALLBACK(on_listview_navigate_cursor), NULL ) ;
00159     g_signal_connect(view, "focus-in-event", G_CALLBACK(on_focus_in), NULL );
00160     g_signal_connect(view, "focus-out-event", G_CALLBACK(on_focus_out), NULL );
00161  
00162     GtkWidget* vbox = GTK_WIDGET( create_frame(GTK_VBOX(vboxtop)) );
00163     create_auto_shutdown_widgets(GTK_BOX(vbox));
00164 
00165 
00166     // Update widget with current settings.
00167     init_widgets_with_settings();
00168 
00169     g_power_settings_window = top_window;
00170 
00171     gtk_widget_grab_focus(view);
00172 
00173     gtk_widget_show_all(top_window);
00174     return top_window;
00175 }
00176 
00177 
00178 //============================================================================
00179 // Local Functions Implementation
00180 //============================================================================
00181 
00182 static gboolean on_focus_in(GtkWidget* widget, gpointer data )
00183 {
00184     g_assert(widget != NULL ) ;
00185     ergtk_list_view_set_cursor( ERGTK_LIST_VIEW(widget), 0); // row = 0;
00186     return FALSE;
00187 }
00188 
00189 
00190 static gboolean on_focus_out(GtkWidget* widget, gpointer data )
00191 {
00192     g_assert(widget != NULL ) ;
00193     GtkTreeSelection* my_selection = gtk_tree_view_get_selection((GtkTreeView*) widget);
00194     g_assert( my_selection != NULL ) ;
00195     gtk_tree_selection_unselect_all(my_selection);
00196     return FALSE;
00197 }
00198 
00199 
00200 static void on_listview_row_activated ( GtkTreeView       *view,
00201                                         GtkTreePath       *path,
00202                                         GtkTreeViewColumn *column,
00203                                         gpointer          user_data )
00204 {
00205     save_power_settings();
00206     main_quit();
00207 
00208     return;
00209 }
00210 
00211 
00212 static void on_listview_navigate_cursor ( erGtkListView         *er_listview,
00213                                           erGtkListViewKeyPress keycode,
00214                                           gpointer              user_data )
00215 {
00216     GtkTreeSelection* my_selection = gtk_tree_view_get_selection((GtkTreeView*) er_listview);
00217     g_assert( my_selection != NULL ) ;
00218 
00219     // determine new cursor position
00220     switch (keycode)
00221     {
00222         case ERGTK_LIST_VIEW_PRESS_SHORT_DOWN:
00223         case ERGTK_LIST_VIEW_PRESS_LONG_DOWN:
00224             gtk_widget_grab_focus(GTK_WIDGET(g_plugged_radios[0])); // down: to first widget
00225             gtk_tree_selection_unselect_all(my_selection);
00226             break;
00227         default:
00228             LOGPRINTF("illegal erGtkListViewKeyPress [%d]", keycode);
00229             ;  // ignore
00230             break;
00231     }
00232 }
00233 
00234 
00235 // Widget Hierarchy
00236 // |--Top Level vbox
00237 //    |--title   ("Automatic shutdown")
00238 //    |--subject ("To save power...")
00239 //    |--vbox
00240 //       |--radio never
00241 //       |--radio on
00242 //       |--radio off
00243 //    |--label ("Choose the automatic shutdown time")
00244 //    |--vbox
00245 //       |--radio 15
00246 //       |--radio 30
00247 //       |--radio 45
00248 //       |--radio 60
00249 static GtkWidget* create_auto_shutdown_widgets(GtkBox* parent)
00250 {
00251     // Top level vbox.
00252     GtkWidget* top_level_vbox = gtk_vbox_new(FALSE, ITEM_SPACING);
00253     gtk_box_pack_start(parent, top_level_vbox, FALSE, FALSE, 0);
00254 
00255     // Subject "Automatic Shutdown".
00256     GtkWidget* subject = subject_create();
00257     gtk_label_set_label(GTK_LABEL(subject), _("Automatic Shutdown") );
00258     gtk_box_pack_start(GTK_BOX(top_level_vbox), subject, FALSE, FALSE, 0);
00259 
00260     // Description "To save power..."
00261     GtkWidget* desc = description_create();
00262     gtk_label_set_label(GTK_LABEL(desc), _("To save power, automatic shutdown can be enabled.") );    
00263     gtk_box_pack_start(GTK_BOX(top_level_vbox), desc, FALSE, FALSE, 0);
00264         
00265     // The vbox containing radio buttons for plugged.
00266     GtkWidget* vbox = gtk_vbox_new(TRUE, 0);
00267     gtk_box_pack_start(GTK_BOX(top_level_vbox), vbox, FALSE, FALSE, 0);
00268     
00269     int i = 0;
00270     for (i=0; i<NUM_STANDBY_MODES; i++)
00271     {
00272         switch (i)
00273         {
00274             case 0:
00275             {
00276                 // the radio button "Never"
00277                 g_plugged_radios[i] = gtk_radio_button_new_with_label(NULL, _("Never use automatic shutdown"));
00278                 break;
00279             }
00280             case 1:
00281             {
00282                 // The radio button "Always".
00283                 g_plugged_radios[i] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(g_plugged_radios[0]), _("Always use automatic shutdown"));
00284                 break;
00285             }
00286             case 2:
00287             {
00288                 // The radio button "Only when running on battery".
00289                 g_plugged_radios[i] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(g_plugged_radios[1]), _("Only use automatic shutdown when running on battery"));
00290                 break;
00291             }
00292             default:
00293             {
00294                 // never happens
00295                 break;
00296             }
00297         }
00298 
00299         // Add signal handler.
00300         g_signal_connect_after(G_OBJECT(g_plugged_radios[i]),
00301             "toggled",
00302             G_CALLBACK(on_plugged_changed),
00303             (gpointer)i);
00304 
00305         gtk_box_pack_start(GTK_BOX(vbox), g_plugged_radios[i], FALSE, FALSE, 0);
00306 
00307     }
00308 
00309     // Subject "Choose the automatic shutdown time".
00310     GtkWidget* choose = description_create(NULL);
00311     gtk_label_set_label(GTK_LABEL(choose), _("Choose the automatic shutdown time:"));
00312     gtk_box_pack_start(GTK_BOX(top_level_vbox), choose, FALSE, FALSE, 0);
00313 
00314     // The vbox containing radio buttons for minutes.
00315     vbox = gtk_vbox_new(TRUE, 0);
00316     gtk_box_pack_start(GTK_BOX(top_level_vbox), vbox, FALSE, FALSE, 0);
00317 
00318     for (i = 0; i < NUM_STANDBY_TIMES; i++)
00319     {
00320         // The radio button "after ...".
00321         // TRANSLATORS: this is an ngettext(3) call which needs a singular and plural translation
00322         gchar* name = g_strdup_printf(ngettext("after %d minute", "after %d minutes", standby_times[i]), standby_times[i]);
00323         if (i == 0)
00324         {
00325             g_standby_radios[i] = gtk_radio_button_new_with_label(NULL, name);
00326         }
00327         else 
00328         {
00329             g_standby_radios[i] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(g_standby_radios[0]), name);
00330         }
00331         g_free(name);
00332 
00333         // Add signal handler.
00334         g_signal_connect_after(G_OBJECT(g_standby_radios[i]),
00335             "toggled",
00336             G_CALLBACK(on_standby_changed),
00337             (gpointer)i);
00338 
00339         gtk_box_pack_start(GTK_BOX(vbox), g_standby_radios[i], FALSE, FALSE, 0);
00340     }
00341 
00342     return top_level_vbox;
00343 }
00344 
00345 
00346 static void on_plugged_changed(GtkWidget *widget, gpointer data)
00347 {
00348     int index = (int)data;
00349     gboolean is_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
00350 
00351     if (is_active == TRUE )
00352     {
00353         switch (index)
00354         {
00355             case 0:
00356             {
00357                 g_cur_power_settings.minutes_standby = STANDBY_NEVER ; // -1 indicates never
00358                 break;
00359             }
00360             case 1:
00361             {
00362                 g_cur_power_settings.standby_if_plugged =  TRUE;
00363                 break;
00364             }
00365             case 2:
00366             {
00367                 g_cur_power_settings.standby_if_plugged =  FALSE;
00368             }
00369             default:
00370                 break;
00371         }
00372         
00373         // minutes
00374         if (index == 0)
00375         {
00376             // greyout minutes
00377             greyout_radio_buttons(g_standby_radios, TRUE, NUM_STANDBY_TIMES);
00378         }
00379         else
00380         {
00381             // restore minutes (or read minutes buttons)
00382             g_cur_power_settings.minutes_standby = 
00383                 standby_times[read_radio_buttons(g_standby_radios, NUM_STANDBY_TIMES)];
00384             
00385             // ungreyout minutes
00386             if ( ! GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(g_standby_radios[0])))
00387             {
00388                 greyout_radio_buttons(g_standby_radios, FALSE, NUM_STANDBY_TIMES);
00389             }
00390         }
00391     }
00392 }
00393 
00394 
00395 static void on_standby_changed(GtkWidget *widget, gpointer data)
00396 {
00397     int index = (int)data;
00398     g_cur_power_settings.minutes_standby = standby_times[index];
00399 }
00400 
00401 
00402 static void greyout_radio_buttons(GtkWidget** widget_list, gboolean to_grey, int length )
00403 {
00404     int i = 0;
00405     for ( i = 0; i < length; i++ )
00406     {
00407         gtk_widget_set_sensitive(widget_list[i], !to_grey);  // to_grey means set to insensitive
00408     }
00409 }
00410 
00411 static gint read_radio_buttons(GtkWidget** widget_list, int length)
00412 {
00413     int i = 0;
00414     for ( i = 0; i < length; i++ )
00415     {
00416         if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget_list[i])) ) 
00417             break; 
00418     }
00419     return i;
00420 }
00421 
00422 static void init_widgets_with_settings()
00423 {
00424     int i;
00425     int to_be_activated = 0;
00426 
00427     //Note: first minutes radiobutton, then plugged radiobutton, because of depencency and callbacks
00428     
00429     //minutes
00430     for (i = 0; i < NUM_STANDBY_TIMES; i++)
00431     {
00432         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_standby_radios[i]), 
00433                 (standby_times[i]==g_cur_power_settings.minutes_standby));
00434     }
00435     
00436     // plugged
00437     if ( STANDBY_NEVER == g_cur_power_settings.minutes_standby )
00438     {
00439         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_plugged_radios[0]), TRUE);
00440         greyout_radio_buttons(g_standby_radios, TRUE, NUM_STANDBY_TIMES);
00441     }
00442     else 
00443     {
00444         to_be_activated = g_cur_power_settings.standby_if_plugged == TRUE ? 1 : 2;
00445 
00446         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_plugged_radios[to_be_activated]),
00447                                  TRUE);
00448     }
00449 }
Generated by  doxygen 1.6.2-20100208