almanah r122 - in trunk: . data po src src/definitions



Author: pwithnall
Date: Sat Dec 13 18:35:02 2008
New Revision: 122
URL: http://svn.gnome.org/viewvc/almanah?rev=122&view=rev

Log:
2008-12-13  Philip Withnall  <philip tecnocode co uk>

	* data/almanah.ui:
	* src/Makefile.am:
	* src/definition-manager-window.c
	(almanah_definition_manager_window_class_init),
	(almanah_definition_manager_window_init), (definitions_dispose_cb),
	(almanah_definition_manager_window_dispose),
	(almanah_definition_manager_window_new),
	(dmw_definition_tree_view_row_activated_cb),
	(dmw_view_button_clicked_cb), (dmw_remove_button_clicked_cb),
	(definition_selection_changed_cb), (definition_added_cb),
	(definition_removed_cb), (populate_definition_store):
	* src/definition-manager-window.h:
	* src/definition.c (almanah_definition_get_blurb):
	* src/definition.h:
	* src/definitions/file.c (almanah_file_definition_class_init),
	(file_get_blurb):
	* src/definitions/note.c (almanah_note_definition_class_init),
	(note_get_blurb):
	* src/definitions/uri.c (almanah_uri_definition_class_init),
	(uri_get_blurb):
	* src/interface.c (definition_tag_event_cb):
	* src/main-window.c (almanah_main_window_dispose),
	(almanah_main_window_new), (mw_entry_buffer_apply_tag_cb),
	(mw_view_definitions_activate_cb), (mw_definition_removed_cb):
	* src/main-window.h:
	* src/storage-manager.c: Added a "Definition Manager" interface, which
	allows the user to list all their definitions and manage them.
	* po/POTFILES.in: Changed files in accordance with various renamings.



Added:
   trunk/src/definition-manager-window.c
   trunk/src/definition-manager-window.h
Modified:
   trunk/ChangeLog
   trunk/data/almanah.ui
   trunk/po/ChangeLog
   trunk/po/POTFILES.in
   trunk/src/Makefile.am
   trunk/src/definition.c
   trunk/src/definition.h
   trunk/src/definitions/file.c
   trunk/src/definitions/note.c
   trunk/src/definitions/uri.c
   trunk/src/interface.c
   trunk/src/main-window.c
   trunk/src/main-window.h
   trunk/src/storage-manager.c

Modified: trunk/data/almanah.ui
==============================================================================
--- trunk/data/almanah.ui	(original)
+++ trunk/data/almanah.ui	Sat Dec 13 18:35:02 2008
@@ -151,7 +151,7 @@
 					<object class="GtkAction" id="almanah_ui_view_definitions">
 						<property name="name">view-definitions</property>
 						<property name="label" translatable="yes">_View Definitions</property>
-						<signal name="activate" handler="mw_remove_definition_activate_cb"/>
+						<signal name="activate" handler="mw_view_definitions_activate_cb"/>
 					</object>
 				</child>
 			</object>
@@ -501,7 +501,7 @@
 		<child internal-child="vbox">
 			<object class="GtkVBox" id="vbox2">
 				<child>
-					<object class="GtkHBox" id="hbox2">
+					<object class="GtkHBox" id="hbox0">
 						<child>
 							<object class="GtkEntry" id="almanah_sd_search_entry">
 								<property name="activates-default">True</property>
@@ -633,4 +633,159 @@
 			<action-widget response="-7">almanah_pd_close_button</action-widget><!-- GTK_RESPONSE_CLOSE -->
 		</action-widgets>
 	</object>
+
+	<object class="GtkListStore" id="almanah_dmw_definition_store">
+		<columns>
+			<column type="AlmanahDefinition"/><!-- Definition object -->
+			<column type="gchararray"/><!-- Definition text -->
+		</columns>
+	</object>
+
+	<object class="AlmanahDefinitionManagerWindow" id="almanah_definition_manager_window">
+		<child>
+			<object class="GtkHBox" id="hbox1">
+				<child>
+					<object class="GtkScrolledWindow" id="scrolledwindow3">
+						<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
+						<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
+						<property name="shadow-type">GTK_SHADOW_IN</property>
+						<property name="width-request">200</property>
+						<child>
+							<object class="GtkTreeView" id="almanah_dmw_definition_tree_view">
+								<property name="model">almanah_dmw_definition_store</property>
+								<property name="headers-visible">False</property>
+								<signal name="row-activated" handler="dmw_definition_tree_view_row_activated_cb"/>
+								<child internal-child="accessible">
+									<object class="AtkObject" id="a11y-almanah_dmw_definition_tree_view">
+										<property name="AtkObject::accessible-name" translatable="yes">Definition List</property>
+									</object>
+								</child>
+								<child>
+									<object class="GtkTreeViewColumn" id="column1">
+										<child>
+											<object class="GtkCellRendererText" id="renderer1"/>
+											<attributes>
+												<attribute name="text">1</attribute>
+											</attributes>
+										</child>
+									</object>
+								</child>
+							</object>
+						</child>
+					</object>
+					<packing>
+						<property name="expand">False</property>
+					</packing>
+				</child>
+				<child>
+					<object class="GtkTable" id="almanah_dmw_table">
+						<property name="n-rows">3</property>
+						<property name="n-columns">2</property>
+						<property name="column-spacing">5</property>
+						<property name="row-spacing">5</property>
+						<property name="border-width">5</property>
+						<child>
+							<object class="GtkLabel" id="almanah_dmw_name_label_label">
+								<property name="label" translatable="yes">Type</property>
+								<property name="xalign">1</property>
+								<accessibility>
+									<relation target="almanah_dmw_name_label" type="label-for"/>
+								</accessibility>
+							</object>
+							<packing>
+								<property name="left-attach">1</property>
+								<property name="right-attach">2</property>
+								<property name="top-attach">1</property>
+								<property name="bottom-attach">2</property>
+								<property name="x-options">GTK_FILL</property>
+								<property name="y-options">GTK_FILL</property>
+							</packing>
+						</child>
+						<child>
+							<object class="GtkLabel" id="almanah_dmw_name_label">
+								<property name="label" translatable="yes">Nothing selected</property>
+								<property name="xalign">0</property>
+								<accessibility>
+									<relation target="almanah_dmw_name_label_label" type="labelled-by"/>
+								</accessibility>
+							</object>
+							<packing>
+								<property name="left-attach">2</property>
+								<property name="right-attach">3</property>
+								<property name="top-attach">1</property>
+								<property name="bottom-attach">2</property>
+								<property name="y-options">GTK_FILL</property>
+							</packing>
+						</child>
+						<child>
+							<object class="GtkLabel" id="almanah_dmw_description_label_label">
+								<property name="label" translatable="yes">Description</property>
+								<property name="xalign">1</property>
+								<property name="yalign">0</property>
+								<accessibility>
+									<relation target="almanah_dmw_description_label" type="label-for"/>
+								</accessibility>
+							</object>
+							<packing>
+								<property name="left-attach">1</property>
+								<property name="right-attach">2</property>
+								<property name="top-attach">2</property>
+								<property name="bottom-attach">3</property>
+								<property name="x-options">GTK_FILL</property>
+								<property name="y-options">GTK_FILL</property>
+							</packing>
+						</child>
+						<child>
+							<object class="GtkLabel" id="almanah_dmw_description_label">
+								<property name="wrap">True</property>
+								<property name="xalign">0</property>
+								<property name="yalign">0</property>
+								<accessibility>
+									<relation target="almanah_dmw_description_label_label" type="labelled-by"/>
+								</accessibility>
+							</object>
+							<packing>
+								<property name="left-attach">2</property>
+								<property name="right-attach">3</property>
+								<property name="top-attach">2</property>
+								<property name="bottom-attach">3</property>
+							</packing>
+						</child>
+						<child>
+							<object class="GtkHButtonBox" id="almanah_dmw_button_box">
+								<child>
+									<object class="GtkButton" id="almanah_dmw_remove_button">
+										<property name="use-stock">True</property>
+										<property name="label">gtk-remove</property>
+										<property name="sensitive">False</property>
+										<signal name="clicked" handler="dmw_remove_button_clicked_cb"/>
+									</object>
+								</child>
+								<child>
+									<object class="GtkButton" id="almanah_dmw_view_button">
+										<property name="image">almanah_mw_view_button_image</property>
+										<property name="label" translatable="yes">View</property>
+										<property name="sensitive">False</property>
+										<signal name="clicked" handler="dmw_view_button_clicked_cb"/>
+										<child internal-child="accessible">
+											<object class="AtkObject" id="a11y-almanah_dmw_view_button">
+												<property name="AtkObject::accessible-name" translatable="yes">View Event</property>
+											</object>
+										</child>
+									</object>
+								</child>
+							</object>
+							<packing>
+								<property name="left-attach">1</property>
+								<property name="right-attach">3</property>
+								<property name="top-attach">3</property>
+								<property name="bottom-attach">4</property>
+								<property name="y-options">GTK_FILL</property>
+							</packing>
+						</child>
+					</object>
+				</child>
+			</object>
+		</child>
+	</object>
 </interface>

Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in	(original)
+++ trunk/po/POTFILES.in	Sat Dec 13 18:35:02 2008
@@ -3,12 +3,17 @@
 data/almanah.desktop.in
 data/almanah.schemas.in
 [type: gettext/glade]data/almanah.ui
-src/add-link-dialog.c
+src/add-definition-dialog.c
+src/events/calendar-appointment.c
+src/events/calendar-task.c
 src/interface.c
-src/link.c
-src/links/file.c
-src/links/note.c
-src/links/uri.c
+src/definition-manager-window.c
+src/definition.c
+src/definitions/file.c
+src/definitions/note.c
+src/definitions/uri.c
+src/links/calendar-appointment.c
+src/links/calendar-task.c
 src/main-window.c
 src/main.c
 src/preferences-dialog.c

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Sat Dec 13 18:35:02 2008
@@ -32,6 +32,8 @@
 	interface.h		\
 	main-window.c		\
 	main-window.h		\
+	definition-manager-window.c	\
+	definition-manager-window.h	\
 	storage-manager.c	\
 	storage-manager.h	\
 	add-definition-dialog.c	\

Added: trunk/src/definition-manager-window.c
==============================================================================
--- (empty file)
+++ trunk/src/definition-manager-window.c	Sat Dec 13 18:35:02 2008
@@ -0,0 +1,325 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Philip Withnall 2008 <philip tecnocode co uk>
+ * 
+ * Almanah 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Almanah 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 Almanah.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <string.h>
+
+#include "definition-manager-window.h"
+#include "main.h"
+#include "interface.h"
+#include "definition.h"
+#include "storage-manager.h"
+
+static void almanah_definition_manager_window_init (AlmanahDefinitionManagerWindow *self);
+static void almanah_definition_manager_window_dispose (GObject *object);
+static void definition_selection_changed_cb (GtkTreeSelection *tree_selection, AlmanahDefinitionManagerWindow *self);
+static void definition_added_cb (AlmanahStorageManager *storage_manager, AlmanahDefinition *definition, AlmanahDefinitionManagerWindow *self);
+static void definition_removed_cb (AlmanahStorageManager *storage_manager, const gchar *definition_text, AlmanahDefinitionManagerWindow *self);
+static void populate_definition_store (AlmanahDefinitionManagerWindow *self);
+
+struct _AlmanahDefinitionManagerWindowPrivate {
+	GtkLabel *name_label;
+	GtkLabel *description_label;
+	GtkListStore *definition_store;
+	GtkTreeSelection *definition_selection;
+	GtkButton *view_button;
+	GtkButton *remove_button;
+
+	AlmanahDefinition *current_definition;
+};
+
+G_DEFINE_TYPE (AlmanahDefinitionManagerWindow, almanah_definition_manager_window, GTK_TYPE_WINDOW)
+#define ALMANAH_DEFINITION_MANAGER_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ALMANAH_TYPE_DEFINITION_MANAGER_WINDOW, AlmanahDefinitionManagerWindowPrivate))
+
+static void
+almanah_definition_manager_window_class_init (AlmanahDefinitionManagerWindowClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	g_type_class_add_private (klass, sizeof (AlmanahDefinitionManagerWindowPrivate));
+	gobject_class->dispose = almanah_definition_manager_window_dispose;
+}
+
+static void
+almanah_definition_manager_window_init (AlmanahDefinitionManagerWindow *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ALMANAH_TYPE_DEFINITION_MANAGER_WINDOW, AlmanahDefinitionManagerWindowPrivate);
+
+	gtk_window_set_title (GTK_WINDOW (self), _("Definition Manager"));
+	gtk_window_set_default_size (GTK_WINDOW (self), 500, 400);
+	/*gtk_window_set_resizable (GTK_WINDOW (self), FALSE);*/
+}
+
+static gboolean
+definitions_dispose_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
+{
+	AlmanahDefinition *definition;
+
+	gtk_tree_model_get (model, iter, 0, &definition, -1);
+	g_object_unref (definition);
+
+	return TRUE;
+}
+
+static void
+almanah_definition_manager_window_dispose (GObject *object)
+{
+	AlmanahDefinitionManagerWindowPrivate *priv = ALMANAH_DEFINITION_MANAGER_WINDOW (object)->priv;
+
+	/* Unref the current definition */
+	if (priv->current_definition != NULL)
+		g_object_unref (priv->current_definition);
+	priv->current_definition = NULL;
+
+	/* Unref all the definitions in the store */
+	if (priv->definition_store != NULL) {
+		gtk_tree_model_foreach (GTK_TREE_MODEL (priv->definition_store), (GtkTreeModelForeachFunc) definitions_dispose_cb, NULL);
+	}
+	priv->definition_store = NULL;
+
+	/* Chain up to the parent class */
+	G_OBJECT_CLASS (almanah_definition_manager_window_parent_class)->dispose (object);
+}
+
+AlmanahDefinitionManagerWindow *
+almanah_definition_manager_window_new (void)
+{
+	GtkBuilder *builder;
+	AlmanahDefinitionManagerWindow *definition_manager_window;
+	AlmanahDefinitionManagerWindowPrivate *priv;
+	GError *error = NULL;
+	const gchar *interface_filename = almanah_get_interface_filename ();
+	const gchar *object_names[] = {
+		"almanah_definition_manager_window",
+		"almanah_dmw_definition_store",
+		"almanah_mw_view_button_image",
+		NULL
+	};
+
+	builder = gtk_builder_new ();
+
+	if (gtk_builder_add_objects_from_file (builder, interface_filename, (gchar**) object_names, &error) == FALSE) {
+		/* Show an error */
+		GtkWidget *dialog = gtk_message_dialog_new (NULL,
+				GTK_DIALOG_MODAL,
+				GTK_MESSAGE_ERROR,
+				GTK_BUTTONS_OK,
+				_("UI file \"%s\" could not be loaded"), interface_filename);
+		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+
+		g_error_free (error);
+		g_object_unref (builder);
+
+		return NULL;
+	}
+
+	gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE);
+	definition_manager_window = ALMANAH_DEFINITION_MANAGER_WINDOW (gtk_builder_get_object (builder, "almanah_definition_manager_window"));
+	gtk_builder_connect_signals (builder, definition_manager_window);
+
+	if (definition_manager_window == NULL) {
+		g_object_unref (builder);
+		return NULL;
+	}
+
+	priv = ALMANAH_DEFINITION_MANAGER_WINDOW (definition_manager_window)->priv;
+
+	/* Grab our child widgets */
+	priv->name_label = GTK_LABEL (gtk_builder_get_object (builder, "almanah_dmw_name_label"));
+	priv->description_label = GTK_LABEL (gtk_builder_get_object (builder, "almanah_dmw_description_label"));
+	priv->definition_store = GTK_LIST_STORE (gtk_builder_get_object (builder, "almanah_dmw_definition_store"));
+	priv->definition_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (gtk_builder_get_object (builder, "almanah_dmw_definition_tree_view")));
+	priv->view_button = GTK_BUTTON (gtk_builder_get_object (builder, "almanah_dmw_view_button"));
+	priv->remove_button = GTK_BUTTON (gtk_builder_get_object (builder, "almanah_dmw_remove_button"));
+
+	/* Prettify some labels */
+	almanah_interface_embolden_label (GTK_LABEL (gtk_builder_get_object (builder, "almanah_dmw_name_label_label")));
+	almanah_interface_embolden_label (GTK_LABEL (gtk_builder_get_object (builder, "almanah_dmw_description_label_label")));
+
+	/* Get notifications about added/removed definitions from the storage manager */
+	g_signal_connect (almanah->storage_manager, "definition-added", G_CALLBACK (definition_added_cb), definition_manager_window);
+	g_signal_connect (almanah->storage_manager, "definition-removed", G_CALLBACK (definition_removed_cb), definition_manager_window);
+
+	/* Set up the treeview */
+	g_signal_connect (priv->definition_selection, "changed", G_CALLBACK (definition_selection_changed_cb), definition_manager_window);
+
+	/* Populate the definition list store */
+	populate_definition_store (definition_manager_window);
+
+	g_object_unref (builder);
+
+	return definition_manager_window;
+}
+
+void
+dmw_definition_tree_view_row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, AlmanahDefinitionManagerWindow *self)
+{
+	g_assert (self->priv->current_definition != NULL);
+	almanah_definition_view (self->priv->current_definition);
+}
+
+void
+dmw_view_button_clicked_cb (GtkButton *button, AlmanahDefinitionManagerWindow *self)
+{
+	g_assert (self->priv->current_definition != NULL);
+	almanah_definition_view (self->priv->current_definition);
+}
+
+void
+dmw_remove_button_clicked_cb (GtkButton *button, AlmanahDefinitionManagerWindow *self)
+{
+	AlmanahDefinitionManagerWindowPrivate *priv = self->priv;
+	GtkWidget *dialog;
+
+	g_assert (priv->current_definition != NULL);
+
+	/* Check to see if it's really OK */
+	dialog = gtk_message_dialog_new (GTK_WINDOW (self),
+					 GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
+					 _("Are you sure you want to delete the definition for \"%s\"?"),
+					 almanah_definition_get_text (priv->current_definition));
+	gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+				GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+				GTK_STOCK_REMOVE, GTK_RESPONSE_ACCEPT,
+				NULL);
+
+	gtk_widget_show_all (dialog);
+	if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_ACCEPT) {
+		/* Cancelled the edit */
+		gtk_widget_destroy (dialog);
+		return;
+	}
+
+	gtk_widget_destroy (dialog);
+
+	/* Delete the definition */
+	almanah_storage_manager_remove_definition (almanah->storage_manager, almanah_definition_get_text (priv->current_definition));
+}
+
+static void
+definition_selection_changed_cb (GtkTreeSelection *tree_selection, AlmanahDefinitionManagerWindow *self)
+{
+	AlmanahDefinitionManagerWindowPrivate *priv = self->priv;
+	gboolean row_selected;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	AlmanahDefinition *definition;
+	gchar *blurb;
+
+	row_selected = gtk_tree_selection_get_selected (tree_selection, &model, &iter);
+
+	/* Change the sensitivity of the "View" and "Remove" buttons */
+	gtk_widget_set_sensitive (GTK_WIDGET (priv->view_button), row_selected);
+	gtk_widget_set_sensitive (GTK_WIDGET (priv->remove_button), row_selected);
+
+	/* Unset priv->current_definition */
+	if (priv->current_definition != NULL)
+		g_object_unref (priv->current_definition);
+	priv->current_definition = NULL;
+
+	/* If nothing's selected, reset the window and return */
+	if (row_selected == FALSE) {
+		gtk_label_set_text (priv->name_label, _("Nothing selected"));
+		gtk_label_set_text (priv->description_label, "");
+		return;
+	}
+
+	/* Set the new priv->current_definition */
+	gtk_tree_model_get (model, &iter, 0, &definition, -1);
+	priv->current_definition = g_object_ref (definition);
+
+	/* Display information about the selected definition */
+	gtk_label_set_text (priv->name_label, almanah_definition_get_name (definition));
+	blurb = almanah_definition_get_blurb (definition);
+	gtk_label_set_text (priv->description_label, blurb);
+	g_free (blurb);
+}
+
+static void
+definition_added_cb (AlmanahStorageManager *storage_manager, AlmanahDefinition *definition, AlmanahDefinitionManagerWindow *self)
+{
+	AlmanahDefinitionManagerWindowPrivate *priv = self->priv;
+	GtkTreeIter iter;
+
+	/* Make sure we get a reference to the definition */
+	g_object_ref (definition);
+
+	gtk_list_store_append (priv->definition_store, &iter);
+	gtk_list_store_set (priv->definition_store, &iter,
+			    0, definition,
+			    1, almanah_definition_get_text (definition),
+			    -1);
+}
+
+static void
+definition_removed_cb (AlmanahStorageManager *storage_manager, const gchar *definition_text, AlmanahDefinitionManagerWindow *self)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	gboolean valid_iter;
+
+	model = GTK_TREE_MODEL (self->priv->definition_store);
+	if (gtk_tree_model_get_iter_first (model, &iter) == FALSE)
+		return;
+
+	do {
+		gchar *model_definition_text;
+		GtkTreeIter next_iter;
+
+		/* Get the next row ready */
+		next_iter = iter;
+		valid_iter = gtk_tree_model_iter_next (model, &next_iter);
+
+		/* Remove the current row if it has the correct definition text, then break */
+		gtk_tree_model_get (model, &iter, 1, &model_definition_text, -1);
+		if (strcmp (model_definition_text, definition_text) == 0) {
+			gtk_list_store_remove (self->priv->definition_store, &iter);
+			valid_iter = FALSE;
+		}
+		g_free (model_definition_text);
+
+		iter = next_iter;
+	} while (valid_iter == TRUE);
+}
+
+static void
+populate_definition_store (AlmanahDefinitionManagerWindow *self)
+{
+	AlmanahDefinitionManagerWindowPrivate *priv = self->priv;
+	AlmanahDefinition **definitions;
+	guint i = 0;
+
+	definitions = almanah_storage_manager_get_definitions (almanah->storage_manager);
+	while (definitions[i] != NULL) {
+		GtkTreeIter iter;
+
+		gtk_list_store_append (priv->definition_store, &iter);
+		gtk_list_store_set (priv->definition_store, &iter,
+				    0, definitions[i],
+				    1, almanah_definition_get_text (definitions[i]),
+				    -1);
+
+		i++;
+	}
+	g_free (definitions);
+}

Added: trunk/src/definition-manager-window.h
==============================================================================
--- (empty file)
+++ trunk/src/definition-manager-window.h	Sat Dec 13 18:35:02 2008
@@ -0,0 +1,51 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Philip Withnall 2008 <philip tecnocode co uk>
+ * 
+ * Almanah 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Almanah 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 Almanah.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ALMANAH_DEFINITION_MANAGER_WINDOW_H
+#define ALMANAH_DEFINITION_MANAGER_WINDOW_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define ALMANAH_TYPE_DEFINITION_MANAGER_WINDOW		(almanah_definition_manager_window_get_type ())
+#define ALMANAH_DEFINITION_MANAGER_WINDOW(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), ALMANAH_TYPE_DEFINITION_MANAGER_WINDOW, AlmanahDefinitionManagerWindow))
+#define ALMANAH_DEFINITION_MANAGER_WINDOW_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), ALMANAH_TYPE_DEFINITION_MANAGER_WINDOW, AlmanahDefinitionManagerWindowClass))
+#define ALMANAH_IS_DEFINITION_MANAGER_WINDOW(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), ALMANAH_TYPE_DEFINITION_MANAGER_WINDOW))
+#define ALMANAH_IS_DEFINITION_MANAGER_WINDOW_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), ALMANAH_TYPE_DEFINITION_MANAGER_WINDOW))
+#define ALMANAH_DEFINITION_MANAGER_WINDOW_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), ALMANAH_TYPE_DEFINITION_MANAGER_WINDOW, AlmanahDefinitionManagerWindowClass))
+
+typedef struct _AlmanahDefinitionManagerWindowPrivate	AlmanahDefinitionManagerWindowPrivate;
+
+typedef struct {
+	GtkWindow parent;
+	AlmanahDefinitionManagerWindowPrivate *priv;
+} AlmanahDefinitionManagerWindow;
+
+typedef struct {
+	GtkWindowClass parent;
+} AlmanahDefinitionManagerWindowClass;
+
+GType almanah_definition_manager_window_get_type (void);
+AlmanahDefinitionManagerWindow *almanah_definition_manager_window_new (void);
+
+G_END_DECLS
+
+#endif /* !ALMANAH_DEFINITION_MANAGER_WINDOW_H */

Modified: trunk/src/definition.c
==============================================================================
--- trunk/src/definition.c	(original)
+++ trunk/src/definition.c	Sat Dec 13 18:35:02 2008
@@ -259,6 +259,14 @@
 	return klass->parse_text (self, text);
 }
 
+gchar *
+almanah_definition_get_blurb (AlmanahDefinition *self)
+{
+	AlmanahDefinitionClass *klass = ALMANAH_DEFINITION_GET_CLASS (self);
+	g_assert (klass->get_blurb != NULL);
+	return klass->get_blurb (self);
+}
+
 const gchar *
 almanah_definition_get_text (AlmanahDefinition *self)
 {

Modified: trunk/src/definition.h
==============================================================================
--- trunk/src/definition.h	(original)
+++ trunk/src/definition.h	Sat Dec 13 18:35:02 2008
@@ -59,6 +59,7 @@
 	void (*build_dialog) (AlmanahDefinition *definition, GtkVBox *parent_vbox);
 	void (*close_dialog) (AlmanahDefinition *definition, GtkVBox *parent_vbox);
 	void (*parse_text) (AlmanahDefinition *definition, const gchar *text);
+	gchar *(*get_blurb) (AlmanahDefinition *definition);
 } AlmanahDefinitionClass;
 
 GType almanah_definition_get_type (void);
@@ -74,6 +75,7 @@
 void almanah_definition_build_dialog (AlmanahDefinition *self, GtkVBox *parent_vbox);
 void almanah_definition_close_dialog (AlmanahDefinition *self, GtkVBox *parent_vbox);
 void almanah_definition_parse_text (AlmanahDefinition *self, const gchar *text);
+gchar *almanah_definition_get_blurb (AlmanahDefinition *self);
 
 const gchar *almanah_definition_get_text (AlmanahDefinition *self);
 void almanah_definition_set_text (AlmanahDefinition *self, const gchar *text);

Modified: trunk/src/definitions/file.c
==============================================================================
--- trunk/src/definitions/file.c	(original)
+++ trunk/src/definitions/file.c	Sat Dec 13 18:35:02 2008
@@ -29,6 +29,7 @@
 static void file_build_dialog (AlmanahDefinition *definition, GtkVBox *parent_vbox);
 static void file_close_dialog (AlmanahDefinition *definition, GtkVBox *parent_vbox);
 static void file_parse_text (AlmanahDefinition *definition, const gchar *text);
+static gchar *file_get_blurb (AlmanahDefinition *definition);
 
 struct _AlmanahFileDefinitionPrivate {
 	GtkWidget *chooser;
@@ -53,6 +54,7 @@
 	definition_class->build_dialog = file_build_dialog;
 	definition_class->close_dialog = file_close_dialog;
 	definition_class->parse_text = file_parse_text;
+	definition_class->get_blurb = file_get_blurb;
 }
 
 static void
@@ -116,3 +118,9 @@
 {
 	/* TODO */
 }
+
+static gchar *
+file_get_blurb (AlmanahDefinition *definition)
+{
+	return g_strdup (almanah_definition_get_value (definition));
+}

Modified: trunk/src/definitions/note.c
==============================================================================
--- trunk/src/definitions/note.c	(original)
+++ trunk/src/definitions/note.c	Sat Dec 13 18:35:02 2008
@@ -30,6 +30,7 @@
 static void note_build_dialog (AlmanahDefinition *definition, GtkVBox *parent_vbox);
 static void note_close_dialog (AlmanahDefinition *definition, GtkVBox *parent_vbox);
 static void note_parse_text (AlmanahDefinition *definition, const gchar *text);
+static gchar *note_get_blurb (AlmanahDefinition *definition);
 
 struct _AlmanahNoteDefinitionPrivate {
 	GtkWidget *text_view;
@@ -54,6 +55,7 @@
 	definition_class->build_dialog = note_build_dialog;
 	definition_class->close_dialog = note_close_dialog;
 	definition_class->parse_text = note_parse_text;
+	definition_class->get_blurb = note_get_blurb;
 }
 
 static void
@@ -127,3 +129,9 @@
 {
 	/* TODO */
 }
+
+static gchar *
+note_get_blurb (AlmanahDefinition *definition)
+{
+	return g_strdup (almanah_definition_get_value (definition));
+}

Modified: trunk/src/definitions/uri.c
==============================================================================
--- trunk/src/definitions/uri.c	(original)
+++ trunk/src/definitions/uri.c	Sat Dec 13 18:35:02 2008
@@ -31,6 +31,7 @@
 static void uri_build_dialog (AlmanahDefinition *definition, GtkVBox *parent_vbox);
 static void uri_close_dialog (AlmanahDefinition *definition, GtkVBox *parent_vbox);
 static void uri_parse_text (AlmanahDefinition *definition, const gchar *text);
+static gchar *uri_get_blurb (AlmanahDefinition *definition);
 
 struct _AlmanahURIDefinitionPrivate {
 	GtkWidget *entry;
@@ -55,6 +56,7 @@
 	definition_class->build_dialog = uri_build_dialog;
 	definition_class->close_dialog = uri_close_dialog;
 	definition_class->parse_text = uri_parse_text;
+	definition_class->get_blurb = uri_get_blurb;
 }
 
 static void
@@ -131,3 +133,9 @@
 {
 	/* TODO */
 }
+
+static gchar *
+uri_get_blurb (AlmanahDefinition *definition)
+{
+	return g_strdup (almanah_definition_get_value (definition));
+}

Modified: trunk/src/interface.c
==============================================================================
--- trunk/src/interface.c	(original)
+++ trunk/src/interface.c	Sat Dec 13 18:35:02 2008
@@ -90,8 +90,11 @@
 	definition = almanah_storage_manager_get_definition (almanah->storage_manager, text);
 	g_free (text);
 
-	if (definition == NULL)
+	if (definition == NULL) {
+		/* If the definition no longer exists, remove the tag */
+		gtk_text_buffer_remove_tag (gtk_text_iter_get_buffer (iter), tag, &start_iter, &end_iter);
 		return FALSE;
+	}
 
 	return almanah_definition_view (definition);
 }

Modified: trunk/src/main-window.c
==============================================================================
--- trunk/src/main-window.c	(original)
+++ trunk/src/main-window.c	Sat Dec 13 18:35:02 2008
@@ -35,6 +35,7 @@
 #include "storage-manager.h"
 #include "event.h"
 #include "definition.h"
+#include "definition-manager-window.h"
 
 static void almanah_main_window_init (AlmanahMainWindow *self);
 static void almanah_main_window_dispose (GObject *object);
@@ -45,6 +46,7 @@
 static void mw_entry_buffer_insert_text_cb (GtkTextBuffer *text_buffer, GtkTextIter *start, gchar *text, gint len, AlmanahMainWindow *main_window);
 static void mw_entry_buffer_insert_text_after_cb (GtkTextBuffer *text_buffer, GtkTextIter *start, gchar *text, gint len, AlmanahMainWindow *main_window);
 static void mw_entry_buffer_has_selection_cb (GObject *object, GParamSpec *pspec, AlmanahMainWindow *main_window);
+static void mw_entry_buffer_apply_tag_cb (GtkTextBuffer *buffer, GtkTextTag *tag, GtkTextIter *start_iter, GtkTextIter *end_iter, AlmanahMainWindow *main_window);
 static void mw_bold_toggled_cb (GtkToggleAction *action, AlmanahMainWindow *main_window);
 static void mw_italic_toggled_cb (GtkToggleAction *action, AlmanahMainWindow *main_window);
 static void mw_underline_toggled_cb (GtkToggleAction *action, AlmanahMainWindow *main_window);
@@ -52,6 +54,7 @@
 void mw_calendar_day_selected_cb (GtkCalendar *calendar, AlmanahMainWindow *main_window);
 static void mw_events_selection_changed_cb (GtkTreeSelection *tree_selection, AlmanahMainWindow *main_window);
 static void mw_events_value_data_cb (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data);
+static void mw_definition_removed_cb (AlmanahStorageManager *storage_manager, const gchar *definition_text, AlmanahMainWindow *main_window);
 
 struct _AlmanahMainWindowPrivate {
 	GtkTextView *entry_view;
@@ -105,10 +108,9 @@
 {
 	AlmanahMainWindowPrivate *priv = ALMANAH_MAIN_WINDOW (object)->priv;
 
-	if (priv->current_entry != NULL) {
+	if (priv->current_entry != NULL)
 		g_object_unref (priv->current_entry);
-		priv->current_entry = NULL;
-	}
+	priv->current_entry = NULL;
 
 	/* Chain up to the parent class */
 	G_OBJECT_CLASS (almanah_main_window_parent_class)->dispose (object);
@@ -222,6 +224,9 @@
 	/* Similarly, make sure we're notified when there's a selection so we can change the status of cut/copy/paste actions */
 	g_signal_connect (priv->entry_buffer, "notify::has-selection", G_CALLBACK (mw_entry_buffer_has_selection_cb), main_window);
 
+	/* Get notified of applied tags so we can check if referenced definitions still exist */
+	g_signal_connect_after (priv->entry_buffer, "apply-tag", G_CALLBACK (mw_entry_buffer_apply_tag_cb), main_window);
+
 	/* Connect up the formatting actions */
 	g_signal_connect (priv->bold_action, "toggled", G_CALLBACK (mw_bold_toggled_cb), main_window);
 	g_signal_connect (priv->italic_action, "toggled", G_CALLBACK (mw_italic_toggled_cb), main_window);
@@ -230,6 +235,9 @@
 	/* Notification for event changes */
 	g_signal_connect (almanah->event_manager, "events-updated", G_CALLBACK (mw_events_updated_cb), main_window);
 
+	/* Notification for changes to definitions in the database */
+	g_signal_connect (almanah->storage_manager, "definition-removed", G_CALLBACK (mw_definition_removed_cb), main_window);
+
 	/* Select the current day and month */
 	almanah_calendar_month_changed_cb (priv->calendar, NULL);
 	mw_calendar_day_selected_cb (priv->calendar, main_window);
@@ -628,6 +636,33 @@
 	gtk_action_set_sensitive (main_window->priv->delete_action, has_selection);
 }
 
+static void
+mw_entry_buffer_apply_tag_cb (GtkTextBuffer *buffer, GtkTextTag *tag, GtkTextIter *start_iter, GtkTextIter *end_iter, AlmanahMainWindow *main_window)
+{
+	gchar *name;
+
+	g_object_get (G_OBJECT (tag), "name", &name, NULL);
+	if (strcmp (name, "definition") == 0) {
+		AlmanahDefinition *definition;
+		gchar *definition_text;
+
+		/* Check to see if the definition still exists in the DB */
+		definition_text = gtk_text_buffer_get_text (buffer, start_iter, end_iter, FALSE);
+		definition = almanah_storage_manager_get_definition (almanah->storage_manager, definition_text);
+		g_free (definition_text);
+
+		/* If the definition doesn't exist, remove the tag */
+		if (definition == NULL) {
+			gtk_text_buffer_remove_tag (buffer, tag, start_iter, end_iter);
+			gtk_text_buffer_set_modified (buffer, TRUE);
+		} else {
+			g_object_unref (definition);
+		}
+	}
+
+	g_free (name);
+}
+
 static gboolean
 mw_delete_event_cb (GtkWindow *window, gpointer user_data)
 {
@@ -808,6 +843,15 @@
 	remove_definition_from_current_entry (main_window);
 }
 
+void
+mw_view_definitions_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
+{
+	GtkWidget *definition_manager_window;
+
+	definition_manager_window = GTK_WIDGET (almanah_definition_manager_window_new ());
+	gtk_widget_show_all (definition_manager_window);
+}
+
 static void
 clear_factory_events (AlmanahMainWindow *self, AlmanahEventFactoryType type_id)
 {
@@ -1022,3 +1066,11 @@
 
 	g_list_free (events);
 }
+
+static void
+mw_definition_removed_cb (AlmanahStorageManager *storage_manager, const gchar *definition_text, AlmanahMainWindow *main_window)
+{
+	/* We need to remove any definition tags in the current entry which match @definition_text. It's
+	 * probably easier to just reload the current entry, though. */
+	mw_calendar_day_selected_cb (main_window->priv->calendar, main_window);
+}

Modified: trunk/src/main-window.h
==============================================================================
--- trunk/src/main-window.h	(original)
+++ trunk/src/main-window.h	Sat Dec 13 18:35:02 2008
@@ -45,7 +45,6 @@
 
 GType almanah_main_window_get_type (void);
 AlmanahMainWindow *almanah_main_window_new (void);
-void almanah_main_window_setup (AlmanahMainWindow *self, GtkBuilder *builder);
 void almanah_main_window_select_date (AlmanahMainWindow *self, GDate *date);
 
 G_END_DECLS

Modified: trunk/src/storage-manager.c
==============================================================================
--- trunk/src/storage-manager.c	(original)
+++ trunk/src/storage-manager.c	Sat Dec 13 18:35:02 2008
@@ -676,7 +676,7 @@
 
 /**
  * almanah_storage_manager_get_entry:
- * @self: a #AlmanahStorageManager
+ * @self: an #AlmanahStorageManager
  * @date: the date of the entry
  *
  * Gets the entry for the specified day from the database.
@@ -724,7 +724,7 @@
 
 /**
  * almanah_storage_manager_set_entry:
- * @self: a #AlmanahStorageManager
+ * @self: an #AlmanahStorageManager
  * @entry: an #AlmanahEntry
  *
  * Saves the specified @entry in the database synchronously.
@@ -787,7 +787,7 @@
 
 /**
  * almanah_storage_manager_search_entries:
- * @self: a #AlmanahStorageManager
+ * @self: an #AlmanahStorageManager
  * @search_string: string for which to search in entry content
  * @matches: return location for the results
  *
@@ -881,7 +881,19 @@
 	return days;
 }
 
-/* NOTE: Free array with g_free and each element with g_object_unref */
+/**
+ * almanah_storage_manager_get_definitions:
+ * @self: an #AlmanahStorageManager
+ *
+ * Returns a %NULL-terminated array of all the #AlmanahDefinitions in the
+ * database. Each #AlmanahDefinition should be unreffed, and the array should
+ * be freed with g_free().
+ *
+ * On error, an array with a single %NULL element will be returned. The array
+ * should still be freed with g_free().
+ *
+ * Return value: a %NULL-terminated array of #AlmanahDefinitions
+ **/
 AlmanahDefinition **
 almanah_storage_manager_get_definitions (AlmanahStorageManager *self)
 {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]