doxygen: blender/editors tagged.
[blender-staging.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                         /* global in meshtools... */
110                         mesh_octree_table(NULL, NULL, NULL, 'e');
111                         mesh_mirrtopo_table(NULL, 'e');
112                         
113                         if(ob) {
114                                 if(ob->type==OB_MESH) {
115                                         Mesh *me= ob->data;
116                                         if(me->edit_mesh) {
117                                                 free_editMesh(me->edit_mesh);
118                                                 MEM_freeN(me->edit_mesh);
119                                                 me->edit_mesh= NULL;
120                                         }
121                                 }
122                                 else if(ob->type==OB_ARMATURE) {
123                                         ED_armature_edit_free(ob);
124                                 }
125                                 else if(ob->type==OB_FONT) {
126                                         //                      free_editText();
127                                 }
128                                 //              else if(ob->type==OB_MBALL) 
129                                 //                      BLI_freelistN(&editelems);
130                                 //      free_editLatt();
131                                 //      free_posebuf();         // XXX this is still a global...
132                         }
133                 }
134                 else if(sce->basact && sce->basact->object) {
135                         Object *ob= sce->basact->object;
136                         
137                         /* if weight-painting is on, free mesh octree data */
138                         if(ob->mode & OB_MODE_WEIGHT_PAINT) {
139                                 mesh_octree_table(NULL, NULL, NULL, 'e');
140                                 mesh_mirrtopo_table(NULL, 'e');
141                         }
142                 }
143         }
144         
145 }
146
147
148 /* ***** XXX: functions are using old blender names, cleanup later ***** */
149
150
151 /* now only used in 2d spaces, like time, ipo, nla, sima... */
152 /* XXX shift/ctrl not configurable */
153 void apply_keyb_grid(int shift, int ctrl, float *val, float fac1, float fac2, float fac3, int invert)
154 {
155         /* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
156         if(invert)
157                 ctrl= !ctrl;
158         
159         if(ctrl && shift) {
160                 if(fac3!= 0.0) *val= fac3*floor(*val/fac3 +.5);
161         }
162         else if(ctrl) {
163                 if(fac2!= 0.0) *val= fac2*floor(*val/fac2 +.5);
164         }
165         else {
166                 if(fac1!= 0.0) *val= fac1*floor(*val/fac1 +.5);
167         }
168 }
169
170
171 int GetButStringLength(const char *str) 
172 {
173         int rt;
174         
175         rt= UI_GetStringWidth(str);
176         
177         return rt + 15;
178 }
179
180
181 void unpack_menu(bContext *C, const char *opname, const char *id_name, const char *abs_name, const char *folder, struct PackedFile *pf)
182 {
183         PointerRNA props_ptr;
184         uiPopupMenu *pup;
185         uiLayout *layout;
186         char line[FILE_MAXDIR + FILE_MAXFILE + 100];
187
188         pup= uiPupMenuBegin(C, "Unpack file", ICON_NONE);
189         layout= uiPupMenuLayout(pup);
190
191         sprintf(line, "Remove Pack");
192         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
193         RNA_enum_set(&props_ptr, "method", PF_REMOVE);
194         RNA_string_set(&props_ptr, "id", id_name);
195
196         if(G.relbase_valid) {
197                 char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
198
199                 BLI_strncpy(local_name, abs_name, sizeof(local_name));
200                 BLI_splitdirstring(local_name, fi);
201                 sprintf(local_name, "//%s/%s", folder, fi);
202                 if(strcmp(abs_name, local_name)!=0) {
203                         switch(checkPackedFile(local_name, pf)) {
204                                 case PF_NOFILE:
205                                         sprintf(line, "Create %s", local_name);
206                                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
207                                         RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
208                                         RNA_string_set(&props_ptr, "id", id_name);
209
210                                         break;
211                                 case PF_EQUAL:
212                                         sprintf(line, "Use %s (identical)", local_name);
213                                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL);
214                                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
215                                         RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
216                                         RNA_string_set(&props_ptr, "id", id_name);
217
218                                         break;
219                                 case PF_DIFFERS:
220                                         sprintf(line, "Use %s (differs)", local_name);
221                                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_LOCAL);
222                                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
223                                         RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
224                                         RNA_string_set(&props_ptr, "id", id_name);
225
226                                         sprintf(line, "Overwrite %s", local_name);
227                                         //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_LOCAL);
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_WRITE_LOCAL);
230                                         RNA_string_set(&props_ptr, "id", id_name);
231                                         break;
232                         }
233                 }
234         }
235
236         switch(checkPackedFile(abs_name, pf)) {
237                 case PF_NOFILE:
238                         sprintf(line, "Create %s", abs_name);
239                         //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL);
240                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
241                         RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
242                         RNA_string_set(&props_ptr, "id", id_name);
243                         break;
244                 case PF_EQUAL:
245                         sprintf(line, "Use %s (identical)", abs_name);
246                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL);
247                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
248                         RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
249                         RNA_string_set(&props_ptr, "id", id_name);
250                         break;
251                 case PF_DIFFERS:
252                         sprintf(line, "Use %s (differs)", abs_name);
253                         //uiItemEnumO(layout, opname, line, 0, "method", PF_USE_ORIGINAL);
254                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
255                         RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
256                         RNA_string_set(&props_ptr, "id", id_name);
257
258                         sprintf(line, "Overwrite %s", abs_name);
259                         //uiItemEnumO(layout, opname, line, 0, "method", PF_WRITE_ORIGINAL);
260                         props_ptr= uiItemFullO(layout, opname, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
261                         RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
262                         RNA_string_set(&props_ptr, "id", id_name);
263                         break;
264         }
265
266         uiPupMenuEnd(C, pup);
267 }