Cleanup: Remove more #if 0 blocks
[blender.git] / source / blender / blenkernel / intern / library.c
index 04ebaaf..a34ebcd 100644 (file)
@@ -289,7 +289,7 @@ static int id_expand_local_callback(
                return IDWALK_RET_NOP;
        }
 
-       /* Can hapen that we get unlinkable ID here, e.g. with shapekey referring to itself (through drivers)...
+       /* Can happen that we get unlinkable ID here, e.g. with shapekey referring to itself (through drivers)...
         * Just skip it, shape key can only be either indirectly linked, or fully local, period.
         * And let's curse one more time that stupid useless shapekey ID type! */
        if (*id_pointer && *id_pointer != id_self && BKE_idcode_is_linkable(GS((*id_pointer)->name))) {
@@ -1373,6 +1373,9 @@ void BKE_libblock_init_empty(ID *id)
                        /* Should not be needed - animation from lib pre-2.5 is broken anyway. */
                        BLI_assert(0);
                        break;
+               case ID_PAL:
+                       BKE_palette_init((Palette *)id);
+                       break;
                default:
                        BLI_assert(0);  /* Should never reach this point... */
        }
@@ -1437,7 +1440,7 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int fla
        BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || bmain != NULL);
        BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || (flag & LIB_ID_CREATE_NO_ALLOCATE) == 0);
        BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) == 0 || (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) != 0);
-       /* Never implicitely copy shapekeys when generating temp data outside of Main database. */
+       /* Never implicitly copy shapekeys when generating temp data outside of Main database. */
        BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) == 0 || (flag & LIB_ID_COPY_SHAPEKEY) == 0);
 
        if ((flag & LIB_ID_CREATE_NO_ALLOCATE) != 0) {
@@ -1979,15 +1982,6 @@ bool new_id(ListBase *lb, ID *id, const char *tname)
        result = check_for_dupid(lb, id, name);
        strcpy(id->name + 2, name);
 
-       /* This was in 2.43 and previous releases
-        * however all data in blender should be sorted, not just duplicate names
-        * sorting should not hurt, but noting just incase it alters the way other
-        * functions work, so sort every time */
-#if 0
-       if (result)
-               id_sort_by_name(lb, id);
-#endif
-
        id_sort_by_name(lb, id);
 
        return result;
@@ -2596,3 +2590,98 @@ bool BKE_id_is_in_gobal_main(ID *id)
        /* We do not want to fail when id is NULL here, even though this is a bit strange behavior... */
        return (id == NULL || BLI_findindex(which_libbase(G_MAIN, GS(id->name)), id) != -1);
 }
+
+/************************* Datablock order in UI **************************/
+
+static int *id_order_get(ID *id)
+{
+       /* Only for workspace tabs currently. */
+       switch (GS(id->name)) {
+               case ID_WS:
+                       return &((WorkSpace *)id)->order;
+               default:
+                       return NULL;
+       }
+}
+
+static int id_order_compare(const void *a, const void *b)
+{
+       ID *id_a = ((LinkData *)a)->data;
+       ID *id_b = ((LinkData *)b)->data;
+
+       int *order_a = id_order_get(id_a);
+       int *order_b = id_order_get(id_b);
+
+       if (order_a && order_b) {
+               if (*order_a < *order_b) {
+                       return -1;
+               }
+               else if (*order_a > *order_b) {
+                       return 1;
+               }
+       }
+
+       return strcmp(id_a->name, id_b->name);
+}
+
+/**
+ * Returns ordered list of datablocks for display in the UI.
+ * Result is list of LinkData of IDs that must be freed.
+ */
+void BKE_id_ordered_list(ListBase *ordered_lb, const ListBase *lb)
+{
+       BLI_listbase_clear(ordered_lb);
+
+       for (ID *id = lb->first; id; id = id->next) {
+               BLI_addtail(ordered_lb, BLI_genericNodeN(id));
+       }
+
+       BLI_listbase_sort(ordered_lb, id_order_compare);
+
+       int num = 0;
+       for (LinkData *link = ordered_lb->first; link; link = link->next) {
+               int *order = id_order_get(link->data);
+               if (order) {
+                       *order = num++;
+               }
+       }
+}
+
+/**
+ * Reorder ID in the list, before or after the "relative" ID.
+ */
+void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after)
+{
+       int *id_order = id_order_get(id);
+       int relative_order;
+
+       if (relative) {
+               relative_order = *id_order_get(relative);
+       }
+       else {
+               relative_order = (after) ? BLI_listbase_count(lb) : 0;
+       }
+
+       if (after) {
+               /* Insert after. */
+               for (ID *other = lb->first; other; other = other->next) {
+                       int *order = id_order_get(other);
+                       if (*order > relative_order) {
+                               (*order)++;
+                       }
+               }
+
+               *id_order = relative_order + 1;
+       }
+       else {
+               /* Insert before. */
+               for (ID *other = lb->first; other; other = other->next) {
+                       int *order = id_order_get(other);
+                       if (*order < relative_order) {
+                               (*order)--;
+                       }
+               }
+
+               *id_order = relative_order - 1;
+       }
+}