riched20: Use para and run ptrs in the table deletion function.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
058ca3d04a
commit
20b4a03553
|
@ -306,12 +306,11 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
|
||||||
|
|
||||||
if (!bForce)
|
if (!bForce)
|
||||||
{
|
{
|
||||||
ME_ProtectPartialTableDeletion(editor, &c, &nChars);
|
table_protect_partial_deletion( editor, &c, &nChars );
|
||||||
if (nChars == 0)
|
if (nChars == 0) return FALSE;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while(nChars > 0)
|
while (nChars > 0)
|
||||||
{
|
{
|
||||||
ME_Run *run;
|
ME_Run *run;
|
||||||
cursor_from_char_ofs( editor, nOfs + nChars, &c );
|
cursor_from_char_ofs( editor, nOfs + nChars, &c );
|
||||||
|
|
|
@ -302,12 +302,12 @@ ME_Paragraph *table_insert_row_end( ME_TextEditor *editor, ME_Cursor *cursor ) D
|
||||||
ME_Paragraph *table_insert_row_start( ME_TextEditor *editor, ME_Cursor *cursor ) DECLSPEC_HIDDEN;
|
ME_Paragraph *table_insert_row_start( ME_TextEditor *editor, ME_Cursor *cursor ) DECLSPEC_HIDDEN;
|
||||||
ME_Paragraph *table_insert_row_start_at_para( ME_TextEditor *editor, ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
ME_Paragraph *table_insert_row_start_at_para( ME_TextEditor *editor, ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
||||||
ME_Paragraph *table_outer_para( ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
ME_Paragraph *table_outer_para( ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
||||||
|
void table_protect_partial_deletion( ME_TextEditor *editor, ME_Cursor *c, int *num_chars ) DECLSPEC_HIDDEN;
|
||||||
ME_Paragraph *table_row_end( ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
ME_Paragraph *table_row_end( ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
||||||
ME_Cell *table_row_end_cell( ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
ME_Cell *table_row_end_cell( ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
||||||
ME_Cell *table_row_first_cell( ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
ME_Cell *table_row_first_cell( ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
||||||
ME_Paragraph *table_row_start( ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
ME_Paragraph *table_row_start( ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
||||||
void ME_CheckTablesForCorruption(ME_TextEditor *editor) DECLSPEC_HIDDEN;
|
void ME_CheckTablesForCorruption(ME_TextEditor *editor) DECLSPEC_HIDDEN;
|
||||||
void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, ME_Cursor *c, int *nChars) DECLSPEC_HIDDEN;
|
|
||||||
void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow) DECLSPEC_HIDDEN;
|
void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow) DECLSPEC_HIDDEN;
|
||||||
void ME_MoveCursorFromTableRowStartParagraph(ME_TextEditor *editor) DECLSPEC_HIDDEN;
|
void ME_MoveCursorFromTableRowStartParagraph(ME_TextEditor *editor) DECLSPEC_HIDDEN;
|
||||||
struct RTFTable *ME_MakeTableDef(ME_TextEditor *editor) DECLSPEC_HIDDEN;
|
struct RTFTable *ME_MakeTableDef(ME_TextEditor *editor) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -315,123 +315,113 @@ BOOL ME_IsInTable(ME_DisplayItem *pItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Table rows should either be deleted completely or not at all. */
|
/* Table rows should either be deleted completely or not at all. */
|
||||||
void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, ME_Cursor *c, int *nChars)
|
void table_protect_partial_deletion( ME_TextEditor *editor, ME_Cursor *c, int *num_chars )
|
||||||
{
|
{
|
||||||
int nOfs = ME_GetCursorOfs(c);
|
int start_ofs = ME_GetCursorOfs( c );
|
||||||
ME_Cursor c2 = *c;
|
ME_Cursor c2 = *c;
|
||||||
ME_DisplayItem *this_para = c->pPara;
|
ME_Paragraph *this_para = &c->pPara->member.para, *end_para;
|
||||||
ME_DisplayItem *end_para;
|
|
||||||
|
|
||||||
ME_MoveCursorChars(editor, &c2, *nChars, FALSE);
|
ME_MoveCursorChars( editor, &c2, *num_chars, FALSE );
|
||||||
end_para = c2.pPara;
|
end_para = &c2.pPara->member.para;
|
||||||
if (c2.pRun->member.run.nFlags & MERF_ENDPARA) {
|
if (c2.pRun->member.run.nFlags & MERF_ENDPARA)
|
||||||
|
{
|
||||||
/* End offset might be in the middle of the end paragraph run.
|
/* End offset might be in the middle of the end paragraph run.
|
||||||
* If this is the case, then we need to use the next paragraph as the last
|
* If this is the case, then we need to use the next paragraph as the last
|
||||||
* paragraphs.
|
* paragraphs.
|
||||||
*/
|
*/
|
||||||
int remaining = nOfs + *nChars - c2.pRun->member.run.nCharOfs
|
int remaining = start_ofs + *num_chars - c2.pRun->member.run.nCharOfs - end_para->nCharOfs;
|
||||||
- end_para->member.para.nCharOfs;
|
|
||||||
if (remaining)
|
if (remaining)
|
||||||
{
|
{
|
||||||
assert(remaining < c2.pRun->member.run.len);
|
assert( remaining < c2.pRun->member.run.len );
|
||||||
end_para = end_para->member.para.next_para;
|
end_para = para_next( end_para );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!editor->bEmulateVersion10) { /* v4.1 */
|
if (!editor->bEmulateVersion10) /* v4.1 */
|
||||||
if (this_para->member.para.pCell != end_para->member.para.pCell ||
|
{
|
||||||
((this_para->member.para.nFlags|end_para->member.para.nFlags)
|
if (para_cell( this_para ) != para_cell( end_para ) ||
|
||||||
& (MEPF_ROWSTART|MEPF_ROWEND)))
|
((this_para->nFlags | end_para->nFlags) & (MEPF_ROWSTART | MEPF_ROWEND)))
|
||||||
{
|
{
|
||||||
while (this_para != end_para)
|
while (this_para != end_para)
|
||||||
{
|
{
|
||||||
ME_DisplayItem *next_para = this_para->member.para.next_para;
|
ME_Paragraph *next_para = para_next( this_para );
|
||||||
BOOL bTruancateDeletion = FALSE;
|
BOOL truancate_del = FALSE;
|
||||||
if (this_para->member.para.nFlags & MEPF_ROWSTART) {
|
if (this_para->nFlags & MEPF_ROWSTART)
|
||||||
|
{
|
||||||
/* The following while loop assumes that next_para is MEPF_ROWSTART,
|
/* The following while loop assumes that next_para is MEPF_ROWSTART,
|
||||||
* so moving back one paragraph let's it be processed as the start
|
* so moving back one paragraph lets it be processed as the start
|
||||||
* of the row. */
|
* of the row. */
|
||||||
next_para = this_para;
|
next_para = this_para;
|
||||||
this_para = this_para->member.para.prev_para;
|
this_para = para_prev( this_para );
|
||||||
} else if (next_para->member.para.pCell != this_para->member.para.pCell
|
}
|
||||||
|| this_para->member.para.nFlags & MEPF_ROWEND)
|
else if (para_cell( next_para) != para_cell( this_para ) || this_para->nFlags & MEPF_ROWEND)
|
||||||
{
|
{
|
||||||
/* Start of the deletion from after the start of the table row. */
|
/* Start of the deletion from after the start of the table row. */
|
||||||
bTruancateDeletion = TRUE;
|
truancate_del = TRUE;
|
||||||
}
|
}
|
||||||
while (!bTruancateDeletion &&
|
while (!truancate_del && next_para->nFlags & MEPF_ROWSTART)
|
||||||
next_para->member.para.nFlags & MEPF_ROWSTART)
|
|
||||||
{
|
{
|
||||||
next_para = table_row_end( &next_para->member.para )->next_para;
|
next_para = para_next( table_row_end( next_para ) );
|
||||||
if (next_para->member.para.nCharOfs > nOfs + *nChars)
|
if (next_para->nCharOfs > start_ofs + *num_chars)
|
||||||
{
|
{
|
||||||
/* End of deletion is not past the end of the table row. */
|
/* End of deletion is not past the end of the table row. */
|
||||||
next_para = this_para->member.para.next_para;
|
next_para = para_next( this_para );
|
||||||
/* Delete the end paragraph preceding the table row if the
|
/* Delete the end paragraph preceding the table row if the
|
||||||
* preceding table row will be empty. */
|
* preceding table row will be empty. */
|
||||||
if (this_para->member.para.nCharOfs >= nOfs)
|
if (this_para->nCharOfs >= start_ofs) next_para = para_next( next_para );
|
||||||
{
|
truancate_del = TRUE;
|
||||||
next_para = next_para->member.para.next_para;
|
|
||||||
}
|
|
||||||
bTruancateDeletion = TRUE;
|
|
||||||
} else {
|
|
||||||
this_para = next_para->member.para.prev_para;
|
|
||||||
}
|
}
|
||||||
|
else this_para = para_prev( next_para );
|
||||||
}
|
}
|
||||||
if (bTruancateDeletion)
|
if (truancate_del)
|
||||||
{
|
{
|
||||||
ME_Run *end_run = &ME_FindItemBack(next_para, diRun)->member.run;
|
ME_Run *end_run = para_end_run( para_prev( next_para ) );
|
||||||
int nCharsNew = (next_para->member.para.nCharOfs - nOfs
|
int new_chars = next_para->nCharOfs - start_ofs - end_run->len;
|
||||||
- end_run->len);
|
new_chars = max( new_chars, 0 );
|
||||||
nCharsNew = max(nCharsNew, 0);
|
assert( new_chars <= *num_chars);
|
||||||
assert(nCharsNew <= *nChars);
|
*num_chars = new_chars;
|
||||||
*nChars = nCharsNew;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this_para = next_para;
|
this_para = next_para;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { /* v1.0 - 3.0 */
|
}
|
||||||
ME_DisplayItem *pRun;
|
else /* v1.0 - 3.0 */
|
||||||
int nCharsToBoundary;
|
{
|
||||||
|
ME_Run *run;
|
||||||
|
int chars_to_boundary;
|
||||||
|
|
||||||
if ((this_para->member.para.nCharOfs != nOfs || this_para == end_para) &&
|
if ((this_para->nCharOfs != start_ofs || this_para == end_para) && para_in_table( this_para ))
|
||||||
this_para->member.para.fmt.dwMask & PFM_TABLE &&
|
|
||||||
this_para->member.para.fmt.wEffects & PFE_TABLE)
|
|
||||||
{
|
{
|
||||||
pRun = c->pRun;
|
run = &c->pRun->member.run;
|
||||||
/* Find the next tab or end paragraph to use as a delete boundary */
|
/* Find the next tab or end paragraph to use as a delete boundary */
|
||||||
while (!(pRun->member.run.nFlags & (MERF_TAB|MERF_ENDPARA)))
|
while (!(run->nFlags & (MERF_TAB | MERF_ENDPARA)))
|
||||||
pRun = ME_FindItemFwd(pRun, diRun);
|
run = run_next( run );
|
||||||
nCharsToBoundary = pRun->member.run.nCharOfs
|
chars_to_boundary = run->nCharOfs - c->pRun->member.run.nCharOfs - c->nOffset;
|
||||||
- c->pRun->member.run.nCharOfs
|
*num_chars = min( *num_chars, chars_to_boundary );
|
||||||
- c->nOffset;
|
}
|
||||||
*nChars = min(*nChars, nCharsToBoundary);
|
else if (para_in_table( end_para ))
|
||||||
} else if (end_para->member.para.fmt.dwMask & PFM_TABLE &&
|
|
||||||
end_para->member.para.fmt.wEffects & PFE_TABLE)
|
|
||||||
{
|
{
|
||||||
/* The deletion starts from before the row, so don't join it with
|
/* The deletion starts from before the row, so don't join it with
|
||||||
* previous non-empty paragraphs. */
|
* previous non-empty paragraphs. */
|
||||||
ME_DisplayItem *curPara;
|
ME_Paragraph *cur_para;
|
||||||
pRun = NULL;
|
run = NULL;
|
||||||
if (nOfs > this_para->member.para.nCharOfs) {
|
if (start_ofs > this_para->nCharOfs)
|
||||||
pRun = ME_FindItemBack(end_para, diRun);
|
|
||||||
curPara = end_para->member.para.prev_para;
|
|
||||||
}
|
|
||||||
if (!pRun) {
|
|
||||||
pRun = ME_FindItemFwd(end_para, diRun);
|
|
||||||
curPara = end_para;
|
|
||||||
}
|
|
||||||
if (pRun)
|
|
||||||
{
|
{
|
||||||
nCharsToBoundary = curPara->member.para.nCharOfs
|
cur_para = para_prev( end_para );
|
||||||
+ pRun->member.run.nCharOfs
|
run = para_end_run( cur_para );
|
||||||
- nOfs;
|
}
|
||||||
if (nCharsToBoundary >= 0)
|
if (!run)
|
||||||
*nChars = min(*nChars, nCharsToBoundary);
|
{
|
||||||
|
cur_para = end_para;
|
||||||
|
run = para_first_run( end_para );
|
||||||
|
}
|
||||||
|
if (run)
|
||||||
|
{
|
||||||
|
chars_to_boundary = cur_para->nCharOfs + run->nCharOfs - start_ofs;
|
||||||
|
if (chars_to_boundary >= 0) *num_chars = min( *num_chars, chars_to_boundary );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*nChars < 0)
|
if (*num_chars < 0) *num_chars = 0;
|
||||||
*nChars = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue