SF.net SVN: geany-plugins:[1065] trunk/geany-plugins

eht16 at users.sourceforge.net eht16 at xxxxx
Sat Nov 28 16:54:23 UTC 2009


Revision: 1065
          http://geany-plugins.svn.sourceforge.net/geany-plugins/?rev=1065&view=rev
Author:   eht16
Date:     2009-11-28 16:54:23 +0000 (Sat, 28 Nov 2009)

Log Message:
-----------
Complete rewrite of the Tasks Addon. Changes:
   - Works on all open documents, not only on the current one
   - Rescan for tokens only on document open/save/close
   - Add keybinding to activate the Tasks tab

Modified Paths:
--------------
    trunk/geany-plugins/addons/ChangeLog
    trunk/geany-plugins/addons/src/Makefile.am
    trunk/geany-plugins/addons/src/addons.c
    trunk/geany-plugins/po/POTFILES.in

Added Paths:
-----------
    trunk/geany-plugins/addons/src/ao_tasks.c
    trunk/geany-plugins/addons/src/ao_tasks.h

Removed Paths:
-------------
    trunk/geany-plugins/addons/src/tasks.c
    trunk/geany-plugins/addons/src/tasks.h

Modified: trunk/geany-plugins/addons/ChangeLog
===================================================================
--- trunk/geany-plugins/addons/ChangeLog	2009-11-28 16:49:09 UTC (rev 1064)
+++ trunk/geany-plugins/addons/ChangeLog	2009-11-28 16:54:23 UTC (rev 1065)
@@ -1,3 +1,13 @@
+2009-11-28  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
+
+ * src/Makefile.am, src/tasks.c, src/tasks.h, src/ao_tasks.h,
+   src/ao_tasks.c, src/addons.c:
+   Complete rewrite of the Tasks Addon. Changes:
+   - Works on all open documents, not only on the current one
+   - Rescan for tokens only on document open/save/close
+   - Add keybinding to activate the Tasks tab
+
+
 2009-11-04  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
 
  * src/ao_bookmarklist.c:

Modified: trunk/geany-plugins/addons/src/Makefile.am
===================================================================
--- trunk/geany-plugins/addons/src/Makefile.am	2009-11-28 16:49:09 UTC (rev 1064)
+++ trunk/geany-plugins/addons/src/Makefile.am	2009-11-28 16:54:23 UTC (rev 1065)
@@ -10,13 +10,13 @@
 	ao_systray.h \
 	ao_bookmarklist.h \
 	ao_markword.h \
-	tasks.h \
+	ao_tasks.h \
 	addons.c \
 	ao_doclist.c \
 	ao_openuri.c \
 	ao_systray.c \
 	ao_bookmarklist.c \
 	ao_markword.c \
-	tasks.c
+	ao_tasks.c
 
 addons_la_LIBADD = $(COMMONLIBS)

Modified: trunk/geany-plugins/addons/src/addons.c
===================================================================
--- trunk/geany-plugins/addons/src/addons.c	2009-11-28 16:49:09 UTC (rev 1064)
+++ trunk/geany-plugins/addons/src/addons.c	2009-11-28 16:54:23 UTC (rev 1065)
@@ -29,7 +29,7 @@
 #include "ao_systray.h"
 #include "ao_bookmarklist.h"
 #include "ao_markword.h"
-#include "tasks.h"
+#include "ao_tasks.h"
 
 
 
@@ -47,6 +47,7 @@
 enum
 {
 	KB_FOCUS_BOOKMARK_LIST,
+	KB_FOCUS_TASKS,
 	KB_COUNT
 };
 
@@ -69,6 +70,7 @@
 	AoSystray *systray;
 	AoBookmarkList *bookmarklist;
 	AoMarkWord *markword;
+	AoTasks *tasks;
 } AddonsInfo;
 static AddonsInfo *ao_info = NULL;
 
@@ -77,6 +79,9 @@
 static void ao_update_editor_menu_cb(GObject *obj, const gchar *word, gint pos,
 									 GeanyDocument *doc, gpointer data);
 static void ao_document_activate_cb(GObject *obj, GeanyDocument *doc, gpointer data);
+static void ao_document_open_cb(GObject *obj, GeanyDocument *doc, gpointer data);
+static void ao_document_save_cb(GObject *obj, GeanyDocument *doc, gpointer data);
+static void ao_document_close_cb(GObject *obj, GeanyDocument *doc, gpointer data);
 gboolean ao_editor_notify_cb(GObject *object, GeanyEditor *editor,
 	SCNotification *nt, gpointer data);
 
@@ -86,8 +91,9 @@
     { "update-editor-menu", (GCallback) &ao_update_editor_menu_cb, FALSE, NULL },
 
 	{ "editor-notify", (GCallback) &ao_editor_notify_cb, TRUE, NULL },
-	{ "document-open", (GCallback) &tasks_on_document_open, TRUE, NULL },
-	{ "document-close", (GCallback) &tasks_on_document_close, TRUE, NULL },
+	{ "document-open", (GCallback) &ao_document_open_cb, TRUE, NULL },
+	{ "document-save", (GCallback) &ao_document_save_cb, TRUE, NULL },
+	{ "document-close", (GCallback) &ao_document_close_cb, TRUE, NULL },
 	{ "document-activate", (GCallback) &ao_document_activate_cb, TRUE, NULL },
 
 	{ NULL, NULL, FALSE, NULL }
@@ -100,17 +106,19 @@
 }
 
 
+static void kb_tasks_activate(guint key_id)
+{
+	ao_tasks_activate(ao_info->tasks);
+}
+
+
 gboolean ao_editor_notify_cb(GObject *object, GeanyEditor *editor,
 							 SCNotification *nt, gpointer data)
 {
-	gboolean ret = FALSE;
-
 	ao_bookmark_list_update_marker(ao_info->bookmarklist, editor, nt);
 	ao_mark_word_check(ao_info->markword, editor, nt);
 
-	ret = tasks_on_editor_notify(object, editor, nt, data);
-
-	return ret;
+	return FALSE;
 }
 
 
@@ -127,11 +135,34 @@
 {
 	g_return_if_fail(doc != NULL && doc->is_valid);
 
-	tasks_on_document_activate(obj, doc, data);
 	ao_bookmark_list_update(ao_info->bookmarklist, doc);
 }
 
 
+static void ao_document_open_cb(GObject *obj, GeanyDocument *doc, gpointer data)
+{
+	g_return_if_fail(doc != NULL && doc->is_valid);
+
+	ao_tasks_update(ao_info->tasks, doc);
+}
+
+
+static void ao_document_close_cb(GObject *obj, GeanyDocument *doc, gpointer data)
+{
+	g_return_if_fail(doc != NULL && doc->is_valid);
+
+	ao_tasks_update(ao_info->tasks, doc);
+}
+
+
+static void ao_document_save_cb(GObject *obj, GeanyDocument *doc, gpointer data)
+{
+	g_return_if_fail(doc != NULL && doc->is_valid);
+
+	ao_tasks_update(ao_info->tasks, doc);
+}
+
+
 GtkWidget *ao_image_menu_item_new(const gchar *stock_id, const gchar *label)
 {
 	GtkWidget *item = gtk_image_menu_item_new_with_label(label);
@@ -175,13 +206,14 @@
 	ao_info->systray = ao_systray_new(ao_info->enable_systray);
 	ao_info->bookmarklist = ao_bookmark_list_new(ao_info->enable_bookmarklist);
 	ao_info->markword = ao_mark_word_new(ao_info->enable_markword);
+	ao_info->tasks = ao_tasks_new(ao_info->enable_tasks);
 
-	tasks_set_enable(ao_info->enable_tasks);
-
 	/* setup keybindings */
 	key_group = plugin_set_key_group(geany_plugin, "addons", KB_COUNT, NULL);
 	keybindings_set_item(key_group, KB_FOCUS_BOOKMARK_LIST, kb_bmlist_activate,
 		0, 0, "focus_bookmark_list", _("Focus Bookmark List"), NULL);
+	keybindings_set_item(key_group, KB_FOCUS_TASKS, kb_tasks_activate,
+		0, 0, "focus_tasks", _("Focus Tasks List"), NULL);
 }
 
 
@@ -205,6 +237,8 @@
 			g_object_get_data(G_OBJECT(dialog), "check_bookmarklist"))));
 		ao_info->enable_markword = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
 			g_object_get_data(G_OBJECT(dialog), "check_markword"))));
+		ao_info->enable_tasks = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+			g_object_get_data(G_OBJECT(dialog), "check_tasks"))));
 
 		g_key_file_load_from_file(config, ao_info->config_file, G_KEY_FILE_NONE, NULL);
 		g_key_file_set_boolean(config, "addons",
@@ -222,7 +256,7 @@
 		g_object_set(ao_info->bookmarklist, "enable-bookmarklist",
 			ao_info->enable_bookmarklist, NULL);
 		g_object_set(ao_info->markword, "enable-markword", ao_info->enable_markword, NULL);
-		tasks_set_enable(ao_info->enable_tasks);
+		g_object_set(ao_info->tasks, "enable-tasks", ao_info->enable_tasks, NULL);
 
 		if (! g_file_test(config_dir, G_FILE_TEST_IS_DIR) && utils_mkdir(config_dir, TRUE) != 0)
 		{
@@ -263,7 +297,7 @@
 	gtk_box_pack_start(GTK_BOX(vbox), check_openuri, FALSE, FALSE, 3);
 
 	check_tasks = gtk_check_button_new_with_label(
-		_("Show available tasks in the Message Window"));
+		_("Show available Tasks in the Messages Window"));
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_tasks),
 		ao_info->enable_tasks);
 	gtk_box_pack_start(GTK_BOX(vbox), check_tasks, FALSE, FALSE, 3);
@@ -311,9 +345,8 @@
 	g_object_unref(ao_info->systray);
 	g_object_unref(ao_info->bookmarklist);
 	g_object_unref(ao_info->markword);
+	g_object_unref(ao_info->tasks);
 
-	tasks_set_enable(FALSE);
-
 	g_free(ao_info->config_file);
 	g_free(ao_info);
 }

Added: trunk/geany-plugins/addons/src/ao_tasks.c
===================================================================
--- trunk/geany-plugins/addons/src/ao_tasks.c	                        (rev 0)
+++ trunk/geany-plugins/addons/src/ao_tasks.c	2009-11-28 16:54:23 UTC (rev 1065)
@@ -0,0 +1,359 @@
+/*
+ *      ao_tasks.c - this file is part of Addons, a Geany plugin
+ *
+ *      Copyright 2009 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)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.
+ *
+ *      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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $Id$
+ */
+
+
+#include <gtk/gtk.h>
+#include <glib-object.h>
+
+#include "geanyplugin.h"
+
+#include "addons.h"
+#include "ao_tasks.h"
+
+#include <gdk/gdkkeysyms.h>
+
+
+/* Make tokens configurable */
+const gchar *tokens[] = { "TODO", "FIXME", NULL };
+
+
+typedef struct _AoTasksPrivate AoTasksPrivate;
+
+#define AO_TASKS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+	AO_TASKS_TYPE, AoTasksPrivate))
+
+struct _AoTasks
+{
+	GObject parent;
+};
+
+struct _AoTasksClass
+{
+	GObjectClass parent_class;
+};
+
+struct _AoTasksPrivate
+{
+	gboolean enable_tasks;
+
+	GtkListStore *store;
+	GtkWidget *tree;
+
+	GtkWidget *page;
+};
+
+enum
+{
+	PROP_0,
+	PROP_ENABLE_TASKS
+};
+
+enum
+{
+	TLIST_COL_FILENAME,
+	TLIST_COL_DISPLAY_FILENAME,
+	TLIST_COL_LINE,
+	TLIST_COL_NAME,
+	TLIST_COL_TOOLTIP,
+	TLIST_COL_MAX
+};
+
+static void ao_tasks_finalize  			(GObject *object);
+static void ao_tasks_show				(AoTasks *t);
+static void ao_tasks_hide				(AoTasks *t);
+
+G_DEFINE_TYPE(AoTasks, ao_tasks, G_TYPE_OBJECT);
+
+
+static void ao_tasks_set_property(GObject *object, guint prop_id,
+								  const GValue *value, GParamSpec *pspec)
+{
+	AoTasksPrivate *priv = AO_TASKS_GET_PRIVATE(object);
+
+	switch (prop_id)
+	{
+		case PROP_ENABLE_TASKS:
+		{
+			gboolean new_val = g_value_get_boolean(value);
+			if (new_val && ! priv->enable_tasks)
+				ao_tasks_show(AO_TASKS(object));
+			if (! new_val && priv->enable_tasks)
+				ao_tasks_hide(AO_TASKS(object));
+
+			priv->enable_tasks = new_val;
+			break;
+		}
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+			break;
+	}
+}
+
+
+static void ao_tasks_class_init(AoTasksClass *klass)
+{
+	GObjectClass *g_object_class;
+
+	g_object_class = G_OBJECT_CLASS(klass);
+	g_object_class->finalize = ao_tasks_finalize;
+	g_object_class->set_property = ao_tasks_set_property;
+	g_type_class_add_private(klass, sizeof(AoTasksPrivate));
+
+	g_object_class_install_property(g_object_class,
+									PROP_ENABLE_TASKS,
+									g_param_spec_boolean(
+									"enable-tasks",
+									"enable-tasks",
+									"Whether to show list of defined tasks",
+									TRUE,
+									G_PARAM_WRITABLE));
+}
+
+
+static void ao_tasks_finalize(GObject *object)
+{
+	g_return_if_fail(object != NULL);
+	g_return_if_fail(IS_AO_TASKS(object));
+
+	ao_tasks_hide(AO_TASKS(object));
+
+	G_OBJECT_CLASS(ao_tasks_parent_class)->finalize(object);
+}
+
+
+static gboolean ao_tasks_selection_changed_cb(gpointer widget)
+{
+	GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+
+	if (gtk_tree_selection_get_selected(selection, &model, &iter))
+	{
+		gint line;
+		gchar *filename, *locale_filename;
+		GeanyDocument *doc;
+
+		gtk_tree_model_get(model, &iter, TLIST_COL_LINE, &line, TLIST_COL_FILENAME, &filename, -1);
+		locale_filename = utils_get_locale_from_utf8(filename);
+		doc = document_open_file(locale_filename, FALSE, NULL, NULL);
+		if (doc != NULL)
+		{
+			sci_goto_line(doc->editor->sci, line - 1, TRUE);
+			gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci));
+		}
+		g_free(filename);
+		g_free(locale_filename);
+	}
+	return FALSE;
+}
+
+
+static gboolean ao_tasks_button_press_cb(GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+	if (event->button == 1)
+	{	/* allow reclicking of a treeview item */
+		g_idle_add(ao_tasks_selection_changed_cb, widget);
+	}
+	return FALSE;
+}
+
+
+static gboolean ao_tasks_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+	if (event->keyval == GDK_Return ||
+		event->keyval == GDK_ISO_Enter ||
+		event->keyval == GDK_KP_Enter ||
+		event->keyval == GDK_space)
+	{
+		g_idle_add(ao_tasks_selection_changed_cb, widget);
+	}
+	return FALSE;
+}
+
+
+static void ao_tasks_hide(AoTasks *t)
+{
+	AoTasksPrivate *priv = AO_TASKS_GET_PRIVATE(t);
+
+	if (priv->page)
+	{
+		gtk_widget_destroy(priv->page);
+		priv->page = NULL;
+	}
+}
+
+
+static void ao_tasks_show(AoTasks *t)
+{
+	GtkCellRenderer *text_renderer;
+	GtkTreeViewColumn *column;
+	GtkTreeSelection *selection;
+	GtkTreeSortable *sortable;
+	AoTasksPrivate *priv = AO_TASKS_GET_PRIVATE(t);
+
+	priv->store = gtk_list_store_new(TLIST_COL_MAX,
+		G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING);
+	priv->tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(priv->store));
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->tree));
+	gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+	/* selection handling */
+	g_signal_connect(priv->tree, "button-press-event", G_CALLBACK(ao_tasks_button_press_cb), t);
+	g_signal_connect(priv->tree, "key-press-event", G_CALLBACK(ao_tasks_key_press_cb), t);
+
+	text_renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_column_set_title(column, _("File"));
+	gtk_tree_view_column_pack_start(column, text_renderer, TRUE);
+	gtk_tree_view_column_set_attributes(column, text_renderer, "text",
+		TLIST_COL_DISPLAY_FILENAME, NULL);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(priv->tree), column);
+
+	text_renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_column_set_title(column, _("Line"));
+	gtk_tree_view_column_pack_start(column, text_renderer, TRUE);
+	gtk_tree_view_column_set_attributes(column, text_renderer, "text", TLIST_COL_LINE, NULL);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(priv->tree), column);
+
+	text_renderer = gtk_cell_renderer_text_new();
+	g_object_set(text_renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_column_set_title(column, _("Task"));
+	gtk_tree_view_column_pack_start(column, text_renderer, TRUE);
+	gtk_tree_view_column_set_attributes(column, text_renderer, "text", TLIST_COL_NAME, NULL);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(priv->tree), column);
+
+	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(priv->tree), TRUE);
+	gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(priv->tree), TRUE);
+	gtk_tree_view_set_search_column(GTK_TREE_VIEW(priv->tree), TLIST_COL_DISPLAY_FILENAME);
+
+	/* sorting */
+	/* TODO improve sorting: sort by filename, then line number; make header clicks sort the data */
+	sortable = GTK_TREE_SORTABLE(GTK_TREE_MODEL(priv->store));
+	gtk_tree_sortable_set_sort_column_id(sortable, TLIST_COL_DISPLAY_FILENAME, GTK_SORT_ASCENDING);
+
+	ui_widget_modify_font_from_string(priv->tree, geany->interface_prefs->tagbar_font);
+
+	/* GTK 2.12 tooltips */
+	if (gtk_check_version(2, 12, 0) == NULL)
+		g_object_set(priv->tree, "has-tooltip", TRUE, "tooltip-column", TLIST_COL_TOOLTIP, NULL);
+
+	/* scrolled window */
+	priv->page = gtk_scrolled_window_new(NULL, NULL);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(priv->page),
+		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+	gtk_container_add(GTK_CONTAINER(priv->page), priv->tree);
+
+	gtk_widget_show_all(priv->page);
+	gtk_notebook_append_page(
+		GTK_NOTEBOOK(ui_lookup_widget(geany->main_widgets->window, "notebook_info")),
+		priv->page,
+		gtk_label_new(_("Tasks")));
+
+	/* initial update */
+	ao_tasks_update(t, NULL);
+}
+
+
+void ao_tasks_activate(AoTasks *t)
+{
+	AoTasksPrivate *priv = AO_TASKS_GET_PRIVATE(t);
+
+	if (priv->enable_tasks)
+	{
+		GtkNotebook *notebook = GTK_NOTEBOOK(
+			ui_lookup_widget(geany->main_widgets->window, "notebook_info"));
+		gint page_number = gtk_notebook_page_num(notebook, priv->page);
+
+		gtk_notebook_set_current_page(notebook, page_number);
+		gtk_widget_grab_focus(priv->tree);
+	}
+}
+
+
+void ao_tasks_update(AoTasks *t, G_GNUC_UNUSED GeanyDocument *cur_doc)
+{
+	guint i, lines, line;
+	gchar *line_buf, *context, *display_name, *tooltip;
+	const gchar **token;
+	GeanyDocument *doc;
+	AoTasksPrivate *priv = AO_TASKS_GET_PRIVATE(t);
+
+	/* TODO this could be improved to only update the currently loaded/saved document instead of
+	 * iterating over all documents. */
+	gtk_list_store_clear(priv->store);
+
+	for (i = 0; i < geany->documents_array->len; i++)
+	{
+		doc = document_index(i);
+		if (doc->is_valid)
+		{
+			display_name = document_get_basename_for_display(doc, -1);
+			lines = sci_get_line_count(doc->editor->sci);
+			for (line = 0; line < lines; line++)
+			{
+				line_buf = g_strstrip(sci_get_line(doc->editor->sci, line));
+				token = tokens;
+				while (*token != NULL)
+				{
+					if (NZV(*token) && strstr(line_buf, *token) != NULL)
+					{
+						context = g_strstrip(sci_get_line(doc->editor->sci, line + 1));
+						setptr(context, g_strconcat(
+							_("Context:"), "\n", line_buf, "\n", context, NULL));
+						tooltip = g_markup_escape_text(context, -1);
+
+						gtk_list_store_insert_with_values(priv->store, NULL, -1,
+							TLIST_COL_FILENAME, DOC_FILENAME(doc),
+							TLIST_COL_DISPLAY_FILENAME, display_name,
+							TLIST_COL_LINE, line + 1,
+							TLIST_COL_NAME, line_buf,
+							TLIST_COL_TOOLTIP, tooltip,
+							-1);
+						g_free(context);
+						g_free(tooltip);
+					}
+					token++;
+				}
+				g_free(line_buf);
+			}
+			g_free(display_name);
+		}
+	}
+}
+
+
+static void ao_tasks_init(AoTasks *self)
+{
+	AoTasksPrivate *priv = AO_TASKS_GET_PRIVATE(self);
+
+	priv->page = NULL;
+}
+
+
+AoTasks *ao_tasks_new(gboolean enable)
+{
+	return g_object_new(AO_TASKS_TYPE, "enable-tasks", enable, NULL);
+}


Property changes on: trunk/geany-plugins/addons/src/ao_tasks.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: trunk/geany-plugins/addons/src/ao_tasks.h
===================================================================
--- trunk/geany-plugins/addons/src/ao_tasks.h	                        (rev 0)
+++ trunk/geany-plugins/addons/src/ao_tasks.h	2009-11-28 16:54:23 UTC (rev 1065)
@@ -0,0 +1,45 @@
+/*
+ *      ao_tasks.h - this file is part of Addons, a Geany plugin
+ *
+ *      Copyright 2009 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)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.
+ *
+ *      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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $Id$
+ */
+
+
+#ifndef __AO_TASKS_H__
+#define __AO_TASKS_H__
+
+G_BEGIN_DECLS
+
+#define AO_TASKS_TYPE				(ao_tasks_get_type())
+#define AO_TASKS(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), AO_TASKS_TYPE, AoTasks))
+#define AO_TASKS_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), AO_TASKS_TYPE, AoTasksClass))
+#define IS_AO_TASKS(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), AO_TASKS_TYPE))
+#define IS_AO_TASKS_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), AO_TASKS_TYPE))
+
+typedef struct _AoTasks			AoTasks;
+typedef struct _AoTasksClass	AoTasksClass;
+
+GType			ao_tasks_get_type		(void);
+AoTasks*		ao_tasks_new			(gboolean enable);
+void			ao_tasks_update			(AoTasks *t, GeanyDocument *cur_doc);
+void			ao_tasks_activate		(AoTasks *t);
+
+G_END_DECLS
+
+#endif /* __AO_TASKS_H__ */


Property changes on: trunk/geany-plugins/addons/src/ao_tasks.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Deleted: trunk/geany-plugins/addons/src/tasks.c
===================================================================
--- trunk/geany-plugins/addons/src/tasks.c	2009-11-28 16:49:09 UTC (rev 1064)
+++ trunk/geany-plugins/addons/src/tasks.c	2009-11-28 16:54:23 UTC (rev 1065)
@@ -1,515 +0,0 @@
-/*
- *      tasks - tasks.c
- *
- *      Copyright 2009 Bert Vermeulen <bert at biot.com>
- *
- *      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., 51 Franklin Street, Fifth Floor, Boston,
- *      MA 02110-1301, USA.
- */
-
-#include "geanyplugin.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <gdk/gdkkeysyms.h>
-
-#include "addons.h"
-#include "tasks.h"
-
-
-#define DEFAULT_TOKENS { "TODO", "FIXME", NULL };
-
-
-typedef struct {
-	unsigned int line;
-	GString *description;
-} GeanyTask;
-
-
-static GString *linebuf = NULL;
-static char *tokens[] = DEFAULT_TOKENS;
-static GHashTable *globaltasks = NULL;
-static GtkListStore *taskstore = NULL;
-static GtkWidget *notebook_page = NULL;
-static gboolean tasks_enabled = FALSE;
-
-
-static gboolean tasks_button_cb(GtkWidget *widget, GdkEventButton *event, gpointer data);
-static gboolean tasks_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data);
-static void free_editor_tasks(gpointer key, gpointer value, gpointer data);
-static void scan_all_documents(void);
-static void scan_document_for_tasks(GeanyDocument *doc);
-static void create_tasks_tab(void);
-static int scan_line_for_tokens(ScintillaObject *sci, unsigned int line);
-static int scan_buf_for_tokens(char *buf);
-static GeanyTask *create_task(unsigned int line, char *description);
-static int find_line(GeanyTask *task, unsigned int *line);
-static void found_token(GeanyEditor *editor, unsigned int line, char *d);
-static void no_token(GeanyEditor *editor, unsigned int line);
-static void lines_moved(GeanyEditor *editor, unsigned int line, int change);
-static int keysort(GeanyTask *a, GeanyTask *b);
-static void render_taskstore(GeanyEditor *editor);
-
-
-static void tasks_init(void)
-{
-	globaltasks = g_hash_table_new(NULL, NULL);
-	linebuf = g_string_sized_new(256);
-	create_tasks_tab();
-	scan_all_documents();
-
-	tasks_enabled = TRUE;
-}
-
-static void tasks_cleanup(void)
-{
-	GtkWidget *notebook;
-	int page;
-
-	g_string_free(linebuf, TRUE);
-
-	g_hash_table_foreach(globaltasks, free_editor_tasks, NULL);
-	g_hash_table_destroy(globaltasks);
-
-	notebook = ui_lookup_widget(geany->main_widgets->window, "notebook_info");
-	page = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), notebook_page);
-	gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page);
-
-	tasks_enabled = FALSE;
-}
-
-void tasks_set_enable(gboolean enable)
-{
-	if (tasks_enabled != enable)
-	{
-		if (enable)
-			tasks_init();
-		else
-			tasks_cleanup();
-	}
-}
-
-void tasks_on_document_close(GObject *object, GeanyDocument *doc, gpointer data)
-{
-
-	if(tasks_enabled && doc->is_valid)
-		free_editor_tasks(doc->editor, NULL, NULL);
-
-}
-
-
-void tasks_on_document_open(GObject *object, GeanyDocument *doc, gpointer data)
-{
-
-	if(tasks_enabled && doc->is_valid)
-		scan_document_for_tasks(doc);
-
-}
-
-
-void tasks_on_document_activate(GObject *object, GeanyDocument *doc, gpointer data)
-{
-
-	if(tasks_enabled && doc->is_valid)
-		render_taskstore(doc->editor);
-
-}
-
-
-gboolean tasks_on_editor_notify(GObject *object, GeanyEditor *editor,
-								 SCNotification *nt, gpointer data)
-{
-	static int mod_line = -1;
-	int pos, line, offset;
-
-	if (! tasks_enabled)
-		return FALSE;
-
-	switch (nt->nmhdr.code)
-	{
-		case SCN_MODIFIED:
-			line = sci_get_line_from_position(editor->sci, nt->position);
-			if(nt->linesAdded != 0)
-				/* check if existing tasks had their line numbers changed */
-				lines_moved(editor, line, nt->linesAdded);
-			else
-				/* same-line change: we'll check it later */
-				mod_line = line;
-			break;
-		case SCN_UPDATEUI:
-			pos = sci_get_current_position(editor->sci);
-			line = sci_get_line_from_position(editor->sci, pos);
-			if(mod_line != -1 && line != mod_line)
-			{
-				/* cursor left a line that was changed, scan it for tokens */
-				offset = scan_line_for_tokens(editor->sci, mod_line);
-				if(offset)
-					found_token(editor, mod_line, linebuf->str + offset);
-				else
-					no_token(editor, mod_line);
-				render_taskstore(editor);
-				mod_line = -1;
-			}
-			break;
-	}
-
-	return FALSE;
-}
-
-
-static gboolean tasks_button_cb(GtkWidget *widget, GdkEventButton *event, gpointer data)
-{
-	GeanyDocument *doc;
-	GtkTreeView *tv;
-	GtkTreeSelection *selection;
-	GtkTreeIter iter;
-	GtkTreeModel *model;
-	gboolean ret = FALSE;
-	unsigned int line;
-
-	if (event->button == 1)
-	{
-		ret = TRUE;
-
-		tv = GTK_TREE_VIEW(ui_lookup_widget(geany->main_widgets->window, "treeview_tasks"));
-		selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv));
-		if (gtk_tree_selection_get_selected(selection, &model, &iter))
-		{
-			gtk_tree_model_get(model, &iter, 0, &line, -1);
-			doc = document_get_current();
-			ret = navqueue_goto_line(NULL, doc, line + 1);
-		}
-	}
-
-	return ret;
-}
-
-
-static gboolean tasks_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
-{
-	GtkTreeView *tv;
-	GdkEventButton button_event;
-
-	if(event->keyval == GDK_Return ||
-		event->keyval == GDK_ISO_Enter ||
-		event->keyval == GDK_KP_Enter ||
-		event->keyval == GDK_space)
-	{
-		button_event.button = 1;
-		button_event.time = event->time;
-		tv = GTK_TREE_VIEW(ui_lookup_widget(geany->main_widgets->window, "treeview_tasks"));
-		tasks_button_cb(NULL, &button_event, tv);
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-
-static void free_editor_tasks(gpointer key, gpointer value, gpointer data)
-{
-	GList *tasklist, *entry;
-	GeanyTask *task;
-
-	tasklist = (value) ? value : g_hash_table_lookup(globaltasks, key);
-	if(tasklist)
-	{
-		for(entry = g_list_first(tasklist); entry; entry = g_list_next(entry))
-		{
-			task = (GeanyTask *) entry->data;
-			g_string_free(task->description, TRUE);
-			g_free(task);
-		}
-		g_list_free(tasklist);
-	}
-	g_hash_table_remove(globaltasks, key);
-
-}
-
-
-static void scan_all_documents(void)
-{
-	unsigned int i;
-
-	for(i = 0; i < geany->documents_array->len; i++)
-	{
-		if(document_index(i)->is_valid)
-		{
-			scan_document_for_tasks(document_index(i));
-		}
-	}
-
-}
-
-/* go through every line of a document and scan it for tasks tokens. add the
- * task to the tasklist for that document if found. */
-static void scan_document_for_tasks(GeanyDocument *doc)
-{
-	unsigned int lines, line, offset;
-
-	lines = sci_get_line_count(doc->editor->sci);
-	for(line = 0; line < lines; line++)
-	{
-		offset = scan_line_for_tokens(doc->editor->sci, line);
-		if(offset)
-			found_token(doc->editor, line, linebuf->str + offset);
-	}
-	render_taskstore(doc->editor);
-
-}
-
-
-static void create_tasks_tab(void)
-{
-	GtkWidget *tv, *notebook;
-	GtkCellRenderer *renderer;
-	GtkTreeViewColumn *column;
-	GtkTreeSelection *selection;
-	int page;
-
-	taskstore = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
-	tv = gtk_tree_view_new_with_model(GTK_TREE_MODEL(taskstore));
-	g_object_set_data(G_OBJECT(geany->main_widgets->window), "treeview_tasks", tv);
-	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tv), FALSE);
-	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv));
-	gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
-	g_signal_connect(tv, "button-release-event", G_CALLBACK(tasks_button_cb), (gpointer) tv);
-	g_signal_connect(tv, "key-press-event", G_CALLBACK(tasks_key_cb), (gpointer) tv);
-
-	renderer = gtk_cell_renderer_text_new();
-	column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "text", 1, NULL);
-	gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column);
-
-	notebook = ui_lookup_widget(geany->main_widgets->window, "notebook_info");
-	page = gtk_notebook_insert_page(GTK_NOTEBOOK(notebook), tv, gtk_label_new(_("Tasks")), -1);
-	gtk_widget_show_all(tv);
-	notebook_page = tv;
-}
-
-
-/* copy the line into linebuf and scan it for tokens. returns 0 if no tokens
- * were found, or the offset to the start of the task in linebuf otherwise. */
-static int scan_line_for_tokens(ScintillaObject *sci, unsigned int line)
-{
-	unsigned int len, len_done, offset;
-
-	offset = 0;
-	len = sci_get_line_length(sci, line);
-	if(len)
-	{
-		if(len+1 > linebuf->allocated_len)
-		{
-			/* why doesn't GString have this functionality? */
-			linebuf->str = g_realloc(linebuf->str, len+1);
-			if(linebuf->str == NULL)
-				return 0;
-			linebuf->allocated_len = len+1;
-		}
-		len_done = scintilla_send_message(sci, SCI_GETLINE, line, (sptr_t) linebuf->str);
-		linebuf->str[len] = 0;
-		if(len_done)
-			offset = scan_buf_for_tokens(linebuf->str);
-	}
-
-	return offset;
-}
-
-
-static int scan_buf_for_tokens(char *buf)
-{
-	unsigned int t, offset, len, i;
-	char *entry;
-
-	offset = 0;
-	for(t = 0; tokens[t]; t++)
-	{
-		entry = strstr(buf, tokens[t]);
-		if(entry)
-		{
-			entry += strlen(tokens[t]);
-			while(*entry == ' ' || *entry == ':')
-				entry++;
-			for(i = 0; entry[i]; i++)
-			{
-				/* strip off line endings */
-				if(entry[i] == '\t' || entry[i] == '\r' || entry[i] == '\n')
-				{
-					entry[i] = 0;
-					break;
-				}
-			}
-			/* strip off */ /* no really, I mean */
-			len = strlen(entry);
-			if(len > 1 && entry[len-2] == '*' && entry[len-1] == '/')
-				entry[len-2] = 0;
-			offset = entry - buf;
-		}
-	}
-
-	return offset;
-}
-
-
-static GeanyTask *create_task(unsigned int line, char *description)
-{
-	GeanyTask *task;
-
-	task = malloc(sizeof(GeanyTask));
-	g_return_val_if_fail(task != NULL, NULL);
-
-	task->line = line;
-	task->description = g_string_new(description);
-
-	return task;
-}
-
-
-static int find_line(GeanyTask *task, unsigned int *line)
-{
-
-	if(task->line == *line)
-		return 0;
-
-	return 1;
-}
-
-
-static void found_token(GeanyEditor *editor, unsigned int line, char *description)
-{
-	GeanyTask *task;
-	GList *tasklist, *entry;
-
-	tasklist = g_hash_table_lookup(globaltasks, editor);
-	if(tasklist)
-	{
-		entry = g_list_find_custom(tasklist, (gconstpointer) &line, (gconstpointer) find_line);
-		if(entry)
-		{
-			task = (GeanyTask *) entry->data;
-			if(strcmp(description, task->description->str))
-				g_string_assign(task->description, description);
-		}
-		else
-		{
-			task = create_task(line, description);
-			tasklist = g_list_append(tasklist, task);
-			g_hash_table_replace(globaltasks, editor, tasklist);
-		}
-	}
-	else
-	{
-		/* this editor doesn't have a tasklist yet */
-		task = create_task(line, description);
-		tasklist = g_list_append(NULL, task);
-		g_hash_table_insert(globaltasks, editor, tasklist);
-	}
-
-}
-
-
-/* no token was found on this line, make sure there's nothing in the tasklist either */
-static void no_token(GeanyEditor *editor, unsigned int line)
-{
-	GList *tasklist, *entry;
-
-	tasklist = g_hash_table_lookup(globaltasks, editor);
-	if(tasklist)
-	{
-		entry = g_list_find_custom(tasklist, (gconstpointer) &line, (gconstpointer) find_line);
-		if(entry)
-		{
-			tasklist = g_list_remove(tasklist, entry);
-			g_hash_table_replace(globaltasks, editor, tasklist);
-		}
-	}
-
-}
-
-
-static void lines_moved(GeanyEditor *editor, unsigned int line, int change)
-{
-	GeanyTask *task;
-	GList *tasklist, *entry, *to_delete;
-
-	to_delete = NULL;
-	tasklist = g_hash_table_lookup(globaltasks, editor);
-	for(entry = g_list_first(tasklist); entry; entry = g_list_next(entry))
-	{
-		task = (GeanyTask *) entry->data;
-		if(task->line >= line)
-		{
-			if(change < 0 && task->line < line - change)
-				/* the line with this task on it was deleted, so mark the task for deletion */
-				to_delete = g_list_append(to_delete, entry->data);
-			else
-				/* shift the line number of this task up or down along with the change */
-				task->line += change;
-		}
-	}
-
-	for(entry = g_list_first(to_delete); entry; entry = g_list_next(entry))
-	{
-		task = (GeanyTask *) entry->data;
-		tasklist = g_list_remove(tasklist, entry->data);
-		g_string_free(task->description, TRUE);
-		g_free(task);
-	}
-	g_list_free(to_delete);
-
-	g_hash_table_replace(globaltasks, editor, tasklist);
-	render_taskstore(editor);
-
-}
-
-
-static int keysort(GeanyTask *a, GeanyTask *b)
-{
-
-	if(a->line < b->line)
-		return -1;
-	else if(a->line > b->line)
-		return 1;
-
-	return 0;
-}
-
-
-static void render_taskstore(GeanyEditor *editor)
-{
-	GeanyTask *task;
-	GtkTreeIter iter;
-	GList *tasklist, *entry;
-
-	gtk_list_store_clear(taskstore);
-	tasklist = g_hash_table_lookup(globaltasks, editor);
-	if(!tasklist)
-		/* empty list */
-		return;
-	tasklist = g_list_sort(tasklist, (GCompareFunc) keysort);
-	g_hash_table_replace(globaltasks, editor, tasklist);
-
-	for(entry = g_list_first(tasklist); entry; entry = g_list_next(entry))
-	{
-		task = (GeanyTask *) entry->data;
-		gtk_list_store_append(taskstore, &iter);
-		gtk_list_store_set(taskstore, &iter, 0, task->line, 1, task->description->str, -1);
-	}
-
-}
-
-
-

Deleted: trunk/geany-plugins/addons/src/tasks.h
===================================================================
--- trunk/geany-plugins/addons/src/tasks.h	2009-11-28 16:49:09 UTC (rev 1064)
+++ trunk/geany-plugins/addons/src/tasks.h	2009-11-28 16:54:23 UTC (rev 1065)
@@ -1,38 +0,0 @@
-/*
- *      tasks - tasks.h
- *
- *      Copyright 2009 Bert Vermeulen <bert at biot.com>
- *
- *      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., 51 Franklin Street, Fifth Floor, Boston,
- *      MA 02110-1301, USA.
- */
-
-#ifndef __TASKS_H__
-#define __TASKS_H__
-
-
-void tasks_set_enable(gboolean enable);
-
-
-gboolean tasks_on_editor_notify(GObject *object, GeanyEditor *editor,
-								SCNotification *nt, gpointer data);
-
-void tasks_on_document_open(GObject *object, GeanyDocument *doc, gpointer data);
-
-void tasks_on_document_activate(GObject *object, GeanyDocument *doc, gpointer data);
-
-void tasks_on_document_close(GObject *object, GeanyDocument *doc, gpointer data);
-
-#endif

Modified: trunk/geany-plugins/po/POTFILES.in
===================================================================
--- trunk/geany-plugins/po/POTFILES.in	2009-11-28 16:49:09 UTC (rev 1064)
+++ trunk/geany-plugins/po/POTFILES.in	2009-11-28 16:54:23 UTC (rev 1065)
@@ -2,7 +2,7 @@
 
 # Addons
 addons/src/ao_systray.c
-addons/src/tasks.c
+addons/src/ao_tasks.c
 addons/src/ao_openuri.c
 addons/src/addons.c
 addons/src/ao_doclist.c


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Plugins-Commits mailing list