comparison src/bar_keywords.c @ 1429:985366bccfb8

do not allow to add keywords with the same name as siblings
author nadvornik
date Fri, 13 Mar 2009 23:19:58 +0000
parents 3019f5d3a3c7
children 7718e351bc45
comparison
equal deleted inserted replaced
1428:3019f5d3a3c7 1429:985366bccfb8
512 512
513 static void bar_pane_keywords_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data) 513 static void bar_pane_keywords_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data)
514 { 514 {
515 } 515 }
516 516
517
518 static gboolean bar_pane_keywords_dnd_can_move(GtkTreeModel *keyword_tree, GtkTreeIter *src_kw_iter, GtkTreeIter *dest_kw_iter)
519 {
520 gchar *src_name;
521 GtkTreeIter parent;
522
523 if (dest_kw_iter && keyword_same_parent(keyword_tree, src_kw_iter, dest_kw_iter))
524 {
525 return TRUE; /* reordering of siblings is ok */
526 }
527 if (!dest_kw_iter && !gtk_tree_model_iter_parent(keyword_tree, &parent, src_kw_iter))
528 {
529 return TRUE; /* reordering of top-level siblings is ok */
530 }
531
532 src_name = keyword_get_name(keyword_tree, src_kw_iter);
533 if (keyword_exists(keyword_tree, NULL, dest_kw_iter, src_name, FALSE))
534 {
535 g_free(src_name);
536 return FALSE;
537 }
538 g_free(src_name);
539 return TRUE;
540 }
541
542 static gboolean bar_pane_keywords_dnd_skip_existing(GtkTreeModel *keyword_tree, GtkTreeIter *dest_kw_iter, GList **keywords)
543 {
544 /* we have to find at least one keyword that does not already exist as a sibling of dest_kw_iter */
545 GList *work = *keywords;
546 while (work)
547 {
548 gchar *keyword = work->data;
549 if (keyword_exists(keyword_tree, NULL, dest_kw_iter, keyword, FALSE))
550 {
551 GList *next = work->next;
552 g_free(keyword);
553 *keywords = g_list_delete_link(*keywords, work);
554 work = next;
555 }
556 else
557 {
558 work = work->next;
559 }
560 }
561 return !!*keywords;
562 }
563
517 static void bar_pane_keywords_dnd_receive(GtkWidget *tree_view, GdkDragContext *context, 564 static void bar_pane_keywords_dnd_receive(GtkWidget *tree_view, GdkDragContext *context,
518 gint x, gint y, 565 gint x, gint y,
519 GtkSelectionData *selection_data, guint info, 566 GtkSelectionData *selection_data, guint info,
520 guint time, gpointer data) 567 guint time, gpointer data)
521 { 568 {
578 } 625 }
579 626
580 if ((pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) && 627 if ((pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) &&
581 !gtk_tree_model_iter_has_child(keyword_tree, &dest_kw_iter)) 628 !gtk_tree_model_iter_has_child(keyword_tree, &dest_kw_iter))
582 { 629 {
630 /* the node has no children, all keywords can be added */
583 gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &new_kw_iter, &dest_kw_iter); 631 gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &new_kw_iter, &dest_kw_iter);
584 } 632 }
585 else 633 else
586 { 634 {
635 if (src_valid && !bar_pane_keywords_dnd_can_move(keyword_tree, &src_kw_iter, &dest_kw_iter))
636 {
637 /* the keyword can't be moved if the same name already exist */
638 return;
639 }
640 if (new_keywords && !bar_pane_keywords_dnd_skip_existing(keyword_tree, &dest_kw_iter, &new_keywords))
641 {
642 /* the keywords can't be added if the same name already exist */
643 return;
644 }
645
587 switch (pos) 646 switch (pos)
588 { 647 {
589 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: 648 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
590 case GTK_TREE_VIEW_DROP_BEFORE: 649 case GTK_TREE_VIEW_DROP_BEFORE:
591 gtk_tree_store_insert_before(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL, &dest_kw_iter); 650 gtk_tree_store_insert_before(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL, &dest_kw_iter);
594 case GTK_TREE_VIEW_DROP_AFTER: 653 case GTK_TREE_VIEW_DROP_AFTER:
595 gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL, &dest_kw_iter); 654 gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL, &dest_kw_iter);
596 break; 655 break;
597 } 656 }
598 } 657 }
658
599 } 659 }
600 else 660 else
601 { 661 {
662 if (src_valid && !bar_pane_keywords_dnd_can_move(keyword_tree, &src_kw_iter, NULL))
663 {
664 /* the keyword can't be moved if the same name already exist */
665 return;
666 }
667 if (new_keywords && !bar_pane_keywords_dnd_skip_existing(keyword_tree, NULL, &new_keywords))
668 {
669 /* the keywords can't be added if the same name already exist */
670 return;
671 }
602 gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL); 672 gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL);
603 } 673 }
604 674
605 675
606 if (src_valid) 676 if (src_valid)
609 } 679 }
610 680
611 work = new_keywords; 681 work = new_keywords;
612 while (work) 682 while (work)
613 { 683 {
614 keyword_set(GTK_TREE_STORE(keyword_tree), &new_kw_iter, work->data, TRUE); 684 gchar *keyword = work->data;
685 keyword_set(GTK_TREE_STORE(keyword_tree), &new_kw_iter, keyword, TRUE);
615 work = work->next; 686 work = work->next;
687
616 if (work) 688 if (work)
617 { 689 {
618 GtkTreeIter add; 690 GtkTreeIter add;
619 gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &add, NULL, &new_kw_iter); 691 gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &add, NULL, &new_kw_iter);
620 new_kw_iter = add; 692 new_kw_iter = add;
703 775
704 keywords = keyword_list_pull(cdd->edit_widget); 776 keywords = keyword_list_pull(cdd->edit_widget);
705 777
706 if (cdd->edit_existing) 778 if (cdd->edit_existing)
707 { 779 {
708 if (keywords && keywords->data) /* there should be one keyword */ 780 if (keywords && keywords->data && /* there should be one keyword */
781 !keyword_exists(keyword_tree, NULL, &kw_iter, keywords->data, TRUE))
709 { 782 {
710 keyword_set(GTK_TREE_STORE(keyword_tree), &kw_iter, keywords->data, cdd->is_keyword); 783 keyword_set(GTK_TREE_STORE(keyword_tree), &kw_iter, keywords->data, cdd->is_keyword);
711 } 784 }
712 } 785 }
713 else 786 else
715 GList *work = keywords; 788 GList *work = keywords;
716 789
717 while (work) 790 while (work)
718 { 791 {
719 GtkTreeIter add; 792 GtkTreeIter add;
793 if (keyword_exists(keyword_tree, NULL, have_dest ? &kw_iter : NULL, work->data, FALSE))
794 {
795 work = work->next;
796 continue;
797 }
720 if (have_dest) 798 if (have_dest)
721 { 799 {
722 gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &add, NULL, &kw_iter); 800 gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &add, NULL, &kw_iter);
723 } 801 }
724 else 802 else