sync riched20 with wine 1.1.7

svn path=/trunk/; revision=37014
This commit is contained in:
Christoph von Wittich 2008-10-27 08:10:25 +00:00
parent 9e8da0db2a
commit bfd33ba526
11 changed files with 346 additions and 204 deletions

View file

@ -101,6 +101,7 @@
- EM_SETIMEOPTIONS 1.0asian
- EM_SETLANGOPTIONS 2.0
- EM_SETLIMITTEXT
- EM_SETMARGINS
+ EM_SETMODIFY (not sure if implementation is correct)
- EM_SETOLECALLBACK
+ EM_SETOPTIONS (partially implemented)
@ -1937,6 +1938,93 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
return -1;
}
typedef struct tagME_GlobalDestStruct
{
HGLOBAL hData;
int nLength;
} ME_GlobalDestStruct;
static DWORD CALLBACK ME_ReadFromHGLOBALUnicode(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb)
{
ME_GlobalDestStruct *pData = (ME_GlobalDestStruct *)dwCookie;
int i;
WORD *pSrc, *pDest;
cb = cb >> 1;
pDest = (WORD *)lpBuff;
pSrc = (WORD *)GlobalLock(pData->hData);
for (i = 0; i<cb && pSrc[pData->nLength+i]; i++) {
pDest[i] = pSrc[pData->nLength+i];
}
pData->nLength += i;
*pcb = 2*i;
GlobalUnlock(pData->hData);
return 0;
}
static DWORD CALLBACK ME_ReadFromHGLOBALRTF(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb)
{
ME_GlobalDestStruct *pData = (ME_GlobalDestStruct *)dwCookie;
int i;
BYTE *pSrc, *pDest;
pDest = lpBuff;
pSrc = (BYTE *)GlobalLock(pData->hData);
for (i = 0; i<cb && pSrc[pData->nLength+i]; i++) {
pDest[i] = pSrc[pData->nLength+i];
}
pData->nLength += i;
*pcb = i;
GlobalUnlock(pData->hData);
return 0;
}
static BOOL ME_Paste(ME_TextEditor *editor)
{
DWORD dwFormat = 0;
EDITSTREAM es;
ME_GlobalDestStruct gds;
UINT nRTFFormat = RegisterClipboardFormatA("Rich Text Format");
UINT cf = 0;
if (IsClipboardFormatAvailable(nRTFFormat))
cf = nRTFFormat, dwFormat = SF_RTF;
else if (IsClipboardFormatAvailable(CF_UNICODETEXT))
cf = CF_UNICODETEXT, dwFormat = SF_TEXT|SF_UNICODE;
else
return FALSE;
if (!OpenClipboard(editor->hWnd))
return FALSE;
gds.hData = GetClipboardData(cf);
gds.nLength = 0;
es.dwCookie = (DWORD)&gds;
es.pfnCallback = dwFormat == SF_RTF ? ME_ReadFromHGLOBALRTF : ME_ReadFromHGLOBALUnicode;
ME_StreamIn(editor, dwFormat|SFF_SELECTION, &es, FALSE);
CloseClipboard();
return TRUE;
}
static BOOL ME_Copy(ME_TextEditor *editor, CHARRANGE *range)
{
LPDATAOBJECT dataObj = NULL;
HRESULT hr = S_OK;
if (editor->cPasswordMask)
return FALSE; /* Copying or Cutting masked text isn't allowed */
if(editor->lpOleCallback)
hr = IRichEditOleCallback_GetClipboardData(editor->lpOleCallback, range, RECO_COPY, &dataObj);
if(FAILED(hr) || !dataObj)
hr = ME_GetDataObject(editor, range, &dataObj);
if(SUCCEEDED(hr)) {
hr = OleSetClipboard(dataObj);
IDataObject_Release(dataObj);
}
return SUCCEEDED(hr) != 0;
}
/* helper to send a msg filter notification */
static BOOL
ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam)
@ -2022,6 +2110,49 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
ME_UpdateRepaint(editor);
ME_SendRequestResize(editor, FALSE);
return TRUE;
case 'A':
if (ctrl_is_down)
{
ME_SetSelection(editor, 0, -1);
return TRUE;
}
break;
case 'V':
if (ctrl_is_down)
return ME_Paste(editor);
break;
case 'C':
case 'X':
if (ctrl_is_down)
{
CHARRANGE range;
BOOL result;
ME_GetSelection(editor, &range.cpMin, &range.cpMax);
result = ME_Copy(editor, &range);
if (result && nKey == 'X')
{
ME_InternalDeleteText(editor, range.cpMin, range.cpMax-range.cpMin, FALSE);
ME_CommitUndo(editor);
ME_UpdateRepaint(editor);
}
return result;
}
break;
case 'Z':
if (ctrl_is_down)
{
ME_Undo(editor);
return TRUE;
}
break;
case 'Y':
if (ctrl_is_down)
{
ME_Redo(editor);
return TRUE;
}
break;
default:
if (nKey != VK_SHIFT && nKey != VK_CONTROL && nKey && nKey != VK_MENU)
@ -2103,10 +2234,29 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
POINT pt;
BOOL isExact;
int offset;
SCROLLBARINFO sbi;
DWORD messagePos = GetMessagePos();
pt.x = (short)LOWORD(messagePos);
pt.y = (short)HIWORD(messagePos);
sbi.cbSize = sizeof(sbi);
GetScrollBarInfo(editor->hWnd, OBJID_HSCROLL, &sbi);
if (!(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)) &&
PtInRect(&sbi.rcScrollBar, pt))
{
SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_ARROW));
return TRUE;
}
sbi.cbSize = sizeof(sbi);
GetScrollBarInfo(editor->hWnd, OBJID_VSCROLL, &sbi);
if (!(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)) &&
PtInRect(&sbi.rcScrollBar, pt))
{
SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_ARROW));
return TRUE;
}
ScreenToClient(editor->hWnd, &pt);
if ((GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_SELECTIONBAR) &&
(pt.x < editor->selofs ||
(editor->nSelectionType == stLine && GetCapture() == editor->hWnd)))
@ -2209,8 +2359,7 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
ed->nParagraphs = 1;
ed->nLastSelStart = ed->nLastSelEnd = 0;
ed->pLastSelStartPara = ed->pLastSelEndPara = ME_FindItemFwd(ed->pBuffer->pFirst, diParagraph);
ed->bRedraw = TRUE;
ed->bWordWrap = (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL) ? FALSE : TRUE;
ed->bWordWrap = (GetWindowLongW(hWnd, GWL_STYLE) & (WS_HSCROLL|ES_AUTOHSCROLL)) ? FALSE : TRUE;
ed->bHideSelection = FALSE;
ed->nInvalidOfs = -1;
ed->pfnWordBreak = NULL;
@ -2251,48 +2400,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
return ed;
}
typedef struct tagME_GlobalDestStruct
{
HGLOBAL hData;
int nLength;
} ME_GlobalDestStruct;
static DWORD CALLBACK ME_ReadFromHGLOBALUnicode(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb)
{
ME_GlobalDestStruct *pData = (ME_GlobalDestStruct *)dwCookie;
int i;
WORD *pSrc, *pDest;
cb = cb >> 1;
pDest = (WORD *)lpBuff;
pSrc = (WORD *)GlobalLock(pData->hData);
for (i = 0; i<cb && pSrc[pData->nLength+i]; i++) {
pDest[i] = pSrc[pData->nLength+i];
}
pData->nLength += i;
*pcb = 2*i;
GlobalUnlock(pData->hData);
return 0;
}
static DWORD CALLBACK ME_ReadFromHGLOBALRTF(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb)
{
ME_GlobalDestStruct *pData = (ME_GlobalDestStruct *)dwCookie;
int i;
BYTE *pSrc, *pDest;
pDest = lpBuff;
pSrc = (BYTE *)GlobalLock(pData->hData);
for (i = 0; i<cb && pSrc[pData->nLength+i]; i++) {
pDest[i] = pSrc[pData->nLength+i];
}
pData->nLength += i;
*pcb = i;
GlobalUnlock(pData->hData);
return 0;
}
void ME_DestroyEditor(ME_TextEditor *editor)
{
ME_DisplayItem *pFirst = editor->pBuffer->pFirst;
@ -2530,6 +2637,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
UNSUPPORTED_MSG(EM_SETEDITSTYLE)
UNSUPPORTED_MSG(EM_SETFONTSIZE)
UNSUPPORTED_MSG(EM_SETLANGOPTIONS)
UNSUPPORTED_MSG(EM_SETMARGINS)
UNSUPPORTED_MSG(EM_SETPALETTE)
UNSUPPORTED_MSG(EM_SETTABSTOPS)
UNSUPPORTED_MSG(EM_SETTYPOGRAPHYOPTIONS)
@ -2741,8 +2849,9 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
ME_GetSelection(editor, &from, &to);
style = ME_GetSelectionInsertStyle(editor);
ME_InternalDeleteText(editor, from, to - from, FALSE);
if (pStruct->codepage != 1200 && lParam && !strncmp((char *)lParam, "{\\rtf", 5))
ME_StreamInRTFString(editor, 1, (char *)lParam);
if (pStruct->codepage != 1200 && lParam &&
(!strncmp((char *)lParam, "{\\rtf", 5) || !strncmp((char *)lParam, "{\\urtf}", 6)))
ME_StreamInRTFString(editor, 1, (char *)lParam);
else ME_InsertTextFromCursor(editor, 0, wszText, len, style);
ME_ReleaseStyle(style);
@ -2750,8 +2859,9 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
}
else {
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor), FALSE);
if (pStruct->codepage != 1200 && lParam && !strncmp((char *)lParam, "{\\rtf", 5))
ME_StreamInRTFString(editor, 0, (char *)lParam);
if (pStruct->codepage != 1200 && lParam &&
(!strncmp((char *)lParam, "{\\rtf", 5) || !strncmp((char *)lParam, "{\\urtf}", 6)))
ME_StreamInRTFString(editor, 0, (char *)lParam);
else ME_InsertTextFromCursor(editor, 0, wszText, len, editor->pBuffer->pDefaultStyle);
len = 1;
@ -2785,11 +2895,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
editor->rgbBackColor = lParam;
editor->hbrBackground = CreateSolidBrush(editor->rgbBackColor);
}
if (editor->bRedraw)
{
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
}
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
return lColor;
}
case EM_GETMODIFY:
@ -3047,51 +3154,15 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
return FALSE;
}
case WM_PASTE:
{
DWORD dwFormat = 0;
EDITSTREAM es;
ME_GlobalDestStruct gds;
UINT nRTFFormat = RegisterClipboardFormatA("Rich Text Format");
UINT cf = 0;
if (IsClipboardFormatAvailable(nRTFFormat))
cf = nRTFFormat, dwFormat = SF_RTF;
else if (IsClipboardFormatAvailable(CF_UNICODETEXT))
cf = CF_UNICODETEXT, dwFormat = SF_TEXT|SF_UNICODE;
else
return 0;
if (!OpenClipboard(hWnd))
return 0;
gds.hData = GetClipboardData(cf);
gds.nLength = 0;
es.dwCookie = (DWORD)&gds;
es.pfnCallback = dwFormat == SF_RTF ? ME_ReadFromHGLOBALRTF : ME_ReadFromHGLOBALUnicode;
ME_StreamIn(editor, dwFormat|SFF_SELECTION, &es, FALSE);
CloseClipboard();
ME_Paste(editor);
return 0;
}
case WM_CUT:
case WM_COPY:
{
LPDATAOBJECT dataObj = NULL;
CHARRANGE range;
HRESULT hr = S_OK;
if (editor->cPasswordMask)
return 0; /* Copying or Cutting masked text isn't allowed */
ME_GetSelection(editor, &range.cpMin, &range.cpMax);
if(editor->lpOleCallback)
hr = IRichEditOleCallback_GetClipboardData(editor->lpOleCallback, &range, RECO_COPY, &dataObj);
if(FAILED(hr) || !dataObj)
hr = ME_GetDataObject(editor, &range, &dataObj);
if(SUCCEEDED(hr)) {
hr = OleSetClipboard(dataObj);
IDataObject_Release(dataObj);
}
if (SUCCEEDED(hr) && msg == WM_CUT)
if (ME_Copy(editor, &range) && msg == WM_CUT)
{
ME_InternalDeleteText(editor, range.cpMin, range.cpMax-range.cpMin, FALSE);
ME_CommitUndo(editor);
@ -3472,18 +3543,15 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
if (wParam >= 0x40000)
nCharOfs = lParam;
nLength = ME_GetTextLength(editor);
if (nCharOfs < nLength) {
ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset);
assert(pRun->type == diRun);
pt.y = pRun->member.run.pt.y;
pt.x = pRun->member.run.pt.x + ME_PointFromChar(editor, &pRun->member.run, nOffset);
pt.y += ME_GetParagraph(pRun)->member.para.pt.y;
} else {
pt.x = 0;
pt.y = editor->pBuffer->pLast->member.para.pt.y;
}
nCharOfs = min(nCharOfs, nLength);
ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset);
assert(pRun->type == diRun);
pt.y = pRun->member.run.pt.y;
pt.x = pRun->member.run.pt.x + ME_PointFromChar(editor, &pRun->member.run, nOffset);
pt.y += ME_GetParagraph(pRun)->member.para.pt.y;
pt.x += editor->selofs;
pt.x++; /* for some reason native offsets x by one */
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
@ -3581,7 +3649,6 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
goto do_default;
break;
case WM_PAINT:
if (editor->bRedraw)
{
HDC hDC;
PAINTSTRUCT ps;
@ -3604,14 +3671,11 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
return 0;
case WM_ERASEBKGND:
{
if (editor->bRedraw)
HDC hDC = (HDC)wParam;
RECT rc;
if (GetUpdateRect(hWnd,&rc,TRUE))
{
HDC hDC = (HDC)wParam;
RECT rc;
if (GetUpdateRect(hWnd,&rc,TRUE))
{
FillRect(hDC, &rc, editor->hbrBackground);
}
FillRect(hDC, &rc, editor->hbrBackground);
}
return 1;
}
@ -3642,36 +3706,11 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
MultiByteToWideChar(CP_ACP, 0, &charA, 1, &wstr, 1);
}
switch (wstr)
{
case 1: /* Ctrl-A */
ME_SetSelection(editor, 0, -1);
return 0;
case 3: /* Ctrl-C */
SendMessageW(editor->hWnd, WM_COPY, 0, 0);
return 0;
}
if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY) {
MessageBeep(MB_ICONERROR);
return 0; /* FIXME really 0 ? */
}
switch (wstr)
{
case 22: /* Ctrl-V */
SendMessageW(editor->hWnd, WM_PASTE, 0, 0);
return 0;
case 24: /* Ctrl-X */
SendMessageW(editor->hWnd, WM_CUT, 0, 0);
return 0;
case 25: /* Ctrl-Y */
SendMessageW(editor->hWnd, EM_REDO, 0, 0);
return 0;
case 26: /* Ctrl-Z */
SendMessageW(editor->hWnd, EM_UNDO, 0, 0);
return 0;
}
if (((unsigned)wstr)>=' '
|| (wstr=='\r' && (GetWindowLongW(hWnd, GWL_STYLE) & ES_MULTILINE))
|| wstr=='\t') {
@ -3930,9 +3969,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
ME_SendRequestResize(editor, TRUE);
return 0;
case WM_SETREDRAW:
if ((editor->bRedraw = wParam))
ME_RewrapRepaint(editor);
return 0;
return DefWindowProcW(hWnd, msg, wParam, lParam);
case WM_SIZE:
{
GetClientRect(hWnd, &editor->rcFormat);

View file

@ -351,7 +351,6 @@ typedef struct tagME_TextEditor
ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE];
int nZoomNumerator, nZoomDenominator;
RECT rcFormat;
BOOL bRedraw;
BOOL bWordWrap;
int nInvalidOfs;
int nTextLimit;
@ -401,7 +400,7 @@ typedef struct tagME_WrapContext
int nAvailWidth;
int nRow;
POINT pt;
BOOL bOverflown;
BOOL bOverflown, bWordWrap;
ME_DisplayItem *pRowStart;
ME_DisplayItem *pLastSplittableRun;

View file

@ -147,6 +147,8 @@ void ME_Repaint(ME_TextEditor *editor)
ME_UpdateScrollBar(editor);
FIXME("ME_Repaint had to call ME_WrapMarkedParagraphs\n");
}
if (!IsWindowVisible(editor->hWnd))
return;
if (!editor->bEmulateVersion10 || (editor->nEventMask & ENM_UPDATE))
ME_SendOldNotify(editor, EN_UPDATE);
UpdateWindow(editor->hWnd);
@ -159,7 +161,6 @@ void ME_UpdateRepaint(ME_TextEditor *editor)
BOOL wrappedParagraphs;
wrappedParagraphs = ME_WrapMarkedParagraphs(editor);
if (!editor->bRedraw) return;
if (wrappedParagraphs)
ME_UpdateScrollBar(editor);
@ -185,12 +186,9 @@ ME_RewrapRepaint(ME_TextEditor *editor)
* looks, but not content. Like resizing. */
ME_MarkAllForWrapping(editor);
if (editor->bRedraw)
{
ME_WrapMarkedParagraphs(editor);
ME_UpdateScrollBar(editor);
ME_Repaint(editor);
}
ME_WrapMarkedParagraphs(editor);
ME_UpdateScrollBar(editor);
ME_Repaint(editor);
}
int ME_twips2pointsX(ME_Context *c, int x)
@ -1074,17 +1072,14 @@ void ME_Scroll(ME_TextEditor *editor, int value, int type)
si.nPos = 0;
}
nNewPos = SetScrollInfo(editor->hWnd, SB_VERT, &si, editor->bRedraw);
nNewPos = SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
editor->vert_si.nPos = nNewPos;
nActualScroll = nOrigPos - nNewPos;
if (editor->bRedraw)
{
if (abs(nActualScroll) > editor->sizeWindow.cy)
InvalidateRect(editor->hWnd, NULL, TRUE);
else
ScrollWindowEx(editor->hWnd, 0, nActualScroll, NULL, NULL, NULL, NULL, SW_INVALIDATE);
ME_Repaint(editor);
}
if (abs(nActualScroll) > editor->sizeWindow.cy)
InvalidateRect(editor->hWnd, NULL, TRUE);
else
ScrollWindowEx(editor->hWnd, 0, nActualScroll, NULL, NULL, NULL, NULL, SW_INVALIDATE);
ME_Repaint(editor);
hWnd = editor->hWnd;
winStyle = GetWindowLongW(hWnd, GWL_STYLE);
@ -1099,7 +1094,7 @@ void ME_Scroll(ME_TextEditor *editor, int value, int type)
}
void ME_UpdateScrollBar(ME_TextEditor *editor)
void ME_UpdateScrollBar(ME_TextEditor *editor)
{
/* Note that this is the only function that should ever call SetScrolLInfo
* with SIF_PAGE or SIF_RANGE. SetScrollPos and SetScrollRange should never

View file

@ -287,6 +287,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
{
ME_AddUndoItem(editor, diUndoSetParagraphFormat, tp);
*tp->member.para.pFmt = *pNext->member.para.pFmt;
tp->member.para.border = pNext->member.para.border;
}
if (!editor->bEmulateVersion10) { /* v4.1 */

View file

@ -109,7 +109,7 @@ int _RTFGetChar(RTF_Info *info)
if (stream->dwSize == 0)
return EOF;
}
ch = stream->buffer[stream->dwUsed++];
ch = (unsigned char)stream->buffer[stream->dwUsed++];
if (!ch)
return EOF;
return ch;

View file

@ -304,6 +304,8 @@ ME_WordBreakProc(LPWSTR s, INT start, INT len, INT code)
/* FIXME: Native also knows about punctuation */
TRACE("s==%s, start==%d, len==%d, code==%d\n",
debugstr_wn(s, len), start, len, code);
/* convert number of bytes to number of characters. */
len /= sizeof(WCHAR);
switch (code)
{
case WB_ISDELIMITER:
@ -330,11 +332,23 @@ ME_WordBreakProc(LPWSTR s, INT start, INT len, INT code)
int
ME_CallWordBreakProc(ME_TextEditor *editor, ME_String *str, INT start, INT code)
{
/* FIXME: ANSIfy the string when bEmulateVersion10 is TRUE */
if (!editor->pfnWordBreak)
return ME_WordBreakProc(str->szData, start, str->nLen, code);
else
return editor->pfnWordBreak(str->szData, start, str->nLen, code);
if (!editor->pfnWordBreak) {
return ME_WordBreakProc(str->szData, start, str->nLen*sizeof(WCHAR), code);
} else if (!editor->bEmulateVersion10) {
/* MSDN lied about the third parameter for EditWordBreakProc being the number
* of characters, it is actually the number of bytes of the string. */
return editor->pfnWordBreak(str->szData, start, str->nLen*sizeof(WCHAR), code);
} else {
int result;
int buffer_size = WideCharToMultiByte(CP_ACP, 0, str->szData, str->nLen,
NULL, 0, NULL, NULL);
char *buffer = (char*)heap_alloc(buffer_size);
WideCharToMultiByte(CP_ACP, 0, str->szData, str->nLen,
buffer, buffer_size, NULL, NULL);
result = editor->pfnWordBreak(str->szData, start, str->nLen, code);
heap_free(buffer);
return result;
}
}
LPWSTR ME_ToUnicode(BOOL unicode, LPVOID psz)

View file

@ -392,9 +392,10 @@ ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor,
assert(table_row);
assert(table_row->type == diParagraph);
if (!editor->bEmulateVersion10) { /* v4.1 */
ME_DisplayItem *insertedCell, *para, *cell;
ME_DisplayItem *insertedCell, *para, *cell, *prevTableEnd;
cell = ME_FindItemFwd(ME_GetTableRowStart(table_row), diCell);
run = ME_GetTableRowEnd(table_row)->member.para.next_para;
prevTableEnd = ME_GetTableRowEnd(table_row);
run = prevTableEnd->member.para.next_para;
run = ME_FindItemFwd(run, diRun);
editor->pCursors[0].pRun = run;
editor->pCursors[0].nOffset = 0;
@ -412,7 +413,8 @@ ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor,
insertedCell->member.cell.nRightBoundary = cell->member.cell.nRightBoundary;
insertedCell->member.cell.border = cell->member.cell.border;
};
ME_InsertTableRowEndFromCursor(editor);
para = ME_InsertTableRowEndFromCursor(editor);
*para->member.para.pFmt = *prevTableEnd->member.para.pFmt;
/* return the table row start for the inserted paragraph */
return ME_FindItemFwd(cell, diParagraph)->member.para.next_para;
} else { /* v1.0 - 3.0 */

View file

@ -57,6 +57,7 @@ typedef struct ITextServicesImpl {
ITextHost *pMyHost;
LONG ref;
CRITICAL_SECTION csTxtSrv;
char spare[256];
} ITextServicesImpl;
static const ITextServicesVtbl textservices_Vtbl;

View file

@ -96,6 +96,7 @@ ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_Disp
pItem->member.para.pFmt->cbSize = sizeof(PARAFORMAT2);
pItem->member.para.pFmt->dwMask = 0;
*pItem->member.para.pFmt = *pdi->member.para.pFmt;
pItem->member.para.border = pdi->member.para.border;
pItem->member.para.nFlags = prev_para->member.para.nFlags & ~MEPF_CELL;
pItem->member.para.pCell = NULL;
break;
@ -293,6 +294,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
para = ME_FindItemBack(tmp.pRun, diParagraph);
ME_AddUndoItem(editor, diUndoSetParagraphFormat, para);
*para->member.para.pFmt = *pItem->member.para.pFmt;
para->member.para.border = pItem->member.para.border;
break;
}
case diUndoSetCharFormat:
@ -343,12 +345,14 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
new_para->member.para.nFlags |= MEPF_ROWSTART;
assert(pItem->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
*new_para->member.para.pFmt = *pItem->member.para.pFmt;
new_para->member.para.border = pItem->member.para.border;
if (pItem->member.para.pCell)
{
ME_DisplayItem *pItemCell, *pCell;
pItemCell = pItem->member.para.pCell;
pCell = new_para->member.para.pCell;
pCell->member.cell.nRightBoundary = pItemCell->member.cell.nRightBoundary;
pCell->member.cell.border = pItemCell->member.cell.border;
}
break;
}

View file

@ -50,8 +50,10 @@ static void ME_BeginRow(ME_WrapContext *wc, ME_DisplayItem *para)
wc->pRowStart = NULL;
wc->bOverflown = FALSE;
wc->pLastSplittableRun = NULL;
wc->bWordWrap = wc->context->editor->bWordWrap;
if (para->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND)) {
wc->nAvailWidth = 0;
wc->bWordWrap = FALSE;
if (para->member.para.nFlags & MEPF_ROWEND)
{
ME_Cell *cell = &ME_FindItemBack(para, diCell)->member.cell;
@ -73,11 +75,11 @@ static void ME_BeginRow(ME_WrapContext *wc, ME_DisplayItem *para)
wc->nAvailWidth = cell->nWidth
- (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin;
} else if (wc->context->editor->bWordWrap) {
wc->nAvailWidth = wc->context->rcView.right - wc->context->rcView.left
- (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin;
wc->bWordWrap = TRUE;
} else {
wc->nAvailWidth = ~0u >> 1;
wc->nAvailWidth = wc->context->rcView.right - wc->context->rcView.left
- (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin
- wc->context->editor->selofs;
}
wc->pt.x = wc->context->pt.x;
if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */
@ -148,9 +150,9 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
assert(para->member.para.pFmt->dwMask & PFM_ALIGNMENT);
align = para->member.para.pFmt->wAlignment;
if (align == PFA_CENTER)
shift = (wc->nAvailWidth-width)/2;
shift = max((wc->nAvailWidth-width)/2, 0);
if (align == PFA_RIGHT)
shift = wc->nAvailWidth-width;
shift = max(wc->nAvailWidth-width, 0);
for (p = wc->pRowStart; p!=pEnd; p = p->next)
{
if (p->type==diRun) { /* FIXME add more run types */
@ -377,7 +379,8 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
}
/* will current run fit? */
if (wc->pt.x + run->nWidth - wc->context->pt.x > wc->nAvailWidth)
if (wc->bWordWrap &&
wc->pt.x + run->nWidth - wc->context->pt.x > wc->nAvailWidth)
{
int loc = wc->context->pt.x + wc->nAvailWidth - wc->pt.x;
/* total white run ? */
@ -416,9 +419,11 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
{
if (run->nFlags & MERF_STARTWHITE)
{
/* we had only spaces so far, so we must be on the first line of the
* paragraph, since no other lines of the paragraph start with spaces. */
assert(!wc->nRow);
/* We had only spaces so far, so we must be on the first line of the
* paragraph (or the first line after MERF_ENDROW forced the line
* break within the paragraph), since no other lines of the paragraph
* start with spaces. */
/* The lines will only contain spaces, and the rest of the run will
* overflow onto the next line. */
wc->bOverflown = TRUE;
@ -730,30 +735,31 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
return bModified;
}
void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor) {
void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor)
{
ME_Context c;
RECT rc;
int ofs;
ME_DisplayItem *item;
ME_InitContext(&c, editor, GetDC(editor->hWnd));
if (editor->bRedraw)
{
RECT rc = c.rcView;
int ofs = ME_GetYScrollPos(editor);
ME_DisplayItem *item = editor->pBuffer->pFirst;
while(item != editor->pBuffer->pLast) {
if (item->member.para.nFlags & MEPF_REPAINT) {
rc.top = item->member.para.pt.y - ofs;
rc.bottom = item->member.para.pt.y + item->member.para.nHeight - ofs;
InvalidateRect(editor->hWnd, &rc, TRUE);
}
item = item->member.para.next_para;
}
if (editor->nTotalLength < editor->nLastTotalLength)
{
rc.top = editor->nTotalLength - ofs;
rc.bottom = editor->nLastTotalLength - ofs;
rc = c.rcView;
ofs = ME_GetYScrollPos(editor);
item = editor->pBuffer->pFirst;
while(item != editor->pBuffer->pLast) {
if (item->member.para.nFlags & MEPF_REPAINT) {
rc.top = item->member.para.pt.y - ofs;
rc.bottom = item->member.para.pt.y + item->member.para.nHeight - ofs;
InvalidateRect(editor->hWnd, &rc, TRUE);
}
item = item->member.para.next_para;
}
if (editor->nTotalLength < editor->nLastTotalLength)
{
rc.top = editor->nTotalLength - ofs;
rc.bottom = editor->nLastTotalLength - ofs;
InvalidateRect(editor->hWnd, &rc, TRUE);
}
ME_DestroyContext(&c, editor->hWnd);
}

View file

@ -196,11 +196,14 @@ ME_StreamOutRTFHeader(ME_OutStream *pStream, int dwFormat)
static BOOL
ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, const ME_DisplayItem *pLastRun)
ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun,
ME_DisplayItem *pLastRun)
{
ME_DisplayItem *item = pFirstRun;
ME_FontTableItem *table = pStream->fonttbl;
int i;
ME_DisplayItem *pLastPara = ME_GetParagraph(pLastRun);
ME_DisplayItem *pCell = NULL;
do {
CHARFORMAT2W *fmt = &item->member.run.style->fmt;
@ -214,7 +217,7 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun,
if (table[i].bCharSet == bCharSet
&& (table[i].szFaceName == face || !lstrcmpW(table[i].szFaceName, face)))
break;
if (i == pStream->nFontTblLen) {
if (i == pStream->nFontTblLen && i < STREAMOUT_FONTTBL_SIZE) {
table[i].bCharSet = bCharSet;
table[i].szFaceName = face;
pStream->nFontTblLen++;
@ -226,7 +229,7 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun,
for (i = 1; i < pStream->nColorTblLen; i++)
if (pStream->colortbl[i] == crColor)
break;
if (i == pStream->nColorTblLen) {
if (i == pStream->nColorTblLen && i < STREAMOUT_COLORTBL_SIZE) {
pStream->colortbl[i] = crColor;
pStream->nColorTblLen++;
}
@ -236,7 +239,7 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun,
for (i = 1; i < pStream->nColorTblLen; i++)
if (pStream->colortbl[i] == crColor)
break;
if (i == pStream->nColorTblLen) {
if (i == pStream->nColorTblLen && i < STREAMOUT_COLORTBL_SIZE) {
pStream->colortbl[i] = crColor;
pStream->nColorTblLen++;
}
@ -246,6 +249,38 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun,
break;
item = ME_FindItemFwd(item, diRun);
} while (item);
item = ME_GetParagraph(pFirstRun);
do {
if (item->member.para.pCell && item->member.para.pCell)
{
pCell = item->member.para.pCell;
if (pCell)
{
ME_Border* borders[4] = { &pCell->member.cell.border.top,
&pCell->member.cell.border.left,
&pCell->member.cell.border.bottom,
&pCell->member.cell.border.right };
for (i = 0; i < 4; i++)
{
if (borders[i]->width > 0)
{
int j;
COLORREF crColor = borders[i]->colorRef;
for (j = 1; j < pStream->nColorTblLen; j++)
if (pStream->colortbl[j] == crColor)
break;
if (j == pStream->nColorTblLen && j < STREAMOUT_COLORTBL_SIZE) {
pStream->colortbl[j] = crColor;
pStream->nColorTblLen++;
}
}
}
}
}
if (item == pLastPara)
break;
item = item->member.para.next_para;
} while (item);
if (!ME_StreamOutPrint(pStream, "{\\fonttbl"))
return FALSE;
@ -286,30 +321,78 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun,
static BOOL
ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream,
const ME_DisplayItem *para)
ME_DisplayItem *para)
{
ME_DisplayItem *cell;
char props[STREAMOUT_BUFFER_SIZE] = "";
int i;
const char sideChar[4] = {'t','l','b','r'};
if (!ME_StreamOutPrint(pStream, "\\trowd"))
return FALSE;
if (!editor->bEmulateVersion10) { /* v4.1 */
assert(para->member.para.nFlags & MEPF_ROWSTART);
PARAFORMAT2 *pFmt = ME_GetTableRowEnd(para)->member.para.pFmt;
para = ME_GetTableRowStart(para);
cell = para->member.para.next_para->member.para.pCell;
assert(cell);
if (pFmt->dxOffset)
sprintf(props + strlen(props), "\\trgaph%d", pFmt->dxOffset);
if (pFmt->dxStartIndent)
sprintf(props + strlen(props), "\\trleft%d", pFmt->dxStartIndent);
do {
ME_Border* borders[4] = { &cell->member.cell.border.top,
&cell->member.cell.border.left,
&cell->member.cell.border.bottom,
&cell->member.cell.border.right };
for (i = 0; i < 4; i++)
{
if (borders[i]->width)
{
int j;
COLORREF crColor = borders[i]->colorRef;
sprintf(props + strlen(props), "\\clbrdr%c", sideChar[i]);
sprintf(props + strlen(props), "\\brdrs");
sprintf(props + strlen(props), "\\brdrw%d", borders[i]->width);
for (j = 1; j < pStream->nColorTblLen; j++) {
if (pStream->colortbl[j] == crColor) {
sprintf(props + strlen(props), "\\brdrcf%u", j);
break;
}
}
}
}
sprintf(props + strlen(props), "\\cellx%d", cell->member.cell.nRightBoundary);
cell = cell->member.cell.next_cell;
} while (cell->member.cell.next_cell);
} else { /* v1.0 - 3.0 */
const ME_Border* borders[4] = { &para->member.para.border.top,
&para->member.para.border.left,
&para->member.para.border.bottom,
&para->member.para.border.right };
PARAFORMAT2 *pFmt = para->member.para.pFmt;
int i;
assert(!(para->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL)));
if (pFmt->dxOffset)
sprintf(props + strlen(props), "\\trgaph%d", pFmt->dxOffset);
if (pFmt->dxStartIndent)
sprintf(props + strlen(props), "\\trleft%d", pFmt->dxStartIndent);
for (i = 0; i < 4; i++)
{
if (borders[i]->width)
{
int j;
COLORREF crColor = borders[i]->colorRef;
sprintf(props + strlen(props), "\\trbrdr%c", sideChar[i]);
sprintf(props + strlen(props), "\\brdrs");
sprintf(props + strlen(props), "\\brdrw%d", borders[i]->width);
for (j = 1; j < pStream->nColorTblLen; j++) {
if (pStream->colortbl[j] == crColor) {
sprintf(props + strlen(props), "\\brdrcf%u", j);
break;
}
}
}
}
for (i = 0; i < pFmt->cTabCount; i++)
{
sprintf(props + strlen(props), "\\cellx%d", pFmt->rgxTabs[i] & 0x00FFFFFF);
@ -727,7 +810,7 @@ ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nC
}
} else if (p->member.para.nFlags & MEPF_ROWEND) {
pStream->nNestingLevel--;
if (pStream->nNestingLevel > 1) {
if (pStream->nNestingLevel >= 1) {
if (!ME_StreamOutPrint(pStream, "{\\*\\nesttableprops"))
return FALSE;
if (!ME_StreamOutRTFTableProps(editor, pStream, p))