Implement more functionality:
[stopish] / src / stopish.c
1 //      stopish.c
2 //
3 //      Copyright 2009 Michael Cronenworth <mike@cchtml.com>
4 //
5 //      This program is free software; you can redistribute it and/or modify
6 //      it under the terms of the GNU General Public License as published by
7 //      the Free Software Foundation; either version 2 of the License, or
8 //      (at your option) any later version.
9 //
10 //      This program is distributed in the hope that it will be useful,
11 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //      GNU General Public License for more details.
14 //
15 //      You should have received a copy of the GNU General Public License
16 //      along with this program; if not, write to the Free Software
17 //      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 //      MA 02110-1301, USA.
19
20 #include <string.h>
21 #include <stdlib.h>
22 #include <sys/time.h>
23 #include <gtk/gtk.h>
24 #include <libosso.h>
25
26 #include "stopish.h"
27
28 static GtkWidget *timerLabel = NULL;
29 static GtkWidget *timerHistoryLabel1 = NULL;
30 static GtkWidget *timerHistoryLabel2 = NULL;
31 static GtkWidget *timerHistoryLabel3 = NULL;
32 static GSList *historyList = NULL;
33 static int stopishMode = STOPISH_MODE_START;
34 static int timerHandle = -1;
35
36 //Prototypes
37 gint dbus_callback( const gchar *interface, const gchar *method,
38                         GArray *arguments, gpointer data, osso_rpc_t *retval );
39 static GtkWindow *stopish_new( void );
40 static void start_cb( GtkButton* button, gpointer data );
41 static void reset_cb( GtkButton* button, gpointer data );
42 static void close_cb( GtkButton* button, gpointer data );
43
44
45 int main( int argc, char *argv[] )
46 {
47     osso_context_t *ctxt;
48     osso_return_t ret;
49     GtkWindow *window;
50
51     //printf( "stopish: starting up\n" );
52
53     ctxt = osso_initialize( "com.nokia.stopish", PACKAGE_VERSION, TRUE, NULL );
54     if ( ctxt == NULL ) {
55         fprintf( stderr, "osso_initialize failed.\n" );
56         exit( 1 );
57     }
58
59     gtk_init( &argc, &argv );
60
61     window = stopish_new(  );
62
63     ret = osso_rpc_set_default_cb_f( ctxt, dbus_callback, window );
64     if ( ret != OSSO_OK ) {
65         fprintf( stderr, "osso_rpc_set_default_cb_f failed: %d.\n", ret );
66         exit( 1 );
67     }
68
69     gtk_main(  );
70
71     return 0;
72 }
73
74
75 gint dbus_callback( const gchar *interface, const gchar *method,
76                     GArray *arguments, gpointer data, osso_rpc_t *retval )
77 {
78     //printf( "stopish dbus: %s, %s\n", interface, method );
79
80     if ( !strcmp( method, "top_application" ) )
81         gtk_window_present( GTK_WINDOW( data ) );
82
83     retval->type = DBUS_TYPE_INVALID;
84
85     return OSSO_OK;
86 }
87
88
89 int stopish_get_mode( void )
90 {
91     return stopishMode;
92 }
93
94
95 static GtkWindow *stopish_new( void )
96 {
97     GtkWidget *window, *hBox, *label, *button, *button0;
98     GtkWidget *vBox, *vBox0, *vBox1;
99
100     window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
101
102     gtk_container_set_border_width( GTK_CONTAINER( window ), 20 );
103
104     gtk_window_set_title( GTK_WINDOW( window ), "Stopish" );
105
106     g_signal_connect( G_OBJECT( window ), "destroy",
107                       G_CALLBACK( close_cb ), window );
108
109     vBox = gtk_vbox_new( FALSE, 20 );
110
111     label = gtk_label_new( "Stopish - The Stopwatch" );
112     gtk_box_pack_start( GTK_BOX( vBox ), label, FALSE, FALSE, 0 );
113
114     hBox = gtk_hbox_new( FALSE, 10 );
115
116     // stop watch area
117     vBox0 = gtk_vbox_new( FALSE, 5 );
118     gtk_widget_set_size_request( vBox0, 250, -1 );
119
120     // main timer
121     timerLabel = gtk_label_new( NULL );
122     gtk_label_set_markup( GTK_LABEL( timerLabel ),
123                           "<span font_family=\"monospace\" size=\"xx-large\">00:00:00.0</span>" );
124     gtk_container_add( GTK_CONTAINER( vBox0 ), timerLabel );
125
126     // history area
127     timerHistoryLabel1 = gtk_label_new( NULL );
128     gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel1, FALSE, FALSE, 0 );
129     timerHistoryLabel2 = gtk_label_new( NULL );
130     gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel2, FALSE, FALSE, 0 );
131     timerHistoryLabel3 = gtk_label_new( NULL );
132     gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel3, FALSE, FALSE, 0 );
133     label = gtk_label_new( NULL );
134     gtk_container_add( GTK_CONTAINER( vBox0 ), label );
135
136     gtk_container_add( GTK_CONTAINER( hBox ), vBox0 );
137
138     // button area
139     vBox1 = gtk_vbox_new( FALSE, 15 );
140     gtk_widget_set_size_request( vBox1, 200, -1 );
141
142     // start/pause stopwatch button
143     button = gtk_button_new_with_label( "Start" );
144     button0 = gtk_button_new_with_label( "Reset" );
145     gtk_widget_set_size_request( button, -1, 60 );
146     g_signal_connect( G_OBJECT( button ), "clicked",
147                       G_CALLBACK( start_cb ), button0 );
148     gtk_box_pack_start( GTK_BOX( vBox1 ), button, FALSE, FALSE, 0 );
149
150     // reset button
151     gtk_widget_set_sensitive( button0, FALSE );
152     gtk_widget_set_size_request( button0, -1, 60 );
153     g_signal_connect( G_OBJECT( button0 ), "clicked",
154                       G_CALLBACK( reset_cb ), button );
155     gtk_box_pack_start( GTK_BOX( vBox1 ), button0, FALSE, FALSE, 0 );
156
157     gtk_container_add( GTK_CONTAINER( hBox ), vBox1 );
158
159     gtk_container_add( GTK_CONTAINER( vBox ), hBox );
160
161     gtk_container_add( GTK_CONTAINER( window ), vBox );
162
163     gtk_widget_show_all( window );
164
165     return GTK_WINDOW( window );
166 }
167
168
169 static void start_cb( GtkButton* button, gpointer data )
170 {
171     if ( stopishMode == STOPISH_MODE_START ) {
172         // set label text and add timer handle
173         gtk_button_set_label( button, "Pause" );
174         stopishMode = STOPISH_MODE_PAUSE;
175         stopish_set_time_start( stopish_current_time(  ) );
176         timerHandle = g_timeout_add( 100, stopish_timeout_cb, timerLabel );
177     }
178     else if ( stopishMode == STOPISH_MODE_RESUME ) {
179         // resume timer
180         gtk_button_set_label( button, "Pause" );
181         stopishMode = STOPISH_MODE_PAUSE;
182         stopish_timer_resume(  );
183         timerHandle = g_timeout_add( 100, stopish_timeout_cb, timerLabel );
184     }
185     else {
186         // pause timer, remove timeout
187         gtk_button_set_label( button, "Resume" );
188         stopishMode = STOPISH_MODE_RESUME;
189         g_source_remove( timerHandle );
190         stopish_timer_save(  );
191     }
192
193     // allow user to reset timer
194     gtk_widget_set_sensitive( GTK_WIDGET( data ), TRUE );
195 }
196
197
198 static void reset_cb( GtkButton* button, gpointer data )
199 {
200     GSList *tempList;
201     char *tempString;
202
203     if ( stopishMode == STOPISH_MODE_RESUME )
204         stopish_timer_resume(  );
205
206     // set label text and remove timer handle
207     gtk_button_set_label( GTK_BUTTON( data ), "Start" );
208     stopishMode = STOPISH_MODE_START;
209     gtk_label_set_markup( GTK_LABEL( timerLabel ),
210                           "<span font_family=\"monospace\" size=\"xx-large\">00:00:00.0</span>" );
211     g_source_remove( timerHandle );
212
213     // add current time to history
214     historyList = g_slist_prepend( historyList,
215                                    ( gpointer ) stopish_get_time_string(  ) );
216     gtk_label_set_text( GTK_LABEL( timerHistoryLabel1 ),
217                         ( char * ) historyList->data );
218     tempList = historyList;
219     tempList = g_slist_next( tempList );
220     if ( tempList )
221         gtk_label_set_text( GTK_LABEL( timerHistoryLabel2 ),
222                             ( char * ) tempList->data );
223     tempList = g_slist_next( tempList );
224     if ( tempList )
225         gtk_label_set_text( GTK_LABEL( timerHistoryLabel3 ),
226                             ( char * ) tempList->data );
227
228     // remove the history time after the 3rd
229     tempList = g_slist_next( tempList );
230     if ( tempList ) {
231         tempString = tempList->data;
232         historyList = g_slist_remove( historyList, tempList->data );
233         free( tempString );
234     }
235
236     // reset start time
237     stopish_set_time_start( 0 );
238
239     // disallow user to reset timer
240     gtk_widget_set_sensitive( GTK_WIDGET( button ), FALSE );
241 }
242
243
244 static void close_cb( GtkButton* button, gpointer data )
245 {
246     // destroy main window and exit gtk main loop
247     gtk_widget_destroy( GTK_WIDGET( data ) );
248     gtk_main_quit(  );
249 }