Blender V2.61 - r43446

interface_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, Joshua Leung
00022  *
00023  * ***** END GPL LICENSE BLOCK *****
00024  */
00025 
00031 #include <stdio.h>
00032 #include <math.h>
00033 #include <string.h>
00034 
00035 #include "MEM_guardedalloc.h"
00036 
00037 #include "DNA_scene_types.h"
00038 #include "DNA_screen_types.h"
00039 #include "DNA_text_types.h" /* for UI_OT_reports_to_text */
00040 
00041 #include "BLI_blenlib.h"
00042 #include "BLI_math_color.h"
00043 #include "BLI_utildefines.h"
00044 
00045 #include "BKE_context.h"
00046 #include "BKE_screen.h"
00047 #include "BKE_global.h"
00048 #include "BKE_text.h" /* for UI_OT_reports_to_text */
00049 #include "BKE_report.h"
00050 
00051 #include "RNA_access.h"
00052 #include "RNA_define.h"
00053 
00054 #include "BIF_gl.h"
00055 
00056 #include "UI_interface.h"
00057 
00058 #include "interface_intern.h"
00059 
00060 #include "WM_api.h"
00061 #include "WM_types.h"
00062 
00063 /* only for UI_OT_editsource */
00064 #include "ED_screen.h"
00065 #include "BKE_main.h"
00066 #include "BLI_ghash.h"
00067 
00068 
00069 /* ********************************************************** */
00070 
00071 typedef struct Eyedropper {
00072     PointerRNA ptr;
00073     PropertyRNA *prop;
00074     int index;
00075 } Eyedropper;
00076 
00077 static int eyedropper_init(bContext *C, wmOperator *op)
00078 {
00079     Eyedropper *eye;
00080     
00081     op->customdata= eye= MEM_callocN(sizeof(Eyedropper), "Eyedropper");
00082     
00083     uiContextActiveProperty(C, &eye->ptr, &eye->prop, &eye->index);
00084     
00085     return (eye->ptr.data && eye->prop && RNA_property_editable(&eye->ptr, eye->prop));
00086 }
00087  
00088 static void eyedropper_exit(bContext *C, wmOperator *op)
00089 {
00090     WM_cursor_restore(CTX_wm_window(C));
00091     
00092     if(op->customdata)
00093         MEM_freeN(op->customdata);
00094     op->customdata= NULL;
00095 }
00096 
00097 static int eyedropper_cancel(bContext *C, wmOperator *op)
00098 {
00099     eyedropper_exit(C, op);
00100     return OPERATOR_CANCELLED;
00101 }
00102 
00103 static void eyedropper_sample(bContext *C, Eyedropper *eye, int mx, int my)
00104 {
00105     if(RNA_property_type(eye->prop) == PROP_FLOAT) {
00106         const int color_manage = CTX_data_scene(C)->r.color_mgt_flag & R_COLOR_MANAGEMENT;
00107         float col[4];
00108     
00109         RNA_property_float_get_array(&eye->ptr, eye->prop, col);
00110         
00111         glReadBuffer(GL_FRONT);
00112         glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, col);
00113         glReadBuffer(GL_BACK);
00114     
00115         if (RNA_property_array_length(&eye->ptr, eye->prop) < 3) return;
00116 
00117         /* convert from screen (srgb) space to linear rgb space */
00118         if (color_manage && RNA_property_subtype(eye->prop) == PROP_COLOR)
00119             srgb_to_linearrgb_v3_v3(col, col);
00120         
00121         RNA_property_float_set_array(&eye->ptr, eye->prop, col);
00122         
00123         RNA_property_update(C, &eye->ptr, eye->prop);
00124     }
00125 }
00126 
00127 /* main modal status check */
00128 static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event)
00129 {
00130     Eyedropper *eye = (Eyedropper *)op->customdata;
00131     
00132     switch(event->type) {
00133         case ESCKEY:
00134         case RIGHTMOUSE:
00135             return eyedropper_cancel(C, op);
00136         case LEFTMOUSE:
00137             if(event->val==KM_RELEASE) {
00138                 eyedropper_sample(C, eye, event->x, event->y);
00139                 eyedropper_exit(C, op);
00140                 return OPERATOR_FINISHED;
00141             }
00142             break;
00143     }
00144     
00145     return OPERATOR_RUNNING_MODAL;
00146 }
00147 
00148 /* Modal Operator init */
00149 static int eyedropper_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00150 {
00151     /* init */
00152     if (eyedropper_init(C, op)) {
00153         WM_cursor_modal(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
00154 
00155         /* add temp handler */
00156         WM_event_add_modal_handler(C, op);
00157         
00158         return OPERATOR_RUNNING_MODAL;
00159     } else {
00160         eyedropper_exit(C, op);
00161         return OPERATOR_CANCELLED;
00162     }
00163 }
00164 
00165 /* Repeat operator */
00166 static int eyedropper_exec (bContext *C, wmOperator *op)
00167 {
00168     /* init */
00169     if (eyedropper_init(C, op)) {
00170         
00171         /* do something */
00172         
00173         /* cleanup */
00174         eyedropper_exit(C, op);
00175         
00176         return OPERATOR_FINISHED;
00177     } else {
00178         return OPERATOR_CANCELLED;
00179     }
00180 }
00181 
00182 static int eyedropper_poll(bContext *C)
00183 {
00184     if (!CTX_wm_window(C)) return 0;
00185     else return 1;
00186 }
00187 
00188 static void UI_OT_eyedropper(wmOperatorType *ot)
00189 {
00190     /* identifiers */
00191     ot->name= "Eyedropper";
00192     ot->idname= "UI_OT_eyedropper";
00193     ot->description= "Sample a color from the Blender Window to store in a property";
00194     
00195     /* api callbacks */
00196     ot->invoke= eyedropper_invoke;
00197     ot->modal= eyedropper_modal;
00198     ot->cancel= eyedropper_cancel;
00199     ot->exec= eyedropper_exec;
00200     ot->poll= eyedropper_poll;
00201     
00202     /* flags */
00203     ot->flag= OPTYPE_BLOCKING;
00204     
00205     /* properties */
00206 }
00207 
00208 /* Reset Default Theme ------------------------ */
00209 
00210 static int reset_default_theme_exec(bContext *C, wmOperator *UNUSED(op))
00211 {
00212     ui_theme_init_default();
00213     WM_event_add_notifier(C, NC_WINDOW, NULL);
00214     
00215     return OPERATOR_FINISHED;
00216 }
00217 
00218 static void UI_OT_reset_default_theme(wmOperatorType *ot)
00219 {
00220     /* identifiers */
00221     ot->name= "Reset to Default Theme";
00222     ot->idname= "UI_OT_reset_default_theme";
00223     ot->description= "Reset to the default theme colors";
00224     
00225     /* callbacks */
00226     ot->exec= reset_default_theme_exec;
00227     
00228     /* flags */
00229     ot->flag= OPTYPE_REGISTER;
00230 }
00231 
00232 /* Copy Data Path Operator ------------------------ */
00233 
00234 static int copy_data_path_button_exec(bContext *C, wmOperator *UNUSED(op))
00235 {
00236     PointerRNA ptr;
00237     PropertyRNA *prop;
00238     char *path;
00239     int success= 0;
00240     int index;
00241 
00242     /* try to create driver using property retrieved from UI */
00243     uiContextActiveProperty(C, &ptr, &prop, &index);
00244 
00245     if (ptr.id.data && ptr.data && prop) {
00246         path= RNA_path_from_ID_to_property(&ptr, prop);
00247         
00248         if (path) {
00249             WM_clipboard_text_set(path, FALSE);
00250             MEM_freeN(path);
00251         }
00252     }
00253 
00254     /* since we're just copying, we don't really need to do anything else...*/
00255     return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
00256 }
00257 
00258 static void UI_OT_copy_data_path_button(wmOperatorType *ot)
00259 {
00260     /* identifiers */
00261     ot->name= "Copy Data Path";
00262     ot->idname= "UI_OT_copy_data_path_button";
00263     ot->description= "Copy the RNA data path for this property to the clipboard";
00264 
00265     /* callbacks */
00266     ot->exec= copy_data_path_button_exec;
00267     //op->poll= ??? // TODO: need to have some valid property before this can be done
00268 
00269     /* flags */
00270     ot->flag= OPTYPE_REGISTER;
00271 }
00272 
00273 /* Reset to Default Values Button Operator ------------------------ */
00274 
00275 static int reset_default_button_poll(bContext *C)
00276 {
00277     PointerRNA ptr;
00278     PropertyRNA *prop;
00279     int index;
00280 
00281     uiContextActiveProperty(C, &ptr, &prop, &index);
00282     
00283     return (ptr.data && prop && RNA_property_editable(&ptr, prop));
00284 }
00285 
00286 static int reset_default_button_exec(bContext *C, wmOperator *op)
00287 {
00288     PointerRNA ptr;
00289     PropertyRNA *prop;
00290     int success= 0;
00291     int index, all = RNA_boolean_get(op->ptr, "all");
00292 
00293     /* try to reset the nominated setting to its default value */
00294     uiContextActiveProperty(C, &ptr, &prop, &index);
00295     
00296     /* if there is a valid property that is editable... */
00297     if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
00298         if(RNA_property_reset(&ptr, prop, (all)? -1: index)) {
00299             /* perform updates required for this property */
00300             RNA_property_update(C, &ptr, prop);
00301 
00302             /* as if we pressed the button */
00303             uiContextActivePropertyHandle(C);
00304 
00305             success= 1;
00306         }
00307     }
00308 
00309     /* Since we dont want to undo _all_ edits to settings, eg window
00310      * edits on the screen or on operator settings.
00311      * it might be better to move undo's inline - campbell */
00312     if(success) {
00313         ID *id= ptr.id.data;
00314         if(id && ID_CHECK_UNDO(id)) {
00315             /* do nothing, go ahead with undo */
00316         }
00317         else {
00318             return OPERATOR_CANCELLED;
00319         }
00320     }
00321     /* end hack */
00322 
00323     return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
00324 }
00325 
00326 static void UI_OT_reset_default_button(wmOperatorType *ot)
00327 {
00328     /* identifiers */
00329     ot->name= "Reset to Default Value";
00330     ot->idname= "UI_OT_reset_default_button";
00331     ot->description= "Reset this property's value to its default value";
00332 
00333     /* callbacks */
00334     ot->poll= reset_default_button_poll;
00335     ot->exec= reset_default_button_exec;
00336 
00337     /* flags */
00338     ot->flag= OPTYPE_UNDO;
00339     
00340     /* properties */
00341     RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
00342 }
00343 
00344 /* Copy To Selected Operator ------------------------ */
00345 
00346 static int copy_to_selected_list(bContext *C, PointerRNA *ptr, ListBase *lb)
00347 {
00348     if(RNA_struct_is_a(ptr->type, &RNA_Object))
00349         *lb = CTX_data_collection_get(C, "selected_editable_objects");
00350     else if(RNA_struct_is_a(ptr->type, &RNA_EditBone))
00351         *lb = CTX_data_collection_get(C, "selected_editable_bones");
00352     else if(RNA_struct_is_a(ptr->type, &RNA_PoseBone))
00353         *lb = CTX_data_collection_get(C, "selected_pose_bones");
00354     else if(RNA_struct_is_a(ptr->type, &RNA_Sequence))
00355         *lb = CTX_data_collection_get(C, "selected_editable_sequences");
00356     else
00357         return 0;
00358     
00359     return 1;
00360 }
00361 
00362 static int copy_to_selected_button_poll(bContext *C)
00363 {
00364     PointerRNA ptr;
00365     PropertyRNA *prop;
00366     int index, success= 0;
00367 
00368     uiContextActiveProperty(C, &ptr, &prop, &index);
00369 
00370     if (ptr.data && prop) {
00371         CollectionPointerLink *link;
00372         ListBase lb;
00373 
00374         if(copy_to_selected_list(C, &ptr, &lb)) {
00375             for(link= lb.first; link; link=link->next)
00376                 if(link->ptr.data != ptr.data && RNA_property_editable(&link->ptr, prop))
00377                     success= 1;
00378 
00379             BLI_freelistN(&lb);
00380         }
00381     }
00382 
00383     return success;
00384 }
00385 
00386 static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
00387 {
00388     PointerRNA ptr;
00389     PropertyRNA *prop;
00390     int success= 0;
00391     int index, all = RNA_boolean_get(op->ptr, "all");
00392 
00393     /* try to reset the nominated setting to its default value */
00394     uiContextActiveProperty(C, &ptr, &prop, &index);
00395     
00396     /* if there is a valid property that is editable... */
00397     if (ptr.data && prop) {
00398         CollectionPointerLink *link;
00399         ListBase lb;
00400 
00401         if(copy_to_selected_list(C, &ptr, &lb)) {
00402             for(link= lb.first; link; link=link->next) {
00403                 if(link->ptr.data != ptr.data && RNA_property_editable(&link->ptr, prop)) {
00404                     if(RNA_property_copy(&link->ptr, &ptr, prop, (all)? -1: index)) {
00405                         RNA_property_update(C, &link->ptr, prop);
00406                         success= 1;
00407                     }
00408                 }
00409             }
00410 
00411             BLI_freelistN(&lb);
00412         }
00413     }
00414     
00415     return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
00416 }
00417 
00418 static void UI_OT_copy_to_selected_button(wmOperatorType *ot)
00419 {
00420     /* identifiers */
00421     ot->name= "Copy To Selected";
00422     ot->idname= "UI_OT_copy_to_selected_button";
00423     ot->description= "Copy property from this object to selected objects or bones";
00424 
00425     /* callbacks */
00426     ot->poll= copy_to_selected_button_poll;
00427     ot->exec= copy_to_selected_button_exec;
00428 
00429     /* flags */
00430     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00431 
00432     /* properties */
00433     RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
00434 }
00435 
00436 /* Reports to Textblock Operator ------------------------ */
00437 
00438 /* FIXME: this is just a temporary operator so that we can see all the reports somewhere 
00439  * when there are too many to display...
00440  */
00441 
00442 static int reports_to_text_poll(bContext *C)
00443 {
00444     return CTX_wm_reports(C) != NULL;
00445 }
00446 
00447 static int reports_to_text_exec(bContext *C, wmOperator *UNUSED(op))
00448 {
00449     ReportList *reports = CTX_wm_reports(C);
00450     Text *txt;
00451     char *str;
00452     
00453     /* create new text-block to write to */
00454     txt = add_empty_text("Recent Reports");
00455     
00456     /* convert entire list to a display string, and add this to the text-block
00457      *  - if commandline debug option enabled, show debug reports too
00458      *  - otherwise, up to info (which is what users normally see)
00459      */
00460     str = BKE_reports_string(reports, (G.f & G_DEBUG)? RPT_DEBUG : RPT_INFO);
00461 
00462     if (str) {
00463         write_text(txt, str);
00464         MEM_freeN(str);
00465 
00466         return OPERATOR_FINISHED;
00467     }
00468     else {
00469         return OPERATOR_CANCELLED;
00470     }
00471 }
00472 
00473 static void UI_OT_reports_to_textblock(wmOperatorType *ot)
00474 {
00475     /* identifiers */
00476     ot->name= "Reports to Text Block";
00477     ot->idname= "UI_OT_reports_to_textblock";
00478     ot->description= "Write the reports ";
00479     
00480     /* callbacks */
00481     ot->poll= reports_to_text_poll;
00482     ot->exec= reports_to_text_exec;
00483 }
00484 
00485 #ifdef WITH_PYTHON
00486 
00487 /* ------------------------------------------------------------------------- */
00488 /* EditSource Utility funcs and operator,
00489  * note, this includes itility functions and button matching checks */
00490 
00491 struct uiEditSourceStore {
00492     uiBut but_orig;
00493     GHash *hash;
00494 } uiEditSourceStore;
00495 
00496 struct uiEditSourceButStore {
00497     char py_dbg_fn[FILE_MAX];
00498     int py_dbg_ln;
00499 } uiEditSourceButStore;
00500 
00501 /* should only ever be set while the edit source operator is running */
00502 static struct uiEditSourceStore *ui_editsource_info= NULL;
00503 
00504 int  UI_editsource_enable_check(void)
00505 {
00506     return (ui_editsource_info != NULL);
00507 }
00508 
00509 static void ui_editsource_active_but_set(uiBut *but)
00510 {
00511     BLI_assert(ui_editsource_info == NULL);
00512 
00513     ui_editsource_info= MEM_callocN(sizeof(uiEditSourceStore), __func__);
00514     memcpy(&ui_editsource_info->but_orig, but, sizeof(uiBut));
00515 
00516     ui_editsource_info->hash = BLI_ghash_new(BLI_ghashutil_ptrhash,
00517                                              BLI_ghashutil_ptrcmp,
00518                                              __func__);
00519 }
00520 
00521 static void ui_editsource_active_but_clear(void)
00522 {
00523     BLI_ghash_free(ui_editsource_info->hash, NULL, (GHashValFreeFP)MEM_freeN);
00524     MEM_freeN(ui_editsource_info);
00525     ui_editsource_info= NULL;
00526 }
00527 
00528 static int ui_editsource_uibut_match(uiBut *but_a, uiBut *but_b)
00529 {
00530 #if 0
00531     printf("matching buttons: '%s' == '%s'\n",
00532            but_a->drawstr, but_b->drawstr);
00533 #endif
00534 
00535     /* this just needs to be a 'good-enough' comparison so we can know beyond
00536      * reasonable doubt that these buttons are the same between redraws.
00537      * if this fails it only means edit-source fails - campbell */
00538     if(     (but_a->x1 == but_b->x1) &&
00539             (but_a->x2 == but_b->x2) &&
00540             (but_a->y1 == but_b->y1) &&
00541             (but_a->y2 == but_b->y2) &&
00542             (but_a->type == but_b->type) &&
00543             (but_a->rnaprop == but_b->rnaprop) &&
00544             (but_a->optype == but_b->optype) &&
00545             (but_a->unit_type == but_b->unit_type) &&
00546             strncmp(but_a->drawstr, but_b->drawstr, UI_MAX_DRAW_STR) == 0
00547     ) {
00548         return TRUE;
00549     }
00550     else {
00551         return FALSE;
00552     }
00553 }
00554 
00555 void UI_editsource_active_but_test(uiBut *but)
00556 {
00557     extern void PyC_FileAndNum_Safe(const char **filename, int *lineno);
00558 
00559     struct uiEditSourceButStore *but_store= MEM_callocN(sizeof(uiEditSourceButStore), __func__);
00560 
00561     const char *fn;
00562     int lineno= -1;
00563 
00564 #if 0
00565     printf("comparing buttons: '%s' == '%s'\n",
00566            but->drawstr, ui_editsource_info->but_orig.drawstr);
00567 #endif
00568 
00569     PyC_FileAndNum_Safe(&fn, &lineno);
00570 
00571     if (lineno != -1) {
00572         BLI_strncpy(but_store->py_dbg_fn, fn,
00573                     sizeof(but_store->py_dbg_fn));
00574         but_store->py_dbg_ln= lineno;
00575     }
00576     else {
00577         but_store->py_dbg_fn[0]= '\0';
00578         but_store->py_dbg_ln= -1;
00579     }
00580 
00581     BLI_ghash_insert(ui_editsource_info->hash, but, but_store);
00582 }
00583 
00584 /* editsource operator component */
00585 
00586 static int editsource_text_edit(bContext *C, wmOperator *op,
00587                                 char filepath[FILE_MAX], int line)
00588 {
00589     struct Main *bmain= CTX_data_main(C);
00590     Text *text;
00591 
00592     for (text=bmain->text.first; text; text=text->id.next) {
00593         if (text->name && BLI_path_cmp(text->name, filepath) == 0) {
00594             break;
00595         }
00596     }
00597 
00598     if (text == NULL) {
00599         text= add_text(filepath, bmain->name);
00600     }
00601 
00602     if (text == NULL) {
00603         BKE_reportf(op->reports, RPT_WARNING,
00604                     "file: '%s' can't be opened", filepath);
00605         return OPERATOR_CANCELLED;
00606     }
00607     else {
00608         /* naughty!, find text area to set, not good behavior
00609          * but since this is a dev tool lets allow it - campbell */
00610         ScrArea *sa= BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_TEXT, 0);
00611         if(sa) {
00612             SpaceText *st= sa->spacedata.first;
00613             st->text= text;
00614         }
00615         else {
00616             BKE_reportf(op->reports, RPT_INFO,
00617                         "See '%s' in the text editor", text->id.name + 2);
00618         }
00619 
00620         txt_move_toline(text, line - 1, FALSE);
00621         WM_event_add_notifier(C, NC_TEXT|ND_CURSOR, text);
00622     }
00623 
00624     return OPERATOR_FINISHED;
00625 }
00626 
00627 static int editsource_exec(bContext *C, wmOperator *op)
00628 {
00629     uiBut *but= uiContextActiveButton(C);
00630 
00631     if (but) {
00632         GHashIterator ghi;
00633         struct uiEditSourceButStore *but_store= NULL;
00634 
00635         ARegion *ar= CTX_wm_region(C);
00636         int ret;
00637 
00638         /* needed else the active button does not get tested */
00639         uiFreeActiveButtons(C, CTX_wm_screen(C));
00640 
00641         // printf("%s: begin\n", __func__);
00642 
00643         /* take care not to return before calling ui_editsource_active_but_clear */
00644         ui_editsource_active_but_set(but);
00645 
00646         /* redraw and get active button python info */
00647         ED_region_do_draw(C, ar);
00648 
00649         for(BLI_ghashIterator_init(&ghi, ui_editsource_info->hash);
00650             !BLI_ghashIterator_isDone(&ghi);
00651             BLI_ghashIterator_step(&ghi))
00652         {
00653             uiBut *but= BLI_ghashIterator_getKey(&ghi);
00654             if (but && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but)) {
00655                 but_store= BLI_ghashIterator_getValue(&ghi);
00656                 break;
00657             }
00658 
00659         }
00660 
00661         if (but_store) {
00662             if (but_store->py_dbg_ln != -1) {
00663                 ret= editsource_text_edit(C, op,
00664                                           but_store->py_dbg_fn,
00665                                           but_store->py_dbg_ln);
00666             }
00667             else {
00668                 BKE_report(op->reports, RPT_ERROR,
00669                            "Active button isn't from a script, cant edit source.");
00670                 ret= OPERATOR_CANCELLED;
00671             }
00672         }
00673         else {
00674             BKE_report(op->reports, RPT_ERROR,
00675                        "Active button match can't be found.");
00676             ret= OPERATOR_CANCELLED;
00677         }
00678 
00679 
00680         ui_editsource_active_but_clear();
00681 
00682         // printf("%s: end\n", __func__);
00683 
00684         return ret;
00685     }
00686     else {
00687         BKE_report(op->reports, RPT_ERROR, "Active button not found");
00688         return OPERATOR_CANCELLED;
00689     }
00690 }
00691 
00692 static void UI_OT_editsource(wmOperatorType *ot)
00693 {
00694     /* identifiers */
00695     ot->name= "Reports to Text Block";
00696     ot->idname= "UI_OT_editsource";
00697     ot->description= "Edit source code for a button";
00698 
00699     /* callbacks */
00700     ot->exec= editsource_exec;
00701 }
00702 
00703 #endif /* WITH_PYTHON */
00704 
00705 /* ********************************************************* */
00706 /* Registration */
00707 
00708 void UI_buttons_operatortypes(void)
00709 {
00710     WM_operatortype_append(UI_OT_eyedropper);
00711     WM_operatortype_append(UI_OT_reset_default_theme);
00712     WM_operatortype_append(UI_OT_copy_data_path_button);
00713     WM_operatortype_append(UI_OT_reset_default_button);
00714     WM_operatortype_append(UI_OT_copy_to_selected_button);
00715     WM_operatortype_append(UI_OT_reports_to_textblock); // XXX: temp?
00716 
00717 #ifdef WITH_PYTHON
00718     WM_operatortype_append(UI_OT_editsource);
00719 #endif
00720 }
00721