5
* (C) 1999 Craig Knudsen, cknudsen@cknudsen.com
6
* See accompanying file "COPYING".
8
* This program is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU General Public License
10
* as published by the Free Software Foundation; either version 2
11
* of the License, or (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the
20
* Free Software Foundation, Inc., 59 Temple Place,
21
* Suite 330, Boston, MA 02111-1307, USA
24
* Helps you keep track of time spent on different tasks.
27
* Craig Knudsen, cknudsen@cknudsen.com, http://www.cknudsen.com
30
* http://www.cknudsen.com/gtimer/
33
* 17-Apr-2005 Added configurability of the browser. (Russ Allbery)
34
* 28-Feb-2003 Added project create/edit window.
35
* 21-Feb-2003 Added project pulldown in task create/edit.
36
* 30-Apr-1999 Fixed bug where \n chars could be included at the
37
* end of a task name (which would screw up the task
38
* data file format and make the task unreachable).
39
* 25-Mar-1999 Fixed bug where adding new tasks messes up the
41
* 18-Mar-1999 Internationalization
42
* 18-Mar-1998 Added calls to gtk_window_set_wmclass so the windows
43
* behave better for window managers.
46
****************************************************************************/
65
#ifdef GTIMER_MEMDEBUG
66
#include "memdebug/memdebug.h"
69
extern TaskData **visible_tasks;
70
extern int num_visible_tasks;
71
extern TaskData **tasks;
73
extern GtkWidget *status;
85
GtkWidget *projectMenu;
94
static void ok_project_callback ( widget, data )
98
ProjectEditData *ed = (ProjectEditData *) data;
101
GtkWidget *item = NULL;
102
int project_updated = 0, loop;
104
/* Update existing project */
106
str = gtk_entry_get_text ( GTK_ENTRY(ed->name) );
107
if ( strcmp ( str, ed->p->name ) ) {
108
free ( ed->p->name );
109
/* remove trailing white space */
110
for ( ptr = str + strlen ( str ) - 1; isspace ( *ptr ) && ptr > str;
113
ed->p->name = (char *) malloc ( strlen ( str ) + 1 );
114
strcpy ( ed->p->name, str );
117
showMessage ( gettext("Project updated") );
122
p = (Project *) malloc ( sizeof ( Project ) );
123
memset ( p, '\0', sizeof ( Project ) );
124
str = gtk_entry_get_text ( GTK_ENTRY(ed->name) );
125
/* remove trailing white space */
126
ptr = (char *) malloc ( strlen ( str ) + 1 );
129
for ( ptr = str + strlen ( str ) - 1; isspace ( *ptr ) && ptr > str;
132
p = projectCreate ( str );
134
showMessage ( gettext("Project added") );
137
/* redraw the task list only if we changed a project name */
138
if ( project_updated ) {
139
for ( loop = 0; ed->p && loop < num_visible_tasks; loop++ ) {
140
if ( visible_tasks[loop]->task->project_id == ed->p->number ) {
141
visible_tasks[loop]->name_updated = 1;
142
visible_tasks[loop]->project_name = ed->p->name;
148
gtk_grab_remove ( ed->window );
149
gtk_widget_destroy ( ed->window );
155
static void cancel_project_callback ( widget, data )
159
ProjectEditData *ed = (ProjectEditData *) data;
160
gtk_grab_remove ( ed->window );
161
gtk_widget_destroy ( ed->window );
169
** Create the add/edit project window.
170
** It's an add if project is NULL.
172
GtkWidget *create_project_edit_window ( project )
175
GtkWidget *edit_window;
177
/*GtkTooltips *tooltips;*/
178
GtkWidget *label, *name_text, *ok_button, *cancel_button;
179
GtkWidget *option, *option_menu, *menuitem;
181
char msg[100], *ptr = NULL;
183
ed = (ProjectEditData *) malloc ( sizeof ( ProjectEditData ) );
184
memset ( ed, 0, sizeof ( ProjectEditData ) );
186
ed->window = edit_window = gtk_dialog_new ();
187
gtk_window_set_wmclass ( GTK_WINDOW ( ed->window ), "GTimer", "gtimer" );
189
sprintf ( msg, "GTimer: %s", gettext ("Edit Project") );
191
sprintf ( msg, "GTimer: %s", gettext ("Add Project") );
192
gtk_window_set_title (GTK_WINDOW (edit_window), msg );
193
gtk_window_position ( GTK_WINDOW(edit_window), GTK_WIN_POS_MOUSE );
194
gtk_grab_add ( edit_window );
195
gtk_widget_realize ( edit_window );
197
table = gtk_table_new (1, 3, FALSE);
198
gtk_table_set_row_spacings (GTK_TABLE (table), 4);
199
gtk_table_set_col_spacings (GTK_TABLE (table), 8);
200
gtk_container_border_width (GTK_CONTAINER (table), 6);
201
gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG (edit_window)->vbox ),
202
table, TRUE, FALSE, 5 );
204
sprintf ( msg, "%s: ", gettext ( "Project name" ) );
205
label = gtk_label_new ( msg );
206
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
207
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
208
0, 1, GTK_FILL, GTK_FILL, 0, 0);
209
gtk_widget_show ( label );
211
ed->name = name_text = gtk_entry_new ();
212
gtk_table_attach_defaults (GTK_TABLE (table), name_text, 1, 3,
215
gtk_entry_set_text ( GTK_ENTRY(name_text),
218
gtk_entry_set_text ( GTK_ENTRY(name_text), gettext ("Unnamed Project") );
219
gtk_entry_select_region ( GTK_ENTRY(name_text), 0,
220
strlen ( gettext ("Unnamed Project") ) );
222
gtk_window_set_focus ( >K_DIALOG ( edit_window )->window,
224
gtk_widget_show ( name_text );
226
gtk_widget_show ( table );
228
/* add command buttons */
229
/*tooltips = gtk_tooltips_new ();*/
231
ok_button = gtk_button_new_with_label ( gettext("Ok") );
232
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (edit_window)->action_area),
233
ok_button, TRUE, TRUE, 5);
234
gtk_signal_connect (GTK_OBJECT (ok_button), "clicked",
235
GTK_SIGNAL_FUNC (ok_project_callback), ed);
236
GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
237
gtk_widget_grab_default (ok_button);
238
gtk_widget_show (ok_button);
239
/*gtk_tooltips_set_tips (tooltips, ok_button,
240
"Save this task" );*/
242
cancel_button = gtk_button_new_with_label ( gettext("Cancel") );
243
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (edit_window)->action_area),
244
cancel_button, TRUE, TRUE, 5);
245
gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked",
246
GTK_SIGNAL_FUNC (cancel_project_callback), ed);
247
gtk_widget_show (cancel_button);
248
/*gtk_tooltips_set_tips (tooltips, cancel_button,
249
"Edit the selected task" );*/
252
gtk_widget_show (hbox);
253
gtk_widget_show (vbox);
255
gtk_widget_show (edit_window);
257
return ( edit_window );
262
static int getMenuSelectionIndex ( GtkWidget *w )
266
GtkMenuShell *menu_shell;
269
menu_shell = GTK_MENU_SHELL ( gtk_option_menu_get_menu (
270
GTK_OPTION_MENU( w) ) );
271
child = menu_shell->children;
273
bin = GTK_BIN ( child->data );
283
static void ok_task_callback ( widget, data )
287
TaskEditData *ed = (TaskEditData *) data;
290
GtkWidget *item = NULL;
291
Project *p = NULL, *selp = NULL;
292
int cnt, loop, new_project_id;
294
/* Determine project */
295
if ( ed->projectMenu ) {
296
cnt = getMenuSelectionIndex ( ed->projectMenu );
297
for ( loop = 0, p = projectGetFirst(); p != NULL && selp == NULL;
298
p = projectGetNext(), loop++ ) {
299
if ( loop + 1 == cnt ) {
305
/* Update existing task */
306
if ( ed->taskdata ) {
307
str = gtk_entry_get_text ( GTK_ENTRY(ed->name) );
308
if ( strcmp ( str, ed->taskdata->task->name ) ) {
309
free ( ed->taskdata->task->name );
310
/* remove trailing white space */
311
for ( ptr = str + strlen ( str ) - 1; isspace ( *ptr ) && ptr > str;
314
ed->taskdata->task->name = (char *) malloc ( strlen ( str ) + 1 );
315
strcpy ( ed->taskdata->task->name, str );
316
ed->taskdata->name_updated = 1;
318
if ( ed->projectMenu ) {
319
new_project_id = selp ? selp->number : -1;
320
if ( ed->taskdata->task->project_id != new_project_id ) {
322
ed->taskdata->task->project_id = -1; /* none */
324
ed->taskdata->task->project_id = selp->number;
325
ed->taskdata->name_updated = 1;
326
ed->taskdata->project_name = selp ? selp->name : "";
329
showMessage ( gettext("Task updated") );
334
td = (TaskData *) malloc ( sizeof ( TaskData ) );
335
memset ( td, '\0', sizeof ( TaskData ) );
337
str = gtk_entry_get_text ( GTK_ENTRY(ed->name) );
338
/* remove trailing white space */
339
ptr = (char *) malloc ( strlen ( str ) + 1 );
342
for ( ptr = str + strlen ( str ) - 1; isspace ( *ptr ) && ptr > str;
345
td->task = taskCreate ( str );
346
taskAdd ( td->task );
347
tasks = (TaskData **) realloc ( tasks,
348
( num_tasks + 1 ) * sizeof ( TaskData * ) );
349
tasks[num_tasks] = td;
350
visible_tasks = (TaskData **) realloc ( visible_tasks,
351
( num_visible_tasks + 1 ) * sizeof ( TaskData * ) );
352
visible_tasks[num_visible_tasks] = td;
355
new_project_id = selp ? selp->number : -1;
356
td->task->project_id = new_project_id;
357
td->project_name = selp ? selp->name : "";
358
showMessage ( gettext("Task updated") );
361
gtk_grab_remove ( ed->window );
362
gtk_widget_destroy ( ed->window );
365
/* redraw the task list */
370
static void cancel_task_callback ( widget, data )
374
TaskEditData *ed = (TaskEditData *) data;
375
gtk_grab_remove ( ed->window );
376
gtk_widget_destroy ( ed->window );
384
** Create the add/edit window.
385
** It's an add if taskdata is NULL.
387
GtkWidget *create_task_edit_window ( taskdata )
390
GtkWidget *edit_window;
392
/*GtkTooltips *tooltips;*/
393
GtkWidget *label, *name_text, *ok_button, *cancel_button;
394
GtkWidget *option, *option_menu, *menuitem;
396
char msg[100], *ptr = NULL;
397
int use_project, loop, selitem;
400
ed = (TaskEditData *) malloc ( sizeof ( TaskEditData ) );
401
memset ( ed, 0, sizeof ( TaskEditData ) );
402
ed->taskdata = taskdata;
403
ed->window = edit_window = gtk_dialog_new ();
404
gtk_window_set_wmclass ( GTK_WINDOW ( ed->window ), "GTimer", "gtimer" );
406
sprintf ( msg, "GTimer: %s", gettext ("Edit Task") );
408
sprintf ( msg, "GTimer: %s", gettext ("Add Task") );
409
gtk_window_set_title (GTK_WINDOW (edit_window), msg );
410
gtk_window_position ( GTK_WINDOW(edit_window), GTK_WIN_POS_MOUSE );
411
gtk_grab_add ( edit_window );
412
gtk_widget_realize ( edit_window );
415
if ( configGetAttribute ( CONFIG_USE_PROJECTS, &ptr ) == 0 &&
416
ptr && ptr[0] == '1' )
419
table = gtk_table_new (1, use_project ? 4 : 3, FALSE);
420
gtk_table_set_row_spacings (GTK_TABLE (table), 4);
421
gtk_table_set_col_spacings (GTK_TABLE (table), 8);
422
gtk_container_border_width (GTK_CONTAINER (table), 6);
423
gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG (edit_window)->vbox ),
424
table, TRUE, FALSE, 5 );
427
sprintf ( msg, "%s: ", gettext ( "Project " ) );
428
label = gtk_label_new ( msg );
429
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
430
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
431
GTK_FILL, GTK_FILL, 0, 0);
432
gtk_widget_show ( label );
434
option = gtk_option_menu_new ();
435
gtk_widget_show ( option );
436
gtk_table_attach_defaults ( GTK_TABLE (table), option, 1, 3, 0, 1);
438
option_menu = gtk_menu_new ();
440
menuitem = gtk_menu_item_new_with_label ( "None" );
441
gtk_menu_append ( GTK_MENU ( option_menu ), menuitem );
442
gtk_widget_show ( menuitem );
446
for ( p = projectGetFirst(); p != NULL; p = projectGetNext(), loop++ ) {
447
menuitem = gtk_menu_item_new_with_label ( p->name );
448
gtk_menu_append ( GTK_MENU ( option_menu ), menuitem );
449
gtk_widget_show ( menuitem );
450
gtk_object_set_data ( GTK_OBJECT ( menuitem ), "Project", p );
451
if ( taskdata && taskdata->task->project_id == p->number )
454
gtk_option_menu_set_menu ( GTK_OPTION_MENU ( option ), option_menu );
456
gtk_option_menu_set_history ( GTK_OPTION_MENU ( option ), selitem );
457
ed->projectMenu = option;
460
sprintf ( msg, "%s: ", gettext ( "Task name" ) );
461
label = gtk_label_new ( msg );
462
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
463
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
464
0 + use_project, 1 + use_project,
465
GTK_FILL, GTK_FILL, 0, 0);
466
gtk_widget_show ( label );
468
ed->name = name_text = gtk_entry_new ();
469
gtk_table_attach_defaults (GTK_TABLE (table), name_text, 1, 3,
470
0 + use_project, 1 + use_project);
472
gtk_entry_set_text ( GTK_ENTRY(name_text),
473
taskdata->task->name );
475
gtk_entry_set_text ( GTK_ENTRY(name_text), gettext ("Unnamed Task") );
476
gtk_entry_select_region ( GTK_ENTRY(name_text), 0,
477
strlen ( gettext ("Unnamed Task") ) );
479
gtk_window_set_focus ( >K_DIALOG ( edit_window )->window,
481
gtk_widget_show ( name_text );
483
gtk_widget_show ( table );
485
/* add command buttons */
486
/*tooltips = gtk_tooltips_new ();*/
488
ok_button = gtk_button_new_with_label ( gettext("Ok") );
489
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (edit_window)->action_area),
490
ok_button, TRUE, TRUE, 5);
491
gtk_signal_connect (GTK_OBJECT (ok_button), "clicked",
492
GTK_SIGNAL_FUNC (ok_task_callback), ed);
493
GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
494
gtk_widget_grab_default (ok_button);
495
gtk_widget_show (ok_button);
496
/*gtk_tooltips_set_tips (tooltips, ok_button,
497
"Save this task" );*/
499
cancel_button = gtk_button_new_with_label ( gettext("Cancel") );
500
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (edit_window)->action_area),
501
cancel_button, TRUE, TRUE, 5);
502
gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked",
503
GTK_SIGNAL_FUNC (cancel_task_callback), ed);
504
gtk_widget_show (cancel_button);
505
/*gtk_tooltips_set_tips (tooltips, cancel_button,
506
"Edit the selected task" );*/
509
gtk_widget_show (hbox);
510
gtk_widget_show (vbox);
512
gtk_widget_show (edit_window);
514
return ( edit_window );
519
static void ok_browser_callback ( widget, data )
523
BrowserEditData *ed = (BrowserEditData *) data;
526
browser = gtk_entry_get_text ( GTK_ENTRY(ed->name) );
527
configSetAttribute ( CONFIG_BROWSER, browser );
528
gtk_grab_remove ( ed->window );
529
gtk_widget_destroy ( ed->window );
534
static void cancel_browser_callback ( widget, data )
538
BrowserEditData *ed = (BrowserEditData *) data;
539
gtk_grab_remove ( ed->window );
540
gtk_widget_destroy ( ed->window );
545
** Create the add/edit browser window.
547
GtkWidget *create_browser_edit_window ()
549
GtkWidget *browser_window;
551
GtkWidget *info, *label, *name_text, *ok_button, *cancel_button;
553
char msg[500], *browser;
555
ed = (BrowserEditData *) malloc ( sizeof ( BrowserEditData ) );
556
memset ( ed, 0, sizeof ( BrowserEditData ) );
557
ed->window = browser_window = gtk_dialog_new ();
558
gtk_window_set_wmclass ( GTK_WINDOW ( ed->window ), "GTimer", "gtimer" );
559
sprintf ( msg, "GTimer: %s", gettext ("Change Browser") );
560
gtk_window_set_title ( GTK_WINDOW ( browser_window ), msg );
561
gtk_window_position ( GTK_WINDOW ( browser_window ), GTK_WIN_POS_MOUSE );
562
gtk_grab_add ( browser_window );
563
gtk_widget_realize ( browser_window );
565
sprintf ( msg, "%s", "The string \"%s\" in this command, if present, will"
566
" be replaced with the URL to open; otherwise, the URL will be added to"
567
" the end of the command.");
568
info = gtk_label_new ( msg );
569
gtk_label_set_line_wrap ( GTK_LABEL (info), 1 );
570
gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG (browser_window)->vbox ),
571
info, TRUE, FALSE, 5 );
573
table = gtk_table_new ( 1, 3, FALSE );
574
gtk_table_set_row_spacings ( GTK_TABLE (table), 4 );
575
gtk_table_set_col_spacings ( GTK_TABLE (table), 8 );
576
gtk_container_border_width ( GTK_CONTAINER (table), 6 );
577
gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG (browser_window)->vbox ),
578
table, TRUE, FALSE, 5 );
580
sprintf ( msg, "%s: ", gettext ( "Command" ) );
581
label = gtk_label_new ( msg );
582
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
583
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
584
0, 1, GTK_FILL, GTK_FILL, 0, 0);
586
ed->name = name_text = gtk_entry_new ();
587
gtk_table_attach_defaults (GTK_TABLE (table), name_text, 1, 3,
589
if ( configGetAttribute ( CONFIG_BROWSER, &browser ) == 0 )
590
gtk_entry_set_text ( GTK_ENTRY(name_text), browser );
592
gtk_entry_set_text ( GTK_ENTRY(name_text),
593
"mozilla -raise -remote 'openURL(file:%s)'" );
594
gtk_entry_select_region ( GTK_ENTRY(name_text), 0,
595
strlen ( "mozilla -raise -remote 'openURL(file:%s)'" ) );
597
gtk_window_set_focus ( >K_DIALOG ( browser_window )->window,
600
ok_button = gtk_button_new_with_label ( gettext("Ok") );
601
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (browser_window)->action_area),
602
ok_button, TRUE, TRUE, 5);
603
gtk_signal_connect (GTK_OBJECT (ok_button), "clicked",
604
GTK_SIGNAL_FUNC (ok_browser_callback), ed);
605
GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
606
gtk_widget_grab_default (ok_button);
608
cancel_button = gtk_button_new_with_label ( gettext("Cancel") );
609
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (browser_window)->action_area),
610
cancel_button, TRUE, TRUE, 5);
611
gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked",
612
GTK_SIGNAL_FUNC (cancel_browser_callback), ed);
614
gtk_widget_show_all ( browser_window );
616
return ( browser_window );