SF.net SVN: geany-plugins:[579] trunk

eht16 at users.sourceforge.net eht16 at xxxxx
Mon Apr 6 21:59:19 UTC 2009


Revision: 579
          http://geany-plugins.svn.sourceforge.net/geany-plugins/?rev=579&view=rev
Author:   eht16
Date:     2009-04-06 21:59:19 +0000 (Mon, 06 Apr 2009)

Log Message:
-----------
Move Tasks plugin into the Addons plugins as of biot's request.

Modified Paths:
--------------
    trunk/addons/AUTHORS
    trunk/addons/README
    trunk/addons/makefile.win32
    trunk/addons/po/POTFILES.in
    trunk/addons/src/Makefile.am
    trunk/addons/src/addons.c
    trunk/wscript

Added Paths:
-----------
    trunk/addons/src/tasks.c
    trunk/addons/src/tasks.h

Removed Paths:
-------------
    trunk/tasks/

Modified: trunk/addons/AUTHORS
===================================================================
--- trunk/addons/AUTHORS	2009-04-06 12:34:01 UTC (rev 578)
+++ trunk/addons/AUTHORS	2009-04-06 21:59:19 UTC (rev 579)
@@ -1 +1,2 @@
 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
+Bert Vermeulen <bert(at)biot(dot)com>

Modified: trunk/addons/README
===================================================================
--- trunk/addons/README	2009-04-06 12:34:01 UTC (rev 578)
+++ trunk/addons/README	2009-04-06 21:59:19 UTC (rev 579)
@@ -19,7 +19,14 @@
 the cursor looks like a URI. 'Open URI' uses the browser command configured in
 Geany to open it.
 
+Tasks
+^^^^^
+The tasks plugin goes through a file being edited and picks out lines with
+"TODO" or "FIXME" in them. It collects the text after those words and puts
+them in a new "Tasks" tab in the message window. Clicking on a task in that
+tab takes you to the line in the file where the task was defined.
 
+
 Requirements
 ------------
 For compiling the plugin yourself, you will need the GTK (>= 2.8.0) libraries
@@ -70,5 +77,4 @@
 
 Ideas, questions, patches and bug reports
 -----------------------------------------
-Send it to enrico(dot)troeger(at)uvena(dot)de
-or report them at http://sourceforge.net/tracker/?group_id=222729.
+Report them at http://sourceforge.net/tracker/?group_id=222729.

Modified: trunk/addons/makefile.win32
===================================================================
--- trunk/addons/makefile.win32	2009-04-06 12:34:01 UTC (rev 578)
+++ trunk/addons/makefile.win32	2009-04-06 21:59:19 UTC (rev 579)
@@ -16,7 +16,7 @@
 -include localwin32.mk
 
 
-OBJS =	addons.o ao_openuri.o ao_doclist.o
+OBJS =	addons.o ao_openuri.o ao_doclist.o tasks.o
 INCLUDEDIRS=  -I. \
               -I$(GEANY_SRC) \
               -I$(GEANY_SRC)\src \
@@ -32,7 +32,7 @@
               -I$(PREFIX)/lib/glib-2.0/include \
               -I$(PREFIX)/include/gettext \
               -I$(PREFIX)/include
-              
+
 ALL_GTK_LIBS= \
 	-L"$(PREFIX)/lib" \
 	-lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lpangowin32-1.0 -lgdi32 \

Modified: trunk/addons/po/POTFILES.in
===================================================================
--- trunk/addons/po/POTFILES.in	2009-04-06 12:34:01 UTC (rev 578)
+++ trunk/addons/po/POTFILES.in	2009-04-06 21:59:19 UTC (rev 579)
@@ -3,3 +3,4 @@
 src/addons.c
 src/ao_openuri.c
 src/ao_doclist.c
+src/tasks.c

Modified: trunk/addons/src/Makefile.am
===================================================================
--- trunk/addons/src/Makefile.am	2009-04-06 12:34:01 UTC (rev 578)
+++ trunk/addons/src/Makefile.am	2009-04-06 21:59:19 UTC (rev 579)
@@ -1,6 +1,6 @@
 
 lib_LTLIBRARIES = addons.la
-addons_la_SOURCES = addons.c addons.h ao_doclist.c ao_doclist.h ao_openuri.c ao_openuri.h
+addons_la_SOURCES = addons.c addons.h ao_doclist.c ao_doclist.h ao_openuri.c ao_openuri.h tasks.c tasks.h
 addons_la_LDFLAGS = -module -avoid-version
 addons_la_LIBADD  = @GEANY_LIBS@  $(INTLLIBS)
 

Modified: trunk/addons/src/addons.c
===================================================================
--- trunk/addons/src/addons.c	2009-04-06 12:34:01 UTC (rev 578)
+++ trunk/addons/src/addons.c	2009-04-06 21:59:19 UTC (rev 579)
@@ -41,6 +41,7 @@
 
 #include "ao_doclist.h"
 #include "ao_openuri.h"
+#include "tasks.h"
 
 
 
@@ -51,7 +52,7 @@
 
 PLUGIN_VERSION_CHECK(132)
 PLUGIN_SET_INFO(_("Addons"), _("Various small addons for Geany."), "0.1",
-	"Enrico Tröger")
+	"Enrico Tröger, Bert Vermeulen")
 
 
 typedef struct
@@ -60,6 +61,7 @@
 	gchar *config_file;
 	gboolean show_toolbar_doclist_item;
 	gboolean enable_openuri;
+	gboolean enable_tasks;
 
 	/* instances and variables of components */
 	AoDocList *doclist;
@@ -76,7 +78,13 @@
 PluginCallback plugin_callbacks[] =
 {
     { "update-editor-menu", (GCallback) &ao_update_editor_menu_cb, FALSE, NULL },
-    { NULL, NULL, FALSE, NULL }
+
+	{ "editor-notify", (GCallback) &tasks_on_editor_notify, TRUE, NULL },
+	{ "document-open", (GCallback) &tasks_on_document_open, TRUE, NULL },
+	{ "document-close", (GCallback) &tasks_on_document_close, TRUE, NULL },
+	{ "document-activate", (GCallback) &tasks_on_document_activate, TRUE, NULL },
+
+	{ NULL, NULL, FALSE, NULL }
 };
 
 
@@ -114,12 +122,16 @@
 		"addons", "show_toolbar_doclist_item", TRUE);
 	ao_info->enable_openuri = utils_get_setting_boolean(config,
 		"addons", "enable_openuri", FALSE);
+	ao_info->enable_tasks = utils_get_setting_boolean(config,
+		"addons", "enable_tasks", TRUE);
 
 	main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
 	plugin_module_make_resident(geany_plugin);
 
 	ao_info->doclist = ao_doc_list_new(ao_info->show_toolbar_doclist_item);
 	ao_info->openuri = ao_open_uri_new(ao_info->enable_openuri);
+
+	tasks_set_enable(ao_info->enable_tasks);
 }
 
 
@@ -135,15 +147,20 @@
 			g_object_get_data(G_OBJECT(dialog), "check_doclist"))));
 		ao_info->enable_openuri = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
 			g_object_get_data(G_OBJECT(dialog), "check_openuri"))));
+		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",
 			"show_toolbar_doclist_item", ao_info->show_toolbar_doclist_item);
 		g_key_file_set_boolean(config, "addons", "enable_openuri", ao_info->enable_openuri);
+		g_key_file_set_boolean(config, "addons", "enable_tasks", ao_info->enable_tasks);
 
 		g_object_set(ao_info->doclist, "enable-doclist", ao_info->show_toolbar_doclist_item, NULL);
 		g_object_set(ao_info->openuri, "enable-openuri", ao_info->enable_openuri, NULL);
 
+		tasks_set_enable(ao_info->enable_tasks);
+
 		if (! g_file_test(config_dir, G_FILE_TEST_IS_DIR) && utils_mkdir(config_dir, TRUE) != 0)
 		{
 			dialogs_show_msgbox(GTK_MESSAGE_ERROR,
@@ -164,7 +181,7 @@
 
 GtkWidget *plugin_configure(GtkDialog *dialog)
 {
-	GtkWidget *vbox, *check_doclist, *check_openuri;
+	GtkWidget *vbox, *check_doclist, *check_openuri, *check_tasks;
 
 	vbox = gtk_vbox_new(FALSE, 6);
 
@@ -181,8 +198,15 @@
 		ao_info->enable_openuri);
 	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"));
+	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);
+
 	g_object_set_data(G_OBJECT(dialog), "check_doclist", check_doclist);
 	g_object_set_data(G_OBJECT(dialog), "check_openuri", check_openuri);
+	g_object_set_data(G_OBJECT(dialog), "check_tasks", check_tasks);
 	g_signal_connect(dialog, "response", G_CALLBACK(ao_configure_response_cb), NULL);
 
 	gtk_widget_show_all(vbox);
@@ -195,6 +219,9 @@
 {
 	g_object_unref(ao_info->doclist);
 	g_object_unref(ao_info->openuri);
+
+	tasks_set_enable(FALSE);
+
 	g_free(ao_info->config_file);
 	g_free(ao_info);
 }

Added: trunk/addons/src/tasks.c
===================================================================
--- trunk/addons/src/tasks.c	                        (rev 0)
+++ trunk/addons/src/tasks.c	2009-04-06 21:59:19 UTC (rev 579)
@@ -0,0 +1,528 @@
+/*
+ *      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 <stdlib.h>
+#include <string.h>
+
+#include <gdk/gdkkeysyms.h>
+
+#include "geany.h"
+#include "support.h"
+#include "sciwrappers.h"
+
+#include "prefs.h"
+#include "ui_utils.h"
+#include "utils.h"
+#include "document.h"
+
+#include "plugindata.h"
+#include "geanyfunctions.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(void *editor);
+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;
+	GList *editors, *editor;
+	int page;
+
+	g_string_free(linebuf, TRUE);
+
+	editors = g_hash_table_get_keys(globaltasks);
+	for(editor = g_list_first(editors); editor; editor = editor->next)
+		free_editor_tasks(editor);
+	g_hash_table_unref(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);
+
+}
+
+
+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(void *editor)
+{
+	GList *tasklist, *entry;
+	GeanyTask *task;
+
+	tasklist = g_hash_table_lookup(globaltasks, editor);
+	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, editor);
+
+}
+
+
+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);
+	}
+
+}
+
+
+


Property changes on: trunk/addons/src/tasks.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Added: trunk/addons/src/tasks.h
===================================================================
--- trunk/addons/src/tasks.h	                        (rev 0)
+++ trunk/addons/src/tasks.h	2009-04-06 21:59:19 UTC (rev 579)
@@ -0,0 +1,38 @@
+/*
+ *      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


Property changes on: trunk/addons/src/tasks.h
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Modified: trunk/wscript
===================================================================
--- trunk/wscript	2009-04-06 12:34:01 UTC (rev 578)
+++ trunk/wscript	2009-04-06 21:59:19 UTC (rev 579)
@@ -61,7 +61,8 @@
 # add a new element for your plugin
 plugins = [
 	Plugin('addons',
-		 [ 'addons/src/addons.c', 'addons/src/ao_doclist.c', 'addons/src/ao_openuri.c' ],
+		 [ 'addons/src/addons.c', 'addons/src/ao_doclist.c', 'addons/src/ao_openuri.c',
+		   'addons/src/tasks.c' ],
 		 [ 'addons', 'addons/src' ],
 		 '0.1'),
 	Plugin('externdbg',
@@ -124,11 +125,7 @@
 	Plugin('shiftcolumn',
 		 [ 'shiftcolumn/src/shiftcolumn.c'],
 		 [ 'shiftcolumn', 'shiftcolumn/src'],
-		 '0.3'),
-	Plugin('tasks',
-		 [ 'tasks/src/tasks.c'],
-		 [ 'tasks', 'tasks/src'],
-		 '1.0')
+		 '0.3')
 ]
 
 makefile_template = '''#!/usr/bin/make -f


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