riched20: Implement list of marked paragraphs.

Signed-off-by: Sergio Gómez Del Real <sdelreal@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Sergio Gómez Del Real 2018-11-29 08:44:53 -05:00 committed by Alexandre Julliard
parent 618f0a8b2a
commit 195f84cfa1
5 changed files with 127 additions and 14 deletions

View File

@ -3035,6 +3035,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
ed->bEmulateVersion10 = bEmulateVersion10;
ed->styleFlags = 0;
ed->exStyleFlags = 0;
ed->first_marked_para = NULL;
ITextHost_TxGetPropertyBits(texthost,
(TXTBIT_RICHTEXT|TXTBIT_MULTILINE|
TXTBIT_READONLY|TXTBIT_USEPASSWORD|

View File

@ -205,6 +205,8 @@ void para_num_clear( struct para_num *pn ) DECLSPEC_HIDDEN;
int get_total_width(ME_TextEditor *editor) DECLSPEC_HIDDEN;
void mark_para_rewrap(ME_TextEditor *editor, ME_DisplayItem *para) DECLSPEC_HIDDEN;
ME_DisplayItem *get_di_from_para(ME_Paragraph *para) DECLSPEC_HIDDEN;
void add_marked_para(ME_TextEditor *editor, ME_DisplayItem *para) DECLSPEC_HIDDEN;
void remove_marked_para(ME_TextEditor *editor, ME_DisplayItem *para) DECLSPEC_HIDDEN;
/* paint.c */
void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLSPEC_HIDDEN;

View File

@ -219,6 +219,7 @@ typedef struct tagME_Paragraph
struct para_num para_num;
ME_Run *eop_run; /* ptr to the end-of-para run */
struct tagME_DisplayItem *prev_para, *next_para;
struct tagME_DisplayItem *prev_marked, *next_marked;
} ME_Paragraph;
typedef struct tagME_Cell /* v4.1 */
@ -432,6 +433,7 @@ typedef struct tagME_TextEditor
int imeStartIndex;
DWORD selofs; /* The size of the selection bar on the left side of control */
ME_SelectionType nSelectionType;
ME_DisplayItem *first_marked_para;
/* Track previous notified selection */
CHARRANGE notified_cr;

View File

@ -26,6 +26,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit);
void mark_para_rewrap(ME_TextEditor *editor, ME_DisplayItem *para)
{
para->member.para.nFlags |= MEPF_REWRAP;
add_marked_para(editor, para);
}
ME_DisplayItem *get_di_from_para(ME_Paragraph *para)
@ -39,6 +40,8 @@ static ME_DisplayItem *make_para(ME_TextEditor *editor)
ME_SetDefaultParaFormat(editor, &item->member.para.fmt);
item->member.para.nFlags = MEPF_REWRAP;
item->member.para.next_marked = item->member.para.prev_marked = NULL;
return item;
}
@ -53,6 +56,7 @@ void destroy_para(ME_TextEditor *editor, ME_DisplayItem *item)
}
ME_DestroyString(item->member.para.text);
para_num_clear( &item->member.para.para_num );
remove_marked_para(editor, item);
ME_DestroyDisplayItem(item);
}
@ -74,6 +78,77 @@ int get_total_width(ME_TextEditor *editor)
return total_width;
}
void remove_marked_para(ME_TextEditor *editor, ME_DisplayItem *di)
{
ME_DisplayItem *head = editor->first_marked_para;
assert(di->type == diParagraph);
if (!di->member.para.next_marked && !di->member.para.prev_marked)
{
if (di == head)
editor->first_marked_para = NULL;
}
else if (di->member.para.next_marked && di->member.para.prev_marked)
{
di->member.para.prev_marked->member.para.next_marked = di->member.para.next_marked;
di->member.para.next_marked->member.para.prev_marked = di->member.para.prev_marked;
di->member.para.prev_marked = di->member.para.next_marked = NULL;
}
else if (di->member.para.next_marked)
{
assert(di == editor->first_marked_para);
editor->first_marked_para = di->member.para.next_marked;
di->member.para.next_marked->member.para.prev_marked = NULL;
di->member.para.next_marked = NULL;
}
else
{
di->member.para.prev_marked->member.para.next_marked = NULL;
di->member.para.prev_marked = NULL;
}
}
void add_marked_para(ME_TextEditor *editor, ME_DisplayItem *di)
{
ME_DisplayItem *iter = editor->first_marked_para;
if (!iter)
{
editor->first_marked_para = di;
return;
}
while (iter)
{
if (iter == di)
return;
else if (di->member.para.nCharOfs < iter->member.para.nCharOfs)
{
if (iter == editor->first_marked_para)
editor->first_marked_para = di;
di->member.para.next_marked = iter;
iter->member.para.prev_marked = di;
break;
}
else if (di->member.para.nCharOfs >= iter->member.para.nCharOfs)
{
if (!iter->member.para.next_marked ||
(iter->member.para.next_marked &&
di->member.para.nCharOfs < iter->member.para.next_marked->member.para.nCharOfs))
{
if (iter->member.para.next_marked)
{
di->member.para.next_marked = iter->member.para.next_marked;
iter->member.para.next_marked->member.para.prev_marked = di;
}
di->member.para.prev_marked = iter;
iter->member.para.next_marked = di;
break;
}
}
iter = iter->member.para.next_marked;
}
}
void ME_MakeFirstParagraph(ME_TextEditor *editor)
{
ME_Context c;
@ -146,6 +221,7 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor)
text->pLast->member.para.nCharOfs = editor->bEmulateVersion10 ? 2 : 1;
add_marked_para(editor, para);
ME_DestroyContext(&c);
}

View File

@ -1098,29 +1098,61 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
{
ME_DisplayItem *item;
ME_Context c;
int totalWidth = 0;
int totalWidth = editor->nTotalWidth, diff = 0, prev_width;
ME_DisplayItem *repaint_start = NULL, *repaint_end = NULL;
ME_Paragraph *para;
if (!editor->first_marked_para)
return FALSE;
ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost));
c.pt.x = 0;
item = editor->pBuffer->pFirst->next;
while(item != editor->pBuffer->pLast) {
BOOL bRedraw = FALSE;
item = editor->first_marked_para;
c.pt = item->member.para.pt;
while (item != editor->pBuffer->pLast)
{
assert(item->type == diParagraph);
if ((item->member.para.nFlags & MEPF_REWRAP)
|| (item->member.para.pt.y != c.pt.y))
bRedraw = TRUE;
item->member.para.pt = c.pt;
prev_width = item->member.para.nWidth;
ME_WrapTextParagraph(&c, item);
if (prev_width == totalWidth && item->member.para.nWidth < totalWidth)
totalWidth = get_total_width(editor);
else
totalWidth = max(totalWidth, item->member.para.nWidth);
if (bRedraw)
ME_MarkRepaintEnd(item, &repaint_start, &repaint_end);
if (!item->member.para.nCharOfs)
ME_MarkRepaintEnd(item->member.para.prev_para, &repaint_start, &repaint_end);
ME_MarkRepaintEnd(item, &repaint_start, &repaint_end);
adjust_para_y(item, &c, repaint_start, repaint_end);
totalWidth = max(totalWidth, item->member.para.nWidth);
item = item->member.para.next_para;
if (item->member.para.next_para)
{
diff = c.pt.y - item->member.para.next_para->member.para.pt.y;
if (diff)
{
para = &item->member.para;
while (para->next_para && para != &item->member.para.next_marked->member.para &&
para != &editor->pBuffer->pLast->member.para)
{
ME_MarkRepaintEnd(para->next_para, &repaint_start, &repaint_end);
para->next_para->member.para.pt.y = c.pt.y;
adjust_para_y(para->next_para, &c, repaint_start, repaint_end);
para = &para->next_para->member.para;
}
}
}
if (item->member.para.next_marked)
{
ME_DisplayItem *rem = item;
item = item->member.para.next_marked;
remove_marked_para(editor, rem);
}
else
{
remove_marked_para(editor, item);
item = editor->pBuffer->pLast;
}
c.pt.y = item->member.para.pt.y;
}
editor->sizeWindow.cx = c.rcView.right-c.rcView.left;
editor->sizeWindow.cy = c.rcView.bottom-c.rcView.top;