123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- #include "TimerSettingsWindow.h"
- #include "TimerGraphWindow.h"
- #include "TimerMainWindow.h"
- #define DEFAULT_DATA_FILE_NAME "practicetimer/data.json"
- struct _TimerSettingsWindow {
- GtkDialog parent;
- GtkWidget *cancelButton;
- GtkWidget *saveButton;
- GtkWidget *dataPathButton;
- GtkWidget *taskBox;
- GtkWidget *removeTaskButton;
- GtkWidget *taskNameEntry;
- GtkWidget *addTaskButton;
- GtkWidget *graphButton;
- GtkWidget *exportButton;
- GtkWidget *alwaysOnTopCheck;
- GtkWidget *versionLabel;
- GKeyFile *keyFile;
- TimerMainWindow *parentWindow;
- };
- G_DEFINE_TYPE(TimerSettingsWindow, timer_settings_window, GTK_TYPE_DIALOG)
- static void timer_settings_window_copy_key_file(TimerSettingsWindow *self,
- GKeyFile *keyFile) {
- self->keyFile = g_key_file_new();
- gsize len;
- char *data = g_key_file_to_data(keyFile, &len, NULL);
- g_key_file_load_from_data(self->keyFile, data, len, G_KEY_FILE_NONE, NULL);
- g_free(data);
- }
- static gboolean
- timer_settings_window_get_boolean_with_default(TimerSettingsWindow *self,
- const char *group,
- const char *key, gboolean def) {
- GError *err = NULL;
- gboolean b = g_key_file_get_boolean(self->keyFile, group, key, &err);
- if (err != NULL) {
- g_error_free(err);
- return def;
- }
- return b;
- }
- static char *timer_settings_window_get_string_with_default(
- TimerSettingsWindow *self, const char *group, const char *key,
- const char *def) {
- GError *err = NULL;
- char *s = g_key_file_get_string(self->keyFile, group, key, &err);
- if (err != NULL) {
- g_error_free(err);
- return g_strdup(def);
- }
- return s;
- }
- static void
- timer_settings_window_interpret_settings(TimerSettingsWindow *self) {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->alwaysOnTopCheck),
- timer_settings_window_get_boolean_with_default(
- self, "Settings", "Always on Top", FALSE));
- /* Data path stuff */
- char *defaultDataPath = g_strdup_printf("%s/%s", g_get_user_config_dir(),
- DEFAULT_DATA_FILE_NAME);
- char *dataPath = timer_settings_window_get_string_with_default(
- self, "Settings", "Data Path", defaultDataPath);
- gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(self->dataPathButton),
- dataPath);
- g_free(defaultDataPath);
- g_free(dataPath);
- /* Task list stuff */
- GError *err = NULL;
- gsize len;
- char **tasks = g_key_file_get_string_list(self->keyFile, "Settings",
- "Tasks", &len, &err);
- if (err == NULL) {
- gsize i;
- for (i = 0; i < len; ++i) {
- gtk_list_box_insert(GTK_LIST_BOX(self->taskBox),
- gtk_label_new(tasks[i]), -1);
- g_free(tasks[i]);
- }
- g_free(tasks);
- } else {
- g_error_free(err);
- }
- gtk_widget_show_all(self->taskBox);
- }
- TimerSettingsWindow *timer_settings_window_new(TimerApplication *app,
- GKeyFile *keyFile,
- GtkWindow *parentWindow) {
- TimerSettingsWindow *win = TIMER_SETTINGS_WINDOW(
- g_object_new(TIMER_TYPE_SETTINGS_WINDOW, "application", app, NULL));
- timer_settings_window_copy_key_file(win, keyFile);
- timer_settings_window_interpret_settings(win);
- if (TIMER_IS_MAIN_WINDOW(parentWindow)) {
- win->parentWindow = TIMER_MAIN_WINDOW(parentWindow);
- }
- return win;
- }
- GKeyFile *timer_settings_window_get_key_file(TimerSettingsWindow *self) {
- return self->keyFile;
- }
- static gboolean timer_settings_window_has_task(TimerSettingsWindow *self,
- const char *task) {
- GList *tasks = gtk_container_get_children(GTK_CONTAINER(self->taskBox));
- GList *i;
- for (i = tasks; i != NULL; i = i->next) {
- if (strcmp(task, gtk_label_get_text(GTK_LABEL(
- gtk_bin_get_child(GTK_BIN(i->data))))) == 0) {
- return TRUE;
- }
- }
- g_list_free(tasks);
- return FALSE;
- }
- static void add_button_callback(GtkButton *btn, TimerSettingsWindow *win) {
- const char *task = gtk_entry_get_text(GTK_ENTRY(win->taskNameEntry));
- if (strlen(task) != 0) {
- if (!timer_settings_window_has_task(win, task)) {
- gtk_list_box_insert(GTK_LIST_BOX(win->taskBox), gtk_label_new(task),
- -1);
- gtk_widget_show_all(win->taskBox);
- }
- gtk_entry_set_text(GTK_ENTRY(win->taskNameEntry), "");
- }
- }
- static void remove_button_callback(GtkButton *btn, TimerSettingsWindow *win) {
- GList *rows = gtk_list_box_get_selected_rows(GTK_LIST_BOX(win->taskBox));
- GList *i;
- for (i = rows; i != NULL; i = i->next) {
- gtk_container_remove(GTK_CONTAINER(win->taskBox), GTK_WIDGET(i->data));
- }
- g_list_free(rows);
- }
- static void cancel_button_callback(GtkButton *btn, TimerSettingsWindow *win) {
- gtk_dialog_response(GTK_DIALOG(win), GTK_RESPONSE_CANCEL);
- gtk_window_close(GTK_WINDOW(win));
- }
- static const char *const *
- timer_settings_window_get_task_list_string(TimerSettingsWindow *self,
- gsize *len) {
- GList *tasks = gtk_container_get_children(GTK_CONTAINER(self->taskBox));
- gsize taskCount = g_list_length(tasks);
- char **taskStrings = g_malloc(sizeof(char *) * taskCount);
- GList *it;
- int in;
- for (in = 0, it = tasks; it != NULL; ++in, it = it->next) {
- taskStrings[in] = (char *)gtk_label_get_text(
- GTK_LABEL(gtk_bin_get_child(GTK_BIN(it->data))));
- }
- g_list_free(tasks);
- if (len != NULL) {
- *len = taskCount;
- }
- return (const char *const *)taskStrings;
- }
- static void save_button_callback(GtkButton *btn, TimerSettingsWindow *win) {
- g_key_file_set_boolean(
- win->keyFile, "Settings", "Always on Top",
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(win->alwaysOnTopCheck)));
- g_key_file_set_string(
- win->keyFile, "Settings", "Data Path",
- gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(win->dataPathButton)));
- gsize taskCount;
- const char *const *taskList =
- timer_settings_window_get_task_list_string(win, &taskCount);
- g_key_file_set_string_list(win->keyFile, "Settings", "Tasks", taskList,
- taskCount);
- g_free((gpointer)taskList);
- gtk_dialog_response(GTK_DIALOG(win), GTK_RESPONSE_APPLY);
- gtk_window_close(GTK_WINDOW(win));
- }
- static void export_button_callback(GtkButton *btn, TimerSettingsWindow *win) {
- GtkWidget *diag = gtk_file_chooser_dialog_new(
- "Export Data", GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel",
- GTK_RESPONSE_CANCEL, "_Export", GTK_RESPONSE_ACCEPT, NULL);
- int resp = gtk_dialog_run(GTK_DIALOG(diag));
- if (resp == GTK_RESPONSE_ACCEPT) {
- char *path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(diag));
- char *csvData = timer_main_window_get_task_csv(win->parentWindow);
- GFile *file = g_file_new_for_path(path);
- GError *err = NULL;
- GFileOutputStream *out =
- g_file_create(file, G_FILE_CREATE_NONE, NULL, &err);
- if (err != NULL) {
- GtkWidget *msgDiag = gtk_message_dialog_new(
- GTK_WINDOW(win), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK, "Could not export data: %s", err->message);
- gtk_window_set_position(GTK_WINDOW(msgDiag), GTK_WIN_POS_MOUSE);
- gtk_dialog_run(GTK_DIALOG(msgDiag));
- gtk_widget_destroy(msgDiag);
- g_clear_error(&err);
- }
- g_output_stream_write(G_OUTPUT_STREAM(out), csvData, strlen(csvData),
- NULL, &err);
- if (err != NULL) {
- GtkWidget *msgDiag = gtk_message_dialog_new(
- GTK_WINDOW(win), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK, "Could not export data: %s", err->message);
- gtk_window_set_position(GTK_WINDOW(msgDiag), GTK_WIN_POS_MOUSE);
- gtk_dialog_run(GTK_DIALOG(msgDiag));
- gtk_widget_destroy(msgDiag);
- g_error_free(err);
- }
- g_object_unref(out);
- g_object_unref(file);
- g_free(csvData);
- g_free(path);
- }
- gtk_widget_destroy(diag);
- }
- static void graph_button_callback(GtkButton *btn, TimerSettingsWindow *win) {
- gsize taskLen;
- TimerDataPoint *taskData = timer_main_window_get_task_data(win->parentWindow, &taskLen);
- gsize dayLen;
- TimerDataPoint *dayData = timer_main_window_get_day_data(win->parentWindow, &dayLen);
- TimerGraphWindow *diag = timer_graph_window_new(TIMER_APPLICATION(gtk_window_get_application(GTK_WINDOW(win))), dayData, dayLen, taskData, taskLen);
- gtk_dialog_run(GTK_DIALOG(diag));
- gtk_widget_destroy(GTK_WIDGET(diag));
- }
- static void timer_settings_window_finalize(GObject *self) {
- g_key_file_free(TIMER_SETTINGS_WINDOW(self)->keyFile);
- G_OBJECT_CLASS(timer_settings_window_parent_class)->finalize(self);
- }
- static void timer_settings_window_class_init(TimerSettingsWindowClass *class) {
- G_OBJECT_CLASS(class)->finalize = timer_settings_window_finalize;
- gtk_widget_class_set_template_from_resource(
- GTK_WIDGET_CLASS(class),
- "/zander/practicetimer/ui/settings-window.glade");
- gtk_widget_class_bind_template_child_internal(
- GTK_WIDGET_CLASS(class), TimerSettingsWindow, cancelButton);
- gtk_widget_class_bind_template_child_internal(
- GTK_WIDGET_CLASS(class), TimerSettingsWindow, saveButton);
- gtk_widget_class_bind_template_child_internal(
- GTK_WIDGET_CLASS(class), TimerSettingsWindow, dataPathButton);
- gtk_widget_class_bind_template_child_internal(GTK_WIDGET_CLASS(class),
- TimerSettingsWindow, taskBox);
- gtk_widget_class_bind_template_child_internal(
- GTK_WIDGET_CLASS(class), TimerSettingsWindow, removeTaskButton);
- gtk_widget_class_bind_template_child_internal(
- GTK_WIDGET_CLASS(class), TimerSettingsWindow, taskNameEntry);
- gtk_widget_class_bind_template_child_internal(
- GTK_WIDGET_CLASS(class), TimerSettingsWindow, addTaskButton);
- gtk_widget_class_bind_template_child_internal(
- GTK_WIDGET_CLASS(class), TimerSettingsWindow, graphButton);
- gtk_widget_class_bind_template_child_internal(
- GTK_WIDGET_CLASS(class), TimerSettingsWindow, exportButton);
- gtk_widget_class_bind_template_child_internal(
- GTK_WIDGET_CLASS(class), TimerSettingsWindow, alwaysOnTopCheck);
- gtk_widget_class_bind_template_child_internal(
- GTK_WIDGET_CLASS(class), TimerSettingsWindow, versionLabel);
- }
- static void timer_settings_window_init(TimerSettingsWindow *self) {
- gtk_widget_init_template(GTK_WIDGET(self));
- gtk_window_set_keep_above(GTK_WINDOW(self), TRUE);
- g_signal_connect(self->cancelButton, "clicked",
- G_CALLBACK(cancel_button_callback), self);
- g_signal_connect(self->saveButton, "clicked",
- G_CALLBACK(save_button_callback), self);
- g_signal_connect(self->addTaskButton, "clicked",
- G_CALLBACK(add_button_callback), self);
- g_signal_connect(self->removeTaskButton, "clicked",
- G_CALLBACK(remove_button_callback), self);
- g_signal_connect(self->exportButton, "clicked",
- G_CALLBACK(export_button_callback), self);
- g_signal_connect(self->graphButton, "clicked",
- G_CALLBACK(graph_button_callback), self);
- gtk_label_set_text(GTK_LABEL(self->versionLabel), "Version " APPLICATION_VERSION);
- }
|