use BLI_strncpy and BLI_snprintf when the size of the string is known.
[blender.git] / source / blender / editors / util / ed_util.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) 2008 Blender Foundation.
19  * All rights reserved.
20  *
21  * 
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/util/ed_util.c
28  *  \ingroup edutil
29  */
30
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <math.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "DNA_object_types.h"
39 #include "DNA_scene_types.h"
40 #include "DNA_packedFile_types.h"
41
42 #include "BLI_blenlib.h"
43 #include "BLI_editVert.h"
44
45 #include "BKE_context.h"
46 #include "BKE_global.h"
47 #include "BKE_main.h"
48 #include "BKE_utildefines.h"
49 #include "BKE_packedFile.h"
50
51 #include "ED_armature.h"
52 #include "ED_mesh.h"
53 #include "ED_object.h"
54 #include "ED_sculpt.h"
55 #include "ED_util.h"
56
57 #include "UI_interface.h"
58 #include "UI_resources.h"
59
60 #include "WM_types.h"
61 #include "RNA_access.h"
62
63
64
65 /* ********* general editor util funcs, not BKE stuff please! ********* */
66
67 void ED_editors_init(bContext *C)
68 {
69         Main *bmain= CTX_data_main(C);
70         Scene *sce= CTX_data_scene(C);
71         Object *ob, *obact= (sce && sce->basact)? sce->basact->object: NULL;
72         ID *data;
73
74         /* toggle on modes for objects that were saved with these enabled. for
75            e.g. linked objects we have to ensure that they are actually the
76            active object in this scene. */
77         for(ob=bmain->object.first; ob; ob=ob->id.next) {
78                 int mode= ob->mode;
79
80                 if(mode && (mode != OB_MODE_POSE)) {
81                         ob->mode= 0;
82                         data= ob->data;
83
84                         if(ob == obact && !ob->id.lib && !(data && data->lib))
85                                 ED_object_toggle_modes(C, mode);
86                 }
87         }
88 }
89
90 /* frees all editmode stuff */
91 void ED_editors_exit(bContext *C)
92 {
93         Main *bmain= CTX_data_main(C);
94         Scene *sce;
95
96         if(!bmain)
97                 return;
98         
99         /* frees all editmode undos */
100         undo_editmode_clear();
101         ED_undo_paint_free();
102         
103         for(sce=bmain->scene.first; sce; sce= sce->id.next) {
104                 if(sce->obedit) {
105                         Object *ob= sce->obedit;
106                 
107                         if(ob) {
108                                 if(ob->type==OB_MESH) {
109                                         Mesh *me= ob->data;
110                                         if(me->edit_mesh) {
111                                                 free_editMesh(me->edit_mesh);
112                                                 MEM_freeN(me->edit_mesh);
113                                                 me->edit_mesh= NULL;
114                                         }
115                                 }
116                                 else if(ob->type==OB_ARMATURE) {
117                                         ED_armature_edit_free(ob);
118                                 }
119                         }
120                 }
121         }
122
123         /* global in meshtools... */
124         mesh_octree_table(NULL, NULL, NULL, 'e');
125         mesh_mirrtopo_table(NULL, 'e');
126 }
127
128
129 /* ***** XXX: functions are using old blender names, cleanup later ***** */
130
131
132 /* now only used in 2d spaces, like time, ipo, nla, sima... */
133 /* XXX shift/ctrl not configurable */
134 void apply_keyb_grid(int shift, int ctrl, float *val, float fac1, float fac2, float fac3, int invert)
135 {
136         /* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
137         if(invert)
138                 ctrl= !ctrl;
139         
140         if(ctrl && shift) {
141                 if(fac3 != 0.0f) *val= fac3*floorf(*val/fac3 +0.5f);
142         }
143         else if(ctrl) {
144                 if(fac2 != 0.0f) *val= fac2*floorf(*val/fac2 +0.5f);
145         }
146         else {
147                 if(fac1 != 0.0f) *val= fac1*floorf(*val/fac1 +0.5f);
148         }
149 }
150
151
152 int GetButStringLength(const char *str) 
153 {
154         int rt;
155         
156         rt= UI_GetStringWidth(str);
157         
158         return rt + 15;
159 }
160
161
162 void unpack_menu(bContext *C, const char *opname, const char *id_name, const char *abs_name, const char *folder, struct PackedFile *pf)
163 {
164         PointerRNA props_ptr;
165         uiPopupMenu *pup;
166         uiLayout *layout;
167         char line[FILE_MAX + 100];
168
169         pup= uiPupMenuBegin(C, "Unpack file", ICON_NONE);
170         layout= uiPupMenuLayout(pup);
171
172         strcpy(line, "Remove Pack");
173         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
174         RNA_enum_set(&props_ptr, "method", PF_REMOVE);
175         RNA_string_set(&props_ptr, "id", id_name);
176
177         if(G.relbase_valid) {
178                 char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
179
180                 BLI_strncpy(local_name, abs_name, sizeof(local_name));
181                 BLI_splitdirstring(local_name, fi);
182                 BLI_snprintf(local_name, sizeof(local_name), "//%s/%s", folder, fi);
183                 if(strcmp(abs_name, local_name)!=0) {
184                         switch(checkPackedFile(local_name, pf)) {
185                                 case PF_NOFILE:
186                                         BLI_snprintf(line, sizeof(line), "Create %s", local_name);
187                                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
188                                         RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
189                                         RNA_string_set(&props_ptr, "id", id_name);
190
191                                         break;
192                                 case PF_EQUAL:
193                                         BLI_snprintf(line, sizeof(line), "Use %s (identical)", local_name);
194                                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL);
195                                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
196                                         RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
197                                         RNA_string_set(&props_ptr, "id", id_name);
198
199                                         break;
200                                 case PF_DIFFERS:
201                                         BLI_snprintf(line, sizeof(line), "Use %s (differs)", local_name);
202                                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL);
203                                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
204                                         RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
205                                         RNA_string_set(&props_ptr, "id", id_name);
206
207                                         BLI_snprintf(line, sizeof(line), "Overwrite %s", local_name);
208                                         //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_LOCAL);
209                                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
210                                         RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
211                                         RNA_string_set(&props_ptr, "id", id_name);
212                                         break;
213                         }
214                 }
215         }
216
217         switch(checkPackedFile(abs_name, pf)) {
218                 case PF_NOFILE:
219                         BLI_snprintf(line, sizeof(line), "Create %s", abs_name);
220                         //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL);
221                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
222                         RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
223                         RNA_string_set(&props_ptr, "id", id_name);
224                         break;
225                 case PF_EQUAL:
226                         BLI_snprintf(line, sizeof(line), "Use %s (identical)", abs_name);
227                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL);
228                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
229                         RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
230                         RNA_string_set(&props_ptr, "id", id_name);
231                         break;
232                 case PF_DIFFERS:
233                         BLI_snprintf(line, sizeof(line), "Use %s (differs)", abs_name);
234                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL);
235                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
236                         RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
237                         RNA_string_set(&props_ptr, "id", id_name);
238
239                         BLI_snprintf(line, sizeof(line), "Overwrite %s", abs_name);
240                         //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL);
241                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
242                         RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
243                         RNA_string_set(&props_ptr, "id", id_name);
244                         break;
245         }
246
247         uiPupMenuEnd(C, pup);
248 }