doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / blender / editors / util / ed_util.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "DNA_object_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_packedFile_types.h"
38
39 #include "BLI_blenlib.h"
40 #include "BLI_editVert.h"
41
42 #include "BKE_context.h"
43 #include "BKE_global.h"
44 #include "BKE_main.h"
45 #include "BKE_utildefines.h"
46 #include "BKE_packedFile.h"
47
48 #include "ED_armature.h"
49 #include "ED_mesh.h"
50 #include "ED_object.h"
51 #include "ED_sculpt.h"
52 #include "ED_util.h"
53
54 #include "UI_interface.h"
55
56 #include "WM_types.h"
57 #include "RNA_access.h"
58
59
60
61 /* ********* general editor util funcs, not BKE stuff please! ********* */
62
63 void ED_editors_init(bContext *C)
64 {
65         Main *bmain= CTX_data_main(C);
66         Scene *sce= CTX_data_scene(C);
67         Object *ob, *obact= (sce && sce->basact)? sce->basact->object: NULL;
68         ID *data;
69
70         /* toggle on modes for objects that were saved with these enabled. for
71            e.g. linked objects we have to ensure that they are actually the
72            active object in this scene. */
73         for(ob=bmain->object.first; ob; ob=ob->id.next) {
74                 int mode= ob->mode;
75
76                 if(mode && (mode != OB_MODE_POSE)) {
77                         ob->mode= 0;
78                         data= ob->data;
79
80                         if(ob == obact && !ob->id.lib && !(data && data->lib))
81                                 ED_object_toggle_modes(C, mode);
82                 }
83         }
84 }
85
86 /* frees all editmode stuff */
87 void ED_editors_exit(bContext *C)
88 {
89         Main *bmain= CTX_data_main(C);
90         Scene *sce;
91
92         if(!bmain)
93                 return;
94         
95         /* frees all editmode undos */
96         undo_editmode_clear();
97         ED_undo_paint_free();
98         
99         for(sce=bmain->scene.first; sce; sce= sce->id.next) {
100                 if(sce->obedit) {
101                         Object *ob= sce->obedit;
102                 
103                         /* global in meshtools... */
104                         mesh_octree_table(NULL, NULL, NULL, 'e');
105                         mesh_mirrtopo_table(NULL, 'e');
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                                 else if(ob->type==OB_FONT) {
120                                         //                      free_editText();
121                                 }
122                                 //              else if(ob->type==OB_MBALL) 
123                                 //                      BLI_freelistN(&editelems);
124                                 //      free_editLatt();
125                                 //      free_posebuf();         // XXX this is still a global...
126                         }
127                 }
128                 else if(sce->basact && sce->basact->object) {
129                         Object *ob= sce->basact->object;
130                         
131                         /* if weight-painting is on, free mesh octree data */
132                         if(ob->mode & OB_MODE_WEIGHT_PAINT) {
133                                 mesh_octree_table(NULL, NULL, NULL, 'e');
134                                 mesh_mirrtopo_table(NULL, 'e');
135                         }
136                 }
137         }
138         
139 }
140
141
142 /* ***** XXX: functions are using old blender names, cleanup later ***** */
143
144
145 /* now only used in 2d spaces, like time, ipo, nla, sima... */
146 /* XXX shift/ctrl not configurable */
147 void apply_keyb_grid(int shift, int ctrl, float *val, float fac1, float fac2, float fac3, int invert)
148 {
149         /* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
150         if(invert)
151                 ctrl= !ctrl;
152         
153         if(ctrl && shift) {
154                 if(fac3!= 0.0) *val= fac3*floor(*val/fac3 +.5);
155         }
156         else if(ctrl) {
157                 if(fac2!= 0.0) *val= fac2*floor(*val/fac2 +.5);
158         }
159         else {
160                 if(fac1!= 0.0) *val= fac1*floor(*val/fac1 +.5);
161         }
162 }
163
164
165 int GetButStringLength(const char *str) 
166 {
167         int rt;
168         
169         rt= UI_GetStringWidth(str);
170         
171         return rt + 15;
172 }
173
174
175 void unpack_menu(bContext *C, const char *opname, const char *id_name, const char *abs_name, const char *folder, struct PackedFile *pf)
176 {
177         PointerRNA props_ptr;
178         uiPopupMenu *pup;
179         uiLayout *layout;
180         char line[FILE_MAXDIR + FILE_MAXFILE + 100];
181
182         pup= uiPupMenuBegin(C, "Unpack file", ICON_NULL);
183         layout= uiPupMenuLayout(pup);
184
185         sprintf(line, "Remove Pack");
186         props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
187         RNA_enum_set(&props_ptr, "method", PF_REMOVE);
188         RNA_string_set(&props_ptr, "id", id_name);
189
190         if(G.relbase_valid) {
191                 char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
192
193                 BLI_strncpy(local_name, abs_name, sizeof(local_name));
194                 BLI_splitdirstring(local_name, fi);
195                 sprintf(local_name, "//%s/%s", folder, fi);
196                 if(strcmp(abs_name, local_name)!=0) {
197                         switch(checkPackedFile(local_name, pf)) {
198                                 case PF_NOFILE:
199                                         sprintf(line, "Create %s", local_name);
200                                         props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
201                                         RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
202                                         RNA_string_set(&props_ptr, "id", id_name);
203
204                                         break;
205                                 case PF_EQUAL:
206                                         sprintf(line, "Use %s (identical)", local_name);
207                                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL);
208                                         props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
209                                         RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
210                                         RNA_string_set(&props_ptr, "id", id_name);
211
212                                         break;
213                                 case PF_DIFFERS:
214                                         sprintf(line, "Use %s (differs)", local_name);
215                                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL);
216                                         props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
217                                         RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
218                                         RNA_string_set(&props_ptr, "id", id_name);
219
220                                         sprintf(line, "Overwrite %s", local_name);
221                                         //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_LOCAL);
222                                         props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
223                                         RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
224                                         RNA_string_set(&props_ptr, "id", id_name);
225                                         break;
226                         }
227                 }
228         }
229
230         switch(checkPackedFile(abs_name, pf)) {
231                 case PF_NOFILE:
232                         sprintf(line, "Create %s", abs_name);
233                         //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL);
234                         props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
235                         RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
236                         RNA_string_set(&props_ptr, "id", id_name);
237                         break;
238                 case PF_EQUAL:
239                         sprintf(line, "Use %s (identical)", abs_name);
240                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL);
241                         props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
242                         RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
243                         RNA_string_set(&props_ptr, "id", id_name);
244                         break;
245                 case PF_DIFFERS:
246                         sprintf(line, "Use %s (differs)", abs_name);
247                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL);
248                         props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
249                         RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
250                         RNA_string_set(&props_ptr, "id", id_name);
251
252                         sprintf(line, "Overwrite %s", abs_name);
253                         //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL);
254                         props_ptr= uiItemFullO(layout, opname, line, ICON_NULL, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
255                         RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
256                         RNA_string_set(&props_ptr, "id", id_name);
257                         break;
258         }
259
260         uiPupMenuEnd(C, pup);
261 }