📄 list-ui.c
字号:
/*
* Copyright (C) 2002, 2003, 2004 Philip Blundell <philb@gnu.org>
* maemo suppoar and UI updtes 2005 Florian Boor <florian@kernelconcepts.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <time.h>
#include <libintl.h>
#include <stdio.h>
#include <gtk/gtk.h>
#include <gpe/pixmaps.h>
#include <gpe/errorbox.h>
#include <gpe/picturebutton.h>
#include <gpe/question.h>
#include <gpe/pim-categories.h>
/* Hildon includes */
#ifdef IS_HILDON
#include <hildon-widgets/hildon-app.h>
#include <gpe/pim-categories-ui.h>
#define ICON_PATH PREFIX "/share/icons/hicolor/26x26"
#endif
#include "todo.h"
#define _(_x) gettext(_x)
static GtkWidget *g_option;
static gint selected_category = -1;
static gboolean show_completed_tasks = TRUE;
GtkListStore *list_store;
GtkWidget *item_menu;
GdkPixbuf *tick_icon, *no_tick_icon, *bar_icon, *dot_icon, *high_icon;
static struct todo_item *current_menu_item;
extern GtkWidget *window;
static GtkWidget *toolbar;
static gchar *
build_categories_string (struct todo_item *item)
{
gchar *s = NULL;
GSList *iter;
for (iter = item->categories; iter; iter = iter->next)
{
const gchar *cat;
cat = gpe_pim_category_name ((int)iter->data);
if (cat)
{
if (s)
{
char *ns = g_strdup_printf ("%s, %s", s, cat);
g_free (s);
s = ns;
}
else
s = g_strdup (cat);
}
}
return s;
}
static void
item_do_edit (void)
{
gtk_widget_show_all (edit_item (current_menu_item, -1, GTK_WINDOW(window)));
current_menu_item = NULL;
}
static void
item_do_delete (void)
{
todo_db_delete_item (current_menu_item);
refresh_items ();
current_menu_item = NULL;
}
static void
set_category (GtkWidget *w, gpointer user_data)
{
selected_category = (gint)user_data;
refresh_items ();
}
static void
toggle_completed_items (GtkWidget *w, gpointer user_data)
{
show_completed_tasks =
gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (w));
refresh_items ();
}
void
categories_menu (void)
{
GtkWidget *menu = gtk_menu_new ();
GSList *l;
GtkWidget *i;
gboolean found;
found = FALSE;
i = gtk_menu_item_new_with_label (_("All items"));
gtk_menu_append (GTK_MENU (menu), i);
g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (set_category), (gpointer)-1);
gtk_widget_show (i);
for (l = gpe_pim_categories_list (); l; l = l->next)
{
struct gpe_pim_category *t = l->data;
i = gtk_menu_item_new_with_label (t->name);
gtk_menu_append (GTK_MENU (menu), i);
g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (set_category), (gpointer)t->id);
gtk_widget_show (i);
if (t->id == selected_category)
found = TRUE;
}
if (!found && selected_category != -1)
{
selected_category = -1;
refresh_items ();
}
i = gtk_separator_menu_item_new ();
gtk_menu_append (GTK_MENU (menu), i);
gtk_widget_show (i);
i = gtk_check_menu_item_new_with_label (_("Show completed"));
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (i),
show_completed_tasks);
g_signal_connect (G_OBJECT (i), "toggled",
G_CALLBACK (toggle_completed_items), NULL);
gtk_menu_append (GTK_MENU (menu), i);
gtk_widget_show (i);
gtk_widget_show (menu);
if (gtk_option_menu_get_menu(GTK_OPTION_MENU (g_option)))
{
gtk_widget_destroy(gtk_option_menu_get_menu(GTK_OPTION_MENU (g_option)));
}
gtk_option_menu_set_menu (GTK_OPTION_MENU (g_option), menu);
}
static void
new_todo_item (GtkWidget *w, gpointer user_data)
{
GtkWidget *todo = edit_item (NULL, selected_category, GTK_WINDOW(window));
gtk_widget_show_all (todo);
}
static void
delete_completed_items (GtkWidget *w, gpointer user_data)
{
GtkWidget *dialog;
#ifdef IS_HILDON
dialog = gtk_message_dialog_new (GTK_WINDOW(gtk_widget_get_toplevel(w)),
GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
"Are you sure you want to delete all " \
"completed items permanently?");
gtk_dialog_add_buttons(GTK_DIALOG(dialog),
_("OK"), GTK_RESPONSE_YES,
_("Cancel"), GTK_RESPONSE_NO, NULL);
#else
dialog = gtk_message_dialog_new (GTK_WINDOW(gtk_widget_get_toplevel(w)),
GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
"Delete completed items?");
#endif
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES)
{
GSList *list, *iter;
list = g_slist_copy (todo_db_get_items_list ());
for (iter = list; iter; iter = iter->next)
{
struct todo_item *i = iter->data;
gboolean complete;
complete = (i->state == COMPLETED) ? TRUE : FALSE;
if (complete && (selected_category == -1 ||
g_slist_find (i->categories, (gpointer)selected_category)))
{
todo_db_delete_item (i);
}
}
g_slist_free (list);
refresh_items ();
}
gtk_widget_destroy (dialog);
}
void
open_editing_window (GtkTreePath *path)
{
GtkTreeIter iter;
struct todo_item *i;
gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store), &iter, path);
gtk_tree_model_get (GTK_TREE_MODEL (list_store), &iter, COL_DATA, &i, -1);
gtk_widget_show_all (edit_item (i, -1, GTK_WINDOW(window)));
}
void
toggle_completed (GtkTreePath *path)
{
GtkTreeIter iter;
struct todo_item *i;
gboolean complete;
gchar time[20] = {0};
struct tm *ti;
GdkPixbuf *sicon;
GdkPixbuf *priority;
gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store), &iter, path);
gtk_tree_model_get (GTK_TREE_MODEL (list_store), &iter, COL_DATA, &i, -1);
i->state = (i->state + 1) % 4;
switch (i->state)
{
case IN_PROGRESS:
sicon = dot_icon;
break;
case COMPLETED:
sicon = tick_icon;
break;
case ABANDONED:
sicon = bar_icon;
break;
default:
sicon = no_tick_icon;
break;
}
complete = ((i->state == COMPLETED) || (i->state == ABANDONED)) ? TRUE : FALSE;
switch (i->priority)
{
case PRIORITY_HIGH:
priority = high_icon;
break;
default:
priority = NULL;
break;
}
if (i->time)
{
ti = localtime(&i->time);
strftime(time, 20, "%x", ti);
}
if (complete && !show_completed_tasks) {
gtk_list_store_remove (list_store, &iter);
} else {
gtk_list_store_set (list_store, &iter,
COL_ICON, sicon,
COL_SUMMARY, i->summary,
COL_STRIKETHROUGH, complete,
COL_DATA, i,
COL_PRIORITY, priority,
COL_PRIORITY_TEXT, state_map[i->state].string,
COL_DUE, time,
-1);
}
todo_db_push_item (i);
}
int
sort_by_priority (gconstpointer a, gconstpointer b)
{
struct todo_item *ia, *ib;
ia = (struct todo_item *)a;
ib = (struct todo_item *)b;
return ib->priority - ia->priority;
}
int
sort_more_complex (gconstpointer a, gconstpointer b)
{
struct todo_item *ia, *ib;
ia = (struct todo_item *)a;
ib = (struct todo_item *)b;
/* status */
if ((ia->state >= COMPLETED) && (ib->state < COMPLETED))
return 1;
if ((ib->state >= COMPLETED) && (ia->state < COMPLETED))
return -1;
/* both due date: sort by date */
if (ia->time && ib->time)
{
if (ia->time != ib->time)
return ((ia->time - ib->time ) > 0 ? 1 : -1);
}
/* only one due date */
if (ia->time != ib->time)
return ((ib->time - ia->time) > 0 ? 1 : -1);
/* no due date: sort by priority */
return ib->priority - ia->priority;
}
void
refresh_items (void)
{
GSList *list, *iter;
GdkPixbuf *sicon;
gchar *categories;
gtk_list_store_clear (list_store);
list = g_slist_copy (todo_db_get_items_list ());
list = g_slist_sort (list, sort_more_complex);
for (iter = list; iter; iter = iter->next)
{
struct todo_item *i = iter->data;
if (selected_category == -1
|| g_slist_find (i->categories, (gpointer)selected_category))
{
GtkTreeIter iter;
gboolean complete;
gchar time[20] = {0};
GdkPixbuf *priority;
struct tm *ti;
switch (i->priority)
{
case PRIORITY_HIGH:
priority = high_icon;
break;
default:
priority = NULL;
break;
}
if (i->time)
{
ti = localtime(&i->time);
strftime(time, 20, "%x", ti);
}
complete = ((i->state == COMPLETED) || (i->state == ABANDONED)) ? TRUE : FALSE;
if (complete && !show_completed_tasks)
continue;
switch (i->state)
{
case IN_PROGRESS:
sicon = dot_icon;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -