Cleanup: style, use braces for blenkernel
[blender.git] / source / blender / blenkernel / intern / idcode.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  * return info about ID types
19  */
20
21 /** \file
22  * \ingroup bke
23  */
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "DNA_ID.h"
29
30 #include "BLI_utildefines.h"
31
32 #include "BLT_translation.h"
33
34 #include "BKE_main.h"
35 #include "BKE_idcode.h"
36
37 typedef struct {
38   unsigned short code;
39   const char *name, *plural;
40
41   const char *i18n_context;
42
43   int flags;
44 #define IDTYPE_FLAGS_ISLINKABLE (1 << 0)
45 } IDType;
46
47 /* Keep alignment for readability. */
48 /* clang-format off */
49 /**
50  * When editing enusre that:
51  * - Plural need to match rna_main.c's #MainCollectionDef.
52  * - Keep it in sync with i18n contexts in BLT_translation.h
53  */
54 static IDType idtypes[] = {
55   /** ID's directly below must all be in #Main, and be kept in sync with #MAX_LIBARRAY (membership, not order) */
56   {ID_AC,   "Action",             "actions",         BLT_I18NCONTEXT_ID_ACTION,             IDTYPE_FLAGS_ISLINKABLE},
57   {ID_AR,   "Armature",           "armatures",       BLT_I18NCONTEXT_ID_ARMATURE,           IDTYPE_FLAGS_ISLINKABLE},
58   {ID_BR,   "Brush",              "brushes",         BLT_I18NCONTEXT_ID_BRUSH,              IDTYPE_FLAGS_ISLINKABLE},
59   {ID_CA,   "Camera",             "cameras",         BLT_I18NCONTEXT_ID_CAMERA,             IDTYPE_FLAGS_ISLINKABLE},
60   {ID_CF,   "CacheFile",          "cache_files",     BLT_I18NCONTEXT_ID_CACHEFILE,          IDTYPE_FLAGS_ISLINKABLE},
61   {ID_GR,   "Collection",         "collections",     BLT_I18NCONTEXT_ID_COLLECTION,         IDTYPE_FLAGS_ISLINKABLE},
62   {ID_CU,   "Curve",              "curves",          BLT_I18NCONTEXT_ID_CURVE,              IDTYPE_FLAGS_ISLINKABLE},
63   {ID_GD,   "GPencil",            "grease_pencils",  BLT_I18NCONTEXT_ID_GPENCIL,            IDTYPE_FLAGS_ISLINKABLE}, /* rename gpencil */
64
65   {ID_IM,   "Image",              "images",          BLT_I18NCONTEXT_ID_IMAGE,              IDTYPE_FLAGS_ISLINKABLE},
66   {ID_IP,   "Ipo",                "ipos",            "",                                    IDTYPE_FLAGS_ISLINKABLE}, /* deprecated */
67   {ID_KE,   "Key",                "shape_keys",      BLT_I18NCONTEXT_ID_SHAPEKEY,           0                      },
68   {ID_LA,   "Light",              "lights",          BLT_I18NCONTEXT_ID_LIGHT,              IDTYPE_FLAGS_ISLINKABLE},
69   {ID_LI,   "Library",            "libraries",       BLT_I18NCONTEXT_ID_LIBRARY,            0                      },
70   {ID_LS,   "FreestyleLineStyle", "linestyles",      BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE, IDTYPE_FLAGS_ISLINKABLE},
71   {ID_LT,   "Lattice",            "lattices",        BLT_I18NCONTEXT_ID_LATTICE,            IDTYPE_FLAGS_ISLINKABLE},
72   {ID_MA,   "Material",           "materials",       BLT_I18NCONTEXT_ID_MATERIAL,           IDTYPE_FLAGS_ISLINKABLE},
73   {ID_MB,   "Metaball",           "metaballs",       BLT_I18NCONTEXT_ID_METABALL,           IDTYPE_FLAGS_ISLINKABLE},
74   {ID_MC,   "MovieClip",          "movieclips",      BLT_I18NCONTEXT_ID_MOVIECLIP,          IDTYPE_FLAGS_ISLINKABLE},
75   {ID_ME,   "Mesh",               "meshes",          BLT_I18NCONTEXT_ID_MESH,               IDTYPE_FLAGS_ISLINKABLE},
76   {ID_MSK,  "Mask",               "masks",           BLT_I18NCONTEXT_ID_MASK,               IDTYPE_FLAGS_ISLINKABLE},
77   {ID_NT,   "NodeTree",           "node_groups",     BLT_I18NCONTEXT_ID_NODETREE,           IDTYPE_FLAGS_ISLINKABLE},
78   {ID_OB,   "Object",             "objects",         BLT_I18NCONTEXT_ID_OBJECT,             IDTYPE_FLAGS_ISLINKABLE},
79   {ID_PA,   "ParticleSettings",   "particles",       BLT_I18NCONTEXT_ID_PARTICLESETTINGS,   IDTYPE_FLAGS_ISLINKABLE},
80   {ID_PAL,  "Palettes",           "palettes",        BLT_I18NCONTEXT_ID_PALETTE,            IDTYPE_FLAGS_ISLINKABLE},
81   {ID_PC,   "PaintCurve",         "paint_curves",    BLT_I18NCONTEXT_ID_PAINTCURVE,         IDTYPE_FLAGS_ISLINKABLE},
82   {ID_LP,   "LightProbe",         "lightprobes",     BLT_I18NCONTEXT_ID_LIGHTPROBE,         IDTYPE_FLAGS_ISLINKABLE},
83   {ID_SCE,  "Scene",              "scenes",          BLT_I18NCONTEXT_ID_SCENE,              IDTYPE_FLAGS_ISLINKABLE},
84   {ID_SCR,  "Screen",             "screens",         BLT_I18NCONTEXT_ID_SCREEN,             IDTYPE_FLAGS_ISLINKABLE},
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   {ID_WS,   "WorkSpace",          "workspaces",      BLT_I18NCONTEXT_ID_WORKSPACE,          IDTYPE_FLAGS_ISLINKABLE},
94
95   /** Keep last, not an ID exactly, only include for completeness */
96   {ID_LINK_PLACEHOLDER, "Link Placeholder", "link_placeholders", BLT_I18NCONTEXT_ID_ID, 0}, /* plural is fake */
97 };
98 /* clang-format on */
99
100 /* -1 for ID_LINK_PLACEHOLDER */
101 BLI_STATIC_ASSERT((ARRAY_SIZE(idtypes) - 1 == MAX_LIBARRAY), "Missing IDType");
102
103 static IDType *idtype_from_name(const char *str)
104 {
105   int i = ARRAY_SIZE(idtypes);
106
107   while (i--) {
108     if (STREQ(str, idtypes[i].name)) {
109       return &idtypes[i];
110     }
111   }
112
113   return NULL;
114 }
115 static IDType *idtype_from_code(short idcode)
116 {
117   int i = ARRAY_SIZE(idtypes);
118
119   while (i--) {
120     if (idcode == idtypes[i].code) {
121       return &idtypes[i];
122     }
123   }
124
125   return NULL;
126 }
127
128 /**
129  * Return if the ID code is a valid ID code.
130  *
131  * \param idcode: The code to check.
132  * \return Boolean, 0 when invalid.
133  */
134 bool BKE_idcode_is_valid(short idcode)
135 {
136   return idtype_from_code(idcode) ? true : false;
137 }
138
139 /**
140  * Return non-zero when an ID type is linkable.
141  *
142  * \param idcode: The code to check.
143  * \return Boolean, 0 when non linkable.
144  */
145 bool BKE_idcode_is_linkable(short idcode)
146 {
147   IDType *idt = idtype_from_code(idcode);
148   BLI_assert(idt);
149   return idt ? ((idt->flags & IDTYPE_FLAGS_ISLINKABLE) != 0) : false;
150 }
151
152 /**
153  * Convert an idcode into a name.
154  *
155  * \param idcode: The code to convert.
156  * \return A static string representing the name of
157  * the code.
158  */
159 const char *BKE_idcode_to_name(short idcode)
160 {
161   IDType *idt = idtype_from_code(idcode);
162   BLI_assert(idt);
163   return idt ? idt->name : NULL;
164 }
165
166 /**
167  * Convert a name into an idcode (ie. ID_SCE)
168  *
169  * \param name: The name to convert.
170  * \return The code for the name, or 0 if invalid.
171  */
172 short BKE_idcode_from_name(const char *name)
173 {
174   IDType *idt = idtype_from_name(name);
175   BLI_assert(idt);
176   return idt ? idt->code : 0;
177 }
178
179 /**
180  * Convert an idcode into an idfilter (e.g. ID_OB -> FILTER_ID_OB).
181  */
182 int BKE_idcode_to_idfilter(const short idcode)
183 {
184 #define CASE_IDFILTER(_id) \
185   case ID_##_id: \
186     return FILTER_ID_##_id
187
188   switch (idcode) {
189     CASE_IDFILTER(AC);
190     CASE_IDFILTER(AR);
191     CASE_IDFILTER(BR);
192     CASE_IDFILTER(CA);
193     CASE_IDFILTER(CF);
194     CASE_IDFILTER(CU);
195     CASE_IDFILTER(GD);
196     CASE_IDFILTER(GR);
197     CASE_IDFILTER(IM);
198     CASE_IDFILTER(LA);
199     CASE_IDFILTER(LS);
200     CASE_IDFILTER(LT);
201     CASE_IDFILTER(MA);
202     CASE_IDFILTER(MB);
203     CASE_IDFILTER(MC);
204     CASE_IDFILTER(ME);
205     CASE_IDFILTER(MSK);
206     CASE_IDFILTER(NT);
207     CASE_IDFILTER(OB);
208     CASE_IDFILTER(PA);
209     CASE_IDFILTER(PAL);
210     CASE_IDFILTER(PC);
211     CASE_IDFILTER(LP);
212     CASE_IDFILTER(SCE);
213     CASE_IDFILTER(SPK);
214     CASE_IDFILTER(SO);
215     CASE_IDFILTER(TE);
216     CASE_IDFILTER(TXT);
217     CASE_IDFILTER(VF);
218     CASE_IDFILTER(WO);
219     CASE_IDFILTER(WS);
220     default:
221       return 0;
222   }
223
224 #undef CASE_IDFILTER
225 }
226
227 /**
228  * Convert an idfilter into an idcode (e.g. FILTER_ID_OB -> ID_OB).
229  */
230 short BKE_idcode_from_idfilter(const int idfilter)
231 {
232 #define CASE_IDFILTER(_id) \
233   case FILTER_ID_##_id: \
234     return ID_##_id
235
236   switch (idfilter) {
237     CASE_IDFILTER(AC);
238     CASE_IDFILTER(AR);
239     CASE_IDFILTER(BR);
240     CASE_IDFILTER(CA);
241     CASE_IDFILTER(CF);
242     CASE_IDFILTER(CU);
243     CASE_IDFILTER(GD);
244     CASE_IDFILTER(GR);
245     CASE_IDFILTER(IM);
246     CASE_IDFILTER(LA);
247     CASE_IDFILTER(LS);
248     CASE_IDFILTER(LT);
249     CASE_IDFILTER(MA);
250     CASE_IDFILTER(MB);
251     CASE_IDFILTER(MC);
252     CASE_IDFILTER(ME);
253     CASE_IDFILTER(MSK);
254     CASE_IDFILTER(NT);
255     CASE_IDFILTER(OB);
256     CASE_IDFILTER(PA);
257     CASE_IDFILTER(PAL);
258     CASE_IDFILTER(PC);
259     CASE_IDFILTER(LP);
260     CASE_IDFILTER(SCE);
261     CASE_IDFILTER(SPK);
262     CASE_IDFILTER(SO);
263     CASE_IDFILTER(TE);
264     CASE_IDFILTER(TXT);
265     CASE_IDFILTER(VF);
266     CASE_IDFILTER(WO);
267     default:
268       return 0;
269   }
270
271 #undef CASE_IDFILTER
272 }
273
274 /**
275  * Convert an idcode into an index (e.g. ID_OB -> INDEX_ID_OB).
276  */
277 int BKE_idcode_to_index(const short idcode)
278 {
279 #define CASE_IDINDEX(_id) \
280   case ID_##_id: \
281     return INDEX_ID_##_id
282
283   switch ((ID_Type)idcode) {
284     CASE_IDINDEX(AC);
285     CASE_IDINDEX(AR);
286     CASE_IDINDEX(BR);
287     CASE_IDINDEX(CA);
288     CASE_IDINDEX(CF);
289     CASE_IDINDEX(CU);
290     CASE_IDINDEX(GD);
291     CASE_IDINDEX(GR);
292     CASE_IDINDEX(IM);
293     CASE_IDINDEX(KE);
294     CASE_IDINDEX(IP);
295     CASE_IDINDEX(LA);
296     CASE_IDINDEX(LI);
297     CASE_IDINDEX(LS);
298     CASE_IDINDEX(LT);
299     CASE_IDINDEX(MA);
300     CASE_IDINDEX(MB);
301     CASE_IDINDEX(MC);
302     CASE_IDINDEX(ME);
303     CASE_IDINDEX(MSK);
304     CASE_IDINDEX(NT);
305     CASE_IDINDEX(OB);
306     CASE_IDINDEX(PA);
307     CASE_IDINDEX(PAL);
308     CASE_IDINDEX(PC);
309     CASE_IDINDEX(LP);
310     CASE_IDINDEX(SCE);
311     CASE_IDINDEX(SCR);
312     CASE_IDINDEX(SPK);
313     CASE_IDINDEX(SO);
314     CASE_IDINDEX(TE);
315     CASE_IDINDEX(TXT);
316     CASE_IDINDEX(VF);
317     CASE_IDINDEX(WM);
318     CASE_IDINDEX(WO);
319     CASE_IDINDEX(WS);
320   }
321
322   BLI_assert(0);
323   return -1;
324
325 #undef CASE_IDINDEX
326 }
327
328 /**
329  * Get an idcode from an index (e.g. INDEX_ID_OB -> ID_OB).
330  */
331 short BKE_idcode_from_index(const int index)
332 {
333 #define CASE_IDCODE(_id) \
334   case INDEX_ID_##_id: \
335     return ID_##_id
336
337   switch (index) {
338     CASE_IDCODE(AC);
339     CASE_IDCODE(AR);
340     CASE_IDCODE(BR);
341     CASE_IDCODE(CA);
342     CASE_IDCODE(CF);
343     CASE_IDCODE(CU);
344     CASE_IDCODE(GD);
345     CASE_IDCODE(GR);
346     CASE_IDCODE(IM);
347     CASE_IDCODE(KE);
348     CASE_IDCODE(IP);
349     CASE_IDCODE(LA);
350     CASE_IDCODE(LI);
351     CASE_IDCODE(LS);
352     CASE_IDCODE(LT);
353     CASE_IDCODE(MA);
354     CASE_IDCODE(MB);
355     CASE_IDCODE(MC);
356     CASE_IDCODE(ME);
357     CASE_IDCODE(MSK);
358     CASE_IDCODE(NT);
359     CASE_IDCODE(OB);
360     CASE_IDCODE(PA);
361     CASE_IDCODE(PAL);
362     CASE_IDCODE(PC);
363     CASE_IDCODE(LP);
364     CASE_IDCODE(SCE);
365     CASE_IDCODE(SCR);
366     CASE_IDCODE(SPK);
367     CASE_IDCODE(SO);
368     CASE_IDCODE(TE);
369     CASE_IDCODE(TXT);
370     CASE_IDCODE(VF);
371     CASE_IDCODE(WM);
372     CASE_IDCODE(WO);
373     CASE_IDCODE(WS);
374   }
375
376   BLI_assert(0);
377   return -1;
378
379 #undef CASE_IDCODE
380 }
381
382 /**
383  * Convert an idcode into a name (plural).
384  *
385  * \param idcode: The code to convert.
386  * \return A static string representing the name of
387  * the code.
388  */
389 const char *BKE_idcode_to_name_plural(short idcode)
390 {
391   IDType *idt = idtype_from_code(idcode);
392   BLI_assert(idt);
393   return idt ? idt->plural : NULL;
394 }
395
396 /**
397  * Convert an idcode into its translations' context.
398  *
399  * \param idcode: The code to convert.
400  * \return A static string representing the i18n context of the code.
401  */
402 const char *BKE_idcode_to_translation_context(short idcode)
403 {
404   IDType *idt = idtype_from_code(idcode);
405   BLI_assert(idt);
406   return idt ? idt->i18n_context : BLT_I18NCONTEXT_DEFAULT;
407 }
408
409 /**
410  * Return an ID code and steps the index forward 1.
411  *
412  * \param index: start as 0.
413  * \return the code, 0 when all codes have been returned.
414  */
415 short BKE_idcode_iter_step(int *index)
416 {
417   return (*index < ARRAY_SIZE(idtypes)) ? idtypes[(*index)++].code : 0;
418 }