doxygen: blender/editors tagged.
[blender.git] / source / blender / editors / curve / editfont.c
index 20355de0e73b227d5f5aedd5a86e54ca6d67088c..798a9d0f7cd49917e40162762fde050c2c97c0c5 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/editors/curve/editfont.c
+ *  \ingroup edcurve
+ */
+
+
 #include <stdlib.h>
 #include <string.h>
 #include <fcntl.h>
@@ -40,6 +45,7 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
+#include "BLI_utildefines.h"
 
 #include "DNA_curve_types.h"
 #include "DNA_object_types.h"
 #include "BKE_curve.h"
 #include "BKE_depsgraph.h"
 #include "BKE_font.h"
-#include "BKE_global.h"
 #include "BKE_library.h"
-#include "BKE_main.h"
 #include "BKE_object.h"
 #include "BKE_report.h"
-#include "BKE_utildefines.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
@@ -64,6 +67,7 @@
 #include "WM_api.h"
 #include "WM_types.h"
 
+#include "ED_curve.h"
 #include "ED_object.h"
 #include "ED_screen.h"
 #include "ED_util.h"
@@ -208,7 +212,7 @@ static char findaccent(char char1, unsigned int code)
 }
 
 
-void update_string(Curve *cu)
+static void update_string(Curve *cu)
 {
        EditFont *ef= cu->editfont;
        int len;
@@ -239,10 +243,7 @@ static int insert_into_textbuf(Object *obedit, uintptr_t c)
                ef->textbuf[cu->pos]= c;
                ef->textbufinfo[cu->pos] = cu->curinfo;
                ef->textbufinfo[cu->pos].kern = 0;
-               if(obedit->actcol>0)
-                       ef->textbufinfo[cu->pos].mat_nr = obedit->actcol;
-               else
-                       ef->textbufinfo[cu->pos].mat_nr = 0;
+               ef->textbufinfo[cu->pos].mat_nr = obedit->actcol;
                                        
                cu->pos++;
                cu->len++;
@@ -260,31 +261,29 @@ static void text_update_edited(bContext *C, Scene *scene, Object *obedit, int re
 {
        Curve *cu= obedit->data;
        EditFont *ef= cu->editfont;
-
-       if(cu->pos)
-               cu->curinfo = ef->textbufinfo[cu->pos-1];
-       else
-               cu->curinfo = ef->textbufinfo[0];
+       cu->curinfo = ef->textbufinfo[cu->pos?cu->pos-1:0];
        
        if(obedit->totcol>0)
-               obedit->actcol= ef->textbufinfo[cu->pos-1].mat_nr;
+               obedit->actcol= ef->textbufinfo[cu->pos?cu->pos-1:0].mat_nr;
+
+       if(mode == FO_EDIT)
+               update_string(cu);
 
-       update_string(cu);
        BKE_text_to_curve(scene, obedit, mode);
 
        if(recalc)
-               DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+               DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 }
 
 /********************** insert lorem operator *********************/
 
-static int insert_lorem_exec(bContext *C, wmOperator *op)
+static int insert_lorem_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
-       char *p, *p2;
+       const char *p, *p2;
        int i;
-       static char *lastlorem;
+       static const char *lastlorem;
        
        if(lastlorem)
                p= lastlorem;
@@ -307,7 +306,7 @@ static int insert_lorem_exec(bContext *C, wmOperator *op)
        insert_into_textbuf(obedit, '\n');
        insert_into_textbuf(obedit, '\n');      
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -333,7 +332,7 @@ void FONT_OT_insert_lorem(wmOperatorType *ot)
 /* note this handles both ascii and utf8 unicode, previously
  * there were 3 functions that did effectively the same thing. */
 
-static int paste_file(bContext *C, ReportList *reports, char *filename)
+static int paste_file(bContext *C, ReportList *reports, const char *filename)
 {
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
@@ -374,7 +373,7 @@ static int paste_file(bContext *C, ReportList *reports, char *filename)
        }
        MEM_freeN(strp);
 
-       text_update_edited(C, scene, obedit, 1, 0);
+       text_update_edited(C, scene, obedit, 1, FO_EDIT);
 
        return OPERATOR_FINISHED;
 }
@@ -391,7 +390,7 @@ static int paste_file_exec(bContext *C, wmOperator *op)
        return retval;
 }
 
-static int paste_file_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int paste_file_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
        if(RNA_property_is_set(op->ptr, "filepath"))
                return paste_file_exec(C, op);
@@ -422,9 +421,9 @@ void FONT_OT_file_paste(wmOperatorType *ot)
 
 /******************* paste buffer operator ********************/
 
-static int paste_buffer_exec(bContext *C, wmOperator *op)
+static int paste_buffer_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       char *filename;
+       const char *filename;
 
 #ifdef WIN32
        filename= "C:\\windows\\temp\\cutbuf.txt";
@@ -634,7 +633,7 @@ static int set_style(bContext *C, int style, int clear)
                        ef->textbufinfo[i].flag |= style;
        }
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -722,7 +721,7 @@ static void copy_selection(Object *obedit)
        }
 }
 
-static int copy_text_exec(bContext *C, wmOperator *op)
+static int copy_text_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
 
@@ -745,7 +744,7 @@ void FONT_OT_text_copy(wmOperatorType *ot)
 
 /******************* cut text operator ********************/
 
-static int cut_text_exec(bContext *C, wmOperator *op)
+static int cut_text_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
@@ -757,7 +756,7 @@ static int cut_text_exec(bContext *C, wmOperator *op)
        copy_selection(obedit);
        kill_selection(obedit, 0);
 
-       text_update_edited(C, scene, obedit, 1, 0);
+       text_update_edited(C, scene, obedit, 1, FO_EDIT);
 
        return OPERATOR_FINISHED;
 }
@@ -815,7 +814,7 @@ static int paste_text_exec(bContext *C, wmOperator *op)
        if(!paste_selection(obedit, op->reports))
                return OPERATOR_CANCELLED;
 
-       text_update_edited(C, scene, obedit, 1, 0);
+       text_update_edited(C, scene, obedit, 1, FO_EDIT);
 
        return OPERATOR_FINISHED;
 }
@@ -856,7 +855,7 @@ static int move_cursor(bContext *C, int type, int select)
        Object *obedit= CTX_data_edit_object(C);
        Curve *cu= obedit->data;
        EditFont *ef= cu->editfont;
-       int cursmove= 0;
+       int cursmove= -1;
 
        switch(type) {
                case LINE_BEGIN:
@@ -926,7 +925,7 @@ static int move_cursor(bContext *C, int type, int select)
                        break;
        }
                
-       if(!cursmove)
+       if(cursmove == -1)
                return OPERATOR_CANCELLED;
 
        if(select == 0) {
@@ -1020,7 +1019,7 @@ static int change_spacing_exec(bContext *C, wmOperator *op)
 
        ef->textbufinfo[cu->pos-1].kern = kern;
 
-       text_update_edited(C, scene, obedit, 1, 0);
+       text_update_edited(C, scene, obedit, 1, FO_EDIT);
 
        return OPERATOR_FINISHED;
 }
@@ -1065,7 +1064,7 @@ static int change_character_exec(bContext *C, wmOperator *op)
 
        ef->textbuf[cu->pos - 1]= character;
 
-       text_update_edited(C, scene, obedit, 1, 0);
+       text_update_edited(C, scene, obedit, 1, FO_EDIT);
 
        return OPERATOR_FINISHED;
 }
@@ -1108,7 +1107,7 @@ static int line_break_exec(bContext *C, wmOperator *op)
 
        cu->selstart = cu->selend = 0;
 
-       text_update_edited(C, scene, obedit, 1, 0);
+       text_update_edited(C, scene, obedit, 1, FO_EDIT);
 
        return OPERATOR_FINISHED;
 }
@@ -1198,7 +1197,7 @@ static int delete_exec(bContext *C, wmOperator *op)
                        return OPERATOR_CANCELLED;
        }
 
-       text_update_edited(C, scene, obedit, 1, 0);
+       text_update_edited(C, scene, obedit, 1, FO_EDIT);
 
        return OPERATOR_FINISHED;
 }
@@ -1228,7 +1227,7 @@ static int insert_text_exec(bContext *C, wmOperator *op)
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
        char *inserted_utf8;
-       wchar_t *inserted_text, first;
+       wchar_t *inserted_text;
        int a, len;
 
        if(!RNA_property_is_set(op->ptr, "text"))
@@ -1239,7 +1238,6 @@ static int insert_text_exec(bContext *C, wmOperator *op)
 
        inserted_text= MEM_callocN(sizeof(wchar_t)*(len+1), "FONT_insert_text");
        utf8towchar(inserted_text, inserted_utf8);
-       first= inserted_text[0];
 
        for(a=0; a<len; a++)
                insert_into_textbuf(obedit, inserted_text[a]);
@@ -1248,7 +1246,7 @@ static int insert_text_exec(bContext *C, wmOperator *op)
        MEM_freeN(inserted_utf8);
 
        kill_selection(obedit, 1);
-       text_update_edited(C, scene, obedit, 1, 0);
+       text_update_edited(C, scene, obedit, 1, FO_EDIT);
 
        return OPERATOR_FINISHED;
 }
@@ -1267,6 +1265,12 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
 
        if(RNA_property_is_set(op->ptr, "text"))
                return insert_text_exec(C, op);
+
+       if(RNA_property_is_set(op->ptr, "accent")) {
+               if(cu->len!=0 && cu->pos>0)
+                       accentcode= 1;
+               return OPERATOR_FINISHED;
+       }
        
        /* tab should exit editmode, but we allow it to be typed using modifier keys */
        if(event==TABKEY) {
@@ -1316,12 +1320,12 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
                        }
                        
                        kill_selection(obedit, 1);
-                       text_update_edited(C, scene, obedit, 1, 0);
+                       text_update_edited(C, scene, obedit, 1, FO_EDIT);
                }
                else {
                        inserted_text[0]= ascii;
                        insert_into_textbuf(obedit, ascii);
-                       text_update_edited(C, scene, obedit, 1, 0);
+                       text_update_edited(C, scene, obedit, 1, FO_EDIT);
                }
        }
        else if(val && event == BACKSPACEKEY) {
@@ -1341,6 +1345,9 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
                RNA_string_set(op->ptr, "text", inserted_utf8);
        }
 
+       /* reset property? */
+       accentcode= 0;
+       
        return OPERATOR_FINISHED;
 }
 
@@ -1361,6 +1368,7 @@ void FONT_OT_text_insert(wmOperatorType *ot)
 
        /* properties */
        RNA_def_string(ot->srna, "text", "", 0, "Text", "Text to insert at the cursor position.");
+       RNA_def_boolean(ot->srna, "accent", 0, "Accent mode", "Next typed character will strike through previous, for special character input.");
 }
 
 
@@ -1375,7 +1383,7 @@ static int textbox_poll(bContext *C)
        return 1;
 }
 
-static int textbox_add_exec(bContext *C, wmOperator *op)
+static int textbox_add_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_active_object(C);
        Curve *cu= obedit->data;
@@ -1563,7 +1571,7 @@ static int set_case(bContext *C, int ccase)
                }
        }
 
-       text_update_edited(C, scene, obedit, 1, 0);
+       text_update_edited(C, scene, obedit, 1, FO_EDIT);
 
        return OPERATOR_FINISHED;
 }
@@ -1593,7 +1601,7 @@ void FONT_OT_case_set(wmOperatorType *ot)
 
 /********************** toggle case operator *********************/
 
-static int toggle_case_exec(bContext *C, wmOperator *op)
+static int toggle_case_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        Curve *cu= obedit->data;
@@ -1633,7 +1641,7 @@ void FONT_OT_case_toggle(wmOperatorType *ot)
 
 /* **************** Open Font ************** */
 
-static void open_init(bContext *C, wmOperator *op)
+static void font_ui_template_init(bContext *C, wmOperator *op)
 {
        PropertyPointerRNA *pprop;
        
@@ -1641,7 +1649,7 @@ static void open_init(bContext *C, wmOperator *op)
        uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
 }
 
-static int open_cancel(bContext *C, wmOperator *op)
+static int open_cancel(bContext *UNUSED(C), wmOperator *op)
 {
        MEM_freeN(op->customdata);
        op->customdata= NULL;
@@ -1650,67 +1658,66 @@ static int open_cancel(bContext *C, wmOperator *op)
 
 static int open_exec(bContext *C, wmOperator *op)
 {
-       Object *ob = CTX_data_active_object(C);
-       Curve *cu;
        VFont *font;
        PropertyPointerRNA *pprop;
        PointerRNA idptr;
        char str[FILE_MAX];
-       
        RNA_string_get(op->ptr, "filepath", str);
 
        font = load_vfont(str);
-       
+
        if(!font) {
                if(op->customdata) MEM_freeN(op->customdata);
                return OPERATOR_CANCELLED;
        }
-       
+
        if(!op->customdata)
-               open_init(C, op);
+               font_ui_template_init(C, op);
        
        /* hook into UI */
        pprop= op->customdata;
-       
+
        if(pprop->prop) {
                /* when creating new ID blocks, use is already 1, but RNA
                 * pointer se also increases user, so this compensates it */
                font->id.us--;
-               
+       
                RNA_id_pointer_create(&font->id, &idptr);
                RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
                RNA_property_update(C, &pprop->ptr, pprop->prop);
-       } else if(ob && ob->type == OB_FONT) {
-               cu = ob->data;
-               id_us_min(&cu->vfont->id);
-               cu->vfont = font;
        }
-       
-       DAG_id_flush_update(ob->data, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_GEOM|ND_DATA|NA_EDITED, ob->data);
-       
+
        MEM_freeN(op->customdata);
-       
+
        return OPERATOR_FINISHED;
 }
 
-static int open_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
-       Object *ob = CTX_data_active_object(C);
-       Curve *cu;
        VFont *font=NULL;
        char *path;
-       if (ob && ob->type == OB_FONT) {
-               cu = ob->data;
-               font = cu->vfont;
+
+       PointerRNA idptr;
+       PropertyPointerRNA *pprop;
+
+       font_ui_template_init(C, op);
+
+       /* hook into UI */
+       pprop= op->customdata;
+
+       if(pprop->prop) {
+               idptr= RNA_property_pointer_get((PointerRNA *)pprop, pprop->prop);
+               font= idptr.id.data;
        }
-       path = (font && font->name)? font->name: U.fontdir;
-        
+
+       path = (font && strcmp(font->name, FO_BUILTIN_NAME) != 0)? font->name: U.fontdir;
+       
+       if(!RNA_property_is_set(op->ptr, "relative_path"))
+               RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
+               
        if(RNA_property_is_set(op->ptr, "filepath"))
                return open_exec(C, op);
-       
-       open_init(C, op);
-       
+
        RNA_string_set(op->ptr, "filepath", path);
        WM_event_add_fileselect(C, op); 
 
@@ -1732,52 +1739,31 @@ void FONT_OT_open(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /* properties */
-       WM_operator_properties_filesel(ot, FOLDERFILE|FTFONTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH);
+       WM_operator_properties_filesel(ot, FOLDERFILE|FTFONTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH);
 }
 
 /******************* delete operator *********************/
-static int font_unlink_poll(bContext *C)
-{
-       Object *ob = CTX_data_active_object(C);
-       Curve *cu;
-       
-       if (!ED_operator_object_active_editable(C) ) return 0;
-       if (ob->type != OB_FONT) return 0;
-       
-       cu = ob->data;
-       if (cu && strcmp(cu->vfont->name, "<builtin>")==0) return 0;
-       return 1;
-}
 
 static int font_unlink_exec(bContext *C, wmOperator *op)
 {
-       Object *ob = CTX_data_active_object(C);
-       Curve *cu;
-       VFont *font, *builtin_font;
-               
-       cu = ob->data;
-       font = cu->vfont;
+       VFont *builtin_font;
+
+       PointerRNA idptr;
+       PropertyPointerRNA pprop;
+
+       uiIDContextProperty(C, &pprop.ptr, &pprop.prop);
        
-       if (!font) {
-               BKE_report(op->reports, RPT_ERROR, "No font datablock available to unlink.");
+       if(pprop.prop==NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Incorrect context for running font unlink");
                return OPERATOR_CANCELLED;
        }
-       
-       if (strcmp(font->name, "<builtin>")==0) {
-               BKE_report(op->reports, RPT_WARNING, "Can't unlink the default builtin font.");
-               return OPERATOR_FINISHED;
-       }
 
-       /* revert back to builtin font */
        builtin_font = get_builtin_font();
 
-       cu->vfont = builtin_font;
-       id_us_plus(&cu->vfont->id);
-       id_us_min(&font->id);
-       
-       DAG_id_flush_update(ob->data, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_GEOM|ND_DATA|NA_EDITED, ob->data);
-       
+       RNA_id_pointer_create(&builtin_font->id, &idptr);
+       RNA_property_pointer_set(&pprop.ptr, pprop.prop, idptr);
+       RNA_property_update(C, &pprop.ptr, pprop.prop);
+
        return OPERATOR_FINISHED;
 }
 
@@ -1790,7 +1776,6 @@ void FONT_OT_unlink(wmOperatorType *ot)
        
        /* api callbacks */
        ot->exec= font_unlink_exec;
-       ot->poll= font_unlink_poll;
 }
 
 
@@ -1847,7 +1832,7 @@ static void *get_undoFont(bContext *C)
 }
 
 /* and this is all the undo system needs to know */
-void undo_push_font(bContext *C, char *name)
+void undo_push_font(bContext *C, const char *name)
 {
        undo_editmode_push(C, name, get_undoFont, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL);
 }