Revision: 1525
http://geeqie.svn.sourceforge.net/geeqie/?rev=1525&view=rev
Author: nadvornik
Date: 2009-03-13 23:19:58 +0000 (Fri, 13 Mar 2009)
Log Message:
-----------
do not allow to add keywords with the same name as siblings
Modified Paths:
--------------
trunk/src/bar_keywords.c
trunk/src/metadata.c
trunk/src/metadata.h
Modified: trunk/src/bar_keywords.c
===================================================================
--- trunk/src/bar_keywords.c 2009-03-13 16:45:21 UTC (rev 1524)
+++ trunk/src/bar_keywords.c 2009-03-13 23:19:58 UTC (rev 1525)
@@ -514,6 +514,53 @@
{
}
+
+static gboolean bar_pane_keywords_dnd_can_move(GtkTreeModel *keyword_tree,
GtkTreeIter *src_kw_iter, GtkTreeIter *dest_kw_iter)
+{
+ gchar *src_name;
+ GtkTreeIter parent;
+
+ if (dest_kw_iter && keyword_same_parent(keyword_tree, src_kw_iter,
dest_kw_iter))
+ {
+ return TRUE; /* reordering of siblings is ok */
+ }
+ if (!dest_kw_iter && !gtk_tree_model_iter_parent(keyword_tree, &parent,
src_kw_iter))
+ {
+ return TRUE; /* reordering of top-level siblings is ok */
+ }
+
+ src_name = keyword_get_name(keyword_tree, src_kw_iter);
+ if (keyword_exists(keyword_tree, NULL, dest_kw_iter, src_name, FALSE))
+ {
+ g_free(src_name);
+ return FALSE;
+ }
+ g_free(src_name);
+ return TRUE;
+}
+
+static gboolean bar_pane_keywords_dnd_skip_existing(GtkTreeModel
*keyword_tree, GtkTreeIter *dest_kw_iter, GList **keywords)
+{
+ /* we have to find at least one keyword that does not already exist as
a sibling of dest_kw_iter */
+ GList *work = *keywords;
+ while (work)
+ {
+ gchar *keyword = work->data;
+ if (keyword_exists(keyword_tree, NULL, dest_kw_iter, keyword,
FALSE))
+ {
+ GList *next = work->next;
+ g_free(keyword);
+ *keywords = g_list_delete_link(*keywords, work);
+ work = next;
+ }
+ else
+ {
+ work = work->next;
+ }
+ }
+ return !!*keywords;
+}
+
static void bar_pane_keywords_dnd_receive(GtkWidget *tree_view, GdkDragContext
*context,
gint x, gint y,
GtkSelectionData *selection_data,
guint info,
@@ -580,10 +627,22 @@
if ((pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE || pos ==
GTK_TREE_VIEW_DROP_INTO_OR_AFTER) &&
!gtk_tree_model_iter_has_child(keyword_tree, &dest_kw_iter))
{
+ /* the node has no children, all keywords can be added
*/
gtk_tree_store_append(GTK_TREE_STORE(keyword_tree),
&new_kw_iter, &dest_kw_iter);
}
else
{
+ if (src_valid &&
!bar_pane_keywords_dnd_can_move(keyword_tree, &src_kw_iter, &dest_kw_iter))
+ {
+ /* the keyword can't be moved if the same name
already exist */
+ return;
+ }
+ if (new_keywords &&
!bar_pane_keywords_dnd_skip_existing(keyword_tree, &dest_kw_iter,
&new_keywords))
+ {
+ /* the keywords can't be added if the same name
already exist */
+ return;
+ }
+
switch (pos)
{
case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
@@ -596,9 +655,20 @@
break;
}
}
+
}
else
{
+ if (src_valid && !bar_pane_keywords_dnd_can_move(keyword_tree,
&src_kw_iter, NULL))
+ {
+ /* the keyword can't be moved if the same name already
exist */
+ return;
+ }
+ if (new_keywords &&
!bar_pane_keywords_dnd_skip_existing(keyword_tree, NULL, &new_keywords))
+ {
+ /* the keywords can't be added if the same name already
exist */
+ return;
+ }
gtk_tree_store_append(GTK_TREE_STORE(keyword_tree),
&new_kw_iter, NULL);
}
@@ -611,8 +681,10 @@
work = new_keywords;
while (work)
{
- keyword_set(GTK_TREE_STORE(keyword_tree), &new_kw_iter,
work->data, TRUE);
+ gchar *keyword = work->data;
+ keyword_set(GTK_TREE_STORE(keyword_tree), &new_kw_iter,
keyword, TRUE);
work = work->next;
+
if (work)
{
GtkTreeIter add;
@@ -705,7 +777,8 @@
if (cdd->edit_existing)
{
- if (keywords && keywords->data) /* there should be one keyword
*/
+ if (keywords && keywords->data && /* there should be one
keyword */
+ !keyword_exists(keyword_tree, NULL, &kw_iter,
keywords->data, TRUE))
{
keyword_set(GTK_TREE_STORE(keyword_tree), &kw_iter,
keywords->data, cdd->is_keyword);
}
@@ -717,6 +790,11 @@
while (work)
{
GtkTreeIter add;
+ if (keyword_exists(keyword_tree, NULL, have_dest ?
&kw_iter : NULL, work->data, FALSE))
+ {
+ work = work->next;
+ continue;
+ }
if (have_dest)
{
gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &add, NULL, &kw_iter);
Modified: trunk/src/metadata.c
===================================================================
--- trunk/src/metadata.c 2009-03-13 16:45:21 UTC (rev 1524)
+++ trunk/src/metadata.c 2009-03-13 23:19:58 UTC (rev 1525)
@@ -765,6 +765,66 @@
return ret;
}
+gboolean keyword_same_parent(GtkTreeModel *keyword_tree, GtkTreeIter *a,
GtkTreeIter *b)
+{
+ GtkTreeIter parent_a;
+ GtkTreeIter parent_b;
+
+ gboolean valid_pa = gtk_tree_model_iter_parent(keyword_tree, &parent_a,
a);
+ gboolean valid_pb = gtk_tree_model_iter_parent(keyword_tree, &parent_b,
b);
+
+ if (valid_pa && valid_pb)
+ {
+ return keyword_compare(keyword_tree, &parent_a, &parent_b) == 0;
+ }
+ else
+ {
+ return (!valid_pa && !valid_pb); /* both are toplevel */
+ }
+}
+
+gboolean keyword_exists(GtkTreeModel *keyword_tree, GtkTreeIter *parent_ptr,
GtkTreeIter *sibling, const gchar *name, gboolean exclude_sibling)
+{
+ GtkTreeIter parent;
+ GtkTreeIter iter;
+ gboolean toplevel = FALSE;
+ gboolean ret;
+ gchar *casefold;
+
+ if (parent_ptr)
+ {
+ parent = *parent_ptr;
+ }
+ else if (sibling)
+ {
+ toplevel = !gtk_tree_model_iter_parent(keyword_tree, &parent,
sibling);
+ }
+ else
+ {
+ toplevel = TRUE;
+ }
+
+ if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(keyword_tree), &iter,
toplevel ? NULL : &parent)) return FALSE;
+
+ casefold = g_utf8_casefold(name, -1);
+ ret = FALSE;
+
+ while (TRUE)
+ {
+ if (!(exclude_sibling && sibling &&
keyword_compare(keyword_tree, &iter, sibling) == 0))
+ {
+ gchar *iter_casefold =
keyword_get_casefold(keyword_tree, &iter);
+ ret = strcmp(casefold, iter_casefold) == 0;
+ g_free(iter_casefold);
+ }
+ if (ret) break;
+ if (!gtk_tree_model_iter_next(keyword_tree, &iter)) break;
+ }
+ g_free(casefold);
+ return ret;
+}
+
+
void keyword_copy(GtkTreeStore *keyword_tree, GtkTreeIter *to, GtkTreeIter
*from)
{
Modified: trunk/src/metadata.h
===================================================================
--- trunk/src/metadata.h 2009-03-13 16:45:21 UTC (rev 1524)
+++ trunk/src/metadata.h 2009-03-13 23:19:58 UTC (rev 1525)
@@ -60,6 +60,8 @@
gboolean keyword_get_is_keyword(GtkTreeModel *keyword_tree, GtkTreeIter *iter);
gboolean keyword_compare(GtkTreeModel *keyword_tree, GtkTreeIter *a,
GtkTreeIter *b);
+gboolean keyword_same_parent(GtkTreeModel *keyword_tree, GtkTreeIter *a,
GtkTreeIter *b);
+gboolean keyword_exists(GtkTreeModel *keyword_tree, GtkTreeIter *parent_ptr,
GtkTreeIter *sibling, const gchar *name, gboolean exclude_sibling);
void keyword_copy(GtkTreeStore *keyword_tree, GtkTreeIter *to, GtkTreeIter
*from);
void keyword_copy_recursive(GtkTreeStore *keyword_tree, GtkTreeIter *to,
GtkTreeIter *from);
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________
Geeqie-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geeqie-svn