Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenlib/BLI_string_utf8.h2
-rw-r--r--source/blender/blenlib/intern/string_utf8.c50
-rw-r--r--source/blender/editors/interface/interface_handlers.c71
-rw-r--r--source/blender/editors/interface/interface_intern.h4
-rw-r--r--source/blender/editors/interface/interface_widgets.c9
-rw-r--r--source/blender/makesrna/RNA_types.h1
-rw-r--r--source/blender/makesrna/intern/makesrna.c1
-rw-r--r--source/blender/python/intern/bpy_props.c1
8 files changed, 117 insertions, 22 deletions
diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h
index 47980d104fe..efb9ac552df 100644
--- a/source/blender/blenlib/BLI_string_utf8.h
+++ b/source/blender/blenlib/BLI_string_utf8.h
@@ -49,7 +49,9 @@ char *BLI_str_prev_char_utf8(const char *p);
/* wchar_t functions, copied from blenders own font.c originally */
size_t BLI_wstrlen_utf8(const wchar_t *src);
+size_t BLI_strlen_utf8_char(const char *strc);
size_t BLI_strlen_utf8(const char *strc);
+size_t BLI_strlen_range_utf8(const char *start, const char *end);
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy);
size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy);
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index ac2334e7d8e..9c7829dbcb6 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -231,28 +231,42 @@ size_t BLI_wstrlen_utf8(const wchar_t *src)
return len;
}
-// utf8slen
+/* size of UTF-8 character in bytes */
+size_t BLI_strlen_utf8_char(const char *strc)
+{
+ if ((*strc & 0xe0) == 0xc0) {
+ if ((strc[1] & 0x80) && (strc[1] & 0x40) == 0x00)
+ return 2;
+ }
+ else if ((*strc & 0xf0) == 0xe0) {
+ if ((strc[1] & strc[2] & 0x80) && ((strc[1] | strc[2]) & 0x40) == 0x00)
+ return 3;
+ }
+ else if ((*strc & 0xf8) == 0xf0) {
+ if ((strc[1] & strc[2] & strc[3] & 0x80) && ((strc[1] | strc[2] | strc[3]) & 0x40) == 0x00)
+ return 4;
+ }
+
+ return 1;
+}
+
size_t BLI_strlen_utf8(const char *strc)
{
- int len = 0;
+ int len;
- while (*strc) {
- if ((*strc & 0xe0) == 0xc0) {
- if ((strc[1] & 0x80) && (strc[1] & 0x40) == 0x00)
- strc++;
- }
- else if ((*strc & 0xf0) == 0xe0) {
- if ((strc[1] & strc[2] & 0x80) && ((strc[1] | strc[2]) & 0x40) == 0x00)
- strc += 2;
- }
- else if ((*strc & 0xf8) == 0xf0) {
- if ((strc[1] & strc[2] & strc[3] & 0x80) && ((strc[1] | strc[2] | strc[3]) & 0x40) == 0x00)
- strc += 3;
- }
+ for (len = 0; *strc; len++)
+ strc += BLI_strlen_utf8_char(strc);
- strc++;
- len++;
- }
+ return len;
+}
+
+size_t BLI_strlen_range_utf8(const char *start, const char *end)
+{
+ const char *strc = start;
+ int len;
+
+ for (len = 0; strc < end; len++)
+ strc += BLI_strlen_utf8_char(strc);
return len;
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index b3d6eac9142..7d7cef21281 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -1299,6 +1299,71 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
}
+/* ************************ password text ******************************
+ *
+ * Functions to convert password strings that should not be displayed
+ * to asterisk representation (e.g. mysecretpasswd -> *************)
+ *
+ * It converts every UTF-8 character to an asterisk, and also remaps
+ * the cursor position and selection start/end.
+ *
+ * Note: remaping is used, because password could contain UTF-8 characters.
+ *
+ */
+
+static int ui_text_position_from_hidden(uiBut *but, int pos)
+{
+ const char *strpos;
+ int i;
+
+ for (i = 0, strpos = but->drawstr; i < pos; i++)
+ strpos = BLI_str_find_next_char_utf8(strpos, NULL);
+
+ return (strpos - but->drawstr);
+}
+
+static int ui_text_position_to_hidden(uiBut *but, int pos)
+{
+ return BLI_strlen_range_utf8(but->drawstr, but->drawstr + pos);
+}
+
+void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, int restore)
+{
+ if (!(but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_PASSWORD))
+ return;
+
+ if (restore) {
+ /* restore original string */
+ BLI_strncpy(but->drawstr, password_str, UI_MAX_DRAW_STR);
+
+ /* remap cursor positions */
+ if(but->pos >= 0) {
+ but->pos = ui_text_position_from_hidden(but, but->pos);
+ but->selsta = ui_text_position_from_hidden(but, but->selsta);
+ but->selend = ui_text_position_from_hidden(but, but->selend);
+ }
+ }
+ else {
+ /* convert text to hidden test using asterisks (e.g. pass -> ****) */
+ int i, len = BLI_strlen_utf8(but->drawstr);
+
+ /* remap cursor positions */
+ if(but->pos >= 0) {
+ but->pos = ui_text_position_to_hidden(but, but->pos);
+ but->selsta = ui_text_position_to_hidden(but, but->selsta);
+ but->selend = ui_text_position_to_hidden(but, but->selend);
+ }
+
+ /* save original string */
+ BLI_strncpy(password_str, but->drawstr, UI_MAX_DRAW_STR);
+
+ for (i = 0; i < len; i++)
+ but->drawstr[i] = '*';
+ but->drawstr[i] = '\0';
+ }
+}
+
+
/* ************* in-button text selection/editing ************* */
@@ -1322,13 +1387,15 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
uiStyle *style = UI_GetStyle(); // XXX pass on as arg
uiFontStyle *fstyle = &style->widget;
int startx = but->rect.xmin;
- char *origstr;
+ char *origstr, password_str[UI_MAX_DRAW_STR];
uiStyleFontSet(fstyle);
if (fstyle->kerning == 1) /* for BLF_width */
BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ ui_button_text_password_hide(password_str, but, FALSE);
+
origstr = MEM_callocN(sizeof(char) * data->maxlen, "ui_textedit origstr");
BLI_strncpy(origstr, but->drawstr, data->maxlen);
@@ -1407,6 +1474,8 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
if (fstyle->kerning == 1)
BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ ui_button_text_password_hide(password_str, but, TRUE);
+
MEM_freeN(origstr);
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index b4b0686d6fc..98b75060aa8 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -160,7 +160,8 @@ struct uiBut {
int flag, drawflag;
eButType type;
eButPointerType pointype;
- short bit, bitnr, retval, strwidth, ofs, pos, selsta, selend, alignnr;
+ short bit, bitnr, retval, strwidth, alignnr;
+ short ofs, pos, selsta, selend;
char *str;
char strdata[UI_MAX_NAME_STR];
@@ -484,6 +485,7 @@ extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut
extern void ui_button_active_free(const struct bContext *C, uiBut *but);
extern int ui_button_is_active(struct ARegion *ar);
extern int ui_button_open_menu_direction(uiBut *but);
+extern void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, int restore);
/* interface_widgets.c */
void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 39d90de91d8..a0a51a724c0 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1276,9 +1276,12 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
/* draws text and icons for buttons */
static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect)
{
- if (but == NULL) {
+ char password_str[UI_MAX_DRAW_STR];
+
+ if (but == NULL)
return;
- }
+
+ ui_button_text_password_hide(password_str, but, FALSE);
/* clip but->drawstr to fit in available space */
if (but->editstr && but->pos >= 0) {
@@ -1337,6 +1340,8 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
widget_draw_text(fstyle, wcol, but, rect);
}
+
+ ui_button_text_password_hide(password_str, but, TRUE);
}
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 511999dfa37..7d6e07baebd 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -113,6 +113,7 @@ typedef enum PropertySubType {
PROP_BYTESTRING = 4, /* a string which should be represented as bytes
* in python, still NULL terminated though. */
PROP_TRANSLATE = 5, /* a string which should be translated */
+ PROP_PASSWORD = 6, /* a string which should not be displayed in UI */
/* numbers */
PROP_UNSIGNED = 13,
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index fbb7fe5a346..df51715a324 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -2345,6 +2345,7 @@ static const char *rna_property_subtypename(PropertySubType type)
case PROP_COORDS: return "PROP_COORDS";
case PROP_LAYER: return "PROP_LAYER";
case PROP_LAYER_MEMBER: return "PROP_LAYER_MEMBER";
+ case PROP_PASSWORD: return "PROP_PASSWORD";
default: {
/* in case we don't have a type preset that includes the subtype */
if (RNA_SUBTYPE_UNIT(type)) {
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 39a05389b63..164c9fec110 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -78,6 +78,7 @@ static EnumPropertyItem property_subtype_string_items[] = {
{PROP_FILENAME, "FILENAME", 0, "Filename", ""},
{PROP_BYTESTRING, "BYTE_STRING", 0, "Byte String", ""},
{PROP_TRANSLATE, "TRANSLATE", 0, "Translate", ""},
+ {PROP_PASSWORD, "PASSWORD", 0, "Password", 0},
{PROP_NONE, "NONE", 0, "None", ""},
{0, NULL, 0, NULL, NULL}};