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