Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / idcode.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  * return info about ID types
27  */
28
29 /** \file blender/blenkernel/intern/idcode.c
30  *  \ingroup bke
31  */
32
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include "DNA_ID.h"
37
38 #include "BLI_utildefines.h"
39
40 #include "BLT_translation.h"
41
42 #include "BKE_library.h"
43 #include "BKE_idcode.h"
44
45 typedef struct {
46         unsigned short code;
47         const char *name, *plural;
48
49         const char *i18n_context;
50         
51         int flags;
52 #define IDTYPE_FLAGS_ISLINKABLE (1 << 0)
53 } IDType;
54
55 /* plural need to match rna_main.c's MainCollectionDef */
56 /* WARNING! Keep it in sync with i18n contexts in BLT_translation.h */
57 static IDType idtypes[] = {
58         /** ID's directly below must all be in #Main, and be kept in sync with #MAX_LIBARRAY (membership, not order) */
59         { ID_AC,   "Action",             "actions",         BLT_I18NCONTEXT_ID_ACTION,             IDTYPE_FLAGS_ISLINKABLE },
60         { ID_AR,   "Armature",           "armatures",       BLT_I18NCONTEXT_ID_ARMATURE,           IDTYPE_FLAGS_ISLINKABLE },
61         { ID_BR,   "Brush",              "brushes",         BLT_I18NCONTEXT_ID_BRUSH,              IDTYPE_FLAGS_ISLINKABLE },
62         { ID_CA,   "Camera",             "cameras",         BLT_I18NCONTEXT_ID_CAMERA,             IDTYPE_FLAGS_ISLINKABLE },
63         { ID_CF,   "CacheFile",          "cache_files",     BLT_I18NCONTEXT_ID_CACHEFILE,          IDTYPE_FLAGS_ISLINKABLE },
64         { ID_CU,   "Curve",              "curves",          BLT_I18NCONTEXT_ID_CURVE,              IDTYPE_FLAGS_ISLINKABLE },
65         { ID_GD,   "GPencil",            "grease_pencil",   BLT_I18NCONTEXT_ID_GPENCIL,            IDTYPE_FLAGS_ISLINKABLE }, /* rename gpencil */
66         { ID_GR,   "Group",              "groups",          BLT_I18NCONTEXT_ID_GROUP,              IDTYPE_FLAGS_ISLINKABLE },
67         { ID_IM,   "Image",              "images",          BLT_I18NCONTEXT_ID_IMAGE,              IDTYPE_FLAGS_ISLINKABLE },
68         { ID_IP,   "Ipo",                "ipos",            "",                                    IDTYPE_FLAGS_ISLINKABLE }, /* deprecated */
69         { ID_KE,   "Key",                "shape_keys",      BLT_I18NCONTEXT_ID_SHAPEKEY,           0                       },
70         { ID_LA,   "Lamp",               "lamps",           BLT_I18NCONTEXT_ID_LAMP,               IDTYPE_FLAGS_ISLINKABLE },
71         { ID_LI,   "Library",            "libraries",       BLT_I18NCONTEXT_ID_LIBRARY,            0                       },
72         { ID_LS,   "FreestyleLineStyle", "linestyles",      BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE, IDTYPE_FLAGS_ISLINKABLE },
73         { ID_LT,   "Lattice",            "lattices",        BLT_I18NCONTEXT_ID_LATTICE,            IDTYPE_FLAGS_ISLINKABLE },
74         { ID_MA,   "Material",           "materials",       BLT_I18NCONTEXT_ID_MATERIAL,           IDTYPE_FLAGS_ISLINKABLE },
75         { ID_MB,   "Metaball",           "metaballs",       BLT_I18NCONTEXT_ID_METABALL,           IDTYPE_FLAGS_ISLINKABLE },
76         { ID_MC,   "MovieClip",          "movieclips",      BLT_I18NCONTEXT_ID_MOVIECLIP,          IDTYPE_FLAGS_ISLINKABLE },
77         { ID_ME,   "Mesh",               "meshes",          BLT_I18NCONTEXT_ID_MESH,               IDTYPE_FLAGS_ISLINKABLE },
78         { ID_MSK,  "Mask",               "masks",           BLT_I18NCONTEXT_ID_MASK,               IDTYPE_FLAGS_ISLINKABLE },
79         { ID_NT,   "NodeTree",           "node_groups",     BLT_I18NCONTEXT_ID_NODETREE,           IDTYPE_FLAGS_ISLINKABLE },
80         { ID_OB,   "Object",             "objects",         BLT_I18NCONTEXT_ID_OBJECT,             IDTYPE_FLAGS_ISLINKABLE },
81         { ID_PAL,  "Palettes",           "palettes",        BLT_I18NCONTEXT_ID_PALETTE,            IDTYPE_FLAGS_ISLINKABLE },
82         { ID_PC,   "PaintCurve",         "paint_curves",    BLT_I18NCONTEXT_ID_PAINTCURVE,         IDTYPE_FLAGS_ISLINKABLE },
83         { ID_SCE,  "Scene",              "scenes",          BLT_I18NCONTEXT_ID_SCENE,              IDTYPE_FLAGS_ISLINKABLE },
84         { ID_SCR,  "Screen",             "screens",         BLT_I18NCONTEXT_ID_SCREEN,             0                       },
85         { ID_SEQ,  "Sequence",           "sequences",       BLT_I18NCONTEXT_ID_SEQUENCE,           0                       }, /* not actually ID data */
86         { ID_SPK,  "Speaker",            "speakers",        BLT_I18NCONTEXT_ID_SPEAKER,            IDTYPE_FLAGS_ISLINKABLE },
87         { ID_SO,   "Sound",              "sounds",          BLT_I18NCONTEXT_ID_SOUND,              IDTYPE_FLAGS_ISLINKABLE },
88         { ID_TE,   "Texture",            "textures",        BLT_I18NCONTEXT_ID_TEXTURE,            IDTYPE_FLAGS_ISLINKABLE },
89         { ID_TXT,  "Text",               "texts",           BLT_I18NCONTEXT_ID_TEXT,               IDTYPE_FLAGS_ISLINKABLE },
90         { ID_VF,   "VFont",              "fonts",           BLT_I18NCONTEXT_ID_VFONT,              IDTYPE_FLAGS_ISLINKABLE },
91         { ID_WO,   "World",              "worlds",          BLT_I18NCONTEXT_ID_WORLD,              IDTYPE_FLAGS_ISLINKABLE },
92         { ID_WM,   "WindowManager",      "window_managers", BLT_I18NCONTEXT_ID_WINDOWMANAGER,      0                       },
93
94         /** Keep last, not an ID exactly, only include for completeness */
95         { ID_ID,   "ID",                 "ids",             BLT_I18NCONTEXT_ID_ID,                 0                       }, /* plural is fake */
96 };
97
98 /* -1 for ID_ID */
99 BLI_STATIC_ASSERT((ARRAY_SIZE(idtypes) - 1 == MAX_LIBARRAY), "Missing IDType");
100
101 static IDType *idtype_from_name(const char *str) 
102 {
103         int i = ARRAY_SIZE(idtypes);
104
105         while (i--) {
106                 if (STREQ(str, idtypes[i].name)) {
107                         return &idtypes[i];
108                 }
109         }
110
111         return NULL;
112 }
113 static IDType *idtype_from_code(short idcode)
114 {
115         int i = ARRAY_SIZE(idtypes);
116
117         while (i--)
118                 if (idcode == idtypes[i].code)
119                         return &idtypes[i];
120         
121         return NULL;
122 }
123
124 /**
125  * Return if the ID code is a valid ID code.
126  *
127  * \param idcode: The code to check.
128  * \return Boolean, 0 when invalid.
129  */
130 bool BKE_idcode_is_valid(short idcode)
131 {
132         return idtype_from_code(idcode) ? true : false;
133 }
134
135 /**
136  * Return non-zero when an ID type is linkable.
137  *
138  * \param idcode: The code to check.
139  * \return Boolean, 0 when non linkable.
140  */
141 bool BKE_idcode_is_linkable(short idcode)
142 {
143         IDType *idt = idtype_from_code(idcode);
144         BLI_assert(idt);
145         return idt ? ((idt->flags & IDTYPE_FLAGS_ISLINKABLE) != 0) : false;
146 }
147
148 /**
149  * Convert an idcode into a name.
150  *
151  * \param idcode: The code to convert.
152  * \return A static string representing the name of
153  * the code.
154  */
155 const char *BKE_idcode_to_name(short idcode)
156 {
157         IDType *idt = idtype_from_code(idcode);
158         BLI_assert(idt);
159         return idt ? idt->name : NULL;
160 }
161
162 /**
163  * Convert a name into an idcode (ie. ID_SCE)
164  *
165  * \param name The name to convert.
166  * \return The code for the name, or 0 if invalid.
167  */
168 short BKE_idcode_from_name(const char *name)
169 {
170         IDType *idt = idtype_from_name(name);
171         BLI_assert(idt);
172         return idt ? idt->code : 0;
173 }
174
175 /**
176  * Convert an idcode into an idfilter (e.g. ID_OB -> FILTER_ID_OB).
177  */
178 int BKE_idcode_to_idfilter(const short idcode)
179 {
180 #define CASE_IDFILTER(_id) case ID_##_id: return FILTER_ID_##_id
181
182         switch (idcode) {
183                 CASE_IDFILTER(AC);
184                 CASE_IDFILTER(AR);
185                 CASE_IDFILTER(BR);
186                 CASE_IDFILTER(CA);
187                 CASE_IDFILTER(CF);
188                 CASE_IDFILTER(CU);
189                 CASE_IDFILTER(GD);
190                 CASE_IDFILTER(GR);
191                 CASE_IDFILTER(IM);
192                 CASE_IDFILTER(LA);
193                 CASE_IDFILTER(LS);
194                 CASE_IDFILTER(LT);
195                 CASE_IDFILTER(MA);
196                 CASE_IDFILTER(MB);
197                 CASE_IDFILTER(MC);
198                 CASE_IDFILTER(ME);
199                 CASE_IDFILTER(MSK);
200                 CASE_IDFILTER(NT);
201                 CASE_IDFILTER(OB);
202                 CASE_IDFILTER(PAL);
203                 CASE_IDFILTER(PC);
204                 CASE_IDFILTER(SCE);
205                 CASE_IDFILTER(SPK);
206                 CASE_IDFILTER(SO);
207                 CASE_IDFILTER(TE);
208                 CASE_IDFILTER(TXT);
209                 CASE_IDFILTER(VF);
210                 CASE_IDFILTER(WO);
211                 default:
212                         return 0;
213         }
214
215 #undef CASE_IDFILTER
216 }
217
218 /**
219  * Convert an idfilter into an idcode (e.g. FILTER_ID_OB -> ID_OB).
220  */
221 short BKE_idcode_from_idfilter(const int idfilter)
222 {
223 #define CASE_IDFILTER(_id) case FILTER_ID_##_id: return ID_##_id
224
225         switch (idfilter) {
226                 CASE_IDFILTER(AC);
227                 CASE_IDFILTER(AR);
228                 CASE_IDFILTER(BR);
229                 CASE_IDFILTER(CA);
230                 CASE_IDFILTER(CF);
231                 CASE_IDFILTER(CU);
232                 CASE_IDFILTER(GD);
233                 CASE_IDFILTER(GR);
234                 CASE_IDFILTER(IM);
235                 CASE_IDFILTER(LA);
236                 CASE_IDFILTER(LS);
237                 CASE_IDFILTER(LT);
238                 CASE_IDFILTER(MA);
239                 CASE_IDFILTER(MB);
240                 CASE_IDFILTER(MC);
241                 CASE_IDFILTER(ME);
242                 CASE_IDFILTER(MSK);
243                 CASE_IDFILTER(NT);
244                 CASE_IDFILTER(OB);
245                 CASE_IDFILTER(PAL);
246                 CASE_IDFILTER(PC);
247                 CASE_IDFILTER(SCE);
248                 CASE_IDFILTER(SPK);
249                 CASE_IDFILTER(SO);
250                 CASE_IDFILTER(TE);
251                 CASE_IDFILTER(TXT);
252                 CASE_IDFILTER(VF);
253                 CASE_IDFILTER(WO);
254                 default:
255                         return 0;
256         }
257
258 #undef CASE_IDFILTER
259 }
260
261 /**
262  * Convert an idcode into a name (plural).
263  *
264  * \param idcode: The code to convert.
265  * \return A static string representing the name of
266  * the code.
267  */
268 const char *BKE_idcode_to_name_plural(short idcode)
269 {
270         IDType *idt = idtype_from_code(idcode);
271         BLI_assert(idt);
272         return idt ? idt->plural : NULL;
273 }
274
275 /**
276  * Convert an idcode into its translations' context.
277  *
278  * \param idcode: The code to convert.
279  * \return A static string representing the i18n context of the code.
280  */
281 const char *BKE_idcode_to_translation_context(short idcode)
282 {
283         IDType *idt = idtype_from_code(idcode);
284         BLI_assert(idt);
285         return idt ? idt->i18n_context : BLT_I18NCONTEXT_DEFAULT;
286 }
287
288 /**
289  * Return an ID code and steps the index forward 1.
290  *
291  * \param index start as 0.
292  * \return the code, 0 when all codes have been returned.
293  */
294 short BKE_idcode_iter_step(int *index)
295 {
296         return (*index < ARRAY_SIZE(idtypes)) ? idtypes[(*index)++].code : 0;
297 }