Blender  V2.59
buttons_ops.c
Go to the documentation of this file.
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 }