edit control: add support for !ES_AUTOH(V)SCROLL
Lauri Tulmin
lauri_ at ut.ee
Sat Sep 25 12:02:55 CDT 2004
changelog:
- add support for !ES_AUTOH(V)SCROLL
-------------- next part --------------
--- dlls/user/edit.c 2004-09-25 15:31:52.925597176 +0300
+++ dlls/user/edit.c 2004-09-25 15:33:55.798917592 +0300
@@ -22,15 +22,6 @@
*
* TODO:
* - ES_OEMCONVERT
- * -!ES_AUTOVSCROLL (every multi line control *is* auto vscroll)
- * -!ES_AUTOHSCROLL (every single line control *is* auto hscroll)
- *
- * When there is no autoscrolling, the control should first check whether
- * the new text would fit. If not, an EN_MAXTEXT should be sent.
- * However, currently this would require the actual change to be made,
- * then call EDIT_BuildLineDefs() and then find out that the new text doesn't
- * fit. After all this, things should be put back in the state before the
- * changes. Note that for multi line controls !ES_AUTOHSCROLL works : wordwrap.
*
*/
@@ -2939,6 +2930,8 @@
UINT size;
LPWSTR p;
HRGN hrgn = 0;
+ LPWSTR buf = NULL;
+ UINT buf_len = 0;
TRACE("%s, can_undo %d, send_update %d\n",
debugstr_w(lpsz_replace), can_undo, send_update);
@@ -2965,12 +2958,71 @@
if (e != s) {
/* there is something to be deleted */
TRACE("deleting stuff.\n");
+ buf_len = e - s;
+ buf = HeapAlloc(GetProcessHeap(), 0, (buf_len + 1) * sizeof(WCHAR));
+ if (!buf) return;
+ strncpyW(buf, es->text + s, buf_len);
+ buf[buf_len] = 0; /* ensure 0 termination */
+ /* now delete */
+ strcpyW(es->text + s, es->text + e);
+ }
+ if (strl) {
+ /* there is an insertion */
+ tl = strlenW(es->text);
+ TRACE("inserting stuff (tl %d, strl %d, selstart %d ('%s'), text '%s')\n", tl, strl, s, debugstr_w(es->text + s), debugstr_w(es->text));
+ for (p = es->text + tl ; p >= es->text + s ; p--)
+ p[strl] = p[0];
+ for (i = 0 , p = es->text + s ; i < strl ; i++)
+ p[i] = lpsz_replace[i];
+ if(es->style & ES_UPPERCASE)
+ CharUpperBuffW(p, strl);
+ else if(es->style & ES_LOWERCASE)
+ CharLowerBuffW(p, strl);
+ }
+ if (es->style & ES_MULTILINE)
+ {
+ INT st = min(es->selection_start, es->selection_end);
+ INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
+
+ hrgn = CreateRectRgn(0, 0, 0, 0);
+ EDIT_BuildLineDefs_ML(es, st, st + strl,
+ strl - abs(es->selection_end - es->selection_start), hrgn);
+ /* if text is too long undo all changes */
+ if (!(es->style & ES_AUTOVSCROLL) && (es->line_count > vlc)) {
+ if (strl)
+ strcpyW(es->text + e, es->text + e + strl);
+ if (e != s)
+ for (i = 0 , p = es->text ; i < e - s ; i++)
+ p[i + s] = buf[i];
+ EDIT_BuildLineDefs_ML(es, s, e,
+ abs(es->selection_end - es->selection_start) - strl, hrgn);
+ strl = 0;
+ e = s;
+ hrgn = CreateRectRgn(0, 0, 0, 0);
+ EDIT_NOTIFY_PARENT(es, EN_MAXTEXT, "EN_MAXTEXT");
+ }
+ }
+ else {
+ INT fw = es->format_rect.right - es->format_rect.left;
+ EDIT_CalcLineWidth_SL(es);
+ /* remove chars that don't fit */
+ if (!(es->style & ES_AUTOHSCROLL) && (es->text_width > fw)) {
+ while ((es->text_width > fw) && s + strl >= s) {
+ strcpyW(es->text + s + strl - 1, es->text + s + strl);
+ strl--;
+ EDIT_CalcLineWidth_SL(es);
+ }
+ EDIT_NOTIFY_PARENT(es, EN_MAXTEXT, "EN_MAXTEXT");
+ }
+ }
+
+ if (e != s) {
if (can_undo) {
utl = strlenW(es->undo_text);
if (!es->undo_insert_count && (*es->undo_text && (s == es->undo_position))) {
/* undo-buffer is extended to the right */
EDIT_MakeUndoFit(es, utl + e - s);
- strncpyW(es->undo_text + utl, es->text + s, e - s + 1);
+ strncpyW(es->undo_text + utl, buf, e - s + 1);
(es->undo_text + utl)[e - s] = 0; /* ensure 0 termination */
} else if (!es->undo_insert_count && (*es->undo_text && (e == es->undo_position))) {
/* undo-buffer is extended to the left */
@@ -2978,12 +3030,12 @@
for (p = es->undo_text + utl ; p >= es->undo_text ; p--)
p[e - s] = p[0];
for (i = 0 , p = es->undo_text ; i < e - s ; i++)
- p[i] = (es->text + s)[i];
+ p[i] = buf[i];
es->undo_position = s;
} else {
/* new undo-buffer */
EDIT_MakeUndoFit(es, e - s);
- strncpyW(es->undo_text, es->text + s, e - s + 1);
+ strncpyW(es->undo_text, buf, e - s + 1);
es->undo_text[e - s] = 0; /* ensure 0 termination */
es->undo_position = s;
}
@@ -2991,16 +3043,12 @@
es->undo_insert_count = 0;
} else
EDIT_EM_EmptyUndoBuffer(es);
-
- /* now delete */
- strcpyW(es->text + s, es->text + e);
}
if (strl) {
- /* there is an insertion */
if (can_undo) {
if ((s == es->undo_position) ||
- ((es->undo_insert_count) &&
- (s == es->undo_position + es->undo_insert_count)))
+ ((es->undo_insert_count) &&
+ (s == es->undo_position + es->undo_insert_count)))
/*
* insertion is new and at delete position or
* an extension to either left or right
@@ -3015,31 +3063,12 @@
}
} else
EDIT_EM_EmptyUndoBuffer(es);
-
- /* now insert */
- tl = strlenW(es->text);
- TRACE("inserting stuff (tl %d, strl %d, selstart %d ('%s'), text '%s')\n", tl, strl, s, debugstr_w(es->text + s), debugstr_w(es->text));
- for (p = es->text + tl ; p >= es->text + s ; p--)
- p[strl] = p[0];
- for (i = 0 , p = es->text + s ; i < strl ; i++)
- p[i] = lpsz_replace[i];
- if(es->style & ES_UPPERCASE)
- CharUpperBuffW(p, strl);
- else if(es->style & ES_LOWERCASE)
- CharLowerBuffW(p, strl);
- s += strl;
}
- if (es->style & ES_MULTILINE)
- {
- INT s = min(es->selection_start, es->selection_end);
-
- hrgn = CreateRectRgn(0, 0, 0, 0);
- EDIT_BuildLineDefs_ML(es, s, s + strl,
- strl - abs(es->selection_end - es->selection_start), hrgn);
- }
- else
- EDIT_CalcLineWidth_SL(es);
+
+ if (buf_len)
+ HeapFree(GetProcessHeap(), 0, buf);
+ s += strl;
EDIT_EM_SetSel(es, s, s, FALSE);
es->flags |= EF_MODIFIED;
if (send_update) es->flags |= EF_UPDATE;
@@ -3155,10 +3184,6 @@
INT x;
INT goal;
INT format_width;
-
- if (!(es->style & ES_AUTOHSCROLL))
- return;
-
x = (short)LOWORD(EDIT_EM_PosFromChar(es, es->selection_end, FALSE));
format_width = es->format_rect.right - es->format_rect.left;
if (x < es->format_rect.left) {
@@ -4433,9 +4458,6 @@
es->style &= ~WS_HSCROLL;
es->style &= ~ES_AUTOHSCROLL;
}
-
- /* FIXME: for now, all multi line controls are AUTOVSCROLL */
- es->style |= ES_AUTOVSCROLL;
} else {
es->buffer_limit = BUFLIMIT_SINGLE;
if ((es->style & ES_CENTER) || (es->style & ES_RIGHT)) {
@@ -4448,9 +4470,6 @@
es->style &= ~ES_WANTRETURN;
if (es->style & ES_PASSWORD)
es->password_char = '*';
-
- /* FIXME: for now, all single line controls are AUTOHSCROLL */
- es->style |= ES_AUTOHSCROLL;
}
alloc_size = ROUND_TO_GROW((es->buffer_size + 1) * sizeof(WCHAR));
More information about the wine-patches
mailing list