ReactOS 0.4.16-dev-109-gf4cb10f
table.c
Go to the documentation of this file.
1/*
2 * RichEdit functions dealing with on tables
3 *
4 * Copyright 2008 by Dylan Smith
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21/*
22 * The implementation of tables differs greatly between version 3.0
23 * (in riched20.dll) and version 4.1 (in msftedit.dll) of richedit controls.
24 * Currently Wine is not distinguishing between version 3.0 and version 4.1,
25 * so v4.1 is assumed unless v1.0 is being emulated (i.e. riched32.dll is used).
26 * If this lack of distinction causes a bug in a Windows application, then Wine
27 * will need to start making this distinction.
28 *
29 * Richedit version 1.0 - 3.0:
30 * Tables are implemented in these versions using tabs at the end of cells,
31 * and tab stops to position the cells. The paragraph format flag PFE_TABLE
32 * will indicate that the paragraph is a table row. Note that in this
33 * implementation there is one paragraph per table row.
34 *
35 * Richedit version 4.1:
36 * Tables are implemented such that cells can contain multiple paragraphs,
37 * each with its own paragraph format, and cells may even contain tables
38 * nested within the cell.
39 *
40 * There is also a paragraph at the start of each table row that contains
41 * the rows paragraph format (e.g. to change the row alignment to row), and a
42 * paragraph at the end of the table row with the PFE_TABLEROWDELIMITER flag
43 * set. The paragraphs at the start and end of the table row should always be
44 * empty, but should have a length of 2.
45 *
46 * Wine implements this using display items (ME_DisplayItem) with a type of
47 * diCell. These cell display items store the cell properties, and are
48 * inserted into the editors linked list before each cell, and at the end of
49 * the last cell. The cell display item for a cell comes before the paragraphs
50 * for the cell, but the last cell display item refers to no cell, so it is
51 * just a delimiter.
52 */
53
54#include "editor.h"
55#include "rtf.h"
56
58
59static const WCHAR cr_lf[] = {'\r', '\n', 0};
60
62 int nCursor,
63 const WCHAR *eol_str, int eol_len,
64 int paraFlags)
65{
66 ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor);
68 ME_Cursor* cursor = &editor->pCursors[nCursor];
69 if (cursor->nOffset)
71
72 tp = ME_SplitParagraph(editor, cursor->pRun, pStyle, eol_str, eol_len, paraFlags);
73 ME_ReleaseStyle(pStyle);
74 cursor->pPara = tp;
75 cursor->pRun = ME_FindItemFwd(tp, diRun);
76 return tp;
77}
78
80{
81 ME_DisplayItem *para;
82 para = ME_InsertEndParaFromCursor(editor, 0, cr_lf, 2, MEPF_ROWSTART);
83 return para->member.para.prev_para;
84}
85
87 ME_DisplayItem *para)
88{
89 ME_DisplayItem *prev_para, *end_para;
90 ME_Cursor savedCursor = editor->pCursors[0];
91 ME_DisplayItem *startRowPara;
92 editor->pCursors[0].pPara = para;
93 editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
94 editor->pCursors[0].nOffset = 0;
95 editor->pCursors[1] = editor->pCursors[0];
96 startRowPara = ME_InsertTableRowStartFromCursor(editor);
97 savedCursor.pPara = ME_GetParagraph(savedCursor.pRun);
98 editor->pCursors[0] = savedCursor;
99 editor->pCursors[1] = editor->pCursors[0];
100
101 end_para = editor->pCursors[0].pPara->member.para.next_para;
102 prev_para = startRowPara->member.para.next_para;
103 para = prev_para->member.para.next_para;
104 while (para != end_para)
105 {
106 para->member.para.pCell = prev_para->member.para.pCell;
107 para->member.para.nFlags |= MEPF_CELL;
111 para->member.para.fmt.wEffects &= ~PFE_TABLEROWDELIMITER;
112 prev_para = para;
113 para = para->member.para.next_para;
114 }
115 return startRowPara;
116}
117
118/* Inserts a diCell and starts a new paragraph for the next cell.
119 *
120 * Returns the first paragraph of the new cell. */
122{
123 ME_DisplayItem *para;
124 WCHAR tab = '\t';
125 para = ME_InsertEndParaFromCursor(editor, 0, &tab, 1, MEPF_CELL);
126 return para;
127}
128
130{
131 ME_DisplayItem *para;
132 para = ME_InsertEndParaFromCursor(editor, 0, cr_lf, 2, MEPF_ROWEND);
133 return para->member.para.prev_para;
134}
135
137{
138 ME_DisplayItem *cell;
139 assert(para);
140 if (para->member.para.nFlags & MEPF_ROWEND)
141 return para;
142 if (para->member.para.nFlags & MEPF_ROWSTART)
143 para = para->member.para.next_para;
144 cell = para->member.para.pCell;
145 assert(cell && cell->type == diCell);
146 while (cell->member.cell.next_cell)
147 cell = cell->member.cell.next_cell;
148
149 para = ME_FindItemFwd(cell, diParagraph);
150 assert(para && para->member.para.nFlags & MEPF_ROWEND);
151 return para;
152}
153
155{
156 ME_DisplayItem *cell;
157 assert(para);
158 if (para->member.para.nFlags & MEPF_ROWSTART)
159 return para;
160 if (para->member.para.nFlags & MEPF_ROWEND)
161 para = para->member.para.prev_para;
162 cell = para->member.para.pCell;
163 assert(cell && cell->type == diCell);
164 while (cell->member.cell.prev_cell)
165 cell = cell->member.cell.prev_cell;
166
167 para = ME_FindItemBack(cell, diParagraph);
168 assert(para && para->member.para.nFlags & MEPF_ROWSTART);
169 return para;
170}
171
173{
174 if (para->member.para.nFlags & MEPF_ROWEND)
175 para = para->member.para.prev_para;
176 while (para->member.para.pCell)
177 {
178 para = ME_GetTableRowStart(para);
179 if (!para->member.para.pCell)
180 break;
182 }
183 return para;
184}
185
186/* Make a bunch of assertions to make sure tables haven't been corrupted.
187 *
188 * These invariants may not hold true in the middle of streaming in rich text
189 * or during an undo and redo of streaming in rich text. It should be safe to
190 * call this method after an event is processed.
191 */
193{
194 if(TRACE_ON(richedit_lists))
195 {
196 TRACE("---\n");
197 ME_DumpDocument(editor->pBuffer);
198 }
199#ifndef NDEBUG
200 {
201 ME_DisplayItem *p, *pPrev;
202 pPrev = editor->pBuffer->pFirst;
203 p = pPrev->next;
204 if (!editor->bEmulateVersion10) /* v4.1 */
205 {
206 while (p->type == diParagraph)
207 {
208 assert(p->member.para.fmt.dwMask & PFM_TABLE);
209 assert(p->member.para.fmt.dwMask & PFM_TABLEROWDELIMITER);
210 if (p->member.para.pCell)
211 {
212 assert(p->member.para.nFlags & MEPF_CELL);
213 assert(p->member.para.fmt.wEffects & PFE_TABLE);
214 }
215 if (p->member.para.pCell != pPrev->member.para.pCell)
216 {
217 /* There must be a diCell in between the paragraphs if pCell changes. */
219 assert(pCell);
221 }
222 if (p->member.para.nFlags & MEPF_ROWEND)
223 {
224 /* ROWEND must come after a cell. */
225 assert(pPrev->member.para.pCell);
226 assert(p->member.para.pCell
227 == pPrev->member.para.pCell->member.cell.parent_cell);
228 assert(p->member.para.fmt.wEffects & PFE_TABLEROWDELIMITER);
229 }
230 else if (p->member.para.pCell)
231 {
232 assert(!(p->member.para.fmt.wEffects & PFE_TABLEROWDELIMITER));
233 assert(pPrev->member.para.pCell ||
235 if (pPrev->member.para.pCell &&
236 !(pPrev->member.para.nFlags & MEPF_ROWSTART))
237 {
238 assert(p->member.para.pCell->member.cell.parent_cell
239 == pPrev->member.para.pCell->member.cell.parent_cell);
240 if (pPrev->member.para.pCell != p->member.para.pCell)
241 assert(pPrev->member.para.pCell
242 == p->member.para.pCell->member.cell.prev_cell);
243 }
244 }
245 else if (!(p->member.para.nFlags & MEPF_ROWSTART))
246 {
247 assert(!(p->member.para.fmt.wEffects & PFE_TABLEROWDELIMITER));
248 /* ROWSTART must be followed by a cell. */
249 assert(!(p->member.para.nFlags & MEPF_CELL));
250 /* ROWSTART must be followed by a cell. */
252 }
253 pPrev = p;
254 p = p->member.para.next_para;
255 }
256 } else { /* v1.0 - 3.0 */
257 while (p->type == diParagraph)
258 {
259 assert(!(p->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL)));
260 assert(p->member.para.fmt.dwMask & PFM_TABLE);
261 assert(!(p->member.para.fmt.wEffects & PFE_TABLEROWDELIMITER));
262 assert(!p->member.para.pCell);
263 p = p->member.para.next_para;
264 }
265 return;
266 }
267 assert(p->type == diTextEnd);
268 assert(!pPrev->member.para.pCell);
269 }
270#endif
271}
272
274{
275 PARAFORMAT2 *pFmt;
276 if (!pItem)
277 return FALSE;
278 if (pItem->type == diRun)
279 pItem = ME_GetParagraph(pItem);
280 if (pItem->type != diParagraph)
281 return FALSE;
282 pFmt = &pItem->member.para.fmt;
283 return pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE;
284}
285
286/* Table rows should either be deleted completely or not at all. */
288{
289 int nOfs = ME_GetCursorOfs(c);
290 ME_Cursor c2 = *c;
291 ME_DisplayItem *this_para = c->pPara;
292 ME_DisplayItem *end_para;
293
294 ME_MoveCursorChars(editor, &c2, *nChars, FALSE);
295 end_para = c2.pPara;
296 if (c2.pRun->member.run.nFlags & MERF_ENDPARA) {
297 /* End offset might be in the middle of the end paragraph run.
298 * If this is the case, then we need to use the next paragraph as the last
299 * paragraphs.
300 */
301 int remaining = nOfs + *nChars - c2.pRun->member.run.nCharOfs
302 - end_para->member.para.nCharOfs;
303 if (remaining)
304 {
305 assert(remaining < c2.pRun->member.run.len);
306 end_para = end_para->member.para.next_para;
307 }
308 }
309 if (!editor->bEmulateVersion10) { /* v4.1 */
310 if (this_para->member.para.pCell != end_para->member.para.pCell ||
311 ((this_para->member.para.nFlags|end_para->member.para.nFlags)
313 {
314 while (this_para != end_para)
315 {
316 ME_DisplayItem *next_para = this_para->member.para.next_para;
317 BOOL bTruancateDeletion = FALSE;
318 if (this_para->member.para.nFlags & MEPF_ROWSTART) {
319 /* The following while loop assumes that next_para is MEPF_ROWSTART,
320 * so moving back one paragraph let's it be processed as the start
321 * of the row. */
322 next_para = this_para;
323 this_para = this_para->member.para.prev_para;
324 } else if (next_para->member.para.pCell != this_para->member.para.pCell
325 || this_para->member.para.nFlags & MEPF_ROWEND)
326 {
327 /* Start of the deletion from after the start of the table row. */
328 bTruancateDeletion = TRUE;
329 }
330 while (!bTruancateDeletion &&
331 next_para->member.para.nFlags & MEPF_ROWSTART)
332 {
333 next_para = ME_GetTableRowEnd(next_para)->member.para.next_para;
334 if (next_para->member.para.nCharOfs > nOfs + *nChars)
335 {
336 /* End of deletion is not past the end of the table row. */
337 next_para = this_para->member.para.next_para;
338 /* Delete the end paragraph preceding the table row if the
339 * preceding table row will be empty. */
340 if (this_para->member.para.nCharOfs >= nOfs)
341 {
342 next_para = next_para->member.para.next_para;
343 }
344 bTruancateDeletion = TRUE;
345 } else {
346 this_para = next_para->member.para.prev_para;
347 }
348 }
349 if (bTruancateDeletion)
350 {
351 ME_Run *end_run = &ME_FindItemBack(next_para, diRun)->member.run;
352 int nCharsNew = (next_para->member.para.nCharOfs - nOfs
353 - end_run->len);
354 nCharsNew = max(nCharsNew, 0);
355 assert(nCharsNew <= *nChars);
356 *nChars = nCharsNew;
357 break;
358 }
359 this_para = next_para;
360 }
361 }
362 } else { /* v1.0 - 3.0 */
363 ME_DisplayItem *pRun;
364 int nCharsToBoundary;
365
366 if ((this_para->member.para.nCharOfs != nOfs || this_para == end_para) &&
367 this_para->member.para.fmt.dwMask & PFM_TABLE &&
368 this_para->member.para.fmt.wEffects & PFE_TABLE)
369 {
370 pRun = c->pRun;
371 /* Find the next tab or end paragraph to use as a delete boundary */
372 while (!(pRun->member.run.nFlags & (MERF_TAB|MERF_ENDPARA)))
373 pRun = ME_FindItemFwd(pRun, diRun);
374 nCharsToBoundary = pRun->member.run.nCharOfs
375 - c->pRun->member.run.nCharOfs
376 - c->nOffset;
377 *nChars = min(*nChars, nCharsToBoundary);
378 } else if (end_para->member.para.fmt.dwMask & PFM_TABLE &&
379 end_para->member.para.fmt.wEffects & PFE_TABLE)
380 {
381 /* The deletion starts from before the row, so don't join it with
382 * previous non-empty paragraphs. */
383 ME_DisplayItem *curPara;
384 pRun = NULL;
385 if (nOfs > this_para->member.para.nCharOfs) {
386 pRun = ME_FindItemBack(end_para, diRun);
387 curPara = end_para->member.para.prev_para;
388 }
389 if (!pRun) {
390 pRun = ME_FindItemFwd(end_para, diRun);
391 curPara = end_para;
392 }
393 if (pRun)
394 {
395 nCharsToBoundary = curPara->member.para.nCharOfs
396 + pRun->member.run.nCharOfs
397 - nOfs;
398 if (nCharsToBoundary >= 0)
399 *nChars = min(*nChars, nCharsToBoundary);
400 }
401 }
402 if (*nChars < 0)
403 *nChars = 0;
404 }
405}
406
408 ME_DisplayItem *table_row)
409{
410 WCHAR endl = '\r', tab = '\t';
411 ME_DisplayItem *run;
412 PARAFORMAT2 *pFmt;
413 int i;
414
415 assert(table_row);
416 assert(table_row->type == diParagraph);
417 if (!editor->bEmulateVersion10) { /* v4.1 */
418 ME_DisplayItem *insertedCell, *para, *cell, *prevTableEnd;
419 cell = ME_FindItemFwd(ME_GetTableRowStart(table_row), diCell);
420 prevTableEnd = ME_GetTableRowEnd(table_row);
421 para = prevTableEnd->member.para.next_para;
422 run = ME_FindItemFwd(para, diRun);
423 editor->pCursors[0].pPara = para;
424 editor->pCursors[0].pRun = run;
425 editor->pCursors[0].nOffset = 0;
426 editor->pCursors[1] = editor->pCursors[0];
428 insertedCell = ME_FindItemFwd(para, diCell);
429 /* Copy cell properties */
430 insertedCell->member.cell.nRightBoundary = cell->member.cell.nRightBoundary;
431 insertedCell->member.cell.border = cell->member.cell.border;
432 while (cell->member.cell.next_cell) {
433 cell = cell->member.cell.next_cell;
434 para = ME_InsertTableCellFromCursor(editor);
435 insertedCell = ME_FindItemBack(para, diCell);
436 /* Copy cell properties */
437 insertedCell->member.cell.nRightBoundary = cell->member.cell.nRightBoundary;
438 insertedCell->member.cell.border = cell->member.cell.border;
439 };
440 para = ME_InsertTableRowEndFromCursor(editor);
441 para->member.para.fmt = prevTableEnd->member.para.fmt;
442 /* return the table row start for the inserted paragraph */
444 } else { /* v1.0 - 3.0 */
445 run = ME_FindItemBack(table_row->member.para.next_para, diRun);
446 pFmt = &table_row->member.para.fmt;
447 assert(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE);
448 editor->pCursors[0].pPara = table_row;
449 editor->pCursors[0].pRun = run;
450 editor->pCursors[0].nOffset = 0;
451 editor->pCursors[1] = editor->pCursors[0];
452 ME_InsertTextFromCursor(editor, 0, &endl, 1, run->member.run.style);
453 run = editor->pCursors[0].pRun;
454 for (i = 0; i < pFmt->cTabCount; i++) {
455 ME_InsertTextFromCursor(editor, 0, &tab, 1, run->member.run.style);
456 }
457 return table_row->member.para.next_para;
458 }
459}
460
461/* Selects the next table cell or appends a new table row if at end of table */
463 ME_DisplayItem *run)
464{
465 ME_DisplayItem *para = ME_GetParagraph(run);
466 int i;
467
468 assert(run && run->type == diRun);
469 assert(ME_IsInTable(run));
470 if (!editor->bEmulateVersion10) { /* v4.1 */
471 ME_DisplayItem *cell;
472 /* Get the initial cell */
473 if (para->member.para.nFlags & MEPF_ROWSTART) {
474 cell = para->member.para.next_para->member.para.pCell;
475 } else if (para->member.para.nFlags & MEPF_ROWEND) {
476 cell = para->member.para.prev_para->member.para.pCell;
477 } else {
478 cell = para->member.para.pCell;
479 }
480 assert(cell);
481 /* Get the next cell. */
482 if (cell->member.cell.next_cell &&
483 cell->member.cell.next_cell->member.cell.next_cell)
484 {
485 cell = cell->member.cell.next_cell;
486 } else {
488 para = para->member.para.next_para;
489 assert(para);
490 if (para->member.para.nFlags & MEPF_ROWSTART) {
491 cell = para->member.para.next_para->member.para.pCell;
492 } else {
493 /* Insert row */
494 para = para->member.para.prev_para;
495 para = ME_AppendTableRow(editor, ME_GetTableRowStart(para));
496 /* Put cursor at the start of the new table row */
497 para = para->member.para.next_para;
498 editor->pCursors[0].pPara = para;
499 editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
500 editor->pCursors[0].nOffset = 0;
501 editor->pCursors[1] = editor->pCursors[0];
503 return;
504 }
505 }
506 /* Select cell */
507 editor->pCursors[1].pRun = ME_FindItemFwd(cell, diRun);
508 editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun);
509 editor->pCursors[1].nOffset = 0;
510 assert(editor->pCursors[0].pRun);
511 cell = cell->member.cell.next_cell;
512 editor->pCursors[0].pRun = ME_FindItemBack(cell, diRun);
513 editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun);
514 editor->pCursors[0].nOffset = 0;
515 assert(editor->pCursors[1].pRun);
516 } else { /* v1.0 - 3.0 */
517 if (run->member.run.nFlags & MERF_ENDPARA &&
519 {
520 run = ME_FindItemFwd(run, diRun);
521 assert(run);
522 }
523 for (i = 0; i < 2; i++)
524 {
525 while (!(run->member.run.nFlags & MERF_TAB))
526 {
528 if (run->type != diRun)
529 {
530 para = run;
531 if (ME_IsInTable(para))
532 {
533 run = ME_FindItemFwd(para, diRun);
534 assert(run);
535 editor->pCursors[0].pPara = para;
536 editor->pCursors[0].pRun = run;
537 editor->pCursors[0].nOffset = 0;
538 i = 1;
539 } else {
540 /* Insert table row */
541 para = ME_AppendTableRow(editor, para->member.para.prev_para);
542 /* Put cursor at the start of the new table row */
543 editor->pCursors[0].pPara = para;
544 editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
545 editor->pCursors[0].nOffset = 0;
546 editor->pCursors[1] = editor->pCursors[0];
548 return;
549 }
550 }
551 }
552 if (i == 0)
553 run = ME_FindItemFwd(run, diRun);
554 editor->pCursors[i].pRun = run;
555 editor->pCursors[i].pPara = ME_GetParagraph(run);
556 editor->pCursors[i].nOffset = 0;
557 }
558 }
559}
560
561
562void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow)
563{
564 /* FIXME: Shift tab should move to the previous cell. */
565 ME_Cursor fromCursor, toCursor;
567 {
568 int from, to;
569 from = ME_GetCursorOfs(&editor->pCursors[0]);
570 to = ME_GetCursorOfs(&editor->pCursors[1]);
571 if (from <= to)
572 {
573 fromCursor = editor->pCursors[0];
574 toCursor = editor->pCursors[1];
575 } else {
576 fromCursor = editor->pCursors[1];
577 toCursor = editor->pCursors[0];
578 }
579 }
580 if (!editor->bEmulateVersion10) /* v4.1 */
581 {
582 if (!ME_IsInTable(toCursor.pRun))
583 {
584 editor->pCursors[0] = toCursor;
585 editor->pCursors[1] = toCursor;
586 } else {
587 ME_SelectOrInsertNextCell(editor, toCursor.pRun);
588 }
589 } else { /* v1.0 - 3.0 */
590 if (!ME_IsInTable(fromCursor.pRun)) {
591 editor->pCursors[0] = fromCursor;
592 editor->pCursors[1] = fromCursor;
593 /* FIXME: For some reason the caret is shown at the start of the
594 * previous paragraph in v1.0 to v3.0, and bCaretAtEnd only works
595 * within the paragraph for wrapped lines. */
596 if (ME_FindItemBack(fromCursor.pRun, diRun))
597 editor->bCaretAtEnd = TRUE;
598 } else if ((bSelectedRow || !ME_IsInTable(toCursor.pRun))) {
599 ME_SelectOrInsertNextCell(editor, fromCursor.pRun);
600 } else {
601 if (ME_IsSelection(editor) && !toCursor.nOffset)
602 {
603 ME_DisplayItem *run;
605 if (run->type == diRun && run->member.run.nFlags & MERF_TAB)
606 ME_SelectOrInsertNextCell(editor, run);
607 else
608 ME_SelectOrInsertNextCell(editor, toCursor.pRun);
609 } else {
610 ME_SelectOrInsertNextCell(editor, toCursor.pRun);
611 }
612 }
613 }
615 ME_Repaint(editor);
616 update_caret(editor);
617 ME_SendSelChange(editor);
618}
619
620/* Make sure the cursor is not in the hidden table row start paragraph
621 * without a selection. */
623{
624 ME_DisplayItem *para = editor->pCursors[0].pPara;
625 if (para == editor->pCursors[1].pPara &&
627 /* The cursors should not be at the hidden start row paragraph without
628 * a selection, so the cursor is moved into the first cell. */
629 para = para->member.para.next_para;
630 editor->pCursors[0].pPara = para;
631 editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
632 editor->pCursors[0].nOffset = 0;
633 editor->pCursors[1] = editor->pCursors[0];
634 }
635}
636
638{
639 RTFTable *tableDef = heap_alloc_zero(sizeof(*tableDef));
640
641 if (!editor->bEmulateVersion10) /* v4.1 */
642 tableDef->gapH = 10;
643 return tableDef;
644}
645
646void ME_InitTableDef(ME_TextEditor *editor, struct RTFTable *tableDef)
647{
648 ZeroMemory(tableDef->cells, sizeof(tableDef->cells));
649 ZeroMemory(tableDef->border, sizeof(tableDef->border));
650 tableDef->numCellsDefined = 0;
651 tableDef->leftEdge = 0;
652 if (!editor->bEmulateVersion10) /* v4.1 */
653 tableDef->gapH = 10;
654 else /* v1.0 - 3.0 */
655 tableDef->gapH = 0;
656}
basic_ostream< _CharT, _Traits > &_STLP_CALL endl(basic_ostream< _CharT, _Traits > &__os)
Definition: _ostream.h:357
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define TRACE_ON(x)
Definition: compat.h:75
BOOL ME_IsSelection(ME_TextEditor *editor)
Definition: caret.c:1578
int ME_GetCursorOfs(const ME_Cursor *cursor)
Definition: caret.c:957
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, const WCHAR *str, int len, ME_Style *style)
Definition: caret.c:595
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
Definition: caret.c:720
void ME_SendSelChange(ME_TextEditor *editor)
Definition: caret.c:1598
void update_caret(ME_TextEditor *editor)
Definition: caret.c:298
static void ME_SelectOrInsertNextCell(ME_TextEditor *editor, ME_DisplayItem *run)
Definition: table.c:462
ME_DisplayItem * ME_GetTableRowEnd(ME_DisplayItem *para)
Definition: table.c:136
static const WCHAR cr_lf[]
Definition: table.c:59
void ME_MoveCursorFromTableRowStartParagraph(ME_TextEditor *editor)
Definition: table.c:622
ME_DisplayItem * ME_InsertTableRowEndFromCursor(ME_TextEditor *editor)
Definition: table.c:129
void ME_CheckTablesForCorruption(ME_TextEditor *editor)
Definition: table.c:192
ME_DisplayItem * ME_GetTableRowStart(ME_DisplayItem *para)
Definition: table.c:154
ME_DisplayItem * ME_InsertTableRowStartFromCursor(ME_TextEditor *editor)
Definition: table.c:79
ME_DisplayItem * ME_AppendTableRow(ME_TextEditor *editor, ME_DisplayItem *table_row)
Definition: table.c:407
ME_DisplayItem * ME_GetOuterParagraph(ME_DisplayItem *para)
Definition: table.c:172
BOOL ME_IsInTable(ME_DisplayItem *pItem)
Definition: table.c:273
static ME_DisplayItem * ME_InsertEndParaFromCursor(ME_TextEditor *editor, int nCursor, const WCHAR *eol_str, int eol_len, int paraFlags)
Definition: table.c:61
void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow)
Definition: table.c:562
ME_DisplayItem * ME_InsertTableCellFromCursor(ME_TextEditor *editor)
Definition: table.c:121
ME_DisplayItem * ME_InsertTableRowStartAtParagraph(ME_TextEditor *editor, ME_DisplayItem *para)
Definition: table.c:86
struct RTFTable * ME_MakeTableDef(ME_TextEditor *editor)
Definition: table.c:637
void ME_InitTableDef(ME_TextEditor *editor, struct RTFTable *tableDef)
Definition: table.c:646
void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, ME_Cursor *c, int *nChars)
Definition: table.c:287
#define assert(x)
Definition: debug.h:53
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2996
void ME_ReleaseStyle(ME_Style *item) DECLSPEC_HIDDEN
Definition: style.c:462
ME_Style * ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) DECLSPEC_HIDDEN
Definition: style.c:476
BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: wrap.c:1093
ME_DisplayItem * ME_FindItemBack(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN
Definition: list.c:111
ME_DisplayItem * ME_SplitRunSimple(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: run.c:258
ME_DisplayItem * ME_GetParagraph(ME_DisplayItem *run) DECLSPEC_HIDDEN
Definition: para.c:815
void ME_DumpDocument(ME_TextBuffer *buffer) DECLSPEC_HIDDEN
Definition: list.c:187
void ME_InvalidateSelection(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: paint.c:1322
ME_DisplayItem * ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *rp, ME_Style *style, const WCHAR *eol_str, int eol_len, int paraFlags) DECLSPEC_HIDDEN
Definition: para.c:545
void ME_Repaint(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: paint.c:106
ME_DisplayItem * ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN
Definition: list.c:134
#define MERF_TAB
Definition: editstr.h:107
#define MERF_ENDPARA
Definition: editstr.h:122
#define MEPF_CELL
Definition: editstr.h:143
#define MEPF_ROWSTART
Definition: editstr.h:144
#define MEPF_ROWEND
Definition: editstr.h:145
@ diTextEnd
Definition: editstr.h:89
@ diRunOrParagraphOrEnd
Definition: editstr.h:97
@ diCell
Definition: editstr.h:86
@ diParagraphOrEnd
Definition: editstr.h:96
@ diRun
Definition: editstr.h:87
@ diParagraph
Definition: editstr.h:85
unsigned int BOOL
Definition: ntddk_ex.h:94
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const char cursor[]
Definition: icontest.c:13
#define c
Definition: ke_i.h:80
#define min(a, b)
Definition: monoChain.cc:55
#define PFM_TABLE
Definition: richedit.h:870
#define PFE_TABLE
Definition: richedit.h:944
#define PFM_TABLEROWDELIMITER
Definition: richedit.h:868
#define PFE_TABLEROWDELIMITER
Definition: richedit.h:942
#define TRACE(s)
Definition: solgame.cpp:4
CardRegion * from
Definition: spigame.cpp:19
Definition: rtf.h:1026
RTFCell cells[MAX_TABLE_CELLS]
Definition: rtf.h:1027
int numCellsDefined
Definition: rtf.h:1028
int gapH
Definition: rtf.h:1030
RTFBorder border[6]
Definition: rtf.h:1032
int leftEdge
Definition: rtf.h:1030
DWORD dwMask
Definition: richedit.h:667
SHORT cTabCount
Definition: richedit.h:674
WORD wEffects
Definition: richedit.h:669
struct tagME_DisplayItem * prev_cell
Definition: editstr.h:229
int nRightBoundary
Definition: editstr.h:224
struct tagME_DisplayItem * next_cell
Definition: editstr.h:229
ME_BorderRect border
Definition: editstr.h:225
ME_DisplayItem * pPara
Definition: editstr.h:275
int nOffset
Definition: editstr.h:277
ME_DisplayItem * pRun
Definition: editstr.h:276
union tagME_DisplayItem::@535 member
ME_DIType type
Definition: editstr.h:256
ME_Cell cell
Definition: editstr.h:261
struct tagME_DisplayItem * next
Definition: editstr.h:257
ME_Paragraph para
Definition: editstr.h:262
struct tagME_DisplayItem * next_para
Definition: editstr.h:217
struct tagME_DisplayItem * prev_para
Definition: editstr.h:217
PARAFORMAT2 fmt
Definition: editstr.h:204
struct tagME_DisplayItem * pCell
Definition: editstr.h:207
int nCharOfs
Definition: editstr.h:162
ME_Style * style
Definition: editstr.h:160
int nFlags
Definition: editstr.h:165
int len
Definition: editstr.h:163
ME_DisplayItem * pFirst
Definition: editstr.h:268
ME_Cursor * pCursors
Definition: editstr.h:387
ME_TextBuffer * pBuffer
Definition: editstr.h:386
BOOL bEmulateVersion10
Definition: editstr.h:385
BOOL bCaretAtEnd
Definition: editstr.h:399
#define max(a, b)
Definition: svc.c:63
#define ZeroMemory
Definition: winbase.h:1712
__wchar_t WCHAR
Definition: xmlstorage.h:180