"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "todo_gui.c" between
jpilot-1.8.2.tar.gz and jpilot-2_0_1.tar.gz

About: J-Pilot is a desktop organizer application for Palm Pilot (PalmOS) devices. Ported to GTK3.

todo_gui.c  (jpilot-1.8.2):todo_gui.c  (jpilot-2_0_1)
skipping to change at line 26 skipping to change at line 26
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
******************************************************************************/ ******************************************************************************/
/********************************* Includes ***********************************/ /********************************* Includes ***********************************/
#include "config.h" #include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <dirent.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h> #include <gdk/gdkkeysyms.h>
#include <pi-dlp.h> #include <pi-dlp.h>
#include <slcurses.h>
#include "todo.h" #include "todo.h"
#include "i18n.h" #include "i18n.h"
#include "utils.h" #include "utils.h"
#include "log.h" #include "log.h"
#include "prefs.h" #include "prefs.h"
#include "password.h" #include "password.h"
#include "print.h" #include "print.h"
#include "export.h" #include "export.h"
#include "stock_buttons.h" #include "stock_buttons.h"
skipping to change at line 60 skipping to change at line 59
#define NUM_TODO_CSV_FIELDS 8 #define NUM_TODO_CSV_FIELDS 8
#define CONNECT_SIGNALS 400 #define CONNECT_SIGNALS 400
#define DISCONNECT_SIGNALS 401 #define DISCONNECT_SIGNALS 401
/* RFCs use CRLF for Internet newline */ /* RFCs use CRLF for Internet newline */
#define CRLF "\x0D\x0A" #define CRLF "\x0D\x0A"
/******************************* Global vars **********************************/ /******************************* Global vars **********************************/
/* Keeps track of whether code is using ToDo, or Tasks database /* Keeps track of whether code is using ToDo, or Tasks database
* 0 is ToDo, 1 is Tasks */ * 0 is ToDo, 1 is Tasks */
static long todo_version=0; static long todo_version = 0;
extern GtkWidget *glob_date_label; extern GtkWidget *glob_date_label;
extern int glob_date_timer_tag; extern int glob_date_timer_tag;
static GtkWidget *clist; static GtkWidget *treeView;
static GtkTreeSelection *treeSelection;
static GtkListStore *listStore;
static GtkWidget *todo_desc, *todo_note; static GtkWidget *todo_desc, *todo_note;
static GObject *todo_desc_buffer, *todo_note_buffer; static GObject *todo_desc_buffer, *todo_note_buffer;
static GtkWidget *todo_completed_checkbox; static GtkWidget *todo_completed_checkbox;
static GtkWidget *private_checkbox; static GtkWidget *private_checkbox;
static struct tm due_date; static struct tm due_date;
static GtkWidget *due_date_button; static GtkWidget *due_date_button;
static GtkWidget *todo_no_due_date_checkbox; static GtkWidget *todo_no_due_date_checkbox;
static GtkWidget *radio_button_todo[NUM_TODO_PRIORITIES]; static GtkWidget *radio_button_todo[NUM_TODO_PRIORITIES];
/* Need two extra slots for the ALL category and Edit Categories... */
static GtkWidget *todo_cat_menu_item1[NUM_TODO_CAT_ITEMS+2];
static GtkWidget *todo_cat_menu_item2[NUM_TODO_CAT_ITEMS];
static GtkWidget *new_record_button; static GtkWidget *new_record_button;
static GtkWidget *apply_record_button; static GtkWidget *apply_record_button;
static GtkWidget *add_record_button; static GtkWidget *add_record_button;
static GtkWidget *delete_record_button; static GtkWidget *delete_record_button;
static GtkWidget *undelete_record_button; static GtkWidget *undelete_record_button;
static GtkWidget *copy_record_button; static GtkWidget *copy_record_button;
static GtkWidget *cancel_record_button; static GtkWidget *cancel_record_button;
static GtkWidget *category_menu1; static GtkWidget *category_menu1;
static GtkWidget *category_menu2; static GtkWidget *category_menu2;
static GtkWidget *pane; static GtkWidget *pane;
static GtkWidget *note_pane; static GtkWidget *note_pane;
static ToDoList *glob_todo_list=NULL; static ToDoList *glob_todo_list = NULL;
static ToDoList *export_todo_list=NULL; static ToDoList *export_todo_list = NULL;
static struct sorted_cats sort_l[NUM_TODO_CAT_ITEMS]; static struct sorted_cats sort_l[NUM_TODO_CAT_ITEMS];
static struct ToDoAppInfo todo_app_info; static struct ToDoAppInfo todo_app_info;
static int todo_category=CATEGORY_ALL; static int todo_category = CATEGORY_ALL;
static int clist_col_selected; static int column_selected;
static int clist_row_selected; static int row_selected;
static int record_changed; static int record_changed;
/****************************** Prototypes ************************************/ /****************************** Prototypes ************************************/
static int todo_clear_details(void); static int todo_clear_details(void);
static int todo_clist_redraw(void);
static int todo_redraw(void);
static int todo_find(void); static int todo_find(void);
static void cb_add_new_record(GtkWidget *widget, gpointer data); static void cb_add_new_record(GtkWidget *widget, gpointer data);
static void connect_changed_signals(int con_or_dis); static void connect_changed_signals(int con_or_dis);
void addNewRecordToDataStructure(MyToDo *mtodo, gpointer data);
void deleteTodo(MyToDo *mtodo, gpointer data);
void undeleteTodo(MyToDo *mtodo, gpointer data);
int printTodo(MyToDo *mtodo, gpointer data);
gboolean printRecord(GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data);
gboolean
findRecord(GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data);
gboolean
selectRecordByRow(GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data);
gint compareNoteColumn(GtkTreeModel *model, GtkTreeIter *left, GtkTreeIter *righ
t);
gint compareCheckColumn(GtkTreeModel *model, GtkTreeIter *left, GtkTreeIter *rig
ht);
/****************************** Main Code *************************************/ /****************************** Main Code *************************************/
/* Called once on initialization of GUI */ /* Called once on initialization of GUI */
static void init(void) static void init(void) {
{ time_t ltime;
time_t ltime; struct tm *now;
struct tm *now; long ivalue;
long ivalue;
time(&ltime); time(&ltime);
now = localtime(&ltime); now = localtime(&ltime);
memcpy(&due_date, now, sizeof(struct tm)); memcpy(&due_date, now, sizeof(struct tm));
get_pref(PREF_TODO_DAYS_TILL_DUE, &ivalue, NULL); get_pref(PREF_TODO_DAYS_TILL_DUE, &ivalue, NULL);
add_days_to_date(&due_date, ivalue); add_days_to_date(&due_date, (int) ivalue);
clist_row_selected = 0; row_selected = 0;
clist_col_selected = 1; column_selected = 0;
record_changed = CLEAR_FLAG; record_changed = CLEAR_FLAG;
} }
static void update_due_button(GtkWidget *button, struct tm *t) static void update_due_button(GtkWidget *button, struct tm *t) {
{ const char *short_date;
const char *short_date; char str[255];
char str[255];
if (t) { if (t) {
get_pref(PREF_SHORTDATE, NULL, &short_date); get_pref(PREF_SHORTDATE, NULL, &short_date);
strftime(str, sizeof(str), short_date, t); strftime(str, sizeof(str), short_date, t);
gtk_label_set_text(GTK_LABEL(GTK_BIN(button)->child), str); gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(button))), str);
} else { } else {
gtk_label_set_text(GTK_LABEL(GTK_BIN(button)->child), _("No Date")); gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(button))), _("No
} Date"));
}
} }
static void cb_cal_dialog(GtkWidget *widget, static void cb_cal_dialog(GtkWidget *widget,
gpointer data) gpointer data) {
{ long fdow;
long fdow; int r = 0;
int r = 0; struct tm t;
struct tm t; GtkWidget *Pcheck_button;
GtkWidget *Pcheck_button; GtkWidget *Pbutton;
GtkWidget *Pbutton;
Pcheck_button = todo_no_due_date_checkbox;
Pcheck_button = todo_no_due_date_checkbox; memcpy(&t, &due_date, sizeof(t));
memcpy(&t, &due_date, sizeof(t)); Pbutton = due_date_button;
Pbutton = due_date_button;
get_pref(PREF_FDOW, &fdow, NULL);
get_pref(PREF_FDOW, &fdow, NULL);
r = cal_dialog(GTK_WINDOW(gtk_widget_get_toplevel(widget)), _("Due Date"), (
r = cal_dialog(GTK_WINDOW(gtk_widget_get_toplevel(widget)), _("Due Date"), fd int) fdow,
ow, &(t.tm_mon),
&(t.tm_mon), &(t.tm_mday),
&(t.tm_mday), &(t.tm_year));
&(t.tm_year));
if (r == CAL_DONE) {
if (r==CAL_DONE) { mktime(&t);
mktime(&t); memcpy(&due_date, &t, sizeof(due_date));
memcpy(&due_date, &t, sizeof(due_date)); if (Pcheck_button) {
if (Pcheck_button) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Pcheck_button), FALSE
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Pcheck_button), FALSE); );
/* The above call sets due_date forward by n days, so we correct it */ /* The above call sets due_date forward by n days, so we correct it
memcpy(&due_date, &t, sizeof(due_date)); */
update_due_button(Pbutton, &t); memcpy(&due_date, &t, sizeof(due_date));
} update_due_button(Pbutton, &t);
if (Pbutton) { }
update_due_button(Pbutton, &t); if (Pbutton) {
} update_due_button(Pbutton, &t);
} }
} }
}
int todo_print(void)
{ int printTodo(MyToDo *mtodo, gpointer data) {
long this_many; long this_many;
MyToDo *mtodo; ToDoList *todo_list;
ToDoList *todo_list; ToDoList todo_list1;
ToDoList todo_list1;
get_pref(PREF_PRINT_THIS_MANY, &this_many, NULL);
get_pref(PREF_PRINT_THIS_MANY, &this_many, NULL);
todo_list = NULL;
todo_list=NULL; if (this_many == 1) {
if (this_many==1) { if (mtodo < (MyToDo *) LIST_MIN_DATA) {
mtodo = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected); return EXIT_FAILURE;
if (mtodo < (MyToDo *)CLIST_MIN_DATA) { }
return EXIT_FAILURE; memcpy(&(todo_list1.mtodo), mtodo, sizeof(MyToDo));
} todo_list1.next = NULL;
memcpy(&(todo_list1.mtodo), mtodo, sizeof(MyToDo)); todo_list = &todo_list1;
todo_list1.next=NULL; }
todo_list = &todo_list1; if (this_many == 2) {
} get_todos2(&todo_list, SORT_ASCENDING, 2, 2, 2, 2, todo_category);
if (this_many==2) { }
get_todos2(&todo_list, SORT_ASCENDING, 2, 2, 2, 2, todo_category); if (this_many == 3) {
} get_todos2(&todo_list, SORT_ASCENDING, 2, 2, 2, 2, CATEGORY_ALL);
if (this_many==3) { }
get_todos2(&todo_list, SORT_ASCENDING, 2, 2, 2, 2, CATEGORY_ALL);
} print_todos(todo_list, PN);
print_todos(todo_list, PN); if ((this_many == 2) || (this_many == 3)) {
free_ToDoList(&todo_list);
if ((this_many==2) || (this_many==3)) { }
free_ToDoList(&todo_list);
} return EXIT_SUCCESS;
}
return EXIT_SUCCESS;
} int todo_print(void) {
gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), printRecord, NULL);
static void set_new_button_to(int new_state) return EXIT_SUCCESS;
{
jp_logf(JP_LOG_DEBUG, "set_new_button_to new %d old %d\n", new_state, record_ }
changed);
static void set_new_button_to(int new_state) {
if (record_changed==new_state) { jp_logf(JP_LOG_DEBUG, "set_new_button_to new %d old %d\n", new_state, record
return; _changed);
}
if (record_changed == new_state) {
switch (new_state) { return;
case MODIFY_FLAG: }
gtk_widget_show(cancel_record_button);
gtk_widget_show(copy_record_button); switch (new_state) {
gtk_widget_show(apply_record_button); case MODIFY_FLAG:
gtk_widget_show(cancel_record_button);
gtk_widget_hide(add_record_button); gtk_widget_show(copy_record_button);
gtk_widget_hide(delete_record_button); gtk_widget_show(apply_record_button);
gtk_widget_hide(new_record_button);
gtk_widget_hide(undelete_record_button); gtk_widget_hide(add_record_button);
gtk_widget_hide(delete_record_button);
break; gtk_widget_hide(new_record_button);
case NEW_FLAG: gtk_widget_hide(undelete_record_button);
gtk_widget_show(cancel_record_button);
gtk_widget_show(add_record_button); break;
case NEW_FLAG:
gtk_widget_hide(apply_record_button); gtk_widget_show(cancel_record_button);
gtk_widget_hide(copy_record_button); gtk_widget_show(add_record_button);
gtk_widget_hide(delete_record_button);
gtk_widget_hide(new_record_button); gtk_widget_hide(apply_record_button);
gtk_widget_hide(undelete_record_button); gtk_widget_hide(copy_record_button);
gtk_widget_hide(delete_record_button);
break; gtk_widget_hide(new_record_button);
case CLEAR_FLAG: gtk_widget_hide(undelete_record_button);
gtk_widget_show(delete_record_button);
gtk_widget_show(copy_record_button); break;
gtk_widget_show(new_record_button); case CLEAR_FLAG:
gtk_widget_show(delete_record_button);
gtk_widget_hide(add_record_button); gtk_widget_show(copy_record_button);
gtk_widget_hide(apply_record_button); gtk_widget_show(new_record_button);
gtk_widget_hide(cancel_record_button);
gtk_widget_hide(undelete_record_button); gtk_widget_hide(add_record_button);
gtk_widget_hide(apply_record_button);
break; gtk_widget_hide(cancel_record_button);
case UNDELETE_FLAG: gtk_widget_hide(undelete_record_button);
gtk_widget_show(undelete_record_button);
gtk_widget_show(copy_record_button); break;
gtk_widget_show(new_record_button); case UNDELETE_FLAG:
gtk_widget_show(undelete_record_button);
gtk_widget_hide(add_record_button); gtk_widget_show(copy_record_button);
gtk_widget_hide(apply_record_button); gtk_widget_show(new_record_button);
gtk_widget_hide(cancel_record_button);
gtk_widget_hide(delete_record_button); gtk_widget_hide(add_record_button);
break; gtk_widget_hide(apply_record_button);
gtk_widget_hide(cancel_record_button);
default: gtk_widget_hide(delete_record_button);
return; break;
}
record_changed=new_state; default:
return;
}
record_changed = new_state;
} }
static void cb_record_changed(GtkWidget *widget, static void cb_record_changed(GtkWidget *widget,
gpointer data) gpointer data) {
{ jp_logf(JP_LOG_DEBUG, "cb_record_changed\n");
jp_logf(JP_LOG_DEBUG, "cb_record_changed\n"); if (record_changed == CLEAR_FLAG) {
if (record_changed==CLEAR_FLAG) { connect_changed_signals(DISCONNECT_SIGNALS);
connect_changed_signals(DISCONNECT_SIGNALS); if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(listStore), NULL) > 0)
if (GTK_CLIST(clist)->rows > 0) { {
set_new_button_to(MODIFY_FLAG); set_new_button_to(MODIFY_FLAG);
} else { } else {
set_new_button_to(NEW_FLAG); set_new_button_to(NEW_FLAG);
} }
} } else if (record_changed == UNDELETE_FLAG) {
else if (record_changed==UNDELETE_FLAG) jp_logf(JP_LOG_INFO | JP_LOG_GUI,
{ _("This record is deleted.\n"
jp_logf(JP_LOG_INFO|JP_LOG_GUI, "Undelete it or copy it to make changes.\n"));
_("This record is deleted.\n" }
"Undelete it or copy it to make changes.\n")); }
}
} static void connect_changed_signals(int con_or_dis) {
int i;
static void connect_changed_signals(int con_or_dis) static int connected = 0;
{
int i; /* CONNECT */
static int connected=0; if ((con_or_dis == CONNECT_SIGNALS) && (!connected)) {
connected = 1;
/* CONNECT */
if ((con_or_dis==CONNECT_SIGNALS) && (!connected)) { if (category_menu2) {
connected=1; g_signal_connect(G_OBJECT(category_menu2), "changed", G_CALLBACK(cb_
record_changed), NULL);
for (i=0; i<NUM_TODO_CAT_ITEMS; i++) { }
if (todo_cat_menu_item2[i]) { for (i = 0; i < NUM_TODO_PRIORITIES; i++) {
gtk_signal_connect(GTK_OBJECT(todo_cat_menu_item2[i]), "toggled", if (radio_button_todo[i]) {
GTK_SIGNAL_FUNC(cb_record_changed), NULL); g_signal_connect(G_OBJECT(radio_button_todo[i]), "toggled",
} G_CALLBACK(cb_record_changed), NULL);
} }
for (i=0; i<NUM_TODO_PRIORITIES; i++) { }
if (radio_button_todo[i]) { g_signal_connect(todo_desc_buffer, "changed",
gtk_signal_connect(GTK_OBJECT(radio_button_todo[i]), "toggled", G_CALLBACK(cb_record_changed), NULL);
GTK_SIGNAL_FUNC(cb_record_changed), NULL); g_signal_connect(todo_note_buffer, "changed",
} G_CALLBACK(cb_record_changed), NULL);
}
g_signal_connect(todo_desc_buffer, "changed", g_signal_connect(G_OBJECT(todo_completed_checkbox), "toggled",
GTK_SIGNAL_FUNC(cb_record_changed), NULL); G_CALLBACK(cb_record_changed), NULL);
g_signal_connect(todo_note_buffer, "changed", g_signal_connect(G_OBJECT(private_checkbox), "toggled",
GTK_SIGNAL_FUNC(cb_record_changed), NULL); G_CALLBACK(cb_record_changed), NULL);
g_signal_connect(G_OBJECT(todo_no_due_date_checkbox), "toggled",
gtk_signal_connect(GTK_OBJECT(todo_completed_checkbox), "toggled", G_CALLBACK(cb_record_changed), NULL);
GTK_SIGNAL_FUNC(cb_record_changed), NULL); g_signal_connect(G_OBJECT(due_date_button), "pressed",
gtk_signal_connect(GTK_OBJECT(private_checkbox), "toggled", G_CALLBACK(cb_record_changed), NULL);
GTK_SIGNAL_FUNC(cb_record_changed), NULL); }
gtk_signal_connect(GTK_OBJECT(todo_no_due_date_checkbox), "toggled",
GTK_SIGNAL_FUNC(cb_record_changed), NULL); /* DISCONNECT */
gtk_signal_connect(GTK_OBJECT(due_date_button), "pressed", if ((con_or_dis == DISCONNECT_SIGNALS) && (connected)) {
GTK_SIGNAL_FUNC(cb_record_changed), NULL); connected = 0;
} if (category_menu2) {
g_signal_handlers_disconnect_by_func(G_OBJECT(category_menu2), G_CAL
/* DISCONNECT */ LBACK(cb_record_changed), NULL);
if ((con_or_dis==DISCONNECT_SIGNALS) && (connected)) { }
connected=0; for (i = 0; i < NUM_TODO_PRIORITIES; i++) {
g_signal_handlers_disconnect_by_func(G_OBJECT(radio_button_todo[i]),
for (i=0; i<NUM_TODO_CAT_ITEMS; i++) { G_CALLBACK(cb_record_changed),
if (todo_cat_menu_item2[i]) { NULL);
gtk_signal_disconnect_by_func(GTK_OBJECT(todo_cat_menu_item2[i]), }
GTK_SIGNAL_FUNC(cb_record_changed), NU g_signal_handlers_disconnect_by_func(todo_desc_buffer,
LL); G_CALLBACK(cb_record_changed), NULL
} );
} g_signal_handlers_disconnect_by_func(todo_note_buffer,
for (i=0; i<NUM_TODO_PRIORITIES; i++) { G_CALLBACK(cb_record_changed), NULL
gtk_signal_disconnect_by_func(GTK_OBJECT(radio_button_todo[i]), );
GTK_SIGNAL_FUNC(cb_record_changed), NULL)
; g_signal_handlers_disconnect_by_func(G_OBJECT(todo_completed_checkbox),
} G_CALLBACK(cb_record_changed), NULL
g_signal_handlers_disconnect_by_func(todo_desc_buffer, );
GTK_SIGNAL_FUNC(cb_record_changed), N g_signal_handlers_disconnect_by_func(G_OBJECT(private_checkbox),
ULL); G_CALLBACK(cb_record_changed), NULL
g_signal_handlers_disconnect_by_func(todo_note_buffer, );
GTK_SIGNAL_FUNC(cb_record_changed), N g_signal_handlers_disconnect_by_func(G_OBJECT(todo_no_due_date_checkbox)
ULL); ,
G_CALLBACK(cb_record_changed), NULL
gtk_signal_disconnect_by_func(GTK_OBJECT(todo_completed_checkbox), );
GTK_SIGNAL_FUNC(cb_record_changed), NULL); g_signal_handlers_disconnect_by_func(G_OBJECT(due_date_button),
gtk_signal_disconnect_by_func(GTK_OBJECT(private_checkbox), G_CALLBACK(cb_record_changed), NULL
GTK_SIGNAL_FUNC(cb_record_changed), NULL); );
gtk_signal_disconnect_by_func(GTK_OBJECT(todo_no_due_date_checkbox), }
GTK_SIGNAL_FUNC(cb_record_changed), NULL); }
gtk_signal_disconnect_by_func(GTK_OBJECT(due_date_button),
GTK_SIGNAL_FUNC(cb_record_changed), NULL); static int todo_to_text(struct ToDo *todo, char *text, int len) {
} char yes[] = "Yes";
} char no[] = "No";
char empty[] = "";
static int todo_to_text(struct ToDo *todo, char *text, int len) char *complete;
{ char *description;
char yes[]="Yes"; char *note;
char no[]="No"; char due[20];
char empty[]=""; const char *short_date;
char *complete;
char *description; if (todo->indefinite) {
char *note; strcpy(due, "Never");
char due[20]; } else {
const char *short_date; get_pref(PREF_SHORTDATE, NULL, &short_date);
strftime(due, sizeof(due), short_date, &(todo->due));
if (todo->indefinite) { }
strcpy(due, "Never"); complete = todo->complete ? yes : no;
} else { description = todo->description ? todo->description : empty;
get_pref(PREF_SHORTDATE, NULL, &short_date); note = todo->note ? todo->note : empty;
strftime(due, sizeof(due), short_date, &(todo->due)); g_snprintf(text, (gulong) len, "Due: %s\nPriority: %d\nComplete: %s\n\
}
complete=todo->complete ? yes : no;
description=todo->description ? todo->description : empty;
note=todo->note ? todo->note : empty;
g_snprintf(text, len, "Due: %s\nPriority: %d\nComplete: %s\n\
Description: %s\nNote: %s\n", due, todo->priority, complete, Description: %s\nNote: %s\n", due, todo->priority, complete,
description, note); description, note);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* /*
* Start Import Code * Start Import Code
*/ */
static int cb_todo_import(GtkWidget *parent_window, static int cb_todo_import(GtkWidget *parent_window,
const char *file_path, int type) const char *file_path, int type) {
{ FILE *in;
FILE *in; char text[65536];
char text[65536]; char description[65536];
char description[65536]; char note[65536];
char note[65536]; struct ToDo new_todo;
struct ToDo new_todo; unsigned char attrib;
unsigned char attrib; int i, ret, index;
int i, ret, index; int import_all;
int import_all; ToDoList *todolist;
ToDoList *todolist; ToDoList *temp_todolist;
ToDoList *temp_todolist; struct CategoryAppInfo cai;
struct CategoryAppInfo cai; char old_cat_name[32];
char old_cat_name[32]; int suggested_cat_num;
int suggested_cat_num; int new_cat_num;
int new_cat_num; int priv, indefinite, priority, completed;
int priv, indefinite, priority, completed; int year, month, day;
int year, month, day;
in = fopen(file_path, "r");
in=fopen(file_path, "r"); if (!in) {
if (!in) { jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), file_path);
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), file_path); return EXIT_FAILURE;
return EXIT_FAILURE; }
}
/* CSV */
/* CSV */ if (type == IMPORT_TYPE_CSV) {
if (type==IMPORT_TYPE_CSV) { jp_logf(JP_LOG_DEBUG, "Todo import CSV [%s]\n", file_path);
jp_logf(JP_LOG_DEBUG, "Todo import CSV [%s]\n", file_path); /* Get the first line containing the format and check for reasonableness
/* Get the first line containing the format and check for reasonableness * */
/ if (fgets(text, sizeof(text), in) == NULL) {
if (fgets(text, sizeof(text), in) == NULL) { jp_logf(JP_LOG_WARN, "fgets failed %s %d\n", __FILE__, __LINE__);
jp_logf(JP_LOG_WARN, "fgets failed %s %d\n", __FILE__, __LINE__); }
} ret = verify_csv_header(text, NUM_TODO_CSV_FIELDS, file_path);
ret = verify_csv_header(text, NUM_TODO_CSV_FIELDS, file_path); if (EXIT_FAILURE == ret) return EXIT_FAILURE;
if (EXIT_FAILURE == ret) return EXIT_FAILURE;
import_all = FALSE;
import_all=FALSE; while (1) {
while (1) { /* Read the category field */
/* Read the category field */ ret = read_csv_field(in, text, sizeof(text));
ret = read_csv_field(in, text, sizeof(text)); if (feof(in)) break;
if (feof(in)) break;
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
printf("category is [%s]\n", text); printf("category is [%s]\n", text);
#endif #endif
g_strlcpy(old_cat_name, text, 16); g_strlcpy(old_cat_name, text, 16);
attrib=0; attrib = 0;
/* Figure out what the best category number is */ /* Figure out what the best category number is */
suggested_cat_num=0; suggested_cat_num = 0;
for (i=0; i<NUM_TODO_CAT_ITEMS; i++) { for (i = 0; i < NUM_TODO_CAT_ITEMS; i++) {
if (todo_app_info.category.name[i][0]=='\0') continue; if (todo_app_info.category.name[i][0] == '\0') continue;
if (!strcmp(todo_app_info.category.name[i], old_cat_name)) { if (!strcmp(todo_app_info.category.name[i], old_cat_name)) {
suggested_cat_num=i; suggested_cat_num = i;
break; break;
}
} }
}
/* Read the private field */ /* Read the private field */
ret = read_csv_field(in, text, sizeof(text)); ret = read_csv_field(in, text, sizeof(text));
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
printf("private is [%s]\n", text); printf("private is [%s]\n", text);
#endif #endif
sscanf(text, "%d", &priv); sscanf(text, "%d", &priv);
/* Read the indefinite field */ /* Read the indefinite field */
ret = read_csv_field(in, text, sizeof(text)); ret = read_csv_field(in, text, sizeof(text));
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
printf("indefinite is [%s]\n", text); printf("indefinite is [%s]\n", text);
#endif #endif
sscanf(text, "%d", &indefinite); sscanf(text, "%d", &indefinite);
/* Read the Due Date field */ /* Read the Due Date field */
ret = read_csv_field(in, text, sizeof(text)); ret = read_csv_field(in, text, sizeof(text));
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
printf("due date is [%s]\n", text); printf("due date is [%s]\n", text);
#endif #endif
sscanf(text, "%d/%d/%d", &year, &month, &day); sscanf(text, "%d/%d/%d", &year, &month, &day);
/* Read the Priority field */ /* Read the Priority field */
ret = read_csv_field(in, text, sizeof(text)); ret = read_csv_field(in, text, sizeof(text));
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
printf("priority is [%s]\n", text); printf("priority is [%s]\n", text);
#endif #endif
sscanf(text, "%d", &priority); sscanf(text, "%d", &priority);
/* Read the Completed field */ /* Read the Completed field */
ret = read_csv_field(in, text, sizeof(text)); ret = read_csv_field(in, text, sizeof(text));
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
printf("completed is [%s]\n", text); printf("completed is [%s]\n", text);
#endif #endif
sscanf(text, "%d", &completed); sscanf(text, "%d", &completed);
/* Read the Description field */ /* Read the Description field */
ret = read_csv_field(in, description, sizeof(text)); ret = read_csv_field(in, description, sizeof(text));
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
printf("todo description [%s]\n", description); printf("todo description [%s]\n", description);
#endif #endif
/* Read the Note field */ /* Read the Note field */
ret = read_csv_field(in, note, sizeof(text)); ret = read_csv_field(in, note, sizeof(text));
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
printf("todo note [%s]\n", note); printf("todo note [%s]\n", note);
#endif #endif
new_todo.indefinite=indefinite; new_todo.indefinite = indefinite;
memset(&(new_todo.due), 0, sizeof(new_todo.due)); memset(&(new_todo.due), 0, sizeof(new_todo.due));
new_todo.due.tm_year=year-1900; new_todo.due.tm_year = year - 1900;
new_todo.due.tm_mon=month-1; new_todo.due.tm_mon = month - 1;
new_todo.due.tm_mday=day; new_todo.due.tm_mday = day;
new_todo.priority=priority; new_todo.priority = priority;
new_todo.complete=completed; new_todo.complete = completed;
new_todo.description=description; new_todo.description = description;
new_todo.note=note; new_todo.note = note;
todo_to_text(&new_todo, text, sizeof(text)); todo_to_text(&new_todo, text, sizeof(text));
if (!import_all) { if (!import_all) {
ret=import_record_ask(parent_window, pane, ret = import_record_ask(parent_window, pane,
text, text,
&(todo_app_info.category), &(todo_app_info.category),
old_cat_name, old_cat_name,
priv, priv,
suggested_cat_num, suggested_cat_num,
&new_cat_num); &new_cat_num);
} else { } else {
new_cat_num=suggested_cat_num; new_cat_num = suggested_cat_num;
} }
if (ret==DIALOG_SAID_IMPORT_QUIT) break; if (ret == DIALOG_SAID_IMPORT_QUIT) break;
if (ret==DIALOG_SAID_IMPORT_SKIP) continue; if (ret == DIALOG_SAID_IMPORT_SKIP) continue;
if (ret==DIALOG_SAID_IMPORT_ALL) import_all=TRUE; if (ret == DIALOG_SAID_IMPORT_ALL) import_all = TRUE;
attrib = (new_cat_num & 0x0F) | (priv ? dlpRecAttrSecret : 0); attrib = (unsigned char) ((new_cat_num & 0x0F) | (priv ? dlpRecAttrS
if ((ret==DIALOG_SAID_IMPORT_YES) || (import_all)) { ecret : 0));
pc_todo_write(&new_todo, NEW_PC_REC, attrib, NULL); if ((ret == DIALOG_SAID_IMPORT_YES) || (import_all)) {
} pc_todo_write(&new_todo, NEW_PC_REC, attrib, NULL);
} }
} }
}
/* Palm Desktop DAT format */
if (type==IMPORT_TYPE_DAT) { /* Palm Desktop DAT format */
jp_logf(JP_LOG_DEBUG, "Todo import DAT [%s]\n", file_path); if (type == IMPORT_TYPE_DAT) {
if (dat_check_if_dat_file(in)!=DAT_TODO_FILE) { jp_logf(JP_LOG_DEBUG, "Todo import DAT [%s]\n", file_path);
jp_logf(JP_LOG_WARN, _("File doesn't appear to be todo.dat format\n")); if (dat_check_if_dat_file(in) != DAT_TODO_FILE) {
fclose(in); jp_logf(JP_LOG_WARN, _("File doesn't appear to be todo.dat format\n"
return EXIT_FAILURE; ));
} fclose(in);
todolist=NULL; return EXIT_FAILURE;
dat_get_todos(in, &todolist, &cai); }
import_all=FALSE; todolist = NULL;
for (temp_todolist=todolist; temp_todolist; temp_todolist=temp_todolist->n dat_get_todos(in, &todolist, &cai);
ext) { import_all = FALSE;
index=temp_todolist->mtodo.unique_id-1; for (temp_todolist = todolist; temp_todolist; temp_todolist = temp_todol
if (index<0) { ist->next) {
g_strlcpy(old_cat_name, _("Unfiled"), 16); index = temp_todolist->mtodo.unique_id - 1;
index=0; if (index < 0) {
} else { g_strlcpy(old_cat_name, _("Unfiled"), 16);
g_strlcpy(old_cat_name, cai.name[index], 16); index = 0;
} } else {
/* Figure out what category it was in the dat file */ g_strlcpy(old_cat_name, cai.name[index], 16);
index=temp_todolist->mtodo.unique_id-1; }
suggested_cat_num=0; /* Figure out what category it was in the dat file */
if (index>-1) { index = temp_todolist->mtodo.unique_id - 1;
for (i=0; i<NUM_TODO_CAT_ITEMS; i++) { suggested_cat_num = 0;
if (todo_app_info.category.name[i][0]=='\0') continue; if (index > -1) {
if (!strcmp(todo_app_info.category.name[i], old_cat_name)) { for (i = 0; i < NUM_TODO_CAT_ITEMS; i++) {
suggested_cat_num=i; if (todo_app_info.category.name[i][0] == '\0') continue;
break; if (!strcmp(todo_app_info.category.name[i], old_cat_name)) {
} suggested_cat_num = i;
} break;
} }
}
ret=0; }
todo_to_text(&(temp_todolist->mtodo.todo), text, sizeof(text));
if (!import_all) { ret = 0;
ret=import_record_ask(parent_window, pane, todo_to_text(&(temp_todolist->mtodo.todo), text, sizeof(text));
text, if (!import_all) {
&(todo_app_info.category), ret = import_record_ask(parent_window, pane,
old_cat_name, text,
(temp_todolist->mtodo.attrib & 0x10), &(todo_app_info.category),
suggested_cat_num, old_cat_name,
&new_cat_num); (temp_todolist->mtodo.attrib & 0x10),
} else { suggested_cat_num,
new_cat_num=suggested_cat_num; &new_cat_num);
} } else {
if (ret==DIALOG_SAID_IMPORT_QUIT) break; new_cat_num = suggested_cat_num;
if (ret==DIALOG_SAID_IMPORT_SKIP) continue; }
if (ret==DIALOG_SAID_IMPORT_ALL) import_all=TRUE; if (ret == DIALOG_SAID_IMPORT_QUIT) break;
if (ret == DIALOG_SAID_IMPORT_SKIP) continue;
attrib = (new_cat_num & 0x0F) | if (ret == DIALOG_SAID_IMPORT_ALL) import_all = TRUE;
((temp_todolist->mtodo.attrib & 0x10) ? dlpRecAttrSecret : 0);
if ((ret==DIALOG_SAID_IMPORT_YES) || (import_all)) { attrib = (unsigned char) ((new_cat_num & 0x0F) |
pc_todo_write(&(temp_todolist->mtodo.todo), NEW_PC_REC, ((temp_todolist->mtodo.attrib & 0x10) ? dl
attrib, NULL); pRecAttrSecret : 0));
} if ((ret == DIALOG_SAID_IMPORT_YES) || (import_all)) {
} pc_todo_write(&(temp_todolist->mtodo.todo), NEW_PC_REC,
free_ToDoList(&todolist); attrib, NULL);
} }
}
todo_refresh(); free_ToDoList(&todolist);
fclose(in); }
return EXIT_SUCCESS;
} todo_refresh();
fclose(in);
int todo_import(GtkWidget *window) return EXIT_SUCCESS;
{ }
char *type_desc[] = {
N_("CSV (Comma Separated Values)"), int todo_import(GtkWidget *window) {
N_("DAT/TDA (Palm Archive Formats)"), char *type_desc[] = {
NULL N_("CSV (Comma Separated Values)"),
}; N_("DAT/TDA (Palm Archive Formats)"),
int type_int[] = { NULL
IMPORT_TYPE_CSV, };
IMPORT_TYPE_DAT, int type_int[] = {
0 IMPORT_TYPE_CSV,
}; IMPORT_TYPE_DAT,
0
/* Hide ABA import of TaskDB until file format has been decoded */ };
/* FIXME: Uncomment when support for Tasks has been added
if (todo_version==1) { /* Hide ABA import of TaskDB until file format has been decoded */
type_desc[1] = NULL; /* FIXME: Uncomment when support for Tasks has been added
type_int[1] = 0; if (todo_version==1) {
} type_desc[1] = NULL;
*/ type_int[1] = 0;
}
*/
import_gui(window, pane, type_desc, type_int, cb_todo_import); import_gui(window, pane, type_desc, type_int, cb_todo_import);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* /*
* End Import Code * End Import Code
*/ */
/* /*
* Start Export code * Start Export code
*/ */
static void cb_todo_export_ok(GtkWidget *export_window, GtkWidget *clist, static void cb_todo_export_ok(GtkWidget *export_window, GtkWidget *treeView,
int type, const char *filename) int type, const char *filename) {
{ MyToDo *mtodo;
MyToDo *mtodo; GList *list, *temp_list;
GList *list, *temp_list; FILE *out;
FILE *out; struct stat statb;
struct stat statb; int i, r;
int i, r; const char *short_date = NULL;
const char *short_date; time_t ltime;
time_t ltime; struct tm *now = NULL;
struct tm *now = NULL; char *button_text[] = {N_("OK")};
char *button_text[]={N_("OK")}; char *button_overwrite_text[] = {N_("No"), N_("Yes")};
char *button_overwrite_text[]={N_("No"), N_("Yes")}; char text[1024];
char text[1024]; char date_string[1024];
char date_string[1024]; char str1[256], str2[256];
char str1[256], str2[256]; char pref_time[40];
char pref_time[40]; char csv_text[65550];
char csv_text[65550]; char *p;
char *p; gchar *end;
gchar *end; char username[256];
char username[256]; char hostname[256];
char hostname[256]; const char *svalue;
const char *svalue; long userid = -1;
long userid; long char_set;
long char_set; char *utf;
char *utf;
/* Open file for export, including corner cases where file exists or
/* Open file for export, including corner cases where file exists or * can't be opened */
* can't be opened */ if (!stat(filename, &statb)) {
if (!stat(filename, &statb)) { if (S_ISDIR(statb.st_mode)) {
if (S_ISDIR(statb.st_mode)) { g_snprintf(text, sizeof(text), _("%s is a directory"), filename);
g_snprintf(text, sizeof(text), _("%s is a directory"), filename); dialog_generic(GTK_WINDOW(export_window),
dialog_generic(GTK_WINDOW(export_window), _("Error Opening File"),
_("Error Opening File"), DIALOG_ERROR, text, 1, button_text);
DIALOG_ERROR, text, 1, button_text); return;
return; }
} g_snprintf(text, sizeof(text), _("Do you want to overwrite file %s?"), f
g_snprintf(text, sizeof(text), _("Do you want to overwrite file %s?"), fil ilename);
ename); r = dialog_generic(GTK_WINDOW(export_window),
r = dialog_generic(GTK_WINDOW(export_window), _("Overwrite File?"),
_("Overwrite File?"), DIALOG_QUESTION, text, 2, button_overwrite_text);
DIALOG_QUESTION, text, 2, button_overwrite_text); if (r != DIALOG_SAID_2) {
if (r!=DIALOG_SAID_2) { return;
return; }
} }
}
out = fopen(filename, "w");
out = fopen(filename, "w"); if (!out) {
if (!out) { g_snprintf(text, sizeof(text), _("Error opening file: %s"), filename);
g_snprintf(text, sizeof(text), _("Error opening file: %s"), filename); dialog_generic(GTK_WINDOW(export_window),
dialog_generic(GTK_WINDOW(export_window), _("Error Opening File"),
_("Error Opening File"), DIALOG_ERROR, text, 1, button_text);
DIALOG_ERROR, text, 1, button_text); return;
return; }
}
/* Write a header for TEXT file */
/* Write a header for TEXT file */ if (type == EXPORT_TYPE_TEXT) {
if (type == EXPORT_TYPE_TEXT) { get_pref(PREF_SHORTDATE, NULL, &short_date);
get_pref(PREF_SHORTDATE, NULL, &short_date); get_pref_time_no_secs(pref_time);
get_pref_time_no_secs(pref_time); time(&ltime);
time(&ltime); now = localtime(&ltime);
now = localtime(&ltime); strftime(str1, sizeof(str1), short_date, now);
strftime(str1, sizeof(str1), short_date, now); strftime(str2, sizeof(str2), pref_time, now);
strftime(str2, sizeof(str2), pref_time, now); g_snprintf(date_string, sizeof(date_string), "%s %s", str1, str2);
g_snprintf(date_string, sizeof(date_string), "%s %s", str1, str2); fprintf(out, _("ToDo exported from %s %s on %s\n\n"),
fprintf(out, _("ToDo exported from %s %s on %s\n\n"), PN, VERSION, date_string);
PN,VERSION,date_string); }
}
/* Write a header to the CSV file */
/* Write a header to the CSV file */ if (type == EXPORT_TYPE_CSV) {
if (type == EXPORT_TYPE_CSV) { fprintf(out,
fprintf(out, "CSV todo version "VERSION": Category, Private, Indefinite, D "CSV todo version "VERSION": Category, Private, Indefinite, Due
ue Date, Priority, Completed, ToDo Text, Note\n"); Date, Priority, Completed, ToDo Text, Note\n");
} }
/* Special setup for ICAL export */ /* Special setup for ICAL export */
if (type == EXPORT_TYPE_ICALENDAR) { if (type == EXPORT_TYPE_ICALENDAR) {
get_pref(PREF_CHAR_SET, &char_set, NULL); get_pref(PREF_CHAR_SET, &char_set, NULL);
if (char_set < CHAR_SET_UTF) { if (char_set < CHAR_SET_UTF) {
jp_logf(JP_LOG_WARN, _("Host character encoding is not UTF-8 based.\n" jp_logf(JP_LOG_WARN, _("Host character encoding is not UTF-8 based.\
" Exported ical file may not be standards-compli n"
ant\n")); " Exported ical file may not be standards-com
} pliant\n"));
}
get_pref(PREF_USER, NULL, &svalue);
/* Convert User Name stored in Palm character set */ get_pref(PREF_USER, NULL, &svalue);
g_strlcpy(text, svalue, 128); /* Convert User Name stored in Palm character set */
text[127] = '\0'; g_strlcpy(text, svalue, 128);
charset_p2j(text, 128, char_set); text[127] = '\0';
str_to_ical_str(username, sizeof(username), text); charset_p2j(text, 128, (int) char_set);
get_pref(PREF_USER_ID, &userid, NULL); str_to_ical_str(username, sizeof(username), text);
gethostname(text, sizeof(hostname)); get_pref(PREF_USER_ID, &userid, NULL);
text[sizeof(hostname)-1]='\0'; gethostname(text, sizeof(hostname));
str_to_ical_str(hostname, sizeof(hostname), text); text[sizeof(hostname) - 1] = '\0';
time(&ltime); str_to_ical_str(hostname, sizeof(hostname), text);
now = gmtime(&ltime); time(&ltime);
} now = gmtime(&ltime);
}
get_pref(PREF_CHAR_SET, &char_set, NULL);
list=GTK_CLIST(clist)->selection; get_pref(PREF_CHAR_SET, &char_set, NULL);
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
for (i=0, temp_list=list; temp_list; temp_list = temp_list->next, i++) { View));
mtodo = gtk_clist_get_row_data(GTK_CLIST(clist), GPOINTER_TO_INT(temp_list GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
->data)); list = gtk_tree_selection_get_selected_rows(selection, &model);
if (!mtodo) {
continue; for (i = 0, temp_list = list; temp_list; temp_list = temp_list->next, i++) {
jp_logf(JP_LOG_WARN, _("Can't export todo %d\n"), (long) temp_list->dat GtkTreePath *path = temp_list->data;
a + 1); GtkTreeIter iter;
} if (gtk_tree_model_get_iter(model, &iter, path)) {
switch (type) { gtk_tree_model_get(model, &iter, TODO_DATA_COLUMN_ENUM, &mtodo, -1);
case EXPORT_TYPE_CSV: if (!mtodo) {
utf = charset_p2newj(todo_app_info.category.name[mtodo->attrib & 0x0F], continue;
16, char_set); jp_logf(JP_LOG_WARN, _("Can't export todo %d\n"), (long) temp_li
str_to_csv_str(csv_text, utf); st->data + 1);
fprintf(out, "\"%s\",", csv_text); }
g_free(utf); switch (type) {
fprintf(out, "\"%s\",", (mtodo->attrib & dlpRecAttrSecret) ? "1":"0"); case EXPORT_TYPE_CSV:
fprintf(out, "\"%s\",", mtodo->todo.indefinite ? "1":"0"); utf = charset_p2newj(todo_app_info.category.name[mtodo->attr
if (mtodo->todo.indefinite) { ib & 0x0F], 16, (int) char_set);
fprintf(out, "\"\","); str_to_csv_str(csv_text, utf);
} else { fprintf(out, "\"%s\",", csv_text);
strftime(text, sizeof(text), "%Y/%02m/%02d", &(mtodo->todo.due)); g_free(utf);
fprintf(out, "\"%s\",", text); fprintf(out, "\"%s\",", (mtodo->attrib & dlpRecAttrSecret) ?
} "1" : "0");
fprintf(out, "\"%d\",", mtodo->todo.priority); fprintf(out, "\"%s\",", mtodo->todo.indefinite ? "1" : "0");
fprintf(out, "\"%s\",", mtodo->todo.complete ? "1":"0"); if (mtodo->todo.indefinite) {
if (mtodo->todo.description) { fprintf(out, "\"\",");
str_to_csv_str(csv_text, mtodo->todo.description); } else {
fprintf(out, "\"%s\",", csv_text); strftime(text, sizeof(text), "%Y/%02m/%02d", &(mtodo->to
} else { do.due));
fprintf(out, "\"\","); fprintf(out, "\"%s\",", text);
} }
if (mtodo->todo.note) { fprintf(out, "\"%d\",", mtodo->todo.priority);
str_to_csv_str(csv_text, mtodo->todo.note); fprintf(out, "\"%s\",", mtodo->todo.complete ? "1" : "0");
fprintf(out, "\"%s\"\n", csv_text); if (mtodo->todo.description) {
} else { str_to_csv_str(csv_text, mtodo->todo.description);
fprintf(out, "\"\","); fprintf(out, "\"%s\",", csv_text);
} } else {
break; fprintf(out, "\"\",");
}
case EXPORT_TYPE_TEXT: if (mtodo->todo.note) {
utf = charset_p2newj(todo_app_info.category.name[mtodo->attrib & 0x0F], str_to_csv_str(csv_text, mtodo->todo.note);
16, char_set); fprintf(out, "\"%s\"\n", csv_text);
fprintf(out, _("Category: %s\n"), utf); } else {
g_free(utf); fprintf(out, "\"\",");
}
fprintf(out, _("Private: %s\n"), break;
(mtodo->attrib & dlpRecAttrSecret) ? _("Yes"):_("No"));
if (mtodo->todo.indefinite) { case EXPORT_TYPE_TEXT:
fprintf(out, _("Due Date: None\n")); utf = charset_p2newj(todo_app_info.category.name[mtodo->attr
} else { ib & 0x0F], 16, (int) char_set);
strftime(text, sizeof(text), short_date, &(mtodo->todo.due)); fprintf(out, _("Category: %s\n"), utf);
fprintf(out, _("Due Date: %s\n"), text); g_free(utf);
}
fprintf(out, _("Priority: %d\n"), mtodo->todo.priority); fprintf(out, _("Private: %s\n"),
fprintf(out, _("Completed: %s\n"), mtodo->todo.complete ? _("Yes"):_("N (mtodo->attrib & dlpRecAttrSecret) ? _("Yes") : _("N
o")); o"));
if (mtodo->todo.description) { if (mtodo->todo.indefinite) {
fprintf(out, _("Description: %s\n"), mtodo->todo.description); fprintf(out, _("Due Date: None\n"));
} } else {
if (mtodo->todo.note) { strftime(text, sizeof(text), short_date, &(mtodo->todo.d
fprintf(out, _("Note: %s\n\n"), mtodo->todo.note); ue));
} fprintf(out, _("Due Date: %s\n"), text);
break; }
fprintf(out, _("Priority: %d\n"), mtodo->todo.priority);
case EXPORT_TYPE_ICALENDAR: fprintf(out, _("Completed: %s\n"), mtodo->todo.complete ? _(
/* RFC 2445: Internet Calendaring and Scheduling Core "Yes") : _("No"));
* Object Specification */ if (mtodo->todo.description) {
if (i == 0) { fprintf(out, _("Description: %s\n"), mtodo->todo.descrip
fprintf(out, "BEGIN:VCALENDAR"CRLF); tion);
fprintf(out, "VERSION:2.0"CRLF); }
fprintf(out, "PRODID:%s"CRLF, FPI_STRING); if (mtodo->todo.note) {
} fprintf(out, _("Note: %s\n\n"), mtodo->todo.note);
fprintf(out, "BEGIN:VTODO"CRLF); }
if (mtodo->attrib & dlpRecAttrSecret) { break;
fprintf(out, "CLASS:PRIVATE"CRLF);
} case EXPORT_TYPE_ICALENDAR:
fprintf(out, "UID:palm-todo-%08x-%08lx-%s@%s"CRLF, /* RFC 2445: Internet Calendaring and Scheduling Core
mtodo->unique_id, userid, username, hostname); * Object Specification */
fprintf(out, "DTSTAMP:%04d%02d%02dT%02d%02d%02dZ"CRLF, if (i == 0) {
now->tm_year+1900, fprintf(out, "BEGIN:VCALENDAR"CRLF);
now->tm_mon+1, fprintf(out, "VERSION:2.0"CRLF);
now->tm_mday, fprintf(out, "PRODID:%s"CRLF, FPI_STRING);
now->tm_hour, }
now->tm_min, fprintf(out, "BEGIN:VTODO"CRLF);
now->tm_sec); if (mtodo->attrib & dlpRecAttrSecret) {
str_to_ical_str(text, sizeof(text), fprintf(out, "CLASS:PRIVATE"CRLF);
todo_app_info.category.name[mtodo->attrib & 0x0F]); }
fprintf(out, "CATEGORIES:%s"CRLF, text); fprintf(out, "UID:palm-todo-%08x-%08lx-%s@%s"CRLF,
if (mtodo->todo.description) { mtodo->unique_id, userid, username, hostname);
g_strlcpy(str1, mtodo->todo.description, 51); fprintf(out, "DTSTAMP:%04d%02d%02dT%02d%02d%02dZ"CRLF,
/* truncate the string on a UTF-8 character boundary */ now->tm_year + 1900,
if (char_set > CHAR_SET_UTF) { now->tm_mon + 1,
if (!g_utf8_validate(str1, -1, (const gchar **)&end)) now->tm_mday,
*end = 0; now->tm_hour,
} now->tm_min,
} else { now->tm_sec);
/* Handle pathological case with null description. */ str_to_ical_str(text, sizeof(text),
str1[0] = '\0'; todo_app_info.category.name[mtodo->attrib &
} 0x0F]);
if ((p = strchr(str1, '\n'))) { fprintf(out, "CATEGORIES:%s"CRLF, text);
*p = '\0'; if (mtodo->todo.description) {
} g_strlcpy(str1, mtodo->todo.description, 51);
str_to_ical_str(text, sizeof(text), str1); /* truncate the string on a UTF-8 character boundary */
fprintf(out, "SUMMARY:%s%s"CRLF, text, if (char_set > CHAR_SET_UTF) {
strlen(str1) > 49 ? "..." : ""); if (!g_utf8_validate(str1, -1, (const gchar **) &end
str_to_ical_str(text, sizeof(text), mtodo->todo.description); ))
fprintf(out, "DESCRIPTION:%s", text); *end = 0;
if (mtodo->todo.note && mtodo->todo.note[0]) { }
str_to_ical_str(text, sizeof(text), mtodo->todo.note); } else {
fprintf(out, "\\n"CRLF" %s"CRLF, text); /* Handle pathological case with null description. */
} else { str1[0] = '\0';
fprintf(out, ""CRLF); }
} if ((p = strchr(str1, '\n'))) {
fprintf(out, "STATUS:%s"CRLF, mtodo->todo.complete ? "COMPLETED" : "NEE *p = '\0';
DS-ACTION"); }
fprintf(out, "PRIORITY:%d"CRLF, mtodo->todo.priority); str_to_ical_str(text, sizeof(text), str1);
if (!mtodo->todo.indefinite) { fprintf(out, "SUMMARY:%s%s"CRLF, text,
fprintf(out, "DUE;VALUE=DATE:%04d%02d%02d"CRLF, strlen(str1) > 49 ? "..." : "");
mtodo->todo.due.tm_year+1900, str_to_ical_str(text, sizeof(text), mtodo->todo.description)
mtodo->todo.due.tm_mon+1, ;
mtodo->todo.due.tm_mday); fprintf(out, "DESCRIPTION:%s", text);
} if (mtodo->todo.note && mtodo->todo.note[0]) {
fprintf(out, "END:VTODO"CRLF); str_to_ical_str(text, sizeof(text), mtodo->todo.note);
if (temp_list->next == NULL) { fprintf(out, "\\n"CRLF" %s"CRLF, text);
fprintf(out, "END:VCALENDAR"CRLF); } else {
} fprintf(out, ""CRLF);
break; }
default: fprintf(out, "STATUS:%s"CRLF, mtodo->todo.complete ? "COMPLE
jp_logf(JP_LOG_WARN, _("Unknown export type\n")); TED" : "NEEDS-ACTION");
} fprintf(out, "PRIORITY:%d"CRLF, mtodo->todo.priority);
} if (!mtodo->todo.indefinite) {
fprintf(out, "DUE;VALUE=DATE:%04d%02d%02d"CRLF,
if (out) { mtodo->todo.due.tm_year + 1900,
fclose(out); mtodo->todo.due.tm_mon + 1,
} mtodo->todo.due.tm_mday);
} }
fprintf(out, "END:VTODO"CRLF);
static void cb_todo_update_clist(GtkWidget *clist, int category) if (temp_list->next == NULL) {
{ fprintf(out, "END:VCALENDAR"CRLF);
todo_update_clist(clist, NULL, &export_todo_list, category, FALSE); }
} break;
default:
static void cb_todo_export_done(GtkWidget *widget, const char *filename) jp_logf(JP_LOG_WARN, _("Unknown export type\n"));
{ }
free_ToDoList(&export_todo_list); }
}
set_pref(PREF_TODO_EXPORT_FILENAME, 0, filename, TRUE);
} if (out) {
fclose(out);
int todo_export(GtkWidget *window) }
{ }
int w, h, x, y;
char *type_text[]={N_("Text"), static void cb_todo_update_listStore(GtkWidget *exportTreeView, int category) {
N_("CSV"), if (exportTreeView == NULL || !GTK_IS_TREE_VIEW(exportTreeView)) {
N_("iCalendar"), return;
NULL}; }
int type_int[]={EXPORT_TYPE_TEXT, EXPORT_TYPE_CSV, EXPORT_TYPE_ICALENDAR}; todo_update_liststore(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(e
xportTreeView))), NULL,
gdk_window_get_size(window->window, &w, &h); &export_todo_list, category, FALSE);
gdk_window_get_root_origin(window->window, &x, &y); }
w = gtk_paned_get_position(GTK_PANED(pane)); static GtkWidget *cb_todo_init_treeView() {
x+=40; GtkListStore *listStore = gtk_list_store_new(TODO_NUM_COLS, G_TYPE_BOOLEAN,
G_TYPE_STRING, GDK_TYPE_PIXBUF,
export_gui(window, G_TYPE_STRING,
w, h, x, y, 5, sort_l, G_TYPE_STRING, G_TYPE_POINTER,
PREF_TODO_EXPORT_FILENAME, GDK_TYPE_RGBA, G_TYPE_BOOLEAN,
type_text, G_TYPE_STRING, G_TYPE_BOOLEAN);
type_int, GtkTreeModel *model = GTK_TREE_MODEL(listStore);
cb_todo_update_clist, GtkWidget *todo_treeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model
cb_todo_export_done, ));
cb_todo_export_ok GtkCellRenderer *taskRenderer = gtk_cell_renderer_text_new();
); // gtk_cell_renderer_set_fixed_size(taskRenderer, -1, 1);
GtkTreeViewColumn *taskColumn = gtk_tree_view_column_new_with_attributes("Ta
sk",
tas
kRenderer,
"te
xt", TODO_TEXT_COLUMN_ENUM,
"ce
ll-background-rgba",
TOD
O_BACKGROUND_COLOR_ENUM,
"ce
ll-background-set",
TOD
O_BACKGROUND_COLOR_ENABLED_ENUM,
NUL
L);
gtk_tree_view_column_set_sort_column_id(taskColumn, TODO_TEXT_COLUMN_ENUM);
GtkCellRenderer *dateRenderer = gtk_cell_renderer_text_new();
// gtk_cell_renderer_set_fixed_size(dateRenderer, -1, 1);
GtkTreeViewColumn *dateColumn = gtk_tree_view_column_new_with_attributes("Du
e",
dat
eRenderer,
"te
xt", TODO_DATE_COLUMN_ENUM,
"ce
ll-background-rgba",
TOD
O_BACKGROUND_COLOR_ENUM,
"ce
ll-background-set",
TOD
O_BACKGROUND_COLOR_ENABLED_ENUM,
"fo
reground", TODO_FOREGROUND_COLOR_ENUM,
"fo
reground-set",
TOD
O_FORGROUND_COLOR_ENABLED_ENUM,
NUL
L);
gtk_tree_view_column_set_sort_column_id(dateColumn, TODO_DATE_COLUMN_ENUM);
GtkCellRenderer *priorityRenderer = gtk_cell_renderer_text_new();
// gtk_cell_renderer_set_fixed_size(priorityRenderer, -1, 1);
GtkTreeViewColumn *priorityColumn = gtk_tree_view_column_new_with_attributes
("",
priorityRenderer,
"text", TODO_PRIORITY_COLUMN_ENUM,
"cell-background-rgba",
TODO_BACKGROUND_COLOR_ENUM,
"cell-background-set",
TODO_BACKGROUND_COLOR_ENABLED_ENUM,
NULL);
gtk_tree_view_column_set_sort_column_id(priorityColumn, TODO_PRIORITY_COLUMN
_ENUM);
GtkCellRenderer *noteRenderer = gtk_cell_renderer_pixbuf_new();
GtkTreeViewColumn *noteColumn = gtk_tree_view_column_new_with_attributes("",
not
eRenderer,
"pi
xbuf", TODO_NOTE_COLUMN_ENUM,
"ce
ll-background-rgba",
TOD
O_BACKGROUND_COLOR_ENUM,
"ce
ll-background-set",
TOD
O_BACKGROUND_COLOR_ENABLED_ENUM,
NUL
L);
gtk_tree_view_column_set_sort_column_id(noteColumn, TODO_NOTE_COLUMN_ENUM);
GtkCellRenderer *checkRenderer = gtk_cell_renderer_toggle_new();
GtkTreeViewColumn *checkColumn = gtk_tree_view_column_new_with_attributes(""
, checkRenderer, "active",
TO
DO_CHECK_COLUMN_ENUM,
"c
ell-background-rgba",
TO
DO_BACKGROUND_COLOR_ENUM,
"c
ell-background-set",
TO
DO_BACKGROUND_COLOR_ENABLED_ENUM, NULL);
gtk_tree_view_insert_column(GTK_TREE_VIEW (todo_treeView), checkColumn, TODO
_CHECK_COLUMN_ENUM);
gtk_tree_view_insert_column(GTK_TREE_VIEW (todo_treeView), priorityColumn, T
ODO_PRIORITY_COLUMN_ENUM);
gtk_tree_view_insert_column(GTK_TREE_VIEW (todo_treeView), noteColumn, TODO_
NOTE_COLUMN_ENUM);
gtk_tree_view_insert_column(GTK_TREE_VIEW (todo_treeView), dateColumn, TODO_
DATE_COLUMN_ENUM);
gtk_tree_view_insert_column(GTK_TREE_VIEW (todo_treeView), taskColumn, TODO_
TEXT_COLUMN_ENUM);
gtk_tree_view_column_set_clickable(checkColumn, gtk_false());
gtk_tree_view_column_set_clickable(priorityColumn, gtk_false());
gtk_tree_view_column_set_clickable(noteColumn, gtk_false());
gtk_tree_view_column_set_clickable(dateColumn, gtk_false());
gtk_tree_view_column_set_clickable(taskColumn, gtk_false());
gtk_tree_view_column_set_sizing(checkColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_sizing(dateColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_sizing(priorityColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZ
E);
gtk_tree_view_column_set_sizing(noteColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_sizing(taskColumn, GTK_TREE_VIEW_COLUMN_FIXED);
return GTK_WIDGET(todo_treeView);
}
static void cb_todo_export_done(GtkWidget *widget, const char *filename) {
free_ToDoList(&export_todo_list);
if (widget != NULL && GTK_IS_TREE_VIEW(widget)) {
gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIE
W(widget))));
}
set_pref(PREF_TODO_EXPORT_FILENAME, 0, filename, TRUE);
}
int todo_export(GtkWidget *window) {
int w, h, x, y;
char *type_text[] = {N_("Text"),
N_("CSV"),
N_("iCalendar"),
NULL};
int type_int[] = {EXPORT_TYPE_TEXT, EXPORT_TYPE_CSV, EXPORT_TYPE_ICALENDAR};
w = gdk_window_get_width(gtk_widget_get_window(window));
h = gdk_window_get_height(gtk_widget_get_window(window));
gdk_window_get_root_origin(gtk_widget_get_window(window), &x, &y);
w = gtk_paned_get_position(GTK_PANED(pane));
x += 40;
export_gui(window,
w, h, x, y, 5, sort_l,
PREF_TODO_EXPORT_FILENAME,
type_text,
type_int,
cb_todo_init_treeView,
cb_todo_update_listStore,
cb_todo_export_done,
cb_todo_export_ok
);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* /*
* End Export Code * End Export Code
*/ */
/* Find position of category in sorted category array /* Find position of category in sorted category array
* via its assigned category number */ * via its assigned category number */
static int find_sort_cat_pos(int cat) static int find_sort_cat_pos(int cat) {
{ int i;
int i;
for (i = 0; i < NUM_TODO_CAT_ITEMS; i++) {
for (i=0; i<NUM_TODO_CAT_ITEMS; i++) { if (sort_l[i].cat_num == cat) {
if (sort_l[i].cat_num==cat) { return i;
return i; }
} }
}
return -1; return -1;
} }
/* Find a category's position in the category menu. /* Find a category's position in the category menu.
* This is equal to the category number except for the Unfiled category. * This is equal to the category number except for the Unfiled category.
* The Unfiled category is always in the last position which changes as * The Unfiled category is always in the last position which changes as
* the number of categories changes */ * the number of categories changes */
static int find_menu_cat_pos(int cat) static int find_menu_cat_pos(int cat) {
{ int i;
int i;
if (cat != NUM_TODO_CAT_ITEMS - 1) {
if (cat != NUM_TODO_CAT_ITEMS-1) { return cat;
return cat; } else { /* Unfiled category */
} else { /* Unfiled category */ /* Count how many category entries are filled */
/* Count how many category entries are filled */ for (i = 0; i < NUM_TODO_CAT_ITEMS; i++) {
for (i=0; i<NUM_TODO_CAT_ITEMS; i++) { if (!sort_l[i].Pcat[0]) {
if (!sort_l[i].Pcat[0]) { return i;
return i; }
} }
} return 0;
return 0; }
} }
gboolean deleteRecord(GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data) {
int *i = gtk_tree_path_get_indices(path);
if (i[0] == row_selected) {
MyToDo *mytodo = NULL;
gtk_tree_model_get(model, iter, TODO_DATA_COLUMN_ENUM, &mytodo, -1);
deleteTodo(mytodo, data);
return TRUE;
}
return FALSE;
}
void deleteTodo(MyToDo *mtodo, gpointer data) {
int flag;
int show_priv;
long char_set;
if (mtodo < (MyToDo *) LIST_MIN_DATA) {
return;
}
/* Convert to Palm character set */
get_pref(PREF_CHAR_SET, &char_set, NULL);
if (char_set != CHAR_SET_LATIN1) {
if (mtodo->todo.description)
charset_j2p(mtodo->todo.description, (int) strlen(mtodo->todo.descri
ption) + 1, char_set);
if (mtodo->todo.note)
charset_j2p(mtodo->todo.note, (int) strlen(mtodo->todo.note) + 1, ch
ar_set);
}
/* Do masking like Palm OS 3.5 */
show_priv = show_privates(GET_PRIVATES);
if ((show_priv != SHOW_PRIVATES) &&
(mtodo->attrib & dlpRecAttrSecret)) {
return;
}
/* End Masking */
flag = GPOINTER_TO_INT(data);
if ((flag == MODIFY_FLAG) || (flag == DELETE_FLAG)) {
jp_logf(JP_LOG_DEBUG, "calling delete_pc_record\n");
delete_pc_record(TODO, mtodo, flag);
if (flag == DELETE_FLAG) {
/* when we redraw we want to go to the line above the deleted one */
if (row_selected > 0) {
row_selected--;
}
}
}
if (flag == DELETE_FLAG) {
todo_redraw();
}
} }
static void cb_delete_todo(GtkWidget *widget, static void cb_delete_todo(GtkWidget *widget,
gpointer data) gpointer data) {
{ gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), deleteRecord, data);
MyToDo *mtodo; return;
int flag;
int show_priv; }
long char_set;
gboolean undeleteRecord(GtkTreeModel *model,
mtodo = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected); GtkTreePath *path,
if (mtodo < (MyToDo *)CLIST_MIN_DATA) { GtkTreeIter *iter,
return; gpointer data) {
} int *i = gtk_tree_path_get_indices(path);
if (i[0] == row_selected) {
/* Convert to Palm character set */ MyToDo *mytodo = NULL;
get_pref(PREF_CHAR_SET, &char_set, NULL); gtk_tree_model_get(model, iter, TODO_DATA_COLUMN_ENUM, &mytodo, -1);
if (char_set != CHAR_SET_LATIN1) { undeleteTodo(mytodo, data);
if (mtodo->todo.description) return TRUE;
charset_j2p(mtodo->todo.description, strlen(mtodo->todo.description)+1, }
char_set);
if (mtodo->todo.note) return FALSE;
charset_j2p(mtodo->todo.note, strlen(mtodo->todo.note)+1, char_set);
} }
/* Do masking like Palm OS 3.5 */ gboolean printRecord(GtkTreeModel *model,
show_priv = show_privates(GET_PRIVATES); GtkTreePath *path,
if ((show_priv != SHOW_PRIVATES) && GtkTreeIter *iter,
(mtodo->attrib & dlpRecAttrSecret)) { gpointer data) {
return; int *i = gtk_tree_path_get_indices(path);
} if (i[0] == row_selected) {
/* End Masking */ MyToDo *mytodo = NULL;
flag = GPOINTER_TO_INT(data); gtk_tree_model_get(model, iter, TODO_DATA_COLUMN_ENUM, &mytodo, -1);
if ((flag==MODIFY_FLAG) || (flag==DELETE_FLAG)) { printTodo(mytodo, data);
jp_logf(JP_LOG_DEBUG, "calling delete_pc_record\n"); return TRUE;
delete_pc_record(TODO, mtodo, flag); }
if (flag==DELETE_FLAG) {
/* when we redraw we want to go to the line above the deleted one */ return FALSE;
if (clist_row_selected>0) {
clist_row_selected--; }
}
} void undeleteTodo(MyToDo *mtodo, gpointer data) {
} int flag;
int show_priv;
if (flag == DELETE_FLAG) { if (mtodo < (MyToDo *) LIST_MIN_DATA) {
todo_clist_redraw(); return;
} }
/* Do masking like Palm OS 3.5 */
show_priv = show_privates(GET_PRIVATES);
if ((show_priv != SHOW_PRIVATES) &&
(mtodo->attrib & dlpRecAttrSecret)) {
return;
}
/* End Masking */
jp_logf(JP_LOG_DEBUG, "mtodo->unique_id = %d\n", mtodo->unique_id);
jp_logf(JP_LOG_DEBUG, "mtodo->rt = %d\n", mtodo->rt);
flag = GPOINTER_TO_INT(data);
if (flag == UNDELETE_FLAG) {
if (mtodo->rt == DELETED_PALM_REC ||
mtodo->rt == DELETED_PC_REC) {
undelete_pc_record(TODO, mtodo, flag);
}
/* Possible later addition of undelete for modified records
else if (mtodo->rt == MODIFIED_PALM_REC)
{
cb_add_new_record(widget, GINT_TO_POINTER(COPY_FLAG));
}
*/
}
todo_redraw();
} }
static void cb_undelete_todo(GtkWidget *widget, static void cb_undelete_todo(GtkWidget *widget,
gpointer data) gpointer data) {
{
MyToDo *mtodo; gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), undeleteRecord, data);
int flag; return;
int show_priv;
}
mtodo = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected);
if (mtodo < (MyToDo *)CLIST_MIN_DATA) { static void cb_cancel(GtkWidget *widget, gpointer data) {
return; set_new_button_to(CLEAR_FLAG);
} todo_refresh();
}
/* Do masking like Palm OS 3.5 */
show_priv = show_privates(GET_PRIVATES); static void cb_edit_cats(GtkWidget *widget, gpointer data) {
if ((show_priv != SHOW_PRIVATES) && struct ToDoAppInfo ai;
(mtodo->attrib & dlpRecAttrSecret)) { char db_name[FILENAME_MAX];
return; char pdb_name[FILENAME_MAX];
} char full_name[FILENAME_MAX];
/* End Masking */ unsigned char buffer[65536];
int num;
jp_logf(JP_LOG_DEBUG, "mtodo->unique_id = %d\n",mtodo->unique_id); size_t size;
jp_logf(JP_LOG_DEBUG, "mtodo->rt = %d\n",mtodo->rt); void *buf;
struct pi_file *pf;
flag = GPOINTER_TO_INT(data);
if (flag==UNDELETE_FLAG) {
if (mtodo->rt == DELETED_PALM_REC ||
mtodo->rt == DELETED_PC_REC)
{
undelete_pc_record(TODO, mtodo, flag);
}
/* Possible later addition of undelete for modified records
else if (mtodo->rt == MODIFIED_PALM_REC)
{
cb_add_new_record(widget, GINT_TO_POINTER(COPY_FLAG));
}
*/
}
todo_clist_redraw();
}
static void cb_cancel(GtkWidget *widget, gpointer data)
{
set_new_button_to(CLEAR_FLAG);
todo_refresh();
}
static void cb_edit_cats(GtkWidget *widget, gpointer data)
{
struct ToDoAppInfo ai;
char db_name[FILENAME_MAX];
char pdb_name[FILENAME_MAX];
char full_name[FILENAME_MAX];
unsigned char buffer[65536];
int num;
size_t size;
void *buf;
struct pi_file *pf;
#ifdef ENABLE_MANANA #ifdef ENABLE_MANANA
long ivalue; long ivalue;
#endif #endif
jp_logf(JP_LOG_DEBUG, "cb_edit_cats\n"); jp_logf(JP_LOG_DEBUG, "cb_edit_cats\n");
#ifdef ENABLE_MANANA #ifdef ENABLE_MANANA
get_pref(PREF_MANANA_MODE, &ivalue, NULL); get_pref(PREF_MANANA_MODE, &ivalue, NULL);
if (ivalue) { if (ivalue) {
strcpy(pdb_name, "MananaDB.pdb"); strcpy(pdb_name, "MananaDB.pdb");
strcpy(db_name, "MananaDB"); strcpy(db_name, "MananaDB");
} else { } else {
strcpy(pdb_name, "ToDoDB.pdb"); strcpy(pdb_name, "ToDoDB.pdb");
strcpy(db_name, "ToDoDB"); strcpy(db_name, "ToDoDB");
} }
#else #else
strcpy(pdb_name, "ToDoDB.pdb"); strcpy(pdb_name, "ToDoDB.pdb");
strcpy(db_name, "ToDoDB"); strcpy(db_name, "ToDoDB");
#endif #endif
get_home_file_name(pdb_name, full_name, sizeof(full_name)); get_home_file_name(pdb_name, full_name, sizeof(full_name));
buf=NULL; buf = NULL;
memset(&ai, 0, sizeof(ai)); memset(&ai, 0, sizeof(ai));
pf = pi_file_open(full_name); pf = pi_file_open(full_name);
pi_file_get_app_info(pf, &buf, &size); pi_file_get_app_info(pf, &buf, &size);
num = unpack_ToDoAppInfo(&ai, buf, size); num = unpack_ToDoAppInfo(&ai, buf, size);
if (num <= 0) { if (num <= 0) {
jp_logf(JP_LOG_WARN, _("Error reading file: %s\n"), pdb_name); jp_logf(JP_LOG_WARN, _("Error reading file: %s\n"), pdb_name);
return; return;
} }
pi_file_close(pf); pi_file_close(pf);
edit_cats(widget, db_name, &(ai.category)); edit_cats(widget, db_name, &(ai.category));
size = pack_ToDoAppInfo(&ai, buffer, sizeof(buffer)); size = (size_t) pack_ToDoAppInfo(&ai, buffer, sizeof(buffer));
pdb_file_write_app_block(db_name, buffer, size); pdb_file_write_app_block(db_name, buffer, (int) size);
cb_app_button(NULL, GINT_TO_POINTER(REDRAW)); cb_app_button(NULL, GINT_TO_POINTER(REDRAW));
} }
static void cb_category(GtkWidget *item, int selection) static void cb_category(GtkComboBox *item, int selection) {
{ int b;
int b; if (!item) return;
if (gtk_combo_box_get_active(GTK_COMBO_BOX(item)) < 0) {
return;
}
int selectedItem = get_selected_category_from_combo_box(item);
if (selectedItem == -1) {
return;
}
if ((GTK_CHECK_MENU_ITEM(item))->active) { if (todo_category == selectedItem) { return; }
if (todo_category == selection) { return; }
b=dialog_save_changed_record_with_cancel(pane, record_changed); b = dialog_save_changed_record_with_cancel(pane, record_changed);
if (b==DIALOG_SAID_1) { /* Cancel */ if (b == DIALOG_SAID_1) { /* Cancel */
int index, index2; int index, index2;
if (todo_category==CATEGORY_ALL) { if (todo_category == CATEGORY_ALL) {
index = 0; index = 0;
index2 = 0; index2 = 0;
} else { } else {
index = find_sort_cat_pos(todo_category); index = find_sort_cat_pos(todo_category);
index2 = find_menu_cat_pos(index) + 1; index2 = find_menu_cat_pos(index) + 1;
index += 1; index += 1;
} }
if (index<0) { if (index < 0) {
jp_logf(JP_LOG_WARN, _("Category is not legal\n")); jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
} else { } else {
gtk_check_menu_item_set_active gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu1), index2);
(GTK_CHECK_MENU_ITEM(todo_cat_menu_item1[index]), TRUE); }
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu1), index2)
; return;
} }
if (b == DIALOG_SAID_3) { /* Save */
return; cb_add_new_record(NULL, GINT_TO_POINTER(record_changed));
} }
if (b==DIALOG_SAID_3) { /* Save */
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed)); if (selectedItem == CATEGORY_EDIT) {
} cb_edit_cats(GTK_WIDGET(item), NULL);
} else {
if (selection==NUM_TODO_CAT_ITEMS+1) { todo_category = selectedItem;
cb_edit_cats(item, NULL); }
} else { row_selected = 0;
todo_category = selection; jp_logf(JP_LOG_DEBUG, "todo_category = %d\n", todo_category);
} todo_update_liststore(listStore, category_menu1, &glob_todo_list, todo_categ
clist_row_selected = 0; ory, TRUE);
jp_logf(JP_LOG_DEBUG, "todo_category = %d\n",todo_category); }
todo_update_clist(clist, category_menu1, &glob_todo_list, todo_category, T
RUE); static void cb_check_button_no_due_date(GtkWidget *widget, gpointer data) {
} long till_due;
} struct tm *now;
time_t ltime;
static void cb_check_button_no_due_date(GtkWidget *widget, gpointer data)
{ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
long till_due; update_due_button(due_date_button, NULL);
struct tm *now; } else {
time_t ltime; time(&ltime);
now = localtime(&ltime);
if (GTK_TOGGLE_BUTTON(widget)->active) { memcpy(&due_date, now, sizeof(struct tm));
update_due_button(due_date_button, NULL);
} else { get_pref(PREF_TODO_DAYS_TILL_DUE, &till_due, NULL);
time(&ltime); add_days_to_date(&due_date, (int) till_due);
now = localtime(&ltime);
memcpy(&due_date, now, sizeof(struct tm)); update_due_button(due_date_button, &due_date);
}
get_pref(PREF_TODO_DAYS_TILL_DUE, &till_due, NULL); }
add_days_to_date(&due_date, till_due);
static int todo_clear_details(void) {
update_due_button(due_date_button, &due_date); time_t ltime;
} struct tm *now;
} int new_cat;
int sorted_position;
static int todo_clear_details(void) long default_due, till_due;
{
time_t ltime; time(&ltime);
struct tm *now; now = localtime(&ltime);
int new_cat;
int sorted_position; /* Need to disconnect these signals first */
long default_due, till_due; connect_changed_signals(DISCONNECT_SIGNALS);
time(&ltime); gtk_widget_freeze_child_notify(todo_desc);
now = localtime(&ltime); gtk_widget_freeze_child_notify(todo_note);
/* Need to disconnect these signals first */ gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_desc_buffer), "", -1);
connect_changed_signals(DISCONNECT_SIGNALS); gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_note_buffer), "", -1);
gtk_widget_freeze_child_notify(todo_desc); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_button_todo[0]), TRUE);
gtk_widget_freeze_child_notify(todo_note);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(todo_completed_checkbox), FAL
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_desc_buffer), "", -1); SE);
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_note_buffer), "", -1);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(private_checkbox), FALSE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_button_todo[0]), TRUE);
get_pref(PREF_TODO_DAYS_DUE, &default_due, NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(todo_completed_checkbox), FALS get_pref(PREF_TODO_DAYS_TILL_DUE, &till_due, NULL);
E); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(todo_no_due_date_checkbox),
!default_due);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(private_checkbox), FALSE);
memcpy(&due_date, now, sizeof(struct tm));
get_pref(PREF_TODO_DAYS_DUE, &default_due, NULL);
get_pref(PREF_TODO_DAYS_TILL_DUE, &till_due, NULL); if (default_due) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(todo_no_due_date_checkbox), add_days_to_date(&due_date, (int) till_due);
! default_due); update_due_button(due_date_button, &due_date);
} else {
memcpy(&due_date, now, sizeof(struct tm)); update_due_button(due_date_button, NULL);
}
if (default_due) {
add_days_to_date(&due_date, till_due); gtk_widget_thaw_child_notify(todo_desc);
update_due_button(due_date_button, &due_date); gtk_widget_thaw_child_notify(todo_note);
} else {
update_due_button(due_date_button, NULL); if (todo_category == CATEGORY_ALL) {
} new_cat = 0;
} else {
gtk_widget_thaw_child_notify(todo_desc); new_cat = todo_category;
gtk_widget_thaw_child_notify(todo_note); }
sorted_position = find_sort_cat_pos(new_cat);
if (todo_category==CATEGORY_ALL) { if (sorted_position < 0) {
new_cat = 0; jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
} else { } else {
new_cat = todo_category; gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu2), find_menu_cat_po
} s(sorted_position));
sorted_position = find_sort_cat_pos(new_cat); }
if (sorted_position<0) {
jp_logf(JP_LOG_WARN, _("Category is not legal\n")); set_new_button_to(CLEAR_FLAG);
} else { connect_changed_signals(CONNECT_SIGNALS);
gtk_check_menu_item_set_active
(GTK_CHECK_MENU_ITEM(todo_cat_menu_item2[sorted_position]), TRUE); return EXIT_SUCCESS;
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu2), }
find_menu_cat_pos(sorted_position));
} static int todo_get_details(struct ToDo *new_todo, unsigned char *attrib) {
int i;
set_new_button_to(CLEAR_FLAG); GtkTextIter start_iter;
connect_changed_signals(CONNECT_SIGNALS); GtkTextIter end_iter;
return EXIT_SUCCESS; new_todo->indefinite = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(todo_
} no_due_date_checkbox)));
if (!(new_todo->indefinite)) {
static int todo_get_details(struct ToDo *new_todo, unsigned char *attrib) new_todo->due.tm_mon = due_date.tm_mon;
{ new_todo->due.tm_mday = due_date.tm_mday;
int i; new_todo->due.tm_year = due_date.tm_year;
GtkTextIter start_iter; jp_logf(JP_LOG_DEBUG, "todo_get_details: setting due date=%d/%d/%d\n", n
GtkTextIter end_iter; ew_todo->due.tm_mon,
new_todo->due.tm_mday, new_todo->due.tm_year);
new_todo->indefinite = (GTK_TOGGLE_BUTTON(todo_no_due_date_checkbox)->active) } else {
; memset(&(new_todo->due), 0, sizeof(new_todo->due));
if (!(new_todo->indefinite)) { }
new_todo->due.tm_mon = due_date.tm_mon; new_todo->priority = 1;
new_todo->due.tm_mday = due_date.tm_mday; for (i = 0; i < NUM_TODO_PRIORITIES; i++) {
new_todo->due.tm_year = due_date.tm_year; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_button_todo[i])
jp_logf(JP_LOG_DEBUG, "todo_get_details: setting due date=%d/%d/%d\n", new )) {
_todo->due.tm_mon, new_todo->priority = i + 1;
new_todo->due.tm_mday, new_todo->due.tm_year);
} else {
memset(&(new_todo->due), 0, sizeof(new_todo->due));
}
new_todo->priority=1;
for (i=0; i<NUM_TODO_PRIORITIES; i++) {
if (GTK_TOGGLE_BUTTON(radio_button_todo[i])->active) {
new_todo->priority=i+1;
break;
}
}
new_todo->complete = (GTK_TOGGLE_BUTTON(todo_completed_checkbox)->active);
/* Can there be an entry with no description? */
/* Yes, but the Palm Pilot gui doesn't allow it to be entered on the Palm, */
/* it will show it though. I allow it. */
gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(todo_desc_buffer),
&start_iter,&end_iter);
new_todo->description = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(todo_desc_bu
ffer),
&start_iter,&end_iter,TRUE);
gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(todo_note_buffer),
&start_iter,&end_iter);
new_todo->note = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(todo_note_buffer),
&start_iter,&end_iter,TRUE);
if (new_todo->note[0]=='\0') {
free(new_todo->note);
new_todo->note=NULL;
}
for (i=0; i<NUM_TODO_CAT_ITEMS; i++) {
if (GTK_IS_WIDGET(todo_cat_menu_item2[i])) {
if (GTK_CHECK_MENU_ITEM(todo_cat_menu_item2[i])->active) {
*attrib = sort_l[i].cat_num;
break; break;
} }
} }
} new_todo->complete = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(todo_co
if (GTK_TOGGLE_BUTTON(private_checkbox)->active) { mpleted_checkbox)));
*attrib |= dlpRecAttrSecret; /* Can there be an entry with no description? */
} /* Yes, but the Palm Pilot gui doesn't allow it to be entered on the Palm, *
/
/* it will show it though. I allow it. */
gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(todo_desc_buffer),
&start_iter, &end_iter);
new_todo->description = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(todo_desc_b
uffer),
&start_iter, &end_iter, TRU
E);
gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(todo_note_buffer),
&start_iter, &end_iter);
new_todo->note = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(todo_note_buffer),
&start_iter, &end_iter, TRUE);
if (new_todo->note[0] == '\0') {
free(new_todo->note);
new_todo->note = NULL;
}
if (GTK_IS_WIDGET(category_menu2)) {
*attrib = get_selected_category_from_combo_box(GTK_COMBO_BOX(category_me
nu2));
}
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(private_checkbox))) {
*attrib |= dlpRecAttrSecret;
}
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
jp_logf(JP_LOG_DEBUG, "attrib = %d\n", *attrib); jp_logf(JP_LOG_DEBUG, "attrib = %d\n", *attrib);
jp_logf(JP_LOG_DEBUG, "indefinite=%d\n",new_todo->indefinite); jp_logf(JP_LOG_DEBUG, "indefinite=%d\n",new_todo->indefinite);
if (!new_todo->indefinite) { if (!new_todo->indefinite) {
jp_logf(JP_LOG_DEBUG, "due: %d/%d/%d\n",new_todo->due.tm_mon, jp_logf(JP_LOG_DEBUG, "due: %d/%d/%d\n",new_todo->due.tm_mon,
new_todo->due.tm_mday, new_todo->due.tm_mday,
new_todo->due.tm_year); new_todo->due.tm_year);
} }
jp_logf(JP_LOG_DEBUG, "priority=%d\n",new_todo->priority); jp_logf(JP_LOG_DEBUG, "priority=%d\n",new_todo->priority);
jp_logf(JP_LOG_DEBUG, "complete=%d\n",new_todo->complete); jp_logf(JP_LOG_DEBUG, "complete=%d\n",new_todo->complete);
jp_logf(JP_LOG_DEBUG, "description=[%s]\n",new_todo->description); jp_logf(JP_LOG_DEBUG, "description=[%s]\n",new_todo->description);
jp_logf(JP_LOG_DEBUG, "note=[%s]\n",new_todo->note); jp_logf(JP_LOG_DEBUG, "note=[%s]\n",new_todo->note);
#endif #endif
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
static void cb_add_new_record(GtkWidget *widget, gpointer data) gboolean
{ addNewRecord(GtkTreeModel *model,
MyToDo *mtodo; GtkTreePath *path,
struct ToDo new_todo; GtkTreeIter *iter,
unsigned char attrib = 0; gpointer data) {
int flag;
int show_priv; int *i = gtk_tree_path_get_indices(path);
unsigned int unique_id; if (i[0] == row_selected) {
MyToDo *mytodo = NULL;
flag=GPOINTER_TO_INT(data); gtk_tree_model_get(model, iter, TODO_DATA_COLUMN_ENUM, &mytodo, -1);
unique_id = 0; addNewRecordToDataStructure(mytodo, data);
mtodo=NULL; return TRUE;
}
/* Do masking like Palm OS 3.5 */ return FALSE;
if ((flag==COPY_FLAG) || (flag==MODIFY_FLAG)) {
show_priv = show_privates(GET_PRIVATES); }
mtodo = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected);
if (mtodo < (MyToDo *)CLIST_MIN_DATA) { void addNewRecordToDataStructure(MyToDo *mtodo, gpointer data) {
return;
} struct ToDo new_todo;
if ((show_priv != SHOW_PRIVATES) && unsigned char attrib = 0;
(mtodo->attrib & dlpRecAttrSecret)) { int flag;
return; int show_priv;
} unsigned int unique_id;
} flag = GPOINTER_TO_INT(data);
/* End Masking */ unique_id = 0;
if (flag==CLEAR_FLAG) {
/* Clear button was hit */ //while(gtk_tree_path_)
todo_clear_details(); /* Do masking like Palm OS 3.5 */
connect_changed_signals(DISCONNECT_SIGNALS); if ((flag == COPY_FLAG) || (flag == MODIFY_FLAG)) {
set_new_button_to(NEW_FLAG); show_priv = show_privates(GET_PRIVATES);
gtk_widget_grab_focus(GTK_WIDGET(todo_desc)); if (mtodo < (MyToDo *) LIST_MIN_DATA) {
return; return;
} }
if ((flag!=NEW_FLAG) && (flag!=MODIFY_FLAG) && (flag!=COPY_FLAG)) { if ((show_priv != SHOW_PRIVATES) &&
return; (mtodo->attrib & dlpRecAttrSecret)) {
} return;
if (flag==MODIFY_FLAG) { }
mtodo = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected); }
unique_id=mtodo->unique_id; /* End Masking */
if (mtodo < (MyToDo *)CLIST_MIN_DATA) { if (flag == CLEAR_FLAG) {
return; /* Clear button was hit */
} todo_clear_details();
if ((mtodo->rt==DELETED_PALM_REC) || connect_changed_signals(DISCONNECT_SIGNALS);
(mtodo->rt==DELETED_PC_REC) || set_new_button_to(NEW_FLAG);
(mtodo->rt==MODIFIED_PALM_REC)) { gtk_widget_grab_focus(GTK_WIDGET(todo_desc));
jp_logf(JP_LOG_INFO, _("You can't modify a record that is deleted\n")); return;
return; }
} if ((flag != NEW_FLAG) && (flag != MODIFY_FLAG) && (flag != COPY_FLAG)) {
} return;
todo_get_details(&new_todo, &attrib); }
if (flag == MODIFY_FLAG) {
set_new_button_to(CLEAR_FLAG);
unique_id = mtodo->unique_id;
if (flag==MODIFY_FLAG) { if (mtodo < (MyToDo *) LIST_MIN_DATA) {
cb_delete_todo(NULL, data); return;
if ((mtodo->rt==PALM_REC) || (mtodo->rt==REPLACEMENT_PALM_REC)) { }
pc_todo_write(&new_todo, REPLACEMENT_PALM_REC, attrib, &unique_id); if ((mtodo->rt == DELETED_PALM_REC) ||
} else { (mtodo->rt == DELETED_PC_REC) ||
unique_id=0; (mtodo->rt == MODIFIED_PALM_REC)) {
pc_todo_write(&new_todo, NEW_PC_REC, attrib, &unique_id); jp_logf(JP_LOG_INFO, _("You can't modify a record that is deleted\n"
} ));
} else { return;
unique_id=0; }
pc_todo_write(&new_todo, NEW_PC_REC, attrib, &unique_id); }
} todo_get_details(&new_todo, &attrib);
free_ToDo(&new_todo);
set_new_button_to(CLEAR_FLAG);
/* Don't return to modified record if search gui active */
if (!glob_find_id) { if (flag == MODIFY_FLAG) {
glob_find_id = unique_id; cb_delete_todo(NULL, data);
} if ((mtodo->rt == PALM_REC) || (mtodo->rt == REPLACEMENT_PALM_REC)) {
todo_clist_redraw(); pc_todo_write(&new_todo, REPLACEMENT_PALM_REC, attrib, &unique_id);
} else {
return; unique_id = 0;
pc_todo_write(&new_todo, NEW_PC_REC, attrib, &unique_id);
}
} else {
unique_id = 0;
pc_todo_write(&new_todo, NEW_PC_REC, attrib, &unique_id);
}
free_ToDo(&new_todo);
/* Don't return to modified record if search gui active */
if (!glob_find_id) {
glob_find_id = unique_id;
}
todo_redraw();
return;
}
static void cb_add_new_record(GtkWidget *widget, gpointer data) {
if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(listStore), NULL) != 0) {
gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), addNewRecord, data);
} else {
//no records exist in category yet.
addNewRecordToDataStructure(NULL, data);
}
} }
/* Do masking like Palm OS 3.5 */ /* Do masking like Palm OS 3.5 */
static void clear_mytodos(MyToDo *mtodo) static void clear_mytodos(MyToDo *mtodo) {
{ mtodo->unique_id = 0;
mtodo->unique_id=0; mtodo->attrib = (unsigned char) (mtodo->attrib & 0xF8);
mtodo->attrib=mtodo->attrib & 0xF8; mtodo->todo.complete = 0;
mtodo->todo.complete=0; mtodo->todo.priority = 1;
mtodo->todo.priority=1; mtodo->todo.indefinite = 1;
mtodo->todo.indefinite=1; if (mtodo->todo.description) {
if (mtodo->todo.description) { free(mtodo->todo.description);
free(mtodo->todo.description); mtodo->todo.description = strdup("");
mtodo->todo.description=strdup(""); }
} if (mtodo->todo.note) {
if (mtodo->todo.note) { free(mtodo->todo.note);
free(mtodo->todo.note); mtodo->todo.note = strdup("");
mtodo->todo.note=strdup(""); }
}
return; return;
} }
/* End Masking */ /* End Masking */
/* Function is used to sort clist based on the completed checkbox */ static gint sortNoteColumn(GtkTreeModel *model,
static gint GtkClistCompareCheckbox(GtkCList *clist, GtkTreeIter *left,
gconstpointer ptr1, GtkTreeIter *right,
gconstpointer ptr2) gpointer columnId) {
{ gint sortcol = GPOINTER_TO_INT(columnId);
GtkCListRow *row1; gint ret = 0;
GtkCListRow *row2; switch (sortcol) {
MyToDo *mtodo1; case TODO_NOTE_COLUMN_ENUM: {
MyToDo *mtodo2; ret = compareNoteColumn(model, left, right);
struct ToDo *todo1; }
struct ToDo *todo2; break;
default:
row1 = (GtkCListRow *) ptr1; break;
row2 = (GtkCListRow *) ptr2; }
return ret;
mtodo1 = row1->data;
mtodo2 = row2->data;
todo1 = &(mtodo1->todo);
todo2 = &(mtodo2->todo);
if (todo1->complete && !todo2->complete) {
return -1;
} else if (todo2->complete && !todo1->complete) {
return 1;
} else {
return 0;
}
}
/* Function is used to sort clist based on the Due Date field */
static gint GtkClistCompareDates(GtkCList *clist,
gconstpointer ptr1,
gconstpointer ptr2)
{
GtkCListRow *row1, *row2;
MyToDo *mtodo1,*mtodo2;
struct ToDo *todo1, *todo2;
time_t time1, time2;
row1 = (GtkCListRow *) ptr1;
row2 = (GtkCListRow *) ptr2;
mtodo1 = row1->data;
mtodo2 = row2->data;
todo1 = &(mtodo1->todo);
todo2 = &(mtodo2->todo);
if ( !(todo1->indefinite) && (todo2->indefinite) ) {
return -1;
}
if ( (todo1->indefinite) && !(todo2->indefinite) ) {
return 1;
}
/* Both todos have due dates which requires further comparison */
time1 = mktime(&(todo1->due));
time2 = mktime(&(todo2->due));
return(time1 - time2);
}
static void cb_clist_click_column(GtkWidget *clist, int column)
{
MyToDo *mtodo;
/* Remember currently selected item and return to it after sort
* This is critically important because sorting without updating the
* global variable clist_row_selected can cause data loss */
mtodo = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected);
if (mtodo < (MyToDo *)CLIST_MIN_DATA) {
glob_find_id = 0;
} else {
glob_find_id = mtodo->unique_id;
}
/* Clicking on same column toggles ascending/descending sort */
if (clist_col_selected == column)
{
if (GTK_CLIST(clist)->sort_type == GTK_SORT_ASCENDING) {
gtk_clist_set_sort_type(GTK_CLIST (clist), GTK_SORT_DESCENDING);
}
else {
gtk_clist_set_sort_type(GTK_CLIST (clist), GTK_SORT_ASCENDING);
}
}
else /* Always sort in ascending order when changing sort column */
{
gtk_clist_set_sort_type(GTK_CLIST (clist), GTK_SORT_ASCENDING);
}
clist_col_selected = column;
gtk_clist_set_sort_column(GTK_CLIST(clist), column);
switch (column) {
case TODO_CHECK_COLUMN: /* Checkbox column */
gtk_clist_set_compare_func(GTK_CLIST(clist),GtkClistCompareCheckbox);
break;
case TODO_DATE_COLUMN: /* Due Date column */
gtk_clist_set_compare_func(GTK_CLIST(clist),GtkClistCompareDates);
break;
default: /* All other columns can use GTK default sort function */
gtk_clist_set_compare_func(GTK_CLIST(clist),NULL);
break;
}
gtk_clist_sort (GTK_CLIST (clist));
/* Return to previously selected item */
todo_find();
}
static void cb_clist_selection(GtkWidget *clist,
gint row,
gint column,
GdkEventButton *event,
gpointer data)
{
struct ToDo *todo;
MyToDo *mtodo;
int b;
int index, sorted_position;
unsigned int unique_id = 0;
time_t ltime;
struct tm *now;
if ((record_changed==MODIFY_FLAG) || (record_changed==NEW_FLAG)) {
if (clist_row_selected == row) { return; }
mtodo = gtk_clist_get_row_data(GTK_CLIST(clist), row);
if (mtodo!=NULL) {
unique_id = mtodo->unique_id;
}
b=dialog_save_changed_record_with_cancel(pane, record_changed);
if (b==DIALOG_SAID_1) { /* Cancel */
if (clist_row_selected >=0)
{
clist_select_row(GTK_CLIST(clist), clist_row_selected, 0);
} else {
clist_row_selected = 0;
clist_select_row(GTK_CLIST(clist), 0, 0);
}
return;
}
if (b==DIALOG_SAID_3) { /* Save */
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed));
}
set_new_button_to(CLEAR_FLAG);
if (unique_id)
{
glob_find_id = unique_id;
todo_find();
} else {
clist_select_row(GTK_CLIST(clist), row, column);
}
return;
}
time(&ltime);
now = localtime(&ltime);
clist_row_selected=row;
mtodo = gtk_clist_get_row_data(GTK_CLIST(clist), row);
if (mtodo==NULL) {
return;
}
if (mtodo->rt == DELETED_PALM_REC ||
(mtodo->rt == DELETED_PC_REC))
/* Possible later addition of undelete code for modified deleted records
|| mtodo->rt == MODIFIED_PALM_REC
*/
{
set_new_button_to(UNDELETE_FLAG);
} else {
set_new_button_to(CLEAR_FLAG);
}
connect_changed_signals(DISCONNECT_SIGNALS);
if (mtodo==NULL) {
return;
}
todo=&(mtodo->todo);
gtk_widget_freeze_child_notify(todo_desc);
gtk_widget_freeze_child_notify(todo_note);
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_desc_buffer), "", -1);
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_note_buffer), "", -1);
index = mtodo->attrib & 0x0F;
sorted_position = find_sort_cat_pos(index);
if (todo_cat_menu_item2[sorted_position]==NULL) {
/* Illegal category */
jp_logf(JP_LOG_DEBUG, "Category is not legal\n");
index = sorted_position = 0;
sorted_position = find_sort_cat_pos(index);
}
if (sorted_position<0) {
jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
} else {
gtk_check_menu_item_set_active
(GTK_CHECK_MENU_ITEM(todo_cat_menu_item2[sorted_position]), TRUE);
}
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu2),
find_menu_cat_pos(sorted_position));
if (todo->description) {
if (todo->description[0]) {
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_desc_buffer), todo->descr
iption, -1);
}
}
if (todo->note) {
if (todo->note[0]) {
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_note_buffer), todo->note,
-1);
}
}
if ( (todo->priority<1) || (todo->priority>5) ) {
jp_logf(JP_LOG_WARN, _("Priority out of range\n"));
} else {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_button_todo[todo->pri
ority-1]), TRUE);
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(todo_completed_checkbox), todo
->complete);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(private_checkbox),
mtodo->attrib & dlpRecAttrSecret);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(todo_no_due_date_checkbox),
todo->indefinite);
if (!todo->indefinite) {
update_due_button(due_date_button, &(todo->due));
due_date.tm_mon=todo->due.tm_mon;
due_date.tm_mday=todo->due.tm_mday;
due_date.tm_year=todo->due.tm_year;
} else {
update_due_button(due_date_button, NULL);
due_date.tm_mon=now->tm_mon;
due_date.tm_mday=now->tm_mday;
due_date.tm_year=now->tm_year;
}
gtk_widget_thaw_child_notify(todo_desc);
gtk_widget_thaw_child_notify(todo_note);
/* If they have clicked on the checkmark box then do a modify */
if (column==0) {
gtk_signal_emit_by_name(GTK_OBJECT(todo_completed_checkbox), "clicked");
gtk_signal_emit_by_name(GTK_OBJECT(apply_record_button), "clicked");
}
connect_changed_signals(CONNECT_SIGNALS);
} }
static gboolean cb_key_pressed_left_side(GtkWidget *widget, gint compareCheckColumn(GtkTreeModel *model, GtkTreeIter *left, GtkTreeIter *rig
ht) {
gint ret;
gboolean *name1, *name2;
gtk_tree_model_get(GTK_TREE_MODEL(model), left, TODO_CHECK_COLUMN_ENUM, &nam
e1, -1);
gtk_tree_model_get(GTK_TREE_MODEL(model), right, TODO_CHECK_COLUMN_ENUM, &na
me2, -1);
if (!name1 && name2) {
ret = 1;
} else if (name1 && !name2) {
ret = -1;
} else {
ret = 0;
}
return ret;
}
gint compareNoteColumn(GtkTreeModel *model, GtkTreeIter *left, GtkTreeIter *righ
t) {
gint ret;
GdkPixbuf *note1, *note2;
gtk_tree_model_get(GTK_TREE_MODEL(model), left, TODO_NOTE_COLUMN_ENUM, &note
1, -1);
gtk_tree_model_get(GTK_TREE_MODEL(model), right, TODO_NOTE_COLUMN_ENUM, &not
e2, -1);
if (note1 == NULL && note2 == NULL) {
ret = 0;
} else if (note1 == NULL && note2 != NULL) {
ret = -1;
} else if (note1 != NULL && note2 == NULL) {
ret = 1;
} else {
ret = 0;
}
return ret;
}
static void column_clicked_cb(GtkTreeViewColumn *column) {
column_selected = gtk_tree_view_column_get_sort_column_id(column);
}
static void checkedCallBack(GtkCellRendererToggle *renderer, gchar *path, GtkLis
tStore *model) {
GtkTreeIter iter;
gboolean active;
MyToDo *mtodo;
active = gtk_cell_renderer_toggle_get_active(renderer);
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL (model), &iter, path);
gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, TODO_DATA_COLUMN_ENUM, &mto
do, -1);
if (active) {
// gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(renderer), 0, 0);
gtk_list_store_set(GTK_LIST_STORE (model), &iter, TODO_CHECK_COLUMN_ENUM
, FALSE, -1);
mtodo->todo.complete = 0;
} else {
// gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(renderer), 0.5, 0.5
);
gtk_list_store_set(GTK_LIST_STORE (model), &iter, TODO_CHECK_COLUMN_ENUM
, TRUE, -1);
mtodo->todo.complete = 1;
}
}
static gboolean handleRowSelection(GtkTreeSelection *selection,
GtkTreeModel *model,
GtkTreePath *path,
gboolean path_currently_selected,
gpointer userdata) {
GtkTreeIter iter;
struct ToDo *todo;
MyToDo *mtodo;
int b;
int index, sorted_position;
//unsigned int unique_id = 0;
time_t ltime;
struct tm *now;
if ((gtk_tree_model_get_iter(model, &iter, path)) && (!path_currently_select
ed)) {
int *i = gtk_tree_path_get_indices(path);
row_selected = i[0];
gtk_tree_model_get(model, &iter, TODO_DATA_COLUMN_ENUM, &mtodo, -1);
if ((record_changed == MODIFY_FLAG) || (record_changed == NEW_FLAG)) {
//if (mtodo != NULL) {
// unique_id = mtodo->unique_id;
//}
// We need to turn this "scroll with mouse held down" thing off
button_set_for_motion(0);
b = dialog_save_changed_record_with_cancel(pane, record_changed);
if (b == DIALOG_SAID_1) { /* Cancel */
return TRUE;
}
if (b == DIALOG_SAID_3) { /* Save */
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed));
}
set_new_button_to(CLEAR_FLAG);
return TRUE;
}
time(&ltime);
now = localtime(&ltime);
if (mtodo == NULL) {
return TRUE;
}
if (mtodo->rt == DELETED_PALM_REC ||
(mtodo->rt == DELETED_PC_REC))
/* Possible later addition of undelete code for modified deleted rec
ords
|| mtodo->rt == MODIFIED_PALM_REC
*/
{
set_new_button_to(UNDELETE_FLAG);
} else {
set_new_button_to(CLEAR_FLAG);
}
connect_changed_signals(DISCONNECT_SIGNALS);
//Not sure this is really needed as about 10 lines up does the same chec
k.
if (mtodo == NULL) {
return TRUE;
}
todo = &(mtodo->todo);
gtk_widget_freeze_child_notify(todo_desc);
gtk_widget_freeze_child_notify(todo_note);
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_desc_buffer), "", -1);
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_note_buffer), "", -1);
index = mtodo->attrib & 0x0F;
sorted_position = find_sort_cat_pos(index);
int pos = findSortedPostion(sorted_position, GTK_COMBO_BOX(category_menu
2));
if (pos != sorted_position && index != 0) {
/* Illegal category */
jp_logf(JP_LOG_DEBUG, "Category is not legal\n");
index = sorted_position = 0;
sorted_position = find_sort_cat_pos(index);
}
if (sorted_position < 0) {
jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
}
gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu2), find_menu_cat_po
s(sorted_position));
if (todo->description) {
if (todo->description[0]) {
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_desc_buffer), todo
->description, -1);
}
}
if (todo->note) {
if (todo->note[0]) {
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_note_buffer), todo
->note, -1);
}
}
if ((todo->priority < 1) || (todo->priority > 5)) {
jp_logf(JP_LOG_WARN, _("Priority out of range\n"));
} else {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_button_todo[tod
o->priority - 1]), TRUE);
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(todo_completed_checkbox),
todo->complete);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(private_checkbox),
mtodo->attrib & dlpRecAttrSecret);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(todo_no_due_date_checkbox
),
todo->indefinite);
if (!todo->indefinite) {
update_due_button(due_date_button, &(todo->due));
due_date.tm_mon = todo->due.tm_mon;
due_date.tm_mday = todo->due.tm_mday;
due_date.tm_year = todo->due.tm_year;
} else {
update_due_button(due_date_button, NULL);
due_date.tm_mon = now->tm_mon;
due_date.tm_mday = now->tm_mday;
due_date.tm_year = now->tm_year;
}
gtk_widget_thaw_child_notify(todo_desc);
gtk_widget_thaw_child_notify(todo_note);
/* If they have clicked on the checkmark box then do a modify */
/* if (column == 0) {
gtk_signal_emit_by_name(G_OBJECT(todo_completed_checkbox), "clicked
");
gtk_signal_emit_by_name(G_OBJECT(apply_record_button), "clicked");
}*/
connect_changed_signals(CONNECT_SIGNALS);
return TRUE;
}
// gtk_tree_model_get(model, &iter, TODO_TEXT_COLUMN_ENUM, &name, -1);
return TRUE; /* allow selection state to change */
}
static gboolean cb_key_pressed_left_side(GtkWidget *widget,
GdkEventKey *event, GdkEventKey *event,
gpointer next_widget) gpointer next_widget) {
{ GtkTextBuffer *text_buffer;
GtkTextBuffer *text_buffer; GtkTextIter iter;
GtkTextIter iter;
if (event->keyval == GDK_KEY_Return) {
if (event->keyval == GDK_Return) { g_signal_stop_emission_by_name(G_OBJECT(widget), "key_press_event");
gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event"); gtk_widget_grab_focus(GTK_WIDGET(next_widget));
gtk_widget_grab_focus(GTK_WIDGET(next_widget)); /* Position cursor at start of text */
/* Position cursor at start of text */ text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(next_widget));
text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(next_widget)); gtk_text_buffer_get_start_iter(text_buffer, &iter);
gtk_text_buffer_get_start_iter(text_buffer, &iter); gtk_text_buffer_place_cursor(text_buffer, &iter);
gtk_text_buffer_place_cursor(text_buffer, &iter); return TRUE;
return TRUE; }
}
return FALSE; return FALSE;
} }
static gboolean cb_key_pressed_right_side(GtkWidget *widget, static gboolean cb_key_pressed_right_side(GtkWidget *widget,
GdkEventKey *event, GdkEventKey *event,
gpointer data) gpointer data) {
{ if ((event->keyval == GDK_KEY_Return) && (event->state & GDK_SHIFT_MASK)) {
if ((event->keyval == GDK_Return) && (event->state & GDK_SHIFT_MASK)) { g_signal_stop_emission_by_name(G_OBJECT(widget), "key_press_event");
gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event"); gtk_widget_grab_focus(GTK_WIDGET(treeView));
/* Call clist_selection to handle any cleanup such as a modified record */ return TRUE;
cb_clist_selection(clist, clist_row_selected, TODO_PRIORITY_COLUMN, }
GINT_TO_POINTER(1), NULL); /* Call external editor for note text */
gtk_widget_grab_focus(GTK_WIDGET(clist)); if (data != NULL &&
return TRUE; (event->keyval == GDK_KEY_e) && (event->state & GDK_CONTROL_MASK)) {
} g_signal_stop_emission_by_name(G_OBJECT(widget), "key_press_event");
/* Call external editor for note text */
if (data != NULL && /* Get current text and place in temporary file */
(event->keyval == GDK_e) && (event->state & GDK_CONTROL_MASK)) { GtkTextIter start_iter;
gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event"); GtkTextIter end_iter;
char *text_out;
/* Get current text and place in temporary file */
GtkTextIter start_iter; gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(todo_note_buffer),
GtkTextIter end_iter; &start_iter, &end_iter);
char *text_out; text_out = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(todo_note_buffer),
&start_iter, &end_iter, TRUE);
gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(todo_note_buffer),
&start_iter, &end_iter); char tmp_fname[] = "jpilot.XXXXXX";
text_out = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(todo_note_buffer), int tmpfd = mkstemp(tmp_fname);
&start_iter, &end_iter, TRUE); if (tmpfd < 0) {
jp_logf(JP_LOG_WARN, _("Could not get temporary file name\n"));
char tmp_fname[] = "jpilot.XXXXXX"; if (text_out)
int tmpfd = mkstemp(tmp_fname); free(text_out);
if (tmpfd < 0) return TRUE;
{ }
jp_logf(JP_LOG_WARN, _("Could not get temporary file name\n"));
if (text_out)
free(text_out);
return TRUE;
}
FILE *fptr = fdopen(tmpfd, "w"); FILE *fptr = fdopen(tmpfd, "w");
if (!fptr) { if (!fptr) {
jp_logf(JP_LOG_WARN, _("Could not open temporary file for external edit jp_logf(JP_LOG_WARN, _("Could not open temporary file for external e
or\n")); ditor\n"));
if (text_out) if (text_out)
free(text_out); free(text_out);
return TRUE; return TRUE;
} }
fwrite(text_out, strlen(text_out), 1, fptr); fwrite(text_out, strlen(text_out), 1, fptr);
fwrite("\n", 1, 1, fptr); fwrite("\n", 1, 1, fptr);
fclose(fptr); fclose(fptr);
/* Call external editor */ /* Call external editor */
char command[1024]; char command[1024];
const char *ext_editor; const char *ext_editor;
get_pref(PREF_EXTERNAL_EDITOR, NULL, &ext_editor); get_pref(PREF_EXTERNAL_EDITOR, NULL, &ext_editor);
if (!ext_editor) { if (!ext_editor) {
jp_logf(JP_LOG_INFO, "External Editor command empty\n"); jp_logf(JP_LOG_INFO, "External Editor command empty\n");
if (text_out) if (text_out)
free(text_out); free(text_out);
return TRUE; return TRUE;
} }
if ((strlen(ext_editor) + strlen(tmp_fname) + 1) > sizeof(command)) if ((strlen(ext_editor) + strlen(tmp_fname) + 1) > sizeof(command)) {
{ jp_logf(JP_LOG_WARN, _("External editor command too long to execute\
jp_logf(JP_LOG_WARN, _("External editor command too long to execute\n") n"));
); if (text_out)
if (text_out) free(text_out);
free(text_out);
return TRUE;
}
g_snprintf(command, sizeof(command), "%s %s", ext_editor, tmp_fname);
/* jp_logf(JP_LOG_STDOUT|JP_LOG_FILE, _("executing command = [%s]\n"), com
mand); */
if (system(command) == -1) {
/* Read data back from temporary file into memo */
char text_in[0xFFFF];
size_t bytes_read;
fptr = fopen(tmp_fname, "rb");
if (!fptr) {
jp_logf(JP_LOG_WARN, _("Could not open temporary file from external
editor\n"));
return TRUE; return TRUE;
} }
bytes_read = fread(text_in, 1, 0xFFFF, fptr); g_snprintf(command, sizeof(command), "%s %s", ext_editor, tmp_fname);
fclose(fptr);
unlink(tmp_fname);
text_in[--bytes_read] = '\0'; /* Strip final newline */
/* Only update text if it has changed */
if (strcmp(text_out, text_in)) {
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_note_buffer),
text_in, -1);
}
}
if (text_out)
free(text_out);
return TRUE;
} /* End of external editor if */
return FALSE;
}
void todo_clist_clear(GtkCList *clist)
{
GtkStyle *base_style, *row_style, *cell_style;
int i;
base_style = gtk_widget_get_style(GTK_WIDGET(clist));
for (i=0; i<GTK_CLIST(clist)->rows ; i++)
{
row_style = gtk_clist_get_row_style(GTK_CLIST(clist), i);
if (row_style && (row_style != base_style))
{
g_object_unref(row_style);
}
cell_style = gtk_clist_get_cell_style(GTK_CLIST(clist), i, TODO_DATE_COLUM
N);
if (cell_style && (cell_style != base_style))
{
g_object_unref(cell_style);
}
}
gtk_clist_clear(GTK_CLIST(clist));
}
void todo_update_clist(GtkWidget *clist, GtkWidget *tooltip_widget,
ToDoList **todo_list, int category, int main)
{
int num_entries, entries_shown, i;
gchar *empty_line[] = { "","","","","" };
GdkPixmap *pixmap_note;
GdkPixmap *pixmap_check;
GdkPixmap *pixmap_checked;
GdkBitmap *mask_note;
GdkBitmap *mask_check;
GdkBitmap *mask_checked;
ToDoList *temp_todo;
char str[50];
char str2[TODO_MAX_COLUMN_LEN+2];
const char *svalue;
long hide_completed, hide_not_due;
long show_tooltips;
int show_priv;
time_t ltime;
struct tm *now, *due;
int comp_now, comp_due;
free_ToDoList(todo_list);
/* Need to get all records including private ones for the tooltips calculatio
n */
num_entries = get_todos2(todo_list, SORT_ASCENDING, 2, 2, 1, 1, CATEGORY_ALL)
;
/* Start by clearing existing entry if in main window */
if (main) {
todo_clear_details();
}
/* Freeze clist to prevent flicker during updating */
gtk_clist_freeze(GTK_CLIST(clist));
if (main) {
gtk_signal_disconnect_by_func(GTK_OBJECT(clist),
GTK_SIGNAL_FUNC(cb_clist_selection), NULL);
}
todo_clist_clear(GTK_CLIST(clist));
#ifdef __APPLE__
gtk_clist_thaw(GTK_CLIST(clist));
gtk_widget_hide(clist);
gtk_widget_show_all(clist);
gtk_clist_freeze(GTK_CLIST(clist));
#endif
/* Collect preferences and constant pixmaps for loop */ /* jp_logf(JP_LOG_STDOUT|JP_LOG_FILE, _("executing command = [%s]\n"), c
get_pref(PREF_TODO_HIDE_COMPLETED, &hide_completed, NULL); ommand); */
get_pref(PREF_TODO_HIDE_NOT_DUE, &hide_not_due, NULL); if (system(command) == -1) {
show_priv = show_privates(GET_PRIVATES); /* Read data back from temporary file into memo */
get_pixmaps(clist, PIXMAP_NOTE, &pixmap_note, &mask_note); char text_in[0xFFFF];
get_pixmaps(clist, PIXMAP_BOX_CHECK, &pixmap_check, &mask_check); size_t bytes_read;
get_pixmaps(clist, PIXMAP_BOX_CHECKED, &pixmap_checked,&mask_checked);
#ifdef __APPLE__ fptr = fopen(tmp_fname, "rb");
mask_note = NULL; if (!fptr) {
mask_check = NULL; jp_logf(JP_LOG_WARN, _("Could not open temporary file from exter
mask_checked = NULL; nal editor\n"));
#endif return TRUE;
/* Current time used for calculating overdue items */ }
time(&ltime); bytes_read = fread(text_in, 1, 0xFFFF, fptr);
now = localtime(&ltime); fclose(fptr);
comp_now=now->tm_year*380+now->tm_mon*31+now->tm_mday-1; unlink(tmp_fname);
entries_shown=0; text_in[--bytes_read] = '\0'; /* Strip final newline */
for (temp_todo = *todo_list, i=0; temp_todo; temp_todo=temp_todo->next) { /* Only update text if it has changed */
if ( ((temp_todo->mtodo.attrib & 0x0F) != category) && if (strcmp(text_out, text_in)) {
category != CATEGORY_ALL) { gtk_text_buffer_set_text(GTK_TEXT_BUFFER(todo_note_buffer),
continue; text_in, -1);
} }
}
/* Do masking like Palm OS 3.5 */
if ((show_priv == MASK_PRIVATES) && if (text_out)
(temp_todo->mtodo.attrib & dlpRecAttrSecret)) { free(text_out);
gtk_clist_append(GTK_CLIST(clist), empty_line);
gtk_clist_set_text(GTK_CLIST(clist), entries_shown, TODO_CHECK_COLUMN, return TRUE;
"---"); } /* End of external editor if */
gtk_clist_set_text(GTK_CLIST(clist), entries_shown, TODO_PRIORITY_COLUM
N, "---"); return FALSE;
gtk_clist_set_text(GTK_CLIST(clist), entries_shown, TODO_TEXT_COLUMN, " }
--------------------");
gtk_clist_set_text(GTK_CLIST(clist), entries_shown, TODO_DATE_COLUMN, " void todo_liststore_clear(GtkListStore *pListStore) {
----------"); gtk_list_store_clear(pListStore);
clear_mytodos(&temp_todo->mtodo);
gtk_clist_set_row_data(GTK_CLIST(clist), entries_shown, &(temp_todo->mt
odo));
gtk_clist_set_row_style(GTK_CLIST(clist), entries_shown, NULL);
entries_shown++;
continue;
}
/* End Masking */
/* Allow a record found through search window to temporarily be
displayed even if it would normally be hidden by option settings */
if (!glob_find_id || (glob_find_id != temp_todo->mtodo.unique_id))
{
/* Hide the completed records if need be */
if (hide_completed && temp_todo->mtodo.todo.complete) {
continue;
}
/* Hide the not due yet records if need be */
if ((hide_not_due) && (!(temp_todo->mtodo.todo.indefinite))) {
due = &(temp_todo->mtodo.todo.due);
comp_due=due->tm_year*380+due->tm_mon*31+due->tm_mday-1;
if (comp_due > comp_now) {
continue;
}
}
}
/* Hide the private records if need be */
if ((show_priv != SHOW_PRIVATES) &&
(temp_todo->mtodo.attrib & dlpRecAttrSecret)) {
continue;
}
/* Add entry to clist */
gtk_clist_append(GTK_CLIST(clist), empty_line);
/* Put a checkbox or checked checkbox pixmap up */
if (temp_todo->mtodo.todo.complete) {
gtk_clist_set_pixmap(GTK_CLIST(clist), entries_shown, TODO_CHECK_COLUMN
, pixmap_checked, mask_checked);
} else {
gtk_clist_set_pixmap(GTK_CLIST(clist), entries_shown, TODO_CHECK_COLUMN
, pixmap_check, mask_check);
}
/* Print the priority number */
sprintf(str, "%d", temp_todo->mtodo.todo.priority);
gtk_clist_set_text(GTK_CLIST(clist), entries_shown, TODO_PRIORITY_COLUMN,
str);
/* Put a note pixmap up */
if (temp_todo->mtodo.todo.note[0]) {
gtk_clist_set_pixmap(GTK_CLIST(clist), entries_shown, TODO_NOTE_COLUMN,
pixmap_note, mask_note);
} else {
gtk_clist_set_text(GTK_CLIST(clist), entries_shown, TODO_NOTE_COLUMN, "
");
}
/* Print the due date */
if (!temp_todo->mtodo.todo.indefinite) {
get_pref(PREF_SHORTDATE, NULL, &svalue);
strftime(str, sizeof(str), svalue, &(temp_todo->mtodo.todo.due));
}
else {
sprintf(str, _("No date"));
}
gtk_clist_set_text(GTK_CLIST(clist), entries_shown, TODO_DATE_COLUMN, str)
;
/* Print the todo text */
lstrncpy_remove_cr_lfs(str2, temp_todo->mtodo.todo.description, TODO_MAX_C
OLUMN_LEN);
gtk_clist_set_text(GTK_CLIST(clist), entries_shown, TODO_TEXT_COLUMN, str2
);
gtk_clist_set_row_data(GTK_CLIST(clist), entries_shown, &(temp_todo->mtodo
));
/* Highlight row background depending on status */
switch (temp_todo->mtodo.rt) {
case NEW_PC_REC:
case REPLACEMENT_PALM_REC:
set_bg_rgb_clist_row(clist, entries_shown,
CLIST_NEW_RED, CLIST_NEW_GREEN, CLIST_NEW_BLUE);
break;
case DELETED_PALM_REC:
case DELETED_PC_REC:
set_bg_rgb_clist_row(clist, entries_shown,
CLIST_DEL_RED, CLIST_DEL_GREEN, CLIST_DEL_BLUE);
break;
case MODIFIED_PALM_REC:
set_bg_rgb_clist_row(clist, entries_shown,
CLIST_MOD_RED, CLIST_MOD_GREEN, CLIST_MOD_BLUE);
break;
default:
if (temp_todo->mtodo.attrib & dlpRecAttrSecret) {
set_bg_rgb_clist_row(clist, entries_shown,
CLIST_PRIVATE_RED, CLIST_PRIVATE_GREEN, CLIST_PRIVA
TE_BLUE);
} else {
gtk_clist_set_row_style(GTK_CLIST(clist), entries_shown, NULL);
}
}
/* Highlight dates of items overdue or due today */
if (!(temp_todo->mtodo.todo.indefinite)) {
due = &(temp_todo->mtodo.todo.due);
comp_due=due->tm_year*380+due->tm_mon*31+due->tm_mday-1;
if (comp_due < comp_now) {
set_fg_rgb_clist_cell(clist, entries_shown, TODO_DATE_COLUMN, CLIST_
OVERDUE_RED, CLIST_OVERDUE_GREEN, CLIST_OVERDUE_BLUE);
} else if (comp_due == comp_now) {
set_fg_rgb_clist_cell(clist, entries_shown, TODO_DATE_COLUMN, CLIST_
DUENOW_RED, CLIST_DUENOW_GREEN, CLIST_DUENOW_BLUE);
}
}
entries_shown++;
}
jp_logf(JP_LOG_DEBUG, "entries_shown=%d\n",entries_shown);
/* Sort the clist */
gtk_clist_sort(GTK_CLIST(clist));
if (main) {
gtk_signal_connect(GTK_OBJECT(clist), "select_row",
GTK_SIGNAL_FUNC(cb_clist_selection), NULL);
}
/* If there are items in the list, highlight the selected row */
if ((main) && (entries_shown>0)) {
/* First, select any record being searched for */
if (glob_find_id)
{
todo_find();
}
/* Second, try the currently selected row */
else if (clist_row_selected < entries_shown)
{
clist_select_row(GTK_CLIST(clist), clist_row_selected, TODO_PRIORITY_CO
LUMN);
if (!gtk_clist_row_is_visible(GTK_CLIST(clist), clist_row_selected)) {
gtk_clist_moveto(GTK_CLIST(clist), clist_row_selected, 0, 0.5, 0.0);
}
}
/* Third, select row 0 if nothing else is possible */
else
{
clist_select_row(GTK_CLIST(clist), 0, TODO_PRIORITY_COLUMN);
}
}
/* Unfreeze clist after all changes */
gtk_clist_thaw(GTK_CLIST(clist));
if (tooltip_widget) {
get_pref(PREF_SHOW_TOOLTIPS, &show_tooltips, NULL);
if (todo_list==NULL) {
set_tooltip(show_tooltips, glob_tooltips, tooltip_widget, _("0 records"
), NULL);
}
else {
sprintf(str, _("%d of %d records"), entries_shown, num_entries);
set_tooltip(show_tooltips, glob_tooltips, tooltip_widget, str, NULL);
}
}
/* return focus to clist after any big operation which requires a redraw */
gtk_widget_grab_focus(GTK_WIDGET(clist));
}
static int todo_find(void)
{
int r, found_at;
if (glob_find_id) {
r = clist_find_id(clist,
glob_find_id,
&found_at);
if (r) {
clist_select_row(GTK_CLIST(clist), found_at, TODO_PRIORITY_COLUMN);
if (!gtk_clist_row_is_visible(GTK_CLIST(clist), found_at)) {
gtk_clist_moveto(GTK_CLIST(clist), found_at, 0, 0.5, 0.0);
}
}
glob_find_id = 0;
}
return EXIT_SUCCESS;
} }
static gboolean cb_key_pressed_tab(GtkWidget *widget, static gboolean cb_key_pressed_tab(GtkWidget *widget,
GdkEventKey *event, GdkEventKey *event,
gpointer next_widget) gpointer next_widget) {
{ GtkTextIter cursor_pos_iter;
GtkTextIter cursor_pos_iter; GtkTextBuffer *text_buffer;
GtkTextBuffer *text_buffer;
if (event->keyval == GDK_KEY_Tab) {
if (event->keyval == GDK_Tab) { /* See if they are at the end of the text */
/* See if they are at the end of the text */ text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)); gtk_text_buffer_get_iter_at_mark(text_buffer, &cursor_pos_iter, gtk_text
gtk_text_buffer_get_iter_at_mark(text_buffer,&cursor_pos_iter,gtk_text_buf _buffer_get_insert(text_buffer));
fer_get_insert(text_buffer)); if (gtk_text_iter_is_end(&cursor_pos_iter)) {
if (gtk_text_iter_is_end(&cursor_pos_iter)) { g_signal_stop_emission_by_name(G_OBJECT(widget), "key_press_event");
gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event"); gtk_widget_grab_focus(GTK_WIDGET(next_widget));
gtk_widget_grab_focus(GTK_WIDGET(next_widget)); return TRUE;
return TRUE; }
} }
} return FALSE;
return FALSE;
} }
static gboolean cb_key_pressed_shift_tab(GtkWidget *widget, static gboolean cb_key_pressed_shift_tab(GtkWidget *widget,
GdkEventKey *event, GdkEventKey *event,
gpointer next_widget) gpointer next_widget) {
{ if (event->keyval == GDK_KEY_ISO_Left_Tab) {
if (event->keyval == GDK_ISO_Left_Tab) { g_signal_stop_emission_by_name(G_OBJECT(widget), "key_press_event");
gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event"); gtk_widget_grab_focus(GTK_WIDGET(next_widget));
gtk_widget_grab_focus(GTK_WIDGET(next_widget)); return TRUE;
return TRUE; }
} return FALSE;
return FALSE; }
}
/* This redraws the treeView and goes back to the same line number */
/* This redraws the clist and goes back to the same line number */ static int todo_redraw(void) {
static int todo_clist_redraw(void) todo_update_liststore(listStore, category_menu1, &glob_todo_list, todo_categ
{ ory, TRUE);
todo_update_clist(clist, category_menu1, &glob_todo_list, todo_category, TRUE return EXIT_SUCCESS;
); }
return EXIT_SUCCESS; int todo_cycle_cat(void) {
} int b;
int i, new_cat;
int todo_cycle_cat(void)
{ b = dialog_save_changed_record(pane, record_changed);
int b; if (b == DIALOG_SAID_2) {
int i, new_cat; cb_add_new_record(NULL, GINT_TO_POINTER(record_changed));
}
b=dialog_save_changed_record(pane, record_changed);
if (b==DIALOG_SAID_2) { if (todo_category == CATEGORY_ALL) {
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed)); new_cat = -1;
} } else {
new_cat = find_sort_cat_pos(todo_category);
if (todo_category == CATEGORY_ALL) { }
new_cat = -1;
} else { for (i = 0; i < NUM_TODO_CAT_ITEMS; i++) {
new_cat = find_sort_cat_pos(todo_category); new_cat++;
} if (new_cat >= NUM_TODO_CAT_ITEMS) {
todo_category = CATEGORY_ALL;
for (i=0; i<NUM_TODO_CAT_ITEMS; i++) { break;
new_cat++; }
if (new_cat >= NUM_TODO_CAT_ITEMS) { if ((sort_l[new_cat].Pcat) && (sort_l[new_cat].Pcat[0])) {
todo_category = CATEGORY_ALL; todo_category = sort_l[new_cat].cat_num;
break; break;
} }
if ((sort_l[new_cat].Pcat) && (sort_l[new_cat].Pcat[0])) { }
todo_category = sort_l[new_cat].cat_num;
break; row_selected = 0;
}
}
clist_row_selected = 0;
return EXIT_SUCCESS;
}
int todo_refresh(void)
{
int index, index2;
if (glob_find_id) {
todo_category = CATEGORY_ALL;
}
if (todo_category==CATEGORY_ALL) {
index = 0;
index2 = 0;
} else {
index=find_sort_cat_pos(todo_category);
index2 = find_menu_cat_pos(index) + 1;
index += 1;
}
todo_update_clist(clist, category_menu1, &glob_todo_list, todo_category, TRUE
);
if (index<0) {
jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
} else {
gtk_check_menu_item_set_active
(GTK_CHECK_MENU_ITEM(todo_cat_menu_item1[index]), TRUE);
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu1), index2);
}
return EXIT_SUCCESS;
}
int todo_gui_cleanup(void)
{
int b;
b=dialog_save_changed_record(pane, record_changed);
if (b==DIALOG_SAID_2) {
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed));
}
free_ToDoList(&glob_todo_list);
connect_changed_signals(DISCONNECT_SIGNALS);
set_pref(PREF_TODO_PANE, gtk_paned_get_position(GTK_PANED(pane)), NULL, TRUE)
;
set_pref(PREF_TODO_NOTE_PANE, gtk_paned_get_position(GTK_PANED(note_pane)), N
ULL, TRUE);
set_pref(PREF_LAST_TODO_CATEGORY, todo_category, NULL, TRUE);
set_pref(PREF_TODO_SORT_COLUMN, clist_col_selected, NULL, TRUE);
set_pref(PREF_TODO_SORT_ORDER, GTK_CLIST(clist)->sort_type, NULL, TRUE);
todo_clist_clear(GTK_CLIST(clist));
return EXIT_SUCCESS; return EXIT_SUCCESS;
}
int todo_refresh(void) {
int index, index2;
if (glob_find_id) {
todo_category = CATEGORY_ALL;
}
if (todo_category == CATEGORY_ALL) {
index = 0;
index2 = 0;
} else {
index = find_sort_cat_pos(todo_category);
index2 = find_menu_cat_pos(index) + 1;
index += 1;
}
todo_update_liststore(listStore, category_menu1, &glob_todo_list, todo_categ
ory, TRUE);
if (index < 0) {
jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
} else {
gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu1), index2);
}
return EXIT_SUCCESS;
}
void todo_update_liststore(GtkListStore *pListStore, GtkWidget *tooltip_widget,
ToDoList **todo_list, int category, int main) {
GtkTreeIter iter;
int num_entries, entries_shown;
char str[50];
GdkPixbuf *pixbuf_note;
GdkPixbuf *pixbuf_check;
GdkPixbuf *pixbuf_checked;
gboolean checkColumnDisplay = gtk_true();
GdkPixbuf *noteColumnDisplay;
ToDoList *temp_todo;
char dateDisplay[50];
char priorityDisplay[50];
char descriptionDisplay[TODO_MAX_COLUMN_LEN + 2];
const char *svalue;
long hide_completed, hide_not_due;
long show_tooltips;
int show_priv;
time_t ltime;
struct tm *now, *due;
int comp_now, comp_due;
free_ToDoList(todo_list);
/* Need to get all records including private ones for the tooltips calculati
on */
num_entries = get_todos2(todo_list, SORT_ASCENDING, 2, 2, 1, 1, CATEGORY_ALL
);
/* Start by clearing existing entry if in main window */
if (main) {
todo_clear_details();
GtkTreeSelection *treeSelection = gtk_tree_view_get_selection(GTK_TREE_V
IEW(treeView));
gtk_tree_selection_set_select_function(treeSelection, NULL, NULL, NULL);
}
todo_liststore_clear(pListStore);
/* Collect preferences and constant pixmaps for loop */
get_pref(PREF_TODO_HIDE_COMPLETED, &hide_completed, NULL);
get_pref(PREF_TODO_HIDE_NOT_DUE, &hide_not_due, NULL);
show_priv = show_privates(GET_PRIVATES);
get_pixbufs(PIXMAP_NOTE, &pixbuf_note);
get_pixbufs(PIXMAP_BOX_CHECK, &pixbuf_check);
get_pixbufs(PIXMAP_BOX_CHECKED, &pixbuf_checked);
/*#ifdef __APPLE__
mask_note = NULL;
mask_check = NULL;
mask_checked = NULL;
#endif
*/
/* Current time used for calculating overdue items */
time(&ltime);
now = localtime(&ltime);
comp_now = now->tm_year * 380 + now->tm_mon * 31 + now->tm_mday - 1;
entries_shown = 0;
for (temp_todo = *todo_list; temp_todo; temp_todo = temp_todo->next) {
if (((temp_todo->mtodo.attrib & 0x0F) != category) &&
category != CATEGORY_ALL) {
continue;
}
/* Do masking like Palm OS 3.5 */
if ((show_priv == MASK_PRIVATES) &&
(temp_todo->mtodo.attrib & dlpRecAttrSecret)) {
gtk_list_store_append(pListStore, &iter);
gtk_list_store_set(pListStore, &iter,
TODO_CHECK_COLUMN_ENUM, "---",
TODO_PRIORITY_COLUMN_ENUM, "---",
TODO_TEXT_COLUMN_ENUM, "--------------------",
TODO_DATE_COLUMN_ENUM, "----------",
TODO_DATA_COLUMN_ENUM, &(temp_todo->mtodo),
-1);
clear_mytodos(&temp_todo->mtodo);
entries_shown++;
continue;
}
/* End Masking */
/* Allow a record found through search window to temporarily be
displayed even if it would normally be hidden by option settings */
if (!glob_find_id || (glob_find_id != temp_todo->mtodo.unique_id)) {
/* Hide the completed records if need be */
if (hide_completed && temp_todo->mtodo.todo.complete) {
continue;
}
/* Hide the not due yet records if need be */
if ((hide_not_due) && (!(temp_todo->mtodo.todo.indefinite))) {
due = &(temp_todo->mtodo.todo.due);
comp_due = due->tm_year * 380 + due->tm_mon * 31 + due->tm_mday
- 1;
if (comp_due > comp_now) {
continue;
}
}
}
/* Hide the private records if need be */
if ((show_priv != SHOW_PRIVATES) &&
(temp_todo->mtodo.attrib & dlpRecAttrSecret)) {
continue;
}
/* Put a checkbox or checked checkbox pixmap up */
if (temp_todo->mtodo.todo.complete > 0) {
checkColumnDisplay = TRUE;
} else {
checkColumnDisplay = FALSE;
}
/* Print the priority number */
sprintf(priorityDisplay, "%d", temp_todo->mtodo.todo.priority);
/* Put a note pixmap up */
if (temp_todo->mtodo.todo.note[0]) {
noteColumnDisplay = pixbuf_note;
} else {
noteColumnDisplay = NULL;
}
/* Print the due date */
if (!temp_todo->mtodo.todo.indefinite) {
get_pref(PREF_SHORTDATE, NULL, &svalue);
strftime(dateDisplay, sizeof(dateDisplay), svalue, &(temp_todo->mtod
o.todo.due));
} else {
sprintf(dateDisplay, _("No date"));
}
/* Print the todo text */
lstrncpy_remove_cr_lfs(descriptionDisplay, temp_todo->mtodo.todo.descrip
tion, TODO_MAX_COLUMN_LEN);
gtk_list_store_append(pListStore, &iter);
GdkRGBA bgColor;
gboolean showBgColor = FALSE;
GdkRGBA fgColor;
gboolean showFgColor = FALSE;
switch (temp_todo->mtodo.rt) {
case NEW_PC_REC:
case REPLACEMENT_PALM_REC:
bgColor = get_color(LIST_NEW_RED, LIST_NEW_GREEN, LIST_NEW_BLUE)
;
showBgColor = TRUE;
break;
case DELETED_PALM_REC:
case DELETED_PC_REC:
bgColor = get_color(LIST_DEL_RED, LIST_DEL_GREEN, LIST_DEL_BLUE)
;
showBgColor = TRUE;
break;
case MODIFIED_PALM_REC:
bgColor = get_color(LIST_MOD_RED, LIST_MOD_GREEN, LIST_MOD_BLUE)
;
showBgColor = TRUE;
break;
default:
if (temp_todo->mtodo.attrib & dlpRecAttrSecret) {
bgColor = get_color(LIST_PRIVATE_RED, LIST_PRIVATE_GREEN, LI
ST_PRIVATE_BLUE);
showBgColor = TRUE;
} else {
showBgColor = FALSE;
}
}
if (!(temp_todo->mtodo.todo.indefinite)) {
due = &(temp_todo->mtodo.todo.due);
comp_due = due->tm_year * 380 + due->tm_mon * 31 + due->tm_mday - 1;
if (comp_due < comp_now) {
fgColor = get_color(LIST_OVERDUE_RED, LIST_OVERDUE_GREEN, LIST_O
VERDUE_BLUE);
} else if (comp_due == comp_now) {
fgColor = get_color(LIST_DUENOW_RED, LIST_DUENOW_GREEN, LIST_DUE
NOW_BLUE);
}
showFgColor = TRUE;
}
gtk_list_store_set(pListStore, &iter,
TODO_CHECK_COLUMN_ENUM, checkColumnDisplay,
TODO_PRIORITY_COLUMN_ENUM, priorityDisplay,
TODO_NOTE_COLUMN_ENUM, noteColumnDisplay,
TODO_TEXT_COLUMN_ENUM, descriptionDisplay,
TODO_DATE_COLUMN_ENUM, dateDisplay,
TODO_DATA_COLUMN_ENUM, &(temp_todo->mtodo),
TODO_BACKGROUND_COLOR_ENUM, showBgColor ? &bgColor :
NULL,
TODO_BACKGROUND_COLOR_ENABLED_ENUM, showBgColor,
TODO_FOREGROUND_COLOR_ENUM, showFgColor ? gdk_rgba_to
_string(&fgColor) : NULL,
TODO_FORGROUND_COLOR_ENABLED_ENUM, showFgColor,
-1);
entries_shown++;
}
if ((main) && (entries_shown > 0)) {
// Set callback for a row selected
gtk_tree_selection_set_select_function(treeSelection, handleRowSelection
, NULL, NULL);
/* First, select any record being searched for */
if (glob_find_id) {
todo_find();
}
/* Second, try the currently selected row */
else if (row_selected < entries_shown) {
gtk_tree_model_foreach(GTK_TREE_MODEL(pListStore), selectRecordByRow
, NULL);
}
/* Third, select row 0 if nothing else is possible */
else {
row_selected = 0;
gtk_tree_model_foreach(GTK_TREE_MODEL(pListStore), selectRecordByRow
, NULL);
}
}
if (tooltip_widget) {
get_pref(PREF_SHOW_TOOLTIPS, &show_tooltips, NULL);
if (todo_list == NULL) {
set_tooltip((int) show_tooltips, tooltip_widget, _("0 records"));
} else {
sprintf(str, _("%d of %d records"), entries_shown, num_entries);
set_tooltip((int) show_tooltips, tooltip_widget, str);
}
}
}
gboolean
findRecord(GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data) {
if (glob_find_id) {
MyToDo *mytodo = NULL;
gtk_tree_model_get(model, iter, TODO_DATA_COLUMN_ENUM, &mytodo, -1);
if (mytodo->unique_id == glob_find_id) {
GtkTreeSelection *selection = NULL;
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
gtk_tree_selection_set_select_function(selection, handleRowSelection
, NULL, NULL);
gtk_tree_selection_select_path(selection, path);
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(treeView), path,
gtk_tree_view_get_column(GTK_TREE_VIEW(
treeView), TODO_TEXT_COLUMN_ENUM),
FALSE, 1.0, 0.0);
glob_find_id = 0;
return TRUE;
}
}
return FALSE;
}
gboolean
selectRecordByRow(GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data) {
int *i = gtk_tree_path_get_indices(path);
if (i[0] == row_selected) {
GtkTreeSelection *selection = NULL;
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
gtk_tree_selection_select_path(selection, path);
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(treeView), path,
gtk_tree_view_get_column(GTK_TREE_VIEW(tree
View), TODO_TEXT_COLUMN_ENUM),
FALSE, 1.0, 0.0);
return TRUE;
}
return FALSE;
}
static int todo_find(void) {
gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), findRecord, NULL);
return EXIT_SUCCESS;
}
int todo_gui_cleanup(void) {
int b;
b = dialog_save_changed_record(pane, record_changed);
if (b == DIALOG_SAID_2) {
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed));
}
free_ToDoList(&glob_todo_list);
connect_changed_signals(DISCONNECT_SIGNALS);
set_pref(PREF_TODO_PANE, gtk_paned_get_position(GTK_PANED(pane)), NULL, TRUE
);
set_pref(PREF_TODO_NOTE_PANE, gtk_paned_get_position(GTK_PANED(note_pane)),
NULL, TRUE);
set_pref(PREF_LAST_TODO_CATEGORY, todo_category, NULL, TRUE);
set_pref(PREF_TODO_SORT_COLUMN, column_selected, NULL, TRUE);
set_pref(PREF_TODO_SORT_ORDER,
gtk_tree_view_column_get_sort_order(gtk_tree_view_get_column(GTK_TR
EE_VIEW(treeView), column_selected)),
NULL, TRUE);
GtkTreeSelection *treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(
treeView));
gtk_tree_selection_set_select_function(treeSelection, NULL, NULL, NULL);
todo_liststore_clear(listStore);
return EXIT_SUCCESS;
} }
/* Main function */ /* Main function */
int todo_gui(GtkWidget *vbox, GtkWidget *hbox) int todo_gui(GtkWidget *vbox, GtkWidget *hbox) {
{ GtkWidget *scrolled_window;
GtkWidget *scrolled_window; GtkWidget *pixbufwid;
GtkWidget *pixmapwid; GdkPixbuf *pixbuf;
GdkPixmap *pixmap; GtkWidget *vbox1, *vbox2;
GdkBitmap *mask; GtkWidget *hbox_temp, *hbox_temp2;
GtkWidget *vbox1, *vbox2; GtkWidget *vbox_temp;
GtkWidget *hbox_temp, *hbox_temp2; GtkWidget *separator;
GtkWidget *vbox_temp; GtkWidget *label;
GtkWidget *separator; char str[MAX_RADIO_BUTTON_LEN];
GtkWidget *label; int i;
time_t ltime; GSList *group;
struct tm *now; long ivalue;
char str[MAX_RADIO_BUTTON_LEN]; GtkAccelGroup *accel_group;
int i; long char_set;
GSList *group; long show_tooltips;
long ivalue; char *cat_name;
char *titles[]={"","","","",""}; get_pref(PREF_TODO_VERSION, &todo_version, NULL);
GtkAccelGroup *accel_group; init();
long char_set; get_todo_app_info(&todo_app_info);
long show_tooltips; /* Initialize categories */
char *cat_name; get_pref(PREF_CHAR_SET, &char_set, NULL);
for (i = 1; i < NUM_TODO_CAT_ITEMS; i++) {
get_pref(PREF_TODO_VERSION, &todo_version, NULL); cat_name = charset_p2newj(todo_app_info.category.name[i], 31, (int) char
_set);
init(); strcpy(sort_l[i - 1].Pcat, cat_name);
free(cat_name);
get_todo_app_info(&todo_app_info); sort_l[i - 1].cat_num = i;
}
/* Initialize categories */ /* put reserved 'Unfiled' category at end of list */
get_pref(PREF_CHAR_SET, &char_set, NULL); cat_name = charset_p2newj(todo_app_info.category.name[0], 31, (int) char_set
for (i=1; i<NUM_TODO_CAT_ITEMS; i++) { );
cat_name = charset_p2newj(todo_app_info.category.name[i], 31, char_set); strcpy(sort_l[NUM_TODO_CAT_ITEMS - 1].Pcat, cat_name);
strcpy(sort_l[i-1].Pcat, cat_name); free(cat_name);
free(cat_name); sort_l[NUM_TODO_CAT_ITEMS - 1].cat_num = 0;
sort_l[i-1].cat_num = i;
}
/* put reserved 'Unfiled' category at end of list */
cat_name = charset_p2newj(todo_app_info.category.name[0], 31, char_set);
strcpy(sort_l[NUM_TODO_CAT_ITEMS-1].Pcat, cat_name);
free(cat_name);
sort_l[NUM_TODO_CAT_ITEMS-1].cat_num = 0;
qsort(sort_l, NUM_TODO_CAT_ITEMS-1, sizeof(struct sorted_cats), cat_compare); qsort(sort_l, NUM_TODO_CAT_ITEMS - 1, sizeof(struct sorted_cats), cat_compar e);
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
for (i=0; i<NUM_TODO_CAT_ITEMS; i++) { for (i=0; i<NUM_TODO_CAT_ITEMS; i++) {
printf("cat %d [%s]\n", sort_l[i].cat_num, sort_l[i].Pcat); printf("cat %d [%s]\n", sort_l[i].cat_num, sort_l[i].Pcat);
} }
#endif #endif
get_pref(PREF_LAST_TODO_CATEGORY, &ivalue, NULL); get_pref(PREF_LAST_TODO_CATEGORY, &ivalue, NULL);
todo_category = ivalue; todo_category = (int) ivalue;
if ((todo_category != CATEGORY_ALL) if ((todo_category != CATEGORY_ALL)
&& (todo_app_info.category.name[todo_category][0]=='\0')) { && (todo_app_info.category.name[todo_category][0] == '\0')) {
todo_category=CATEGORY_ALL; todo_category = CATEGORY_ALL;
} }
/* Create basic GUI with left and right boxes and sliding pane */ /* Create basic GUI with left and right boxes and sliding pane */
accel_group = gtk_accel_group_new(); accel_group = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(gtk_widget_get_toplevel(vbox)), gtk_window_add_accel_group(GTK_WINDOW(gtk_widget_get_toplevel(vbox)),
accel_group); accel_group);
get_pref(PREF_SHOW_TOOLTIPS, &show_tooltips, NULL); get_pref(PREF_SHOW_TOOLTIPS, &show_tooltips, NULL);
pane = gtk_hpaned_new(); pane = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
get_pref(PREF_TODO_PANE, &ivalue, NULL); get_pref(PREF_TODO_PANE, &ivalue, NULL);
gtk_paned_set_position(GTK_PANED(pane), ivalue); gtk_paned_set_position(GTK_PANED(pane), (gint) ivalue);
gtk_box_pack_start(GTK_BOX(hbox), pane, TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(hbox), pane, TRUE, TRUE, 5);
vbox1 = gtk_vbox_new(FALSE, 0); vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
vbox2 = gtk_vbox_new(FALSE, 0); vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_paned_pack1(GTK_PANED(pane), vbox1, TRUE, FALSE); gtk_paned_pack1(GTK_PANED(pane), vbox1, TRUE, FALSE);
gtk_paned_pack2(GTK_PANED(pane), vbox2, TRUE, FALSE); gtk_paned_pack2(GTK_PANED(pane), vbox2, TRUE, FALSE);
/* Left side of GUI */ /* Left side of GUI */
/* Separator */ /* Separator */
separator = gtk_hseparator_new(); separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
gtk_box_pack_start(GTK_BOX(vbox1), separator, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox1), separator, FALSE, FALSE, 5);
time(&ltime); //time(&ltime);
now = localtime(&ltime); //now = localtime(&ltime);
/* Make the 'Today is:' label */ /* Make the 'Today is:' label */
glob_date_label = gtk_label_new(" "); glob_date_label = gtk_label_new(" ");
gtk_box_pack_start(GTK_BOX(vbox1), glob_date_label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox1), glob_date_label, FALSE, FALSE, 0);
timeout_date(NULL); timeout_date(NULL);
glob_date_timer_tag = gtk_timeout_add(CLOCK_TICK, timeout_sync_up, NULL); glob_date_timer_tag = g_timeout_add(CLOCK_TICK, timeout_sync_up, NULL);
/* Separator */ /* Separator */
separator = gtk_hseparator_new(); separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
gtk_box_pack_start(GTK_BOX(vbox1), separator, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox1), separator, FALSE, FALSE, 5);
/* Left-side Category box */ /* Left-side Category box */
hbox_temp = gtk_hbox_new(FALSE, 0); hbox_temp = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start(GTK_BOX(vbox1), hbox_temp, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox1), hbox_temp, FALSE, FALSE, 0);
/* Left-side Category menu */ /* Left-side Category menu */
make_category_menu(&category_menu1, todo_cat_menu_item1, make_category_menu(&category_menu1,
sort_l, cb_category, TRUE, TRUE); sort_l, cb_category, TRUE, TRUE);
gtk_box_pack_start(GTK_BOX(hbox_temp), category_menu1, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_temp), category_menu1, TRUE, TRUE, 0);
/* Todo list scrolled window */ /* Todo list scrolled window */
scrolled_window = gtk_scrolled_window_new(NULL, NULL); scrolled_window = gtk_scrolled_window_new(NULL, NULL);
gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 0); gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(vbox1), scrolled_window, TRUE, TRUE, 0); //gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),
(GtkShadowType) GTK_TYPE_SHADOW_TYPE);
clist = gtk_clist_new_with_titles(5, titles); gtk_box_pack_start(GTK_BOX(vbox1), scrolled_window, TRUE, TRUE, 0);
gtk_clist_set_column_title(GTK_CLIST(clist), TODO_TEXT_COLUMN, _("Task")); //
gtk_clist_set_column_title(GTK_CLIST(clist), TODO_DATE_COLUMN, _("Due")); listStore = gtk_list_store_new(TODO_NUM_COLS, G_TYPE_BOOLEAN, G_TYPE_STRING,
/* Put pretty pictures in the clist column headings */ GDK_TYPE_PIXBUF, G_TYPE_STRING,
get_pixmaps(vbox, PIXMAP_NOTE, &pixmap, &mask); G_TYPE_STRING, G_TYPE_POINTER, GDK_TYPE_RGBA,
#ifdef __APPLE__ G_TYPE_BOOLEAN, G_TYPE_STRING,
mask = NULL; G_TYPE_BOOLEAN);
#endif GtkTreeSortable *sortable;
pixmapwid = gtk_pixmap_new(pixmap, mask); sortable = GTK_TREE_SORTABLE(listStore);
gtk_clist_set_column_widget(GTK_CLIST(clist), TODO_NOTE_COLUMN, pixmapwid); gtk_tree_sortable_set_sort_func(sortable, TODO_NOTE_COLUMN_ENUM, sortNoteCol
gtk_clist_set_column_justification(GTK_CLIST(clist), TODO_NOTE_COLUMN, GTK_JU umn,
STIFY_CENTER); GINT_TO_POINTER(TODO_NOTE_COLUMN_ENUM), NULL
);
get_pixmaps(vbox, PIXMAP_BOX_CHECKED, &pixmap, &mask); GtkTreeModel *model = GTK_TREE_MODEL(listStore);
#ifdef __APPLE__ treeView = gtk_tree_view_new_with_model(model);
mask = NULL;
#endif GtkCellRenderer *taskRenderer = gtk_cell_renderer_text_new();
pixmapwid = gtk_pixmap_new(pixmap, mask); // gtk_cell_renderer_set_fixed_size(taskRenderer, -1, 1);
gtk_clist_set_column_widget(GTK_CLIST(clist), TODO_CHECK_COLUMN, pixmapwid);
gtk_clist_set_column_justification(GTK_CLIST(clist), TODO_CHECK_COLUMN, GTK_J GtkTreeViewColumn *taskColumn = gtk_tree_view_column_new_with_attributes("Ta
USTIFY_CENTER); sk",
tas
gtk_clist_column_titles_active(GTK_CLIST(clist)); kRenderer,
gtk_signal_connect(GTK_OBJECT(clist), "click_column", "te
GTK_SIGNAL_FUNC (cb_clist_click_column), NULL); xt", TODO_TEXT_COLUMN_ENUM,
"ce
gtk_signal_connect(GTK_OBJECT(clist), "select_row", ll-background-rgba",
GTK_SIGNAL_FUNC(cb_clist_selection), NULL); TOD
gtk_clist_set_shadow_type(GTK_CLIST(clist), SHADOW); O_BACKGROUND_COLOR_ENUM,
gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_BROWSE); "ce
ll-background-set",
gtk_clist_set_column_auto_resize(GTK_CLIST(clist), TODO_CHECK_COLUMN, TRUE); TOD
gtk_clist_set_column_auto_resize(GTK_CLIST(clist), TODO_PRIORITY_COLUMN, TRUE O_BACKGROUND_COLOR_ENABLED_ENUM,
); NUL
gtk_clist_set_column_auto_resize(GTK_CLIST(clist), TODO_NOTE_COLUMN, TRUE); L);
gtk_clist_set_column_auto_resize(GTK_CLIST(clist), TODO_DATE_COLUMN, TRUE); gtk_tree_view_column_set_sort_column_id(taskColumn, TODO_TEXT_COLUMN_ENUM);
gtk_clist_set_column_auto_resize(GTK_CLIST(clist), TODO_TEXT_COLUMN, FALSE);
GtkCellRenderer *dateRenderer = gtk_cell_renderer_text_new();
/* Restore previous sorting configuration */ // gtk_cell_renderer_set_fixed_size(dateRenderer, -1, 1);
get_pref(PREF_TODO_SORT_COLUMN, &ivalue, NULL);
clist_col_selected = ivalue; GtkTreeViewColumn *dateColumn = gtk_tree_view_column_new_with_attributes("Du
gtk_clist_set_sort_column(GTK_CLIST(clist), clist_col_selected); e",
switch (clist_col_selected) { dat
case TODO_CHECK_COLUMN: /* Checkbox column */ eRenderer,
gtk_clist_set_compare_func(GTK_CLIST(clist),GtkClistCompareCheckbox); "te
break; xt", TODO_DATE_COLUMN_ENUM,
case TODO_DATE_COLUMN: /* Due Date column */ "ce
gtk_clist_set_compare_func(GTK_CLIST(clist),GtkClistCompareDates); ll-background-rgba",
break; TOD
default: /* All other columns can use GTK default sort function */ O_BACKGROUND_COLOR_ENUM,
gtk_clist_set_compare_func(GTK_CLIST(clist),NULL); "ce
break; ll-background-set",
} TOD
get_pref(PREF_TODO_SORT_ORDER, &ivalue, NULL); O_BACKGROUND_COLOR_ENABLED_ENUM,
gtk_clist_set_sort_type(GTK_CLIST (clist), ivalue); "fo
reground", TODO_FOREGROUND_COLOR_ENUM,
gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(clist)); "fo
reground-set",
/* Right side of GUI */ TOD
O_FORGROUND_COLOR_ENABLED_ENUM,
hbox_temp = gtk_hbox_new(FALSE, 3); NUL
gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0); L);
gtk_tree_view_column_set_sort_column_id(dateColumn, TODO_DATE_COLUMN_ENUM);
/* Cancel button */
CREATE_BUTTON(cancel_record_button, _("Cancel"), CANCEL, _("Cancel the modifi GtkCellRenderer *priorityRenderer = gtk_cell_renderer_text_new();
cations"), GDK_Escape, 0, "ESC") // gtk_cell_renderer_set_fixed_size(priorityRenderer, -1, 1);
gtk_signal_connect(GTK_OBJECT(cancel_record_button), "clicked", GtkTreeViewColumn *priorityColumn = gtk_tree_view_column_new_with_attributes
GTK_SIGNAL_FUNC(cb_cancel), NULL); ("",
/* Delete button */ priorityRenderer,
CREATE_BUTTON(delete_record_button, _("Delete"), DELETE, _("Delete the select
ed record"), GDK_d, GDK_CONTROL_MASK, "Ctrl+D") "text", TODO_PRIORITY_COLUMN_ENUM,
gtk_signal_connect(GTK_OBJECT(delete_record_button), "clicked",
GTK_SIGNAL_FUNC(cb_delete_todo), "cell-background-rgba",
GINT_TO_POINTER(DELETE_FLAG));
TODO_BACKGROUND_COLOR_ENUM,
/* Undelete Button */
CREATE_BUTTON(undelete_record_button, _("Undelete"), UNDELETE, _("Undelete th "cell-background-set",
e selected record"), 0, 0, "")
gtk_signal_connect(GTK_OBJECT(undelete_record_button), "clicked", TODO_BACKGROUND_COLOR_ENABLED_ENUM,
GTK_SIGNAL_FUNC(cb_undelete_todo),
GINT_TO_POINTER(UNDELETE_FLAG)); NULL);
gtk_tree_view_column_set_sort_column_id(priorityColumn, TODO_PRIORITY_COLUMN
/* Copy button */ _ENUM);
CREATE_BUTTON(copy_record_button, _("Copy"), COPY, _("Copy the selected recor
d"), GDK_c, GDK_CONTROL_MASK|GDK_SHIFT_MASK, "Ctrl+Shift+C") GtkCellRenderer *noteRenderer = gtk_cell_renderer_pixbuf_new();
gtk_signal_connect(GTK_OBJECT(copy_record_button), "clicked", gtk_cell_renderer_set_alignment(noteRenderer,0,0);
GTK_SIGNAL_FUNC(cb_add_new_record), gtk_cell_renderer_set_padding(noteRenderer,4,0);
GINT_TO_POINTER(COPY_FLAG));
GtkTreeViewColumn *noteColumn = gtk_tree_view_column_new_with_attributes("",
/* New button */ not
CREATE_BUTTON(new_record_button, _("New Record"), NEW, _("Add a new record"), eRenderer,
GDK_n, GDK_CONTROL_MASK, "Ctrl+N") "pi
gtk_signal_connect(GTK_OBJECT(new_record_button), "clicked", xbuf", TODO_NOTE_COLUMN_ENUM,
GTK_SIGNAL_FUNC(cb_add_new_record), "ce
GINT_TO_POINTER(CLEAR_FLAG)); ll-background-rgba",
TOD
/* "Add Record" button */ O_BACKGROUND_COLOR_ENUM,
CREATE_BUTTON(add_record_button, _("Add Record"), ADD, _("Add the new record" "ce
), GDK_Return, GDK_CONTROL_MASK, "Ctrl+Enter") ll-background-set",
gtk_signal_connect(GTK_OBJECT(add_record_button), "clicked", TOD
GTK_SIGNAL_FUNC(cb_add_new_record), O_BACKGROUND_COLOR_ENABLED_ENUM,
GINT_TO_POINTER(NEW_FLAG)); NUL
L);
gtk_tree_view_column_set_sort_column_id(noteColumn, TODO_NOTE_COLUMN_ENUM);
GtkCellRenderer *checkRenderer = gtk_cell_renderer_toggle_new();
gtk_cell_renderer_set_alignment(checkRenderer,0,0);
gtk_cell_renderer_set_padding(checkRenderer,4,0);
GtkTreeViewColumn *checkColumn = gtk_tree_view_column_new_with_attributes(""
, checkRenderer, "active",
TO
DO_CHECK_COLUMN_ENUM,
"c
ell-background-rgba",
TO
DO_BACKGROUND_COLOR_ENUM,
"c
ell-background-set",
TO
DO_BACKGROUND_COLOR_ENABLED_ENUM, NULL);
// FIXME, this doesn't mark the record changed and toggle the right side tog
gle button
g_signal_connect (checkRenderer, "toggled",
G_CALLBACK(checkedCallBack),
listStore);
gtk_tree_view_column_set_sort_column_id(checkColumn, TODO_CHECK_COLUMN_ENUM)
;
gtk_tree_view_insert_column(GTK_TREE_VIEW (treeView), checkColumn, TODO_CHEC
K_COLUMN_ENUM);
gtk_tree_view_insert_column(GTK_TREE_VIEW (treeView), priorityColumn, TODO_P
RIORITY_COLUMN_ENUM);
gtk_tree_view_insert_column(GTK_TREE_VIEW (treeView), noteColumn, TODO_NOTE_
COLUMN_ENUM);
gtk_tree_view_insert_column(GTK_TREE_VIEW (treeView), dateColumn, TODO_DATE_
COLUMN_ENUM);
gtk_tree_view_insert_column(GTK_TREE_VIEW (treeView), taskColumn, TODO_TEXT_
COLUMN_ENUM);
gtk_tree_view_column_set_clickable(checkColumn, gtk_true());
gtk_tree_view_column_set_clickable(priorityColumn, gtk_true());
gtk_tree_view_column_set_clickable(noteColumn, gtk_true());
gtk_tree_view_column_set_clickable(dateColumn, gtk_true());
gtk_tree_view_column_set_clickable(taskColumn, gtk_true());
gtk_tree_view_column_set_sizing(checkColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_sizing(dateColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_sizing(priorityColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZ
E);
gtk_tree_view_column_set_sizing(noteColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_sizing(taskColumn, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeVi
ew)),
GTK_SELECTION_BROWSE);
/* Put pretty pictures in the treeView column headings */
get_pixbufs(PIXMAP_NOTE, &pixbuf);
pixbufwid = gtk_image_new_from_pixbuf(pixbuf);
gtk_widget_show(GTK_WIDGET(pixbufwid));
gtk_tree_view_column_set_widget(noteColumn, pixbufwid);
gtk_tree_view_column_set_alignment(noteColumn, GTK_JUSTIFY_LEFT);
get_pixbufs(PIXMAP_BOX_CHECKED, &pixbuf);
pixbufwid = gtk_image_new_from_pixbuf(pixbuf);
gtk_widget_show(GTK_WIDGET(pixbufwid));
gtk_tree_view_column_set_widget(checkColumn, pixbufwid);
gtk_tree_view_column_set_alignment(checkColumn, GTK_JUSTIFY_LEFT);
// register function to handle column header clicks..
g_signal_connect (taskColumn, "clicked", G_CALLBACK(column_clicked_cb), NULL
);
g_signal_connect (noteColumn, "clicked", G_CALLBACK(column_clicked_cb), NULL
);
g_signal_connect (checkColumn, "clicked", G_CALLBACK(column_clicked_cb), NUL
L);
g_signal_connect (priorityColumn, "clicked", G_CALLBACK(column_clicked_cb),
NULL);
g_signal_connect (dateColumn, "clicked", G_CALLBACK(column_clicked_cb), NULL
);
treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolled_window),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
gtk_tree_selection_set_select_function(treeSelection, handleRowSelection, NU
LL, NULL);
gtk_widget_set_events(treeView, GDK_BUTTON1_MOTION_MASK);
g_signal_connect (G_OBJECT(treeView), "motion_notify_event",
G_CALLBACK(motion_notify_event), NULL);
g_signal_connect (G_OBJECT(treeView), "button-press-event",
G_CALLBACK(button_pressed_for_motion), NULL);
g_signal_connect (G_OBJECT(treeView), "button-release-event",
G_CALLBACK(button_released_for_motion), NULL);
/* Restore previous sorting configuration */
get_pref(PREF_TODO_SORT_COLUMN, &ivalue, NULL);
column_selected = (int) ivalue;
for (int x = 0; x < TODO_NUM_COLS - 5; x++) {
gtk_tree_view_column_set_sort_indicator(gtk_tree_view_get_column(GTK_TRE
E_VIEW(treeView), x), gtk_false());
}
gtk_tree_view_column_set_sort_indicator(gtk_tree_view_get_column(GTK_TREE_VI
EW(treeView), column_selected),
gtk_true());
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(treeView));
get_pref(PREF_TODO_SORT_ORDER, &ivalue, NULL);
gtk_tree_sortable_set_sort_column_id(sortable, column_selected, (GtkSortType
) ivalue);
g_object_unref(model);
gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(treeView));
/* Right side of GUI */
hbox_temp = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3);
gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0);
/* Cancel button */
CREATE_BUTTON(cancel_record_button, _("Cancel"), CANCEL, _("Cancel the modif
ications"), GDK_KEY_Escape, 0, "ESC")
g_signal_connect(G_OBJECT(cancel_record_button), "clicked",
G_CALLBACK(cb_cancel), NULL);
/* Delete button */
CREATE_BUTTON(delete_record_button, _("Delete"), DELETE, _("Delete the selec
ted record"), GDK_d, GDK_CONTROL_MASK,
"Ctrl+D")
g_signal_connect(G_OBJECT(delete_record_button), "clicked",
G_CALLBACK(cb_delete_todo),
GINT_TO_POINTER(DELETE_FLAG));
/* Undelete Button */
CREATE_BUTTON(undelete_record_button, _("Undelete"), UNDELETE, _("Undelete t
he selected record"), 0, 0, "")
g_signal_connect(G_OBJECT(undelete_record_button), "clicked",
G_CALLBACK(cb_undelete_todo),
GINT_TO_POINTER(UNDELETE_FLAG));
/* Copy button */
CREATE_BUTTON(copy_record_button, _("Copy"), COPY, _("Copy the selected reco
rd"), GDK_c,
GDK_CONTROL_MASK | GDK_SHIFT_MASK, "Ctrl+Shift+C")
g_signal_connect(G_OBJECT(copy_record_button), "clicked",
G_CALLBACK(cb_add_new_record),
GINT_TO_POINTER(COPY_FLAG));
/* New button */
CREATE_BUTTON(new_record_button, _("New Record"), NEW, _("Add a new record")
, GDK_n, GDK_CONTROL_MASK, "Ctrl+N")
g_signal_connect(G_OBJECT(new_record_button), "clicked",
G_CALLBACK(cb_add_new_record),
GINT_TO_POINTER(CLEAR_FLAG));
/* "Add Record" button */
CREATE_BUTTON(add_record_button, _("Add Record"), ADD, _("Add the new record
"), GDK_KEY_Return, GDK_CONTROL_MASK,
"Ctrl+Enter")
g_signal_connect(G_OBJECT(add_record_button), "clicked",
G_CALLBACK(cb_add_new_record),
GINT_TO_POINTER(NEW_FLAG));
#ifndef ENABLE_STOCK_BUTTONS #ifndef ENABLE_STOCK_BUTTONS
gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(GTK_BIN(add_record_button)->child)), gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(gtk_bin_get_child(GTK_BIN(add_recor
"label_high"); d_button)))),
"label_high");
#endif #endif
/* "Apply Changes" button */ /* "Apply Changes" button */
CREATE_BUTTON(apply_record_button, _("Apply Changes"), APPLY, _("Commit the m CREATE_BUTTON(apply_record_button, _("Apply Changes"), APPLY, _("Commit the
odifications"), GDK_Return, GDK_CONTROL_MASK, "Ctrl+Enter") modifications"), GDK_KEY_Return,
gtk_signal_connect(GTK_OBJECT(apply_record_button), "clicked", GDK_CONTROL_MASK, "Ctrl+Enter")
GTK_SIGNAL_FUNC(cb_add_new_record), g_signal_connect(G_OBJECT(apply_record_button), "clicked",
GINT_TO_POINTER(MODIFY_FLAG)); G_CALLBACK(cb_add_new_record),
GINT_TO_POINTER(MODIFY_FLAG));
#ifndef ENABLE_STOCK_BUTTONS #ifndef ENABLE_STOCK_BUTTONS
gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(GTK_BIN(apply_record_button)->child) gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(gtk_bin_get_child(GTK_BIN(apply_rec
), ord_button)))),
"label_high"); "label_high");
#endif #endif
/* Separator */ /* Separator */
separator = gtk_hseparator_new(); separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
gtk_box_pack_start(GTK_BOX(vbox2), separator, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox2), separator, FALSE, FALSE, 5);
hbox_temp = gtk_hbox_new(FALSE, 0); hbox_temp = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0);
/* Right-side Category menu */ /* Right-side Category menu */
/* Clear GTK option menus before use */
for (i=0; i<NUM_TODO_CAT_ITEMS; i++) { make_category_menu(&category_menu2,
todo_cat_menu_item2[i] = NULL; sort_l, NULL, FALSE, FALSE);
} gtk_box_pack_start(GTK_BOX(hbox_temp), category_menu2, TRUE, TRUE, 0);
make_category_menu(&category_menu2, todo_cat_menu_item2,
sort_l, NULL, FALSE, FALSE); /* Private checkbox */
gtk_box_pack_start(GTK_BOX(hbox_temp), category_menu2, TRUE, TRUE, 0); private_checkbox = gtk_check_button_new_with_label(_("Private"));
gtk_box_pack_end(GTK_BOX(hbox_temp), private_checkbox, FALSE, FALSE, 0);
/* Private checkbox */
private_checkbox = gtk_check_button_new_with_label(_("Private")); /* Completed checkbox */
gtk_box_pack_end(GTK_BOX(hbox_temp), private_checkbox, FALSE, FALSE, 0); todo_completed_checkbox = gtk_check_button_new_with_label(_("Completed"));
gtk_box_pack_start(GTK_BOX(vbox2), todo_completed_checkbox, FALSE, FALSE, 0)
/* Completed checkbox */ ;
todo_completed_checkbox = gtk_check_button_new_with_label(_("Completed"));
gtk_box_pack_start(GTK_BOX(vbox2), todo_completed_checkbox, FALSE, FALSE, 0); /* Priority radio buttons */
hbox_temp = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
/* Priority radio buttons */ gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0);
hbox_temp = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0); label = gtk_label_new(_("Priority:"));
gtk_box_pack_start(GTK_BOX(hbox_temp), label, FALSE, FALSE, 2);
label = gtk_label_new(_("Priority:")); set_tooltip((int) show_tooltips, label, _("Set priority Alt+#"));
gtk_box_pack_start(GTK_BOX(hbox_temp), label, FALSE, FALSE, 2);
set_tooltip(show_tooltips, glob_tooltips, label, _("Set priority Alt+#"), N group = NULL;
ULL); for (i = 0; i < NUM_TODO_PRIORITIES; i++) {
sprintf(str, "%d", i + 1);
group = NULL; radio_button_todo[i] = gtk_radio_button_new_with_label(group, str);
for (i=0; i<NUM_TODO_PRIORITIES; i++) { group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio_button_todo[i]
sprintf(str,"%d",i+1); ));
radio_button_todo[i] = gtk_radio_button_new_with_label(group, str); gtk_widget_add_accelerator(radio_button_todo[i], "clicked", accel_group,
group = gtk_radio_button_group(GTK_RADIO_BUTTON(radio_button_todo[i])); (guint) GDK_KEY_1 + i, GDK_MOD1_MASK, GTK_ACC
gtk_widget_add_accelerator(radio_button_todo[i], "clicked", accel_group, EL_VISIBLE);
GDK_1+i, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE); gtk_box_pack_start(GTK_BOX(hbox_temp),
gtk_box_pack_start(GTK_BOX(hbox_temp), radio_button_todo[i], FALSE, FALSE, 0);
radio_button_todo[i], FALSE, FALSE, 0); }
}
/* "Date Due:" label */
/* "Date Due:" label */ hbox_temp = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
hbox_temp = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0);
/* Spacer to line up */
/* Spacer to line up */ hbox_temp2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
hbox_temp2 = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox_temp), hbox_temp2, FALSE, FALSE, 1);
gtk_box_pack_start(GTK_BOX(hbox_temp), hbox_temp2, FALSE, FALSE, 1);
label = gtk_label_new(_("Date Due:"));
label = gtk_label_new(_("Date Due:")); gtk_box_pack_start(GTK_BOX(hbox_temp), label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox_temp), label, FALSE, FALSE, 0);
/* "Date Due" button */
/* "Date Due" button */ due_date_button = gtk_button_new_with_label("");
due_date_button = gtk_button_new_with_label(""); gtk_box_pack_start(GTK_BOX(hbox_temp), due_date_button, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(hbox_temp), due_date_button, FALSE, FALSE, 5); g_signal_connect(G_OBJECT(due_date_button), "clicked",
gtk_signal_connect(GTK_OBJECT(due_date_button), "clicked", G_CALLBACK(cb_cal_dialog), NULL);
GTK_SIGNAL_FUNC(cb_cal_dialog), NULL);
/* "No Date" check box */
/* "No Date" check box */ todo_no_due_date_checkbox = gtk_check_button_new_with_label(_("No Date"));
todo_no_due_date_checkbox = gtk_check_button_new_with_label(_("No Date")); g_signal_connect(G_OBJECT(todo_no_due_date_checkbox), "clicked",
gtk_signal_connect(GTK_OBJECT(todo_no_due_date_checkbox), "clicked", G_CALLBACK(cb_check_button_no_due_date), NULL);
GTK_SIGNAL_FUNC(cb_check_button_no_due_date), NULL); gtk_box_pack_start(GTK_BOX(hbox_temp), todo_no_due_date_checkbox, FALSE, FAL
gtk_box_pack_start(GTK_BOX(hbox_temp), todo_no_due_date_checkbox, FALSE, FALS SE, 0);
E, 0);
note_pane = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
note_pane = gtk_vpaned_new(); get_pref(PREF_TODO_NOTE_PANE, &ivalue, NULL);
get_pref(PREF_TODO_NOTE_PANE, &ivalue, NULL); gtk_paned_set_position(GTK_PANED(note_pane), (gint) ivalue);
gtk_paned_set_position(GTK_PANED(note_pane), ivalue); gtk_box_pack_start(GTK_BOX(vbox2), note_pane, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox2), note_pane, TRUE, TRUE, 0);
/* Description text box */
/* Description text box */ hbox_temp = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
hbox_temp = gtk_hbox_new (FALSE, 0); gtk_paned_pack1(GTK_PANED(note_pane), hbox_temp, TRUE, FALSE);
gtk_paned_pack1(GTK_PANED(note_pane), hbox_temp, TRUE, FALSE);
todo_desc = gtk_text_view_new();
todo_desc = gtk_text_view_new(); todo_desc_buffer = G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(todo_desc
todo_desc_buffer = G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(todo_desc) )));
)); gtk_text_view_set_editable(GTK_TEXT_VIEW(todo_desc), TRUE);
gtk_text_view_set_editable(GTK_TEXT_VIEW(todo_desc), TRUE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(todo_desc), GTK_WRAP_WORD);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(todo_desc), GTK_WRAP_WORD);
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
scrolled_window = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 1);
gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 1); gtk_container_add(GTK_CONTAINER(scrolled_window), todo_desc);
gtk_container_add(GTK_CONTAINER(scrolled_window), todo_desc); gtk_box_pack_start(GTK_BOX(hbox_temp), scrolled_window, TRUE, TRUE, 0);
gtk_box_pack_start_defaults(GTK_BOX(hbox_temp), scrolled_window); /* Note text box */
vbox_temp = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
/* Note text box */ gtk_paned_pack2(GTK_PANED(note_pane), vbox_temp, TRUE, FALSE);
vbox_temp = gtk_vbox_new(FALSE, 0);
gtk_paned_pack2(GTK_PANED(note_pane), vbox_temp, TRUE, FALSE); label = gtk_label_new(_("Note"));
gtk_box_pack_start(GTK_BOX(vbox_temp), label, FALSE, FALSE, 0);
label = gtk_label_new(_("Note"));
/* Center "Note" label visually */ todo_note = gtk_text_view_new();
gtk_misc_set_alignment(GTK_MISC(label), 0.506, 0.5); todo_note_buffer = G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(todo_note
gtk_box_pack_start(GTK_BOX(vbox_temp), label, FALSE, FALSE, 0); )));
gtk_text_view_set_editable(GTK_TEXT_VIEW(todo_note), TRUE);
todo_note = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(todo_note), GTK_WRAP_WORD);
todo_note_buffer = G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(todo_note)
)); scrolled_window = gtk_scrolled_window_new(NULL, NULL);
gtk_text_view_set_editable(GTK_TEXT_VIEW(todo_note), TRUE); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(todo_note), GTK_WRAP_WORD); GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 1);
scrolled_window = gtk_scrolled_window_new(NULL, NULL); gtk_container_add(GTK_CONTAINER(scrolled_window), todo_note);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), gtk_box_pack_start(GTK_BOX(vbox_temp), scrolled_window, TRUE, TRUE, 0);
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 1); /* Capture the TAB key to change focus with it */
gtk_container_add(GTK_CONTAINER(scrolled_window), todo_note); g_signal_connect(G_OBJECT(todo_desc), "key_press_event",
gtk_box_pack_start_defaults(GTK_BOX(vbox_temp), scrolled_window); G_CALLBACK(cb_key_pressed_tab), todo_note);
/* Capture the TAB key to change focus with it */ g_signal_connect(G_OBJECT(todo_note), "key_press_event",
gtk_signal_connect(GTK_OBJECT(todo_desc), "key_press_event", G_CALLBACK(cb_key_pressed_shift_tab), todo_desc);
GTK_SIGNAL_FUNC(cb_key_pressed_tab), todo_note);
/* Capture the Enter & Shift-Enter key combinations to move back and
gtk_signal_connect(GTK_OBJECT(todo_note), "key_press_event", * forth between the left- and right-hand sides of the display. */
GTK_SIGNAL_FUNC(cb_key_pressed_shift_tab), todo_desc); g_signal_connect(G_OBJECT(treeView), "key_press_event",
G_CALLBACK(cb_key_pressed_left_side), todo_desc);
/* Capture the Enter & Shift-Enter key combinations to move back and
* forth between the left- and right-hand sides of the display. */ g_signal_connect(G_OBJECT(todo_desc), "key_press_event",
gtk_signal_connect(GTK_OBJECT(clist), "key_press_event", G_CALLBACK(cb_key_pressed_right_side), NULL);
GTK_SIGNAL_FUNC(cb_key_pressed_left_side), todo_desc);
g_signal_connect(G_OBJECT(todo_note), "key_press_event",
gtk_signal_connect(GTK_OBJECT(todo_desc), "key_press_event", G_CALLBACK(cb_key_pressed_right_side),
GTK_SIGNAL_FUNC(cb_key_pressed_right_side), NULL); GINT_TO_POINTER(1));
gtk_signal_connect(GTK_OBJECT(todo_note), "key_press_event", /**********************************************************************/
GTK_SIGNAL_FUNC(cb_key_pressed_right_side),
GINT_TO_POINTER(1)); gtk_widget_show_all(vbox);
gtk_widget_show_all(hbox);
/**********************************************************************/
gtk_widget_hide(add_record_button);
gtk_widget_show_all(vbox); gtk_widget_hide(apply_record_button);
gtk_widget_show_all(hbox); gtk_widget_hide(undelete_record_button);
gtk_widget_hide(cancel_record_button);
gtk_widget_hide(add_record_button);
gtk_widget_hide(apply_record_button);
gtk_widget_hide(undelete_record_button);
gtk_widget_hide(cancel_record_button);
todo_refresh(); todo_refresh();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
 End of changes. 111 change blocks. 
2344 lines changed or deleted 2693 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)