Blender V2.61 - r43446

buttons_ops.c

Go to the documentation of this file.
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 }