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:
authorJiri Hnidek <jiri.hnidek@tul.cz>2012-10-26 16:58:54 +0400
committerJiri Hnidek <jiri.hnidek@tul.cz>2012-10-26 16:58:54 +0400
commit2821f822c52146e2e6fbcdeb70232ad2fd9a176f (patch)
tree2a0bc903bd8eb02768ecb6b5b2790850c58b3172 /source/blender
parent608d62f6a6af224d2d2356e886b1a02855857ff6 (diff)
* New string property subtype: PASSWORD
When this new subtypes is used, then string of property is hidden using asterisks, e.g.: mysecretpassword -> **************** This code was reviewed and modified by Brecht. Thanks very much: - https://codereview.appspot.com/6713044/ This new subtype of string property is intended mostly for Add-on developers writing Add-on which communicates with some server (http, sql, ftp, verse, etc.). When this server requires user authentication and user has to type username and password, then current API didn't allow to type 'hidden' password, e.g. when you want to demonstrate this script, then everybody can see this security password. Some examples of Add-on which could use this new subtype: - On-line database of textures - Integration of render farm - Integration of Verse Security Notes: - You can copy paste hiddent string of property from text input using (Ctrl-C, Ctrl-V), but you can do this in other GUI toolkits too (this behavior it is widely used). - Text of string property is stored in plain text, but it is widely used in other GUI toolkits (Qt, Gtk, etc.). Simple examples: - https://dl.dropbox.com/u/369894/draw_op_passwd.py - https://dl.dropbox.com/u/369894/blender-password.png
Diffstat (limited to 'source/blender')
-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}};