/*
 * Osmo - a handy personal organizer
 *
 * Copyright (C) 2007-2014 Tomasz Mąka <pasp@users.sourceforge.net>
 *           (C) 2007-2014 Piotr Mąka <silloz@users.sourceforge.net>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "about.h"
#include "backup.h"
#include "calendar.h"
#include "calendar_utils.h"
#include "calendar_widget.h"
#include "i18n.h"
#include "tasks_preferences_gui.h"
#include "options_prefs.h"
#include "preferences_gui.h"
#include "stock_icons.h"
#include "tasks.h"
#include "tasks_items.h"
#include "tasks_export.h"
#include "tasks_print.h"
#include "tasks_utils.h"
#include "utils.h"
#include "utils_gui.h"
#include "check_events.h"

#ifdef TASKS_ENABLED

/*============================================================================*/

static void
show_preferences_window_cb(GtkToolButton *toolbutton, gpointer data) {
    GUI *appGUI = (GUI *) data;
    appGUI->opt->window = opt_create_preferences_window(appGUI);
    gtk_widget_show(appGUI->opt->window);

    gint page = gtk_notebook_page_num(GTK_NOTEBOOK(appGUI->opt->notebook), appGUI->opt->tasks);
    gtk_notebook_set_current_page(GTK_NOTEBOOK(appGUI->opt->notebook), page);
}

/*============================================================================*/

gint
task_calculate_new_date (TASK_ITEM *item, GUI *appGUI, guint32 *new_date, gint *new_time)
{
	GDate *cdate;
	guint32 current_julian;
	gint current_time;
	gint i, cycles;
	gboolean repeat_time, repeat_date, set_start_time;

	gboolean month_mode_flag = item->repeat_month_interval > 0 && item->repeat_day_interval == 0;

	repeat_time = repeat_date = FALSE;
	set_start_time = TRUE;

	cycles = 0;
	current_julian = utl_date_get_current_julian ();
	current_time = utl_time_get_current_seconds ();
	*new_date = item->due_date_julian;
	*new_time = item->due_time;

	if (item->repeat_time_start < item->repeat_time_end && item->repeat_time_interval > 0 && item->due_time >= 0)
		repeat_time = TRUE;
	
	if (item->repeat_month_interval > 0 || item->repeat_day_interval > 0)
		repeat_date = TRUE;

	if (repeat_time)
	{
		for (i = item->repeat_time_start; i <= item->repeat_time_end; i += item->repeat_time_interval)
		{
			if (i * 60 > item->due_time && i * 60 > current_time)
			{
				*new_time = i * 60;
				set_start_time = FALSE;
				break;
			}
		}
		if (set_start_time && repeat_date)
			*new_time = item->repeat_time_start * 60;
	}

	if (*new_time < current_time || item->due_time < 0)
		current_julian++;

	if (item->due_date_julian < current_julian && repeat_date)
	{
		cdate = g_date_new_julian (item->due_date_julian);

		while (*new_date < current_julian)
		{
			g_date_add_months (cdate, item->repeat_month_interval);
			g_date_add_days (cdate, item->repeat_day_interval);

			if (month_mode_flag)
			{
				utl_date_set_valid_day (cdate, item->repeat_start_day);
				utl_date_set_nearest_weekday (cdate, item->repeat_day, TRUE);
			}
			else
				utl_date_set_nearest_weekday (cdate, item->repeat_day, FALSE);

			*new_date = g_date_get_julian (cdate);
			cycles++;

			if (item->repeat_counter != 0 && cycles >= item->repeat_counter)
			{
				g_date_free (cdate);
				return cycles;
			}
		}

		if (repeat_time)
			*new_time = item->repeat_time_start * 60;

		g_date_free (cdate);
	}

	return cycles;
}

/*------------------------------------------------------------------------------*/

void
tasks_done(GtkTreeIter *iter, TASK_ITEM *item, GUI *appGUI) {
    g_return_if_fail(item->repeat == FALSE);

    if (config.delete_completed) {
        gtk_list_store_remove(appGUI->tsk->tasks_list_store, iter);
    } else {
        gtk_list_store_set(appGUI->tsk->tasks_list_store, iter,
                TA_COLUMN_COLOR, get_date_color(item->due_date_julian, item->due_time, TRUE, appGUI),
                TA_COLUMN_DONE, TRUE, -1);
    }
    if (config.save_data_after_modification)
        write_tasks_entries(appGUI);
}
/*------------------------------------------------------------------------------*/

void
tasks_repeat_done (GtkTreeIter *iter, TASK_ITEM *item, GUI *appGUI)
{
	guint32 new_date;
	gint new_time;
	gint cycles;

	g_return_if_fail (item->repeat == TRUE);

	cycles = task_calculate_new_date (item, appGUI, &new_date, &new_time);

	if (item->repeat_counter == 0 || item->repeat_counter > cycles)
	{
		if (item->repeat_counter > cycles)
		{
			gtk_list_store_set (appGUI->tsk->tasks_list_store, iter,
			                    TA_COLUMN_REPEAT_COUNTER, item->repeat_counter - cycles, -1);
		}

		if (new_date == item->due_date_julian && new_time == item->due_time)
		{
			if (config.delete_completed)
				gtk_list_store_remove (appGUI->tsk->tasks_list_store, iter);
			else
				gtk_list_store_set (appGUI->tsk->tasks_list_store, iter,
				                    TA_COLUMN_COLOR, get_date_color (item->due_date_julian, item->due_time, TRUE, appGUI),
				                    TA_COLUMN_DONE, TRUE, -1);
		}
		else
		{
			gtk_list_store_set (appGUI->tsk->tasks_list_store, iter,
			                    TA_COLUMN_COLOR, get_date_color (new_date, new_time, FALSE, appGUI),
			                    TA_COLUMN_DUE_DATE_JULIAN, new_date,
			                    TA_COLUMN_DUE_DATE, get_date_time_full_str (new_date, new_time),
			                    TA_COLUMN_DUE_TIME, new_time,
			                    TA_COLUMN_DONE, FALSE, -1);
		}
	}
	else
	{
		if (config.delete_completed)
			gtk_list_store_remove (appGUI->tsk->tasks_list_store, iter);
		else
			gtk_list_store_set (appGUI->tsk->tasks_list_store, iter,
			                    TA_COLUMN_REPEAT_COUNTER, 0,
			                    TA_COLUMN_COLOR, get_date_color (new_date, new_time, TRUE, appGUI),
			                    TA_COLUMN_DUE_DATE_JULIAN, new_date,
			                    TA_COLUMN_DUE_DATE, get_date_time_full_str (new_date, new_time),
			                    TA_COLUMN_DUE_TIME, new_time,
			                    TA_COLUMN_DONE, TRUE, -1);
	}
    if (config.save_data_after_modification)
        write_tasks_entries(appGUI);
}

/*------------------------------------------------------------------------------*/

void
panel_close_desc_cb (GtkWidget *widget, gpointer data)
{
    GtkPaned *paned;
    gint max_position;
    GUI *appGUI = (GUI *)data;

    paned = GTK_PANED (appGUI->tsk->tasks_paned);
    g_object_get(paned, "max-position", &max_position, NULL);
    gtk_paned_set_position(paned, max_position);
}

/*------------------------------------------------------------------------------*/

void
tasks_item_selected (GtkTreeSelection *selection, gpointer data)
{
	GtkTreeIter iter;
	gint selection_size;
	GtkTreeModel *model;
	gchar *text;
	guint32 start_date_julian, done_date_julian, due_date_julian;
	gint due_time;
	gchar tmpbuf[BUFFER_SIZE];
	gboolean repeat, prev_state, next_state;

#ifndef HAVE_LIBWEBKIT
	GtkTextBuffer *text_buffer;
	GtkTextIter titer;
	GtkTextChildAnchor *anchor;
	GtkWidget *hseparator;
#else
	gchar *toutput = g_strdup (""), *output;
	PangoFontDescription *font_desc;
#endif  /* HAVE_LIBWEBKIT */

	GUI *appGUI = (GUI *)data;

#ifndef HAVE_LIBWEBKIT
	text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (appGUI->tsk->tasks_desc_textview));
	utl_gui_clear_text_buffer (text_buffer, &titer);
#endif  /* HAVE_LIBWEBKIT */

	selection_size = gtk_tree_selection_count_selected_rows(selection);
	if (selection_size > 1)
        {
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->edit_button), FALSE);
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->delete_button), TRUE);
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->prev_button), FALSE);
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->next_button), FALSE);

#ifdef HAVE_LIBWEBKIT                
		webkit_web_view_load_html (appGUI->tsk->html_webkitview, "", "file://");
#endif  /* HAVE_LIBWEBKIT */
        }
        else if (selection_size == 1)
	{
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->edit_button), TRUE);
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->delete_button), TRUE);

                iter = utl_gui_get_first_selection_iter(selection, &model);
		gtk_tree_model_get (model, &iter,
		                    TA_COLUMN_DESCRIPTION, &text,
		                    TA_COLUMN_DUE_DATE_JULIAN, &due_date_julian,
		                    TA_COLUMN_START_DATE_JULIAN, &start_date_julian,
		                    TA_COLUMN_DONE_DATE_JULIAN, &done_date_julian,
		                    TA_COLUMN_DUE_TIME, &due_time,
		                    TA_COLUMN_REPEAT, &repeat, -1);

		if (repeat == TRUE)
		{
			prev_state = FALSE;
			next_state = utl_date_time_in_the_past_js (due_date_julian, due_time);
		}
		else
		{
			prev_state = next_state = (due_date_julian != 0) ? TRUE : FALSE;
		}

		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->prev_button), prev_state);
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->next_button), next_state);

		g_snprintf (tmpbuf, BUFFER_SIZE, "\n%s: %s\n",
		            _("Started"), julian_to_str (start_date_julian, DATE_FULL, config.override_locale_settings));

		if (text != NULL)
		{
#ifndef HAVE_LIBWEBKIT
			gtk_text_buffer_insert_with_tags_by_name (text_buffer, &titer, text, -1, "info_font", NULL);
			gtk_text_buffer_insert (text_buffer, &titer, "\n", -1);
#endif  /* HAVE_LIBWEBKIT */
		}

		if (start_date_julian)
		{
#ifdef HAVE_LIBWEBKIT
			if (text == NULL)
				toutput = utl_strconcat (toutput, "<i>", tmpbuf, "</i><br />", NULL);
			else
				toutput = utl_strconcat (toutput, "<br /><hr /><i>", tmpbuf, "</i><br />", NULL);
#else
			gtk_text_buffer_insert (text_buffer, &titer, "\n", -1);
			anchor = gtk_text_buffer_create_child_anchor (text_buffer, &titer);
			gtk_text_buffer_insert_with_tags_by_name (text_buffer, &titer, tmpbuf, -1, "italic", NULL);
#endif  /* HAVE_LIBWEBKIT */

			if (done_date_julian != 0)
			{
				g_snprintf (tmpbuf, BUFFER_SIZE, "%s: %s\n",
				            _("Finished"), julian_to_str (done_date_julian, DATE_FULL, config.override_locale_settings));
#ifdef HAVE_LIBWEBKIT
				toutput = utl_strconcat (toutput, "<i>", tmpbuf, "</i>", NULL);
#else
				gtk_text_buffer_insert_with_tags_by_name (text_buffer, &titer, tmpbuf, -1, "italic", NULL);
#endif  /* HAVE_LIBWEBKIT */
			}

#ifdef HAVE_LIBWEBKIT
			if (text == NULL)
				text = g_strdup ("");
			font_desc = pango_font_description_from_string((gchar *) config.task_info_font);
			output = utl_text_to_html_page (text, pango_font_description_get_family (font_desc), NULL, NULL, NULL, NULL, toutput);
			g_free (toutput);

                        webkit_settings_set_default_font_size (webkit_web_view_get_settings(appGUI->tsk->html_webkitview), PANGO_PIXELS(pango_font_description_get_size (font_desc)));
			webkit_web_view_load_html (appGUI->tsk->html_webkitview, output, "file://");

			g_free (output);
			pango_font_description_free (font_desc);
#else
			gtk_text_view_set_buffer (GTK_TEXT_VIEW (appGUI->tsk->tasks_desc_textview), text_buffer);
			hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
			gtk_widget_show (hseparator);
			if (!config.gui_layout)
				gtk_widget_set_size_request (hseparator, 320, -1);
			else
				gtk_widget_set_size_request (hseparator, 200, -1);

			gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (appGUI->tsk->tasks_desc_textview), hseparator, anchor);
#endif  /* HAVE_LIBWEBKIT */
		}
		g_free (text);
	}
	else
	{
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->edit_button), FALSE);
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->delete_button), FALSE);
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->prev_button), FALSE);
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->next_button), FALSE);

#ifdef HAVE_LIBWEBKIT                
                webkit_web_view_load_html (appGUI->tsk->html_webkitview, "", "file://");
#endif  /* HAVE_LIBWEBKIT */
	}
}

/*------------------------------------------------------------------------------*/

static void
tasks_add_item_cb (GtkToolButton *toolbutton, gpointer data)
{
	GUI *appGUI = (GUI *) data;
	tasks_add_edit_dialog_show (FALSE, 0, utl_time_get_current_seconds (), appGUI);
}

/*------------------------------------------------------------------------------*/

static void
tasks_edit_item_cb (GtkToolButton *toolbutton, gpointer data)
{
	GUI *appGUI = (GUI *) data;

	if (gtk_tree_selection_count_selected_rows(appGUI->tsk->tasks_list_selection) == 1)
		tasks_add_edit_dialog_show (TRUE, appGUI->tsk->tasks_due_julian_day, appGUI->tsk->tasks_due_time, appGUI);
}

/*------------------------------------------------------------------------------*/

static void
tasks_remove_item_cb (GtkToolButton *toolbutton, gpointer data)
{
	GUI *appGUI = (GUI *) data;
	tasks_remove_dialog_show (appGUI);
}

/*------------------------------------------------------------------------------*/

void
task_modify_due_date (GtkTreeRowReference *ref, gint value, GUI *appGUI) {
    GtkTreeIter iter, *e_iter;
    guint32 due_date;
    gint due_time;
    guint id;
    TASK_ITEM *item;
    GtkTreePath *path;
    GtkTreeModel *model;

    model = gtk_tree_row_reference_get_model(ref);
    path = gtk_tree_row_reference_get_path(ref);
    if (path != NULL) {
        if (gtk_tree_model_get_iter(model, &iter, path)) {
            gtk_tree_model_get(model, &iter, TA_COLUMN_DUE_DATE_JULIAN, &due_date,
                    TA_COLUMN_DUE_TIME, &due_time, TA_COLUMN_ID, &id, -1);

            e_iter = tsk_get_iter(id, appGUI);
            g_return_if_fail(e_iter != NULL);

            item = tsk_get_item(e_iter, appGUI);
            g_return_if_fail(item != NULL);

            if (item->repeat == TRUE)
                tasks_repeat_done(e_iter, item, appGUI);
            else if (due_date != 0) {
                due_date += value;
                gtk_list_store_set(appGUI->tsk->tasks_list_store, e_iter,
                        TA_COLUMN_COLOR, get_date_color(due_date, due_time, FALSE, appGUI),
                        TA_COLUMN_DUE_DATE_JULIAN, due_date,
                        TA_COLUMN_DUE_DATE, get_date_time_full_str(due_date, due_time), -1);
            }
            tsk_item_free(item);
        }
        gtk_tree_path_free(path);
    }
}

/*------------------------------------------------------------------------------*/

void
tasks_increment_due_date (GtkTreeRowReference *ref, GUI *appGUI) {
    task_modify_due_date(ref, 1, appGUI);
}

/*------------------------------------------------------------------------------*/
void
tasks_decrement_due_date (GtkTreeRowReference *ref, GUI *appGUI) {
    task_modify_due_date(ref, -1, appGUI);
}

/*------------------------------------------------------------------------------*/

void
tasks_modify_due_date (GFunc modify_function, GUI *appGUI)
{
    utl_gui_foreach_selected(appGUI->tsk->tasks_list_selection, GTK_TREE_MODEL(appGUI->tsk->tasks_list_store),
                modify_function, appGUI);
}

/*------------------------------------------------------------------------------*/

static void
tasks_change_due_date_to_prev_date_cb (GtkToolButton *toolbutton, gpointer data)
{
	GUI *appGUI = (GUI *) data;
	tasks_modify_due_date ((GFunc)tasks_decrement_due_date, appGUI);
}

/*------------------------------------------------------------------------------*/

static void
tasks_change_due_date_to_next_date_cb (GtkToolButton *toolbutton, gpointer data)
{
	GUI *appGUI = (GUI *) data;
	tasks_modify_due_date ((GFunc)tasks_increment_due_date, appGUI);
}

/*------------------------------------------------------------------------------*/

#ifdef HAVE_LIBICAL
static void
tasks_export_visible_items_cb (GtkToolButton *toolbutton, gpointer data)
{
	GUI *appGUI = (GUI *) data;
	export_tasks_to_file (appGUI);
}
#endif /* HAVE_LIBICAL */

/*------------------------------------------------------------------------------*/

#ifdef PRINTING_SUPPORT
static void
tasks_print_visible_items_cb (GtkToolButton *toolbutton, gpointer data)
{
	GUI *appGUI = (GUI *) data;
	tasks_print (appGUI);
}
#endif /* PRINTING_SUPPORT */

/*------------------------------------------------------------------------------*/

void
done_toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer user_data)
{
	GtkTreePath *sort_path, *filter_path, *path;
	GtkTreeIter  iter;
	gboolean done_status;
	guint32 done_date, category;
	GtkTreeModel *model;
	guint id;

	GUI *appGUI = (GUI *) user_data;
	model = GTK_TREE_MODEL (appGUI->tsk->tasks_list_store);

	category = gtk_combo_box_get_active (GTK_COMBO_BOX (appGUI->tsk->cf_combobox));

	sort_path = gtk_tree_path_new_from_string (path_str);

	if (sort_path != NULL)
	{
		filter_path = gtk_tree_model_sort_convert_path_to_child_path (GTK_TREE_MODEL_SORT (appGUI->tsk->tasks_sort), sort_path);

		if (filter_path != NULL)
		{
			path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (appGUI->tsk->tasks_filter), filter_path);

			if (path != NULL)
			{
				gtk_tree_model_get_iter (model, &iter, path);   /* get toggled iter */
				gtk_tree_model_get (model, &iter, TA_COLUMN_DONE, &done_status,
                                        TA_COLUMN_ID, &id, -1);

				if (done_status == FALSE)
					done_date = utl_date_get_current_julian ();
				else
					done_date = 0;

				gtk_list_store_set (GTK_LIST_STORE (model), &iter,
				                    TA_COLUMN_DONE, !done_status,
				                    TA_COLUMN_DONE_DATE_JULIAN, done_date, -1);

				if (done_status == FALSE && config.delete_completed)
					gtk_list_store_remove (GTK_LIST_STORE (model), &iter);

				gtk_tree_path_free (path);
			}

			gtk_tree_path_free (filter_path);
		}

		gtk_tree_path_free (sort_path);
	}

	cal_set_day_info (appGUI);
	refresh_tasks (appGUI);

	gtk_combo_box_set_active (GTK_COMBO_BOX (appGUI->tsk->cf_combobox), category);

	if (config.save_data_after_modification)
		write_tasks_entries (appGUI);
}

/*------------------------------------------------------------------------------*/

gchar *
get_date_color (guint32 julian_day, gint time, gboolean done, GUI *appGUI)
{
	static gchar due_date_color[MAXCOLORNAME];
	GdkRGBA color;
	gint current_time;
	gint32 r;

	current_time = utl_time_get_current_seconds ();

    gtk_style_context_get_color(gtk_widget_get_style_context(appGUI->main_window), GTK_STATE_NORMAL, &color);
    utl_gui_convert_color_to_string(&color, due_date_color);

	if (julian_day != 0 && done == FALSE)
	{
		r = julian_day - utl_date_get_current_julian ();

		if (r == 0)
		{
			if (time >= 0 && current_time > time)
				g_strlcpy (due_date_color, config.past_due_color, MAXCOLORNAME);
			else
				g_strlcpy (due_date_color, config.due_today_color, MAXCOLORNAME);
		}
		else if (r > 0 && r < 7)
			g_strlcpy (due_date_color, config.due_7days_color, MAXCOLORNAME);
		else if (r < 0)
			g_strlcpy (due_date_color, config.past_due_color, MAXCOLORNAME);
	}

	return due_date_color;
}

/*------------------------------------------------------------------------------*/

void
set_categories (GUI *appGUI)
{
	GtkTreeIter iter;
	gchar *category;
	gboolean tasks_state, has_next;
	gint i, n;

	n = utl_gui_get_combobox_items (GTK_COMBO_BOX (appGUI->tsk->cf_combobox));

	for (i = n-1; i >= 0; i--)
		gtk_combo_box_text_remove (GTK_COMBO_BOX_TEXT (appGUI->tsk->cf_combobox), i);

	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (appGUI->tsk->cf_combobox), NULL, _("All items"));

	has_next = gtk_tree_model_get_iter_first(GTK_TREE_MODEL (appGUI->opt->tasks_category_store), &iter);
	while (has_next)
	{
		gtk_tree_model_get (GTK_TREE_MODEL (appGUI->opt->tasks_category_store), &iter,
		                    TC_COLUMN_NAME, &category,
		                    TC_COLUMN_TASKS, &tasks_state, -1);

		if (tasks_state == TRUE)
			gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (appGUI->tsk->cf_combobox), NULL, category);

		g_free (category);
                has_next = gtk_tree_model_iter_next(GTK_TREE_MODEL (appGUI->opt->tasks_category_store), &iter);
	}
	
	if (config.remember_category_in_tasks == TRUE)
		gtk_combo_box_set_active (GTK_COMBO_BOX (appGUI->tsk->cf_combobox), config.current_category_in_tasks);
	else
		gtk_combo_box_set_active (GTK_COMBO_BOX (appGUI->tsk->cf_combobox), 0);
}

/*------------------------------------------------------------------------------*/

void
refresh_tasks (GUI *appGUI)
{
	GtkTreeIter iter;
	gint due_time;
	guint32 julian_day;
	gchar *priority;
	gboolean done, has_next;
        
        has_next = gtk_tree_model_get_iter_first(GTK_TREE_MODEL (appGUI->tsk->tasks_list_store), &iter);
	while (has_next)
	{
		gtk_tree_model_get (GTK_TREE_MODEL (appGUI->tsk->tasks_list_store), &iter,
		                    TA_COLUMN_DONE, &done,
		                    TA_COLUMN_DUE_DATE_JULIAN, &julian_day,
		                    TA_COLUMN_DUE_TIME, &due_time,
		                    TA_COLUMN_PRIORITY, &priority, -1);

		if (tsk_get_priority_index (priority) == HIGH_PRIORITY && config.tasks_high_in_bold == TRUE) /* high priority ? */
		{
			gtk_list_store_set (appGUI->tsk->tasks_list_store, &iter,
			                    TA_COLUMN_DUE_DATE, get_date_time_full_str (julian_day, due_time),
			                    TA_COLUMN_COLOR, get_date_color (julian_day, due_time, done, appGUI),
			                    TA_COLUMN_BOLD, PANGO_WEIGHT_BOLD,-1);
		}
		else
		{
			gtk_list_store_set (appGUI->tsk->tasks_list_store, &iter,
			                    TA_COLUMN_DUE_DATE, get_date_time_full_str (julian_day, due_time),
			                    TA_COLUMN_COLOR, get_date_color (julian_day, due_time, done, appGUI),
			                    TA_COLUMN_BOLD, PANGO_WEIGHT_NORMAL,-1);
		}

		g_free (priority);
                has_next = gtk_tree_model_iter_next(GTK_TREE_MODEL (appGUI->tsk->tasks_list_store), &iter);
	}
}

/*------------------------------------------------------------------------------*/

void
update_tasks_number (GUI *appGUI)
{
	gint i;
	gchar tmpbuf[BUFFER_SIZE];

	i = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (appGUI->tsk->tasks_filter), NULL);

	if (i > 0)
	{
		g_snprintf (tmpbuf, BUFFER_SIZE, "<i>%4d %s</i>", i, ngettext ("entry", "entries", i));
#ifdef PRINTING_SUPPORT
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->print_button), TRUE);
#endif /* PRINTING_SUPPORT */
#ifdef HAVE_LIBICAL
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->export_button), TRUE);
#endif /* HAVE_LIBICAL */
	}
	else
	{
		g_snprintf (tmpbuf, BUFFER_SIZE, "<i>%s</i>", _("no entries"));
#ifdef PRINTING_SUPPORT
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->print_button), FALSE);
#endif /* PRINTING_SUPPORT */
#ifdef HAVE_LIBICAL
		gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->export_button), FALSE);
#endif /* HAVE_LIBICAL */
	}

	gtk_label_set_markup (GTK_LABEL (appGUI->tsk->n_items_label), tmpbuf);

}

void
task_list_row_changed_cb (GtkTreeModel *tree_model, GtkTreePath  *path, GtkTreeIter  *iter, GUI *appGUI)
{
    TASK_ITEM *item = tsk_get_item(iter, appGUI);
    change_task_notification(item, appGUI);
    tsk_item_free(item);
}

void
task_filter_row_inserted_cb (GtkTreeModel *tree_model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
{
    update_tasks_number ((GUI *) user_data);
}

void
task_filter_row_deleted_cb (GtkTreeModel *tree_model, GtkTreePath *path, gpointer user_data)
{
    update_tasks_number ((GUI *) user_data);
}

/*------------------------------------------------------------------------------*/

guint
get_number_of_visible_tasks_with_date (GUI *appGUI)
{
	guint32 date, n;
	GtkTreeIter sort_iter;
        gboolean valid;

	valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(appGUI->tsk->tasks_sort), &sort_iter);
	n = 0;

        while (valid) {
            GtkTreeIter filter_iter, iter;
            gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(appGUI->tsk->tasks_sort), &filter_iter, &sort_iter);
            gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(appGUI->tsk->tasks_filter), &iter, &filter_iter);
            gtk_tree_model_get(GTK_TREE_MODEL(appGUI->tsk->tasks_list_store), &iter,
                    TA_COLUMN_DUE_DATE_JULIAN, &date, -1);
            if (date != 0)
                n++;
            valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(appGUI->tsk->tasks_sort), &sort_iter);
        }

	return n;
}

/*------------------------------------------------------------------------------*/

void
add_item_to_list (TASK_ITEM *item, GUI *appGUI)
{
	GtkTreeIter iter;
	GdkPixbuf *image;
	const gchar *icon_name;
	gchar *date_time_str;

	gtk_list_store_append (appGUI->tsk->tasks_list_store, &iter);

	gtk_list_store_set (appGUI->tsk->tasks_list_store, &iter,
	                    TA_COLUMN_DONE, item->done,
	                    TA_COLUMN_DUE_DATE_JULIAN, item->due_date_julian,
	                    TA_COLUMN_START_DATE_JULIAN, item->start_date_julian,
	                    TA_COLUMN_DONE_DATE_JULIAN, item->done_date_julian,
	                    TA_COLUMN_DUE_TIME, item->due_time,
	                    TA_COLUMN_PRIORITY, item->priority,
	                    TA_COLUMN_CATEGORY, item->category,
	                    TA_COLUMN_SUMMARY, item->summary,
	                    TA_COLUMN_DESCRIPTION, item->desc,
	                    TA_COLUMN_SOUND_ENABLE, item->sound_enable,
	                    TA_COLUMN_NDIALOG_ENABLE, item->ndialog_enable,
	                    TA_COLUMN_COLOR, get_date_color (item->due_date_julian, item->due_time, item->done, appGUI),
	                    TA_COLUMN_ACTIVE, item->active,
	                    TA_COLUMN_OFFLINE_IGNORE, item->offline_ignore,
	                    TA_COLUMN_REPEAT, item->repeat,
	                    TA_COLUMN_REPEAT_DAY, item->repeat_day,
	                    TA_COLUMN_REPEAT_MONTH_INTERVAL, item->repeat_month_interval,
	                    TA_COLUMN_REPEAT_DAY_INTERVAL, item->repeat_day_interval,
	                    TA_COLUMN_REPEAT_START_DAY, item->repeat_start_day,
	                    TA_COLUMN_REPEAT_TIME_START, item->repeat_time_start,
	                    TA_COLUMN_REPEAT_TIME_END, item->repeat_time_end,
	                    TA_COLUMN_REPEAT_TIME_INTERVAL, item->repeat_time_interval,
	                    TA_COLUMN_REPEAT_COUNTER, item->repeat_counter,
	                    TA_COLUMN_ALARM_COMMAND, item->alarm_command,
	                    TA_COLUMN_WARNING_DAYS, item->warning_days,
	                    TA_COLUMN_WARNING_TIME, item->warning_time,
	                    TA_COLUMN_POSTPONE_TIME, item->postpone_time,
	                    TA_COLUMN_ID, item->id,
	                    -1);

	icon_name = (item->repeat == TRUE) ? OSMO_STOCK_TYPE_RECURRENT : OSMO_STOCK_TYPE_NORMAL;
	image = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), icon_name, 16, 0, NULL);
	gtk_list_store_set (appGUI->tsk->tasks_list_store, &iter, TA_COLUMN_TYPE, image, -1);
	g_object_unref (image);

	date_time_str = utl_date_time_print_default (item->due_date_julian, item->due_time, FALSE);
	gtk_list_store_set (appGUI->tsk->tasks_list_store, &iter, TA_COLUMN_DUE_DATE, date_time_str, -1);
	g_free (date_time_str);
}

/*------------------------------------------------------------------------------*/

gint
list_dbclick_cb (GtkWidget * widget, GdkEventButton * event, gpointer data)
{
	GUI *appGUI = (GUI *) data;

	if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1))
	{
                if (config.add_edit == FALSE)
                        tasks_edit_item_cb (NULL, appGUI);
                else
                        tasks_add_edit_dialog_show (FALSE, 0, utl_time_get_current_seconds (), appGUI);

                return TRUE;
	}

	return FALSE;
}

/*------------------------------------------------------------------------------*/

gboolean
tasks_list_filter_cb (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
{
	gchar *category;
	gchar *value;
	gboolean done, result;

	GUI *appGUI = (GUI *) data;

	gtk_tree_model_get (model, iter,
	                    TA_COLUMN_DONE, &done,
	                    TA_COLUMN_CATEGORY, &category,
	                    TA_COLUMN_SUMMARY, &value, -1);

    if (tsk_get_category_state(category, STATE_TASKS, appGUI) == FALSE) {
        result = FALSE;
    } else if (config.hide_completed && done == TRUE) {
        result = FALSE;
    } else if (appGUI->tsk->filter_index && (utl_gui_list_store_get_text_index(appGUI->opt->tasks_category_store, category) != appGUI->tsk->filter_index)) {
        result = FALSE;
    } else if (value == NULL) {
        result = FALSE;
    } else {
        const gchar *text = gtk_entry_get_text(GTK_ENTRY(appGUI->tsk->tasks_find_entry));

        if (text == NULL) {
            result = TRUE;
        } else if (!g_utf8_strlen(text, -1)) {
            result = TRUE;
        } else {
            result = utl_text_strcasestr(value, text);
        }
    }
    

    g_free(category);
    g_free(value);
    return result;
}

/*------------------------------------------------------------------------------*/

void
category_filter_cb (GtkComboBox *widget, gpointer data)
{
	GUI *appGUI = (GUI *) data;

	appGUI->tsk->filter_index = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));

	if (appGUI->tsk->filter_index != -1)
	{
		gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (appGUI->tsk->tasks_filter));
	}
}

/*------------------------------------------------------------------------------*/
gint
tasks_column_sort_function (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer user_data)
{
    gboolean done_a, done_b;
    gchar *priority_a, *priority_b;
    guint32 due_date_a, due_date_b;
    gint due_time_a, due_time_b;
    gboolean repeat_a, repeat_b;
    gchar *summary_a, *summary_b;
    gchar *category_a, *category_b;
    gint diff;
    gint sort_column = GPOINTER_TO_INT(user_data);

    if (iter_a == NULL || iter_b == NULL) {
        return 0;
    }

    switch(sort_column) {
        case TA_COLUMN_DUE_DATE:
            gtk_tree_model_get (model, iter_a,
	                    TA_COLUMN_DUE_TIME, &due_time_a,
	                    TA_COLUMN_DUE_DATE_JULIAN, &due_date_a, -1);

            gtk_tree_model_get (model, iter_b,
	                    TA_COLUMN_DUE_TIME, &due_time_b,
	                    TA_COLUMN_DUE_DATE_JULIAN, &due_date_b, -1);
            if (!due_date_a)
		due_date_a = 1 << 31;

            if (!due_date_b)
		due_date_b = 1 << 31;
            diff = utl_date_time_compare_js(due_date_a, due_time_a, due_date_b, due_time_b);
            break;
        case TA_COLUMN_PRIORITY:
            gtk_tree_model_get (model, iter_a,
	                    TA_COLUMN_PRIORITY, &priority_a, -1);

            gtk_tree_model_get (model, iter_b,
	                    TA_COLUMN_PRIORITY, &priority_b, -1);
            diff = tsk_get_priority_index (priority_a) - tsk_get_priority_index (priority_b);
            g_free (priority_a);
            g_free (priority_b);
            break;
        case TA_COLUMN_DONE:
            gtk_tree_model_get (model, iter_a,
	                    TA_COLUMN_DONE, &done_a, -1);

            gtk_tree_model_get (model, iter_b,
	                    TA_COLUMN_DONE, &done_b, -1);
            diff = done_a - done_b;
            break;
        case TA_COLUMN_TYPE:
            gtk_tree_model_get (model, iter_a,
	                    TA_COLUMN_REPEAT, &repeat_a, -1);

            gtk_tree_model_get (model, iter_b,
	                    TA_COLUMN_REPEAT, &repeat_b, -1);
            diff = repeat_a - repeat_b;
            break;
        case TA_COLUMN_SUMMARY:
            gtk_tree_model_get (model, iter_a,
	                    TA_COLUMN_SUMMARY, &summary_a, -1);

            gtk_tree_model_get (model, iter_b,
	                    TA_COLUMN_SUMMARY, &summary_b, -1);
            diff = utl_text_strcmp(summary_a, summary_b);
            g_free (summary_a);
            g_free (summary_b);
            break;
        case TA_COLUMN_CATEGORY:
            gtk_tree_model_get (model, iter_a,
	                    TA_COLUMN_CATEGORY, &category_a, -1);

            gtk_tree_model_get (model, iter_b,
	                    TA_COLUMN_CATEGORY, &category_b, -1);
            diff = utl_text_strcmp(category_a, category_b);
            g_free (category_a);
            g_free (category_b);
            break;
        default:
            diff = 0;
    }
    return diff;
}

/*------------------------------------------------------------------------------*/

void tasks_sort_column_changed_cb (GtkTreeSortable *sortable, gpointer user_data)
{
    GtkSortType sort_order;

    gtk_tree_sortable_get_sort_column_id(sortable, &config.tasks_sorting_column, &sort_order);
    config.tasks_sorting_order = sort_order;
}

/*------------------------------------------------------------------------------*/

void
tasks_select_first_position_in_list (GUI *appGUI)
{
	GtkTreeIter iter;
	GtkTreePath *path;

	/* set cursor at first position */
	if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (appGUI->tsk->tasks_list_store), &iter) == TRUE)
	{
		path = gtk_tree_model_get_path (GTK_TREE_MODEL (appGUI->tsk->tasks_list_store), &iter);
		if (path != NULL)
		{
			gtk_tree_view_set_cursor (GTK_TREE_VIEW (appGUI->tsk->tasks_list), path, NULL, TRUE);
			gtk_tree_path_free (path);
		}
	}
}

/*------------------------------------------------------------------------------*/

gboolean
category_combo_box_focus_cb (GtkWidget *widget, GtkDirectionType *arg1, gpointer user_data)
{
	return TRUE;
}

/*------------------------------------------------------------------------------*/

void
tasks_selection_activate (gboolean active, GUI *appGUI)
{
	if (active == TRUE)
		g_signal_connect (G_OBJECT (appGUI->tsk->tasks_list_selection), "changed", G_CALLBACK (tasks_item_selected), appGUI);
	else
		g_signal_handlers_disconnect_by_func (G_OBJECT (appGUI->tsk->tasks_list_selection), G_CALLBACK (tasks_item_selected), appGUI);
}

/*------------------------------------------------------------------------------*/

void
store_task_columns_info (GUI *appGUI)
{
	gint n;

	config.tasks_column_idx_0 = utl_gui_get_column_position (appGUI->tsk->tasks_columns[TA_COLUMN_DONE],
	                                                         GTK_TREE_VIEW (appGUI->tsk->tasks_list), MAX_VISIBLE_TASK_COLUMNS, appGUI);
	config.tasks_column_idx_1 = utl_gui_get_column_position (appGUI->tsk->tasks_columns[TA_COLUMN_TYPE],
	                                                         GTK_TREE_VIEW (appGUI->tsk->tasks_list), MAX_VISIBLE_TASK_COLUMNS, appGUI);
	config.tasks_column_idx_2 = utl_gui_get_column_position (appGUI->tsk->tasks_columns[TA_COLUMN_DUE_DATE],
	                                                         GTK_TREE_VIEW (appGUI->tsk->tasks_list), MAX_VISIBLE_TASK_COLUMNS, appGUI);
	config.tasks_column_idx_3 = utl_gui_get_column_position (appGUI->tsk->tasks_columns[TA_COLUMN_PRIORITY],
	                                                         GTK_TREE_VIEW (appGUI->tsk->tasks_list), MAX_VISIBLE_TASK_COLUMNS, appGUI);
	config.tasks_column_idx_4 = utl_gui_get_column_position (appGUI->tsk->tasks_columns[TA_COLUMN_CATEGORY],
	                                                         GTK_TREE_VIEW (appGUI->tsk->tasks_list), MAX_VISIBLE_TASK_COLUMNS, appGUI);
	config.tasks_column_idx_5 = utl_gui_get_column_position (appGUI->tsk->tasks_columns[TA_COLUMN_SUMMARY],
	                                                         GTK_TREE_VIEW (appGUI->tsk->tasks_list), MAX_VISIBLE_TASK_COLUMNS, appGUI);

	n = gtk_tree_view_column_get_width (gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 0));
	if (n > 1)
		config.tasks_column_idx_0_width = n;

	n = gtk_tree_view_column_get_width (gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 1));
	if (n > 1)
		config.tasks_column_idx_1_width = n;

	n = gtk_tree_view_column_get_width (gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 2));
	if (n > 1)
		config.tasks_column_idx_2_width = n;

	n = gtk_tree_view_column_get_width (gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 3));
	if (n > 1)
		config.tasks_column_idx_3_width = n;

	n = gtk_tree_view_column_get_width (gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 4));
	if (n > 1)
		config.tasks_column_idx_4_width = n;

	n = gtk_tree_view_column_get_width (gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 5));
	if (n > 1)
		config.tasks_column_idx_5_width = n;
}

/*------------------------------------------------------------------------------*/

void
set_tasks_columns_width (GUI *appGUI)
{
	GtkTreeViewColumn *col;
	gint w;

	w = 2 * utl_gui_get_sw_vscrollbar_width (appGUI->tsk->scrolled_win);

	col = gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 0);
	if (gtk_tree_view_column_get_visible (col) == TRUE && config.tasks_column_idx_0_width > 0)
		gtk_tree_view_column_set_fixed_width (col, config.tasks_column_idx_0_width);

	col = gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 1);
	if (gtk_tree_view_column_get_visible (col) == TRUE && config.tasks_column_idx_1_width > 0)
		gtk_tree_view_column_set_fixed_width (col, config.tasks_column_idx_1_width);

	col = gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 2);
	if (gtk_tree_view_column_get_visible (col) == TRUE && config.tasks_column_idx_2_width > 0)
		gtk_tree_view_column_set_fixed_width (col, config.tasks_column_idx_2_width);

	col = gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 3);
	if (gtk_tree_view_column_get_visible (col) == TRUE && config.tasks_column_idx_3_width > 0)
		gtk_tree_view_column_set_fixed_width (col, config.tasks_column_idx_3_width);

	col = gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 4);
	if (gtk_tree_view_column_get_visible (col) == TRUE && config.tasks_column_idx_4_width > 0)
		gtk_tree_view_column_set_fixed_width (col, config.tasks_column_idx_4_width);

	col = gtk_tree_view_get_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), 5);
	if (gtk_tree_view_column_get_visible (col) == TRUE && config.tasks_column_idx_5_width > w)
		gtk_tree_view_column_set_fixed_width (col, config.tasks_column_idx_5_width - w);
}

/*------------------------------------------------------------------------------*/

gboolean
tasks_search_entry_changed_cb (GtkEditable *editable, gpointer user_data)
{
	GtkTreePath *path;
	GtkTreeIter iter;

	GUI *appGUI = (GUI *) user_data;

	gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (appGUI->tsk->tasks_filter));

	if (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (appGUI->tsk->tasks_find_entry)), -1))
	{
		gboolean has_next = gtk_tree_model_get_iter_first(GTK_TREE_MODEL (appGUI->tsk->tasks_filter), &iter);
		if (has_next)
		{
			path = gtk_tree_path_new_first ();
			if (path != NULL)
			{
				gtk_tree_view_set_cursor (GTK_TREE_VIEW (appGUI->tsk->tasks_list), path, NULL, FALSE);
				gtk_tree_path_free (path);
			}
		}
	}

	return FALSE;
}

/*------------------------------------------------------------------------------*/

void
gui_clear_find_cb (GtkWidget *widget, gpointer user_data)
{
	GUI *appGUI = (GUI *) user_data;

	if (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (appGUI->tsk->tasks_find_entry)), -1))
	{
		gtk_entry_set_text (GTK_ENTRY (appGUI->tsk->tasks_find_entry), "");
		refresh_tasks (appGUI);
	}

	gtk_widget_grab_focus (appGUI->tsk->tasks_find_entry);
}

/*------------------------------------------------------------------------------*/

#if defined(BACKUP_SUPPORT) && defined(HAVE_LIBGRINGOTTS)

static void
button_create_backup_cb(GtkToolButton *toolbutton, gpointer data) {
    GUI *appGUI = (GUI *) data;
    backup_create(appGUI);
}

static void
button_restore_backup_cb(GtkToolButton *toolbutton, gpointer data) {
    GUI *appGUI = (GUI *) data;
    backup_restore(appGUI);
}

#endif  /* BACKUP_SUPPORT && HAVE_LIBGRINGOTTS */

/*------------------------------------------------------------------------------*/

void
tasks_paned_position_change_cb (GObject *gobject, GParamSpec *pspec, GUI *appGUI)
{
    config.tasks_pane_pos = gtk_paned_get_position (GTK_PANED (appGUI->tsk->tasks_paned));
}


void
gui_create_tasks (GUI *appGUI)
{
	GtkWidget           *vbox1;
	GtkWidget           *vbox2;
	GtkWidget           *vbox3;
	GtkWidget           *grid;
	GtkWidget           *label;
	GtkWidget           *frame;
	GtkWidget           *hseparator;
	GtkWidget           *close_button;
	GtkCellRenderer     *renderer;
	GtkWidget           *top_viewport;
	GtkWidget           *bottom_viewport;
	GtkToolbar          *tasks_toolbar;
	gchar tmpbuf[BUFFER_SIZE];
	gint i, n;
#ifndef HAVE_LIBWEBKIT
	GtkTextBuffer       *text_buffer;
#endif  /* HAVE_LIBWEBKIT */

	gint columns_order[MAX_VISIBLE_TASK_COLUMNS];

	gint ta_columns[MAX_VISIBLE_TASK_COLUMNS] =
	{
		TA_COLUMN_DONE,
		TA_COLUMN_TYPE,
		TA_COLUMN_DUE_DATE,
		TA_COLUMN_PRIORITY,
		TA_COLUMN_CATEGORY,
		TA_COLUMN_SUMMARY
	};


	appGUI->tsk->filter_index = 0;

	vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
	gtk_widget_show (vbox1);
	gtk_container_set_border_width (GTK_CONTAINER (vbox1), 0);
	g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s</b>", _("Tasks"));
	gui_add_to_notebook (vbox1, tmpbuf, appGUI);

	appGUI->tsk->vbox = GTK_BOX (vbox1);

	if (config.hide_tasks == TRUE)
		gtk_widget_hide (GTK_WIDGET (appGUI->tsk->vbox));

	/*-------------------------------------------------------------------------------------*/
    tasks_toolbar = GTK_TOOLBAR(gtk_toolbar_new());
    gtk_box_pack_start(GTK_BOX(vbox1), GTK_WIDGET(tasks_toolbar), FALSE, FALSE, 0);
    gtk_toolbar_insert(tasks_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_TASKS_ADD, _("New task"), tasks_add_item_cb), -1);
    appGUI->tsk->edit_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_TASKS_EDIT, _("Edit task"), tasks_edit_item_cb);
    gtk_toolbar_insert(tasks_toolbar, appGUI->tsk->edit_button, -1);
    gtk_toolbar_insert(tasks_toolbar, gtk_separator_tool_item_new(), -1);
    appGUI->tsk->delete_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_TASKS_REMOVE, _("Remove task"), tasks_remove_item_cb);
    gtk_toolbar_insert(tasks_toolbar, appGUI->tsk->delete_button, -1);
    gtk_toolbar_insert(tasks_toolbar, gtk_separator_tool_item_new(), -1);
    appGUI->tsk->prev_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_TASKS_PREV_DATE, _("Change due date to previous date"), tasks_change_due_date_to_prev_date_cb);
    gtk_toolbar_insert(tasks_toolbar, appGUI->tsk->prev_button, -1);
    appGUI->tsk->next_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_TASKS_NEXT_DATE, _("Change due date to next date"), tasks_change_due_date_to_next_date_cb);
    gtk_toolbar_insert(tasks_toolbar, appGUI->tsk->next_button, -1);
#ifdef HAVE_LIBICAL
    gtk_toolbar_insert(tasks_toolbar, gtk_separator_tool_item_new(), -1);
    appGUI->tsk->export_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_TASKS_EXPORT, _("Export tasks"), tasks_export_visible_items_cb);
    gtk_toolbar_insert(tasks_toolbar, appGUI->tsk->export_button, -1);
#endif
#ifdef PRINTING_SUPPORT
    gtk_toolbar_insert(tasks_toolbar, gtk_separator_tool_item_new(), -1);
    appGUI->tsk->print_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_PRINT, _("Print visible tasks list"), tasks_print_visible_items_cb);
    gtk_toolbar_insert(tasks_toolbar, appGUI->tsk->print_button, -1);
#endif
    gui_append_toolbar_spring(tasks_toolbar);
#if defined(BACKUP_SUPPORT) && defined(HAVE_LIBGRINGOTTS)
    gtk_toolbar_insert(tasks_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_BACKUP, _("Backup data"), button_create_backup_cb), -1);
    gtk_toolbar_insert(tasks_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_RESTORE, _("Restore data"), button_restore_backup_cb), -1);
    gtk_toolbar_insert(tasks_toolbar, gtk_separator_tool_item_new(), -1);
#endif
    gtk_toolbar_insert(tasks_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_PREFERENCES, _("Preferences"), show_preferences_window_cb), -1);
    gtk_toolbar_insert(tasks_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_ABOUT, _("About"), gui_show_about_window_cb), -1);
    appGUI->tsk->quit_button = gui_create_toolbar_button(appGUI, "application-exit", _("Quit"), gui_quit_osmo_cb);
    gtk_toolbar_insert(tasks_toolbar, appGUI->tsk->quit_button, -1);

    gtk_toolbar_set_style(tasks_toolbar, GTK_TOOLBAR_ICONS);
    gtk_toolbar_set_icon_size(tasks_toolbar, GTK_ICON_SIZE_LARGE_TOOLBAR);
    gtk_widget_show_all(GTK_WIDGET(tasks_toolbar));

    /*-------------------------------------------------------------------------------------*/

    gtk_widget_set_sensitive(GTK_WIDGET(appGUI->tsk->edit_button), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(appGUI->tsk->delete_button), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(appGUI->tsk->prev_button), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(appGUI->tsk->next_button), FALSE);
#ifdef PRINTING_SUPPORT
    gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->print_button), FALSE);
#endif /* PRINTING_SUPPORT */

	/*-------------------------------------------------------------------------------------*/

	if (!config.gui_layout) {
	    appGUI->tsk->tasks_paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL );
	} else {
	    appGUI->tsk->tasks_paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
    }

	gtk_widget_show (appGUI->tsk->tasks_paned);
	gtk_box_pack_start (GTK_BOX (vbox1), appGUI->tsk->tasks_paned, TRUE, TRUE, 0);

	top_viewport = gtk_viewport_new (NULL, NULL);
	gtk_widget_show (top_viewport);
	gtk_viewport_set_shadow_type (GTK_VIEWPORT (top_viewport), GTK_SHADOW_NONE);
	gtk_paned_pack1 (GTK_PANED (appGUI->tsk->tasks_paned), top_viewport, FALSE, TRUE);

	vbox3 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
	gtk_widget_show (vbox3);
	gtk_container_add (GTK_CONTAINER (top_viewport), vbox3);
	gtk_widget_set_margin_left (vbox3, 8);
	gtk_widget_set_margin_right (vbox3, 8);
	gtk_widget_set_margin_bottom (vbox3, 8);

	hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
	gtk_widget_show (hseparator);
	gtk_box_pack_start (GTK_BOX (vbox3), hseparator, FALSE, TRUE, 6);

	grid = gtk_grid_new ();
	gtk_widget_show (grid);
	gtk_box_pack_start (GTK_BOX (vbox3), grid, FALSE, TRUE, 0);
	gtk_grid_set_column_spacing (GTK_GRID (grid), 4);
	gtk_grid_set_row_spacing (GTK_GRID (grid), 4);

	g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Category"));
	label = gtk_label_new (tmpbuf);
	gtk_widget_show (label);
	gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);

	appGUI->tsk->cf_combobox = gtk_combo_box_text_new ();
	gtk_widget_show (appGUI->tsk->cf_combobox);
	gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (appGUI->tsk->cf_combobox), FALSE);
	gtk_widget_set_can_focus (appGUI->tsk->cf_combobox, FALSE);

	gtk_grid_attach (GTK_GRID (grid), appGUI->tsk->cf_combobox, 1, 0, 1, 1);
    gtk_widget_set_hexpand(appGUI->tsk->cf_combobox, TRUE);

	g_signal_connect (G_OBJECT (appGUI->tsk->cf_combobox), "changed", G_CALLBACK (category_filter_cb), appGUI);
	g_signal_connect (G_OBJECT (appGUI->tsk->cf_combobox), "focus", G_CALLBACK (category_combo_box_focus_cb), NULL);

	appGUI->tsk->n_items_label = gtk_label_new ("");
	gtk_widget_show (appGUI->tsk->n_items_label);

	gtk_grid_attach (GTK_GRID (grid), appGUI->tsk->n_items_label, 4, 0, 2, 1);
	gtk_label_set_use_markup (GTK_LABEL (appGUI->tsk->n_items_label), TRUE);

	g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Search"));
	label = gtk_label_new (tmpbuf);
	gtk_widget_show (label);
	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
    gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
    gtk_widget_set_halign(label, GTK_ALIGN_START);
	gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);

	appGUI->tsk->tasks_find_entry = gtk_entry_new ();
	gtk_entry_set_max_length (GTK_ENTRY (appGUI->tsk->tasks_find_entry), 128);
	gtk_widget_show (appGUI->tsk->tasks_find_entry);
	g_signal_connect (G_OBJECT (appGUI->tsk->tasks_find_entry), "changed",
	                  G_CALLBACK (tasks_search_entry_changed_cb), appGUI);
    gtk_widget_set_hexpand(appGUI->tsk->tasks_find_entry, TRUE);
	gtk_grid_attach (GTK_GRID (grid), appGUI->tsk->tasks_find_entry, 1, 1, 4, 1);

	appGUI->tsk->tasks_find_clear_button = gtk_button_new_from_icon_name ("edit-clear", GTK_ICON_SIZE_BUTTON);
	gtk_widget_show (appGUI->tsk->tasks_find_clear_button);
	gtk_widget_set_can_focus (appGUI->tsk->tasks_find_clear_button, FALSE);
	gtk_button_set_relief (GTK_BUTTON(appGUI->tsk->tasks_find_clear_button), GTK_RELIEF_NONE);

	if (config.enable_tooltips)
		gtk_widget_set_tooltip_text (appGUI->tsk->tasks_find_clear_button, _("Clear"));

	g_signal_connect (G_OBJECT (appGUI->tsk->tasks_find_clear_button), "clicked",
	                  G_CALLBACK (gui_clear_find_cb), appGUI);
	gtk_grid_attach (GTK_GRID (grid), appGUI->tsk->tasks_find_clear_button, 5, 1, 1, 1);

	hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
	gtk_widget_show (hseparator);
	gtk_box_pack_start (GTK_BOX (vbox3), hseparator, FALSE, TRUE, 6);

	appGUI->tsk->scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_widget_show (appGUI->tsk->scrolled_win);
	gtk_box_pack_start (GTK_BOX (vbox3), appGUI->tsk->scrolled_win, TRUE, TRUE, 0);

	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (appGUI->tsk->scrolled_win), GTK_SHADOW_IN);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (appGUI->tsk->scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

	appGUI->tsk->tasks_list_store = gtk_list_store_new (TASKS_NUM_COLUMNS,          /* columns are defined in gui.h */
	                                    G_TYPE_BOOLEAN,     /* TA_COLUMN_DONE */
										GDK_TYPE_PIXBUF,    /* TA_COLUMN_TYPE */
										G_TYPE_STRING,      /* TA_COLUMN_DUE_DATE */
										G_TYPE_UINT,        /* TA_COLUMN_DUE_DATE_JULIAN */
										G_TYPE_INT,         /* TA_COLUMN_DUE_TIME */
	                                    G_TYPE_UINT,        /* TA_COLUMN_START_DATE_JULIAN */
										G_TYPE_UINT,        /* TA_COLUMN_DONE_DATE_JULIAN */
										G_TYPE_STRING,      /* TA_COLUMN_PRIORITY */
										G_TYPE_STRING,      /* TA_COLUMN_CATEGORY */
										G_TYPE_STRING,      /* TA_COLUMN_SUMMARY */
	                                    G_TYPE_STRING,      /* TA_COLUMN_DESCRIPTION */
										G_TYPE_STRING,      /* TA_COLUMN_COLOR */
										G_TYPE_UINT,        /* TA_COLUMN_BOLD */
										G_TYPE_BOOLEAN,     /* TA_COLUMN_ACTIVE */
	                                    G_TYPE_BOOLEAN,     /* TA_COLUMN_OFFLINE_IGNORE */
	                                    G_TYPE_BOOLEAN,     /* TA_COLUMN_SOUND_ENABLE */
										G_TYPE_BOOLEAN,     /* TA_COLUMN_NDIALOG_ENABLE */
										G_TYPE_BOOLEAN,     /* TA_COLUMN_REPEAT */
										G_TYPE_INT,         /* TA_COLUMN_REPEAT_DAY */
	                                    G_TYPE_INT,         /* TA_COLUMN_REPEAT_MONTH_INTERVAL */
										G_TYPE_INT,         /* TA_COLUMN_REPEAT_DAY_INTERVAL */
										G_TYPE_INT,         /* TA_COLUMN_REPEAT_START_DAY */
										G_TYPE_INT,         /* TA_COLUMN_REPEAT_TIME_START */
										G_TYPE_INT,         /* TA_COLUMN_REPEAT_TIME_END */
										G_TYPE_INT,         /* TA_COLUMN_REPEAT_TIME_INTERVAL */
	                                    G_TYPE_INT,         /* TA_COLUMN_REPEAT_COUNTER */
										G_TYPE_STRING,      /* TA_COLUMN_ALARM_COMMAND */
										G_TYPE_INT,         /* TA_COLUMN_WARNING_DAYS */
										G_TYPE_INT,         /* TA_COLUMN_WARNING_TIME */
										G_TYPE_INT,         /* TA_COLUMN_POSTPONE_TIME */
										G_TYPE_INT          /* TA_COLUMN_ID */
									);

	g_signal_connect (G_OBJECT (appGUI->tsk->tasks_list_store), "row-changed",
	                  G_CALLBACK (task_list_row_changed_cb), appGUI);

	appGUI->tsk->tasks_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (appGUI->tsk->tasks_list_store), NULL);
	gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (appGUI->tsk->tasks_filter),
	                                        (GtkTreeModelFilterVisibleFunc) tasks_list_filter_cb,
	                                        appGUI, NULL);
	g_signal_connect (G_OBJECT (appGUI->tsk->tasks_filter), "row-inserted",
	                  G_CALLBACK (task_filter_row_inserted_cb), appGUI);
	g_signal_connect (G_OBJECT (appGUI->tsk->tasks_filter), "row-deleted",
	                  G_CALLBACK (task_filter_row_deleted_cb), appGUI);

	appGUI->tsk->tasks_sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (appGUI->tsk->tasks_filter));

	appGUI->tsk->tasks_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (appGUI->tsk->tasks_sort));
	gtk_tree_view_set_enable_search (GTK_TREE_VIEW (appGUI->tsk->tasks_list), FALSE);
	gtk_widget_show (appGUI->tsk->tasks_list);

	g_signal_connect (G_OBJECT (appGUI->tsk->tasks_list), "button_press_event",
	                  G_CALLBACK (list_dbclick_cb), appGUI);

	appGUI->tsk->tasks_list_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (appGUI->tsk->tasks_list));
	gtk_tree_selection_set_mode (appGUI->tsk->tasks_list_selection, GTK_SELECTION_MULTIPLE);
	tasks_selection_activate (TRUE, appGUI);

	/* create columns */
	renderer = gtk_cell_renderer_toggle_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_DONE] = gtk_tree_view_column_new_with_attributes (_("Done"),
	                         renderer,
	                         "active", TA_COLUMN_DONE,
	                         NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_DONE]);
	gtk_tree_view_column_set_reorderable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_DONE]), TRUE);
	gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_DONE]), TRUE);
	gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_DONE]), GTK_TREE_VIEW_COLUMN_FIXED);

	g_signal_connect (renderer, "toggled", G_CALLBACK (done_toggled), appGUI);

	renderer = gtk_cell_renderer_pixbuf_new ();  /* icon */
	appGUI->tsk->tasks_columns[TA_COLUMN_TYPE]  = gtk_tree_view_column_new_with_attributes (_("Type"),
	                         renderer,
	                         "pixbuf", TA_COLUMN_TYPE,
	                         NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_TYPE], config.tsk_visible_type_column);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_TYPE]);
	gtk_tree_view_column_set_reorderable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_TYPE]), TRUE);
	gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_TYPE]), TRUE);
	gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_TYPE]), GTK_TREE_VIEW_COLUMN_FIXED);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_DUE_DATE] = gtk_tree_view_column_new_with_attributes(_("Due date"),
	                          renderer,
	                          "text", TA_COLUMN_DUE_DATE,
	                          "strikethrough", TA_COLUMN_DONE,
	                          "foreground", TA_COLUMN_COLOR,
	                          "weight", TA_COLUMN_BOLD,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_DUE_DATE], config.tsk_visible_due_date_column);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_DUE_DATE]);
	gtk_tree_view_column_set_reorderable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_DUE_DATE]), TRUE);
	gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_DUE_DATE]), TRUE);
	gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_DUE_DATE]), GTK_TREE_VIEW_COLUMN_FIXED);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_PRIORITY] = gtk_tree_view_column_new_with_attributes (_("Priority"),
	                          renderer,
	                          "text", TA_COLUMN_PRIORITY,
	                          "strikethrough", TA_COLUMN_DONE,
	                          "foreground", TA_COLUMN_COLOR,
	                          "weight", TA_COLUMN_BOLD,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_PRIORITY], config.tsk_visible_priority_column);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_PRIORITY]);
	gtk_tree_view_column_set_reorderable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_PRIORITY]), TRUE);
	gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_PRIORITY]), TRUE);
	gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_PRIORITY]), GTK_TREE_VIEW_COLUMN_FIXED);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_CATEGORY] = gtk_tree_view_column_new_with_attributes (_("Category"),
	                          renderer,
	                          "text", TA_COLUMN_CATEGORY,
	                          "strikethrough", TA_COLUMN_DONE,
	                          "foreground", TA_COLUMN_COLOR,
	                          "weight", TA_COLUMN_BOLD,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_CATEGORY], config.tsk_visible_category_column);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_CATEGORY]);
	gtk_tree_view_column_set_reorderable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_CATEGORY]), TRUE);
	gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_CATEGORY]), TRUE);
	gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_CATEGORY]), GTK_TREE_VIEW_COLUMN_FIXED);

	renderer = gtk_cell_renderer_text_new ();
	g_object_set (G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
	gtk_cell_renderer_set_fixed_size (renderer, 0, -1);
	appGUI->tsk->tasks_columns[TA_COLUMN_SUMMARY] = gtk_tree_view_column_new_with_attributes (_("Summary"),
	                          renderer,
	                          "text", TA_COLUMN_SUMMARY,
	                          "strikethrough", TA_COLUMN_DONE,
	                          "foreground", TA_COLUMN_COLOR,
	                          "weight", TA_COLUMN_BOLD,
	                          NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW(appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_SUMMARY]);
	gtk_tree_view_column_set_reorderable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_SUMMARY]), TRUE);
	gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_SUMMARY]), TRUE);
	gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (appGUI->tsk->tasks_columns[TA_COLUMN_SUMMARY]), GTK_TREE_VIEW_COLUMN_FIXED);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_DUE_DATE_JULIAN] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_DUE_DATE_JULIAN,
	                          "strikethrough", TA_COLUMN_DONE,
	                          "foreground", TA_COLUMN_COLOR,
	                          "weight", TA_COLUMN_BOLD,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_DUE_DATE_JULIAN], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_DUE_DATE_JULIAN]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_DUE_TIME] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_DUE_TIME,
	                          "strikethrough", TA_COLUMN_DONE,
	                          "foreground", TA_COLUMN_COLOR,
	                          "weight", TA_COLUMN_BOLD,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_DUE_TIME], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_DUE_TIME]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_START_DATE_JULIAN] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_START_DATE_JULIAN,
	                          "strikethrough", TA_COLUMN_DONE,
	                          "foreground", TA_COLUMN_COLOR,
	                          "weight", TA_COLUMN_BOLD,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_START_DATE_JULIAN], FALSE);
	gtk_tree_view_append_column(GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_START_DATE_JULIAN]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_DONE_DATE_JULIAN] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_DONE_DATE_JULIAN,
	                          "strikethrough", TA_COLUMN_DONE,
	                          "foreground", TA_COLUMN_COLOR,
	                          "weight", TA_COLUMN_BOLD,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_DONE_DATE_JULIAN], FALSE);
	gtk_tree_view_append_column(GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_DONE_DATE_JULIAN]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_DESCRIPTION] = gtk_tree_view_column_new_with_attributes (_("Description"),
	                          renderer,
	                          "text", TA_COLUMN_DESCRIPTION,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_DESCRIPTION], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_DESCRIPTION]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_COLOR] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_COLOR,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_COLOR], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_COLOR]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_BOLD] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_BOLD,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_BOLD], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_BOLD]);

	renderer = gtk_cell_renderer_toggle_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_ACTIVE] = gtk_tree_view_column_new_with_attributes (NULL,
	                         renderer,
	                         "active", TA_COLUMN_ACTIVE,
	                         NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_ACTIVE], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_ACTIVE]);

	renderer = gtk_cell_renderer_toggle_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_OFFLINE_IGNORE] = gtk_tree_view_column_new_with_attributes (NULL,
	                         renderer,
	                         "active", TA_COLUMN_OFFLINE_IGNORE,
	                         NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_OFFLINE_IGNORE], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_OFFLINE_IGNORE]);

	renderer = gtk_cell_renderer_toggle_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_SOUND_ENABLE] = gtk_tree_view_column_new_with_attributes (NULL,
	                         renderer,
	                         "active", TA_COLUMN_SOUND_ENABLE,
	                         NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_SOUND_ENABLE], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_SOUND_ENABLE]);

	renderer = gtk_cell_renderer_toggle_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_NDIALOG_ENABLE] = gtk_tree_view_column_new_with_attributes (NULL,
	                         renderer,
	                         "active", TA_COLUMN_NDIALOG_ENABLE,
	                         NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_NDIALOG_ENABLE], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_NDIALOG_ENABLE]);

	renderer = gtk_cell_renderer_toggle_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT] = gtk_tree_view_column_new_with_attributes (NULL,
	                         renderer,
	                         "active", TA_COLUMN_REPEAT,
	                         NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_DAY] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_REPEAT_DAY,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_DAY], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_DAY]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_MONTH_INTERVAL] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_REPEAT_MONTH_INTERVAL,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_MONTH_INTERVAL], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_MONTH_INTERVAL]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_DAY_INTERVAL] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_REPEAT_DAY_INTERVAL,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_DAY_INTERVAL], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_DAY_INTERVAL]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_START_DAY] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_REPEAT_START_DAY,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_START_DAY], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_START_DAY]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_TIME_START] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_REPEAT_TIME_START,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_TIME_START], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_TIME_START]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_TIME_END] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_REPEAT_TIME_END,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_TIME_END], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_TIME_END]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_TIME_INTERVAL] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_REPEAT_TIME_INTERVAL,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_TIME_INTERVAL], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_TIME_INTERVAL]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_COUNTER] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_REPEAT_COUNTER,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_COUNTER], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_REPEAT_COUNTER]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_ALARM_COMMAND] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_ALARM_COMMAND,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_ALARM_COMMAND], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_ALARM_COMMAND]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_WARNING_DAYS] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_WARNING_DAYS,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_WARNING_DAYS], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_WARNING_DAYS]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_WARNING_TIME] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_WARNING_TIME,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_WARNING_TIME], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_WARNING_TIME]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_POSTPONE_TIME] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_POSTPONE_TIME,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_POSTPONE_TIME], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_POSTPONE_TIME]);

	renderer = gtk_cell_renderer_text_new ();
	appGUI->tsk->tasks_columns[TA_COLUMN_ID] = gtk_tree_view_column_new_with_attributes (NULL,
	                          renderer,
	                          "text", TA_COLUMN_ID,
	                          NULL);
	gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[TA_COLUMN_ID], FALSE);
	gtk_tree_view_append_column (GTK_TREE_VIEW (appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[TA_COLUMN_ID]);

	/* restore columns order */
	columns_order[0] = config.tasks_column_idx_0;
	columns_order[1] = config.tasks_column_idx_1;
	columns_order[2] = config.tasks_column_idx_2;
	columns_order[3] = config.tasks_column_idx_3;
	columns_order[4] = config.tasks_column_idx_4;
	columns_order[5] = config.tasks_column_idx_5;

	n = MAX_VISIBLE_TASK_COLUMNS-1;

	while (n >= 0)
	{
		for (i = 0; i < MAX_VISIBLE_TASK_COLUMNS; i++)
		{
			if (n == columns_order[i])
			{
				gtk_tree_view_move_column_after (GTK_TREE_VIEW (appGUI->tsk->tasks_list),
				                                 appGUI->tsk->tasks_columns[ta_columns[i]], NULL);
				n--;
			}
		}
	}

	set_tasks_columns_width (appGUI);

	gtk_container_add (GTK_CONTAINER (appGUI->tsk->scrolled_win), appGUI->tsk->tasks_list);

	/* configure sorting */
	for (i = 0; i < MAX_VISIBLE_TASK_COLUMNS; i++) {
		gtk_tree_view_column_set_sort_column_id (appGUI->tsk->tasks_columns[ta_columns[i]], ta_columns[i]);
		gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (appGUI->tsk->tasks_sort), ta_columns[i],
				tasks_column_sort_function, GINT_TO_POINTER(ta_columns[i]), NULL);
	}

	/* restore sorting */
	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (appGUI->tsk->tasks_sort),
			config.tasks_sorting_column, config.tasks_sorting_order);

	g_signal_connect (appGUI->tsk->tasks_sort, "sort-column-changed", G_CALLBACK (tasks_sort_column_changed_cb), appGUI);

	/*----------------------------------------------------------------------------*/

	bottom_viewport = gtk_viewport_new (NULL, NULL);
	gtk_widget_show (bottom_viewport);
	gtk_viewport_set_shadow_type (GTK_VIEWPORT (bottom_viewport), GTK_SHADOW_NONE);
	gtk_paned_pack2 (GTK_PANED (appGUI->tsk->tasks_paned), bottom_viewport, TRUE, TRUE);

	vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	gtk_widget_show (vbox2);
	gtk_container_set_border_width (GTK_CONTAINER (vbox2), 0);
	gtk_container_add (GTK_CONTAINER (bottom_viewport), vbox2);

	appGUI->tsk->panel_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
	gtk_box_pack_start (GTK_BOX (vbox2), appGUI->tsk->panel_hbox, FALSE, FALSE, 0);
	gtk_widget_show (appGUI->tsk->panel_hbox);

	frame = gtk_frame_new (NULL);
	gtk_widget_show (frame);
	gtk_box_pack_start (GTK_BOX (vbox2), frame, TRUE, TRUE, 0);
	gtk_widget_set_margin_left(GTK_WIDGET(frame), 8);
	gtk_widget_set_margin_right(GTK_WIDGET(frame), 8);
	gtk_widget_set_margin_bottom(GTK_WIDGET(frame), 8);
	gtk_frame_set_label_align (GTK_FRAME (frame), 0.98, 0.5);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);

	g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s</b>", _("Task details"));
	label = gtk_label_new (tmpbuf);
	gtk_widget_show (label);
    gtk_frame_set_label_widget (GTK_FRAME (frame), label);
    gtk_label_set_use_markup (GTK_LABEL (label), TRUE);

	if (!config.gui_layout) {
		close_button = gtk_button_new_from_icon_name("window-close", GTK_ICON_SIZE_BUTTON);
		gtk_widget_set_can_focus(close_button, FALSE);
		gtk_button_set_relief (GTK_BUTTON(close_button), GTK_RELIEF_NONE);
		if (config.enable_tooltips) {
			gtk_widget_set_tooltip_text (close_button, _("Close description panel"));
		}
		gtk_widget_show (close_button);
		gtk_box_pack_end (GTK_BOX (appGUI->tsk->panel_hbox), close_button, FALSE, FALSE, 0);
		g_signal_connect (G_OBJECT (close_button), "clicked", G_CALLBACK (panel_close_desc_cb), appGUI);
	}

	appGUI->tsk->panel_scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
	gtk_widget_show (appGUI->tsk->panel_scrolledwindow);
    gtk_container_add (GTK_CONTAINER (frame), appGUI->tsk->panel_scrolledwindow);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (appGUI->tsk->panel_scrolledwindow), GTK_SHADOW_NONE);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (appGUI->tsk->panel_scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

#ifdef HAVE_LIBWEBKIT
	appGUI->tsk->html_webkitview = utl_create_webkit_web_view(appGUI);

	g_signal_connect (appGUI->tsk->html_webkitview, "context-menu", G_CALLBACK (utl_webkit_on_menu), appGUI);
	g_signal_connect (appGUI->tsk->html_webkitview, "decide-policy", G_CALLBACK (utl_webkit_link_clicked), appGUI);

	gtk_widget_show (GTK_WIDGET (appGUI->tsk->html_webkitview));
	gtk_container_add (GTK_CONTAINER (appGUI->tsk->panel_scrolledwindow), GTK_WIDGET (appGUI->tsk->html_webkitview));
#else
	appGUI->tsk->tasks_desc_textview = gtk_text_view_new ();
	gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (appGUI->tsk->tasks_desc_textview), GTK_WRAP_WORD);
	gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (appGUI->tsk->tasks_desc_textview), 4);
	gtk_text_view_set_left_margin (GTK_TEXT_VIEW (appGUI->tsk->tasks_desc_textview), 4);
	gtk_text_view_set_right_margin (GTK_TEXT_VIEW (appGUI->tsk->tasks_desc_textview), 4);
	gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (appGUI->tsk->tasks_desc_textview), FALSE);
	gtk_text_view_set_editable (GTK_TEXT_VIEW (appGUI->tsk->tasks_desc_textview), FALSE);
	gtk_widget_show (appGUI->tsk->tasks_desc_textview);
	gtk_container_add (GTK_CONTAINER (appGUI->tsk->panel_scrolledwindow), appGUI->tsk->tasks_desc_textview);

	text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (appGUI->tsk->tasks_desc_textview));
	gtk_text_buffer_create_tag (text_buffer, "italic", "style", PANGO_STYLE_ITALIC, NULL);
	appGUI->tsk->font_tag_object = gtk_text_buffer_create_tag (text_buffer, "info_font", "font", (gchar *) config.task_info_font, NULL);
#endif  /* HAVE_LIBWEBKIT */

	g_signal_connect(G_OBJECT(appGUI->tsk->tasks_paned), "notify::position", G_CALLBACK(tasks_paned_position_change_cb), appGUI);
	gtk_paned_set_position (GTK_PANED (appGUI->tsk->tasks_paned), config.tasks_pane_pos);

	gtk_widget_grab_focus (appGUI->tsk->tasks_find_entry);
}

/*------------------------------------------------------------------------------*/
#endif  /* TASKS_ENABLED */
