Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2009 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Blender Foundation 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 #include <stdlib.h> 00032 #include <string.h> 00033 00034 #include "MEM_guardedalloc.h" 00035 00036 #include "DNA_userdef_types.h" 00037 00038 #include "BLI_fileops.h" 00039 #include "BLI_path_util.h" 00040 #include "BLI_string.h" 00041 #include "BLI_utildefines.h" 00042 00043 #include "BKE_context.h" 00044 #include "BKE_global.h" 00045 #include "BKE_main.h" 00046 00047 #include "WM_api.h" 00048 #include "WM_types.h" 00049 00050 #include "ED_screen.h" 00051 #include "ED_util.h" 00052 00053 #include "RNA_access.h" 00054 00055 #include "UI_interface.h" 00056 #include "UI_resources.h" 00057 00058 #include "buttons_intern.h" // own include 00059 00060 /********************** toolbox operator *********************/ 00061 00062 static int toolbox_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event)) 00063 { 00064 bScreen *sc= CTX_wm_screen(C); 00065 SpaceButs *sbuts= CTX_wm_space_buts(C); 00066 PointerRNA ptr; 00067 uiPopupMenu *pup; 00068 uiLayout *layout; 00069 00070 RNA_pointer_create(&sc->id, &RNA_SpaceProperties, sbuts, &ptr); 00071 00072 pup= uiPupMenuBegin(C, "Align", ICON_NONE); 00073 layout= uiPupMenuLayout(pup); 00074 uiItemsEnumR(layout, &ptr, "align"); 00075 uiPupMenuEnd(C, pup); 00076 00077 return OPERATOR_CANCELLED; 00078 } 00079 00080 void BUTTONS_OT_toolbox(wmOperatorType *ot) 00081 { 00082 /* identifiers */ 00083 ot->name= "Toolbox"; 00084 ot->description="Display button panel toolbox"; 00085 ot->idname= "BUTTONS_OT_toolbox"; 00086 00087 /* api callbacks */ 00088 ot->invoke= toolbox_invoke; 00089 ot->poll= ED_operator_buttons_active; 00090 } 00091 00092 /********************** filebrowse operator *********************/ 00093 00094 typedef struct FileBrowseOp { 00095 PointerRNA ptr; 00096 PropertyRNA *prop; 00097 } FileBrowseOp; 00098 00099 static int file_browse_exec(bContext *C, wmOperator *op) 00100 { 00101 FileBrowseOp *fbo= op->customdata; 00102 ID *id; 00103 char *str, path[FILE_MAX]; 00104 const char *path_prop= RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath"; 00105 00106 if (RNA_struct_property_is_set(op->ptr, path_prop)==0 || fbo==NULL) 00107 return OPERATOR_CANCELLED; 00108 00109 str= RNA_string_get_alloc(op->ptr, path_prop, NULL, 0); 00110 00111 /* add slash for directories, important for some properties */ 00112 if(RNA_property_subtype(fbo->prop) == PROP_DIRPATH) { 00113 char name[FILE_MAX]; 00114 00115 id = fbo->ptr.id.data; 00116 00117 BLI_strncpy(path, str, FILE_MAX); 00118 BLI_path_abs(path, id ? ID_BLEND_PATH(G.main, id) : G.main->name); 00119 00120 if(BLI_is_dir(path)) { 00121 str = MEM_reallocN(str, strlen(str)+2); 00122 BLI_add_slash(str); 00123 } 00124 else 00125 BLI_splitdirstring(str, name); 00126 } 00127 00128 RNA_property_string_set(&fbo->ptr, fbo->prop, str); 00129 RNA_property_update(C, &fbo->ptr, fbo->prop); 00130 MEM_freeN(str); 00131 00132 00133 /* special, annoying exception, filesel on redo panel [#26618] */ 00134 { 00135 wmOperator *redo_op= WM_operator_last_redo(C); 00136 if(redo_op) { 00137 if(fbo->ptr.data == redo_op->ptr->data) { 00138 ED_undo_operator_repeat(C, redo_op); 00139 } 00140 } 00141 } 00142 00143 MEM_freeN(op->customdata); 00144 00145 return OPERATOR_FINISHED; 00146 } 00147 00148 static int file_browse_cancel(bContext *UNUSED(C), wmOperator *op) 00149 { 00150 MEM_freeN(op->customdata); 00151 op->customdata= NULL; 00152 00153 return OPERATOR_CANCELLED; 00154 } 00155 00156 static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event) 00157 { 00158 PointerRNA ptr; 00159 PropertyRNA *prop; 00160 FileBrowseOp *fbo; 00161 char *str; 00162 00163 uiFileBrowseContextProperty(C, &ptr, &prop); 00164 00165 if(!prop) 00166 return OPERATOR_CANCELLED; 00167 00168 str= RNA_property_string_get_alloc(&ptr, prop, NULL, 0, NULL); 00169 00170 /* useful yet irritating feature, Shift+Click to open the file 00171 * Alt+Click to browse a folder in the OS's browser */ 00172 if(event->shift || event->alt) { 00173 PointerRNA props_ptr; 00174 00175 if(event->alt) { 00176 char *lslash= BLI_last_slash(str); 00177 if(lslash) 00178 *lslash= '\0'; 00179 } 00180 00181 00182 WM_operator_properties_create(&props_ptr, "WM_OT_path_open"); 00183 RNA_string_set(&props_ptr, "filepath", str); 00184 WM_operator_name_call(C, "WM_OT_path_open", WM_OP_EXEC_DEFAULT, &props_ptr); 00185 WM_operator_properties_free(&props_ptr); 00186 00187 MEM_freeN(str); 00188 return OPERATOR_CANCELLED; 00189 } 00190 else { 00191 const char *path_prop= RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath"; 00192 fbo= MEM_callocN(sizeof(FileBrowseOp), "FileBrowseOp"); 00193 fbo->ptr= ptr; 00194 fbo->prop= prop; 00195 op->customdata= fbo; 00196 00197 RNA_string_set(op->ptr, path_prop, str); 00198 MEM_freeN(str); 00199 00200 /* normally ED_fileselect_get_params would handle this but we need to because of stupid 00201 * user-prefs exception - campbell */ 00202 if(RNA_struct_find_property(op->ptr, "relative_path")) { 00203 if(!RNA_struct_property_is_set(op->ptr, "relative_path")) { 00204 /* annoying exception!, if were dealign with the user prefs, default relative to be off */ 00205 RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS && (ptr.data != &U)); 00206 } 00207 } 00208 WM_event_add_fileselect(C, op); 00209 00210 return OPERATOR_RUNNING_MODAL; 00211 } 00212 } 00213 00214 void BUTTONS_OT_file_browse(wmOperatorType *ot) 00215 { 00216 /* identifiers */ 00217 ot->name= "Accept"; 00218 ot->description="Open a file browser, Hold Shift to open the file, Alt to browse containing directory"; 00219 ot->idname= "BUTTONS_OT_file_browse"; 00220 00221 /* api callbacks */ 00222 ot->invoke= file_browse_invoke; 00223 ot->exec= file_browse_exec; 00224 ot->cancel= file_browse_cancel; 00225 00226 /* properties */ 00227 WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); 00228 } 00229 00230 /* second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY */ 00231 void BUTTONS_OT_directory_browse(wmOperatorType *ot) 00232 { 00233 /* identifiers */ 00234 ot->name= "Accept"; 00235 ot->description="Open a directory browser, Hold Shift to open the file, Alt to browse containing directory"; 00236 ot->idname= "BUTTONS_OT_directory_browse"; 00237 00238 /* api callbacks */ 00239 ot->invoke= file_browse_invoke; 00240 ot->exec= file_browse_exec; 00241 ot->cancel= file_browse_cancel; 00242 00243 /* properties */ 00244 WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH); 00245 }