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