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

Reply via email to