- RTF reader doesn't use RichEdit messages anymore (which saves on

unnecessary repaints)
- added unicode character support to RTF import (like: \u12345 ?)
- small fixes
- fixed whitespace identification bug
- removed drawing of paragraph marks
- improved stub implementations for IRichEditOle
This commit is contained in:
Krzysztof Foltman 2005-03-17 10:23:40 +00:00 committed by Alexandre Julliard
parent 48061e6899
commit f089de1f4d
11 changed files with 107 additions and 47 deletions

View File

@ -300,12 +300,6 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
assert(style); assert(style);
editor->bCaretAtEnd = FALSE; editor->bCaretAtEnd = FALSE;
/*
if (!style)
style = ME_GetInsertStyle(editor, nCursor);
else
ME_AddRefStyle(style);
*/
ME_AddRefStyle(style); ME_AddRefStyle(style);
/* FIXME really HERE ? */ /* FIXME really HERE ? */
@ -800,8 +794,6 @@ BOOL ME_CancelSelection(ME_TextEditor *editor, int dir)
editor->pCursors[1] = editor->pCursors[0]; editor->pCursors[1] = editor->pCursors[0];
else else
editor->pCursors[0] = editor->pCursors[1]; editor->pCursors[0] = editor->pCursors[1];
/* FIXME optimize */
ME_MarkAllForWrapping(editor);
ME_Repaint(editor); ME_Repaint(editor);
return TRUE; return TRUE;
} }
@ -809,14 +801,6 @@ BOOL ME_CancelSelection(ME_TextEditor *editor, int dir)
void ME_RepaintSelection(ME_TextEditor *editor, ME_Cursor *pTempCursor) void ME_RepaintSelection(ME_TextEditor *editor, ME_Cursor *pTempCursor)
{ {
ME_Cursor old_anchor = editor->pCursors[1]; ME_Cursor old_anchor = editor->pCursors[1];
BOOL bRedraw = FALSE;
bRedraw = memcmp(&editor->pCursors[0], &editor->pCursors[1], sizeof(ME_Cursor));
if (bRedraw)
{
/* FIXME optimize */
ME_MarkAllForWrapping(editor);
}
if (GetKeyState(VK_SHIFT)>=0) /* cancelling selection */ if (GetKeyState(VK_SHIFT)>=0) /* cancelling selection */
{ {
@ -915,6 +899,7 @@ BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, int nCtrl)
} }
if (ME_ArrowLeft(editor, p)) { if (ME_ArrowLeft(editor, p)) {
editor->bCaretAtEnd = FALSE; /* FIXME or maybe not */ editor->bCaretAtEnd = FALSE; /* FIXME or maybe not */
ME_ClearTempStyle(editor);
ME_MoveCaret(editor); ME_MoveCaret(editor);
ME_DeleteTextAtCursor(editor, nCursor, 1); ME_DeleteTextAtCursor(editor, nCursor, 1);
ME_UpdateRepaint(editor); ME_UpdateRepaint(editor);
@ -928,10 +913,12 @@ BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, int nCtrl)
if (ME_IsSelection(editor)) if (ME_IsSelection(editor))
{ {
ME_DeleteSelection(editor); ME_DeleteSelection(editor);
ME_ClearTempStyle(editor);
ME_UpdateRepaint(editor); ME_UpdateRepaint(editor);
return TRUE; return TRUE;
} }
ME_DeleteTextAtCursor(editor, nCursor, 1); ME_DeleteTextAtCursor(editor, nCursor, 1);
ME_ClearTempStyle(editor);
ME_UpdateRepaint(editor); ME_UpdateRepaint(editor);
return TRUE; return TRUE;
} }

View File

@ -277,7 +277,7 @@ static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM
void ME_RTFCharAttrHook(RTF_Info *info) void ME_RTFCharAttrHook(RTF_Info *info)
{ {
CHARFORMAT2A fmt; CHARFORMAT2W fmt;
fmt.cbSize = sizeof(fmt); fmt.cbSize = sizeof(fmt);
fmt.dwMask = 0; fmt.dwMask = 0;
@ -334,8 +334,8 @@ void ME_RTFCharAttrHook(RTF_Info *info)
RTFFont *f = RTFGetFont(info, info->rtfParam); RTFFont *f = RTFGetFont(info, info->rtfParam);
if (f) if (f)
{ {
strncpy(fmt.szFaceName, f->rtfFName, sizeof(fmt.szFaceName)-1); MultiByteToWideChar(CP_ACP, 0, f->rtfFName, -1, fmt.szFaceName, sizeof(fmt.szFaceName)/sizeof(WCHAR));
fmt.szFaceName[sizeof(fmt.szFaceName)-1] = '\0'; fmt.szFaceName[sizeof(fmt.szFaceName)/sizeof(WCHAR)-1] = '\0';
fmt.dwMask = CFM_FACE; fmt.dwMask = CFM_FACE;
} }
} }
@ -347,8 +347,12 @@ void ME_RTFCharAttrHook(RTF_Info *info)
break; break;
} }
if (fmt.dwMask) { if (fmt.dwMask) {
ME_Style *style2;
RTFFlushOutputBuffer(info); RTFFlushOutputBuffer(info);
SendMessageW(info->hwndEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt); /* FIXME too slow ? how come ? */
style2 = ME_ApplyStyle(info->style, &fmt);
ME_ReleaseStyle(info->style);
info->style = style2;
} }
} }
@ -380,7 +384,8 @@ void ME_RTFParAttrHook(RTF_Info *info)
} }
if (fmt.dwMask) { if (fmt.dwMask) {
RTFFlushOutputBuffer(info); RTFFlushOutputBuffer(info);
SendMessageW(info->hwndEdit, EM_SETPARAFORMAT, 0, (LPARAM)&fmt); /* FIXME too slow ? how come ?*/
ME_SetSelectionParaFormat(info->editor, &fmt);
} }
} }
@ -393,18 +398,22 @@ void ME_RTFReadHook(RTF_Info *info) {
case rtfBeginGroup: case rtfBeginGroup:
if (info->formatStackTop < maxCharFormatStack) { if (info->formatStackTop < maxCharFormatStack) {
info->formatStack[info->formatStackTop].cbSize = sizeof(info->formatStack[0]); info->formatStack[info->formatStackTop].cbSize = sizeof(info->formatStack[0]);
SendMessageW(info->hwndEdit, EM_GETCHARFORMAT, 1, (LPARAM)&info->formatStack[info->formatStackTop]); memcpy(&info->formatStack[info->formatStackTop], &info->style->fmt, sizeof(CHARFORMAT2W));
} }
info->formatStackTop++; info->formatStackTop++;
break; break;
case rtfEndGroup: case rtfEndGroup:
{
ME_Style *s;
RTFFlushOutputBuffer(info); RTFFlushOutputBuffer(info);
info->formatStackTop--; info->formatStackTop--;
if (info->formatStackTop < maxCharFormatStack) { /* FIXME too slow ? how come ? */
SendMessageW(info->hwndEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&info->formatStack[info->formatStackTop]); s = ME_ApplyStyle(info->style, &info->formatStack[info->formatStackTop]);
} ME_ReleaseStyle(info->style);
info->style = s;
break; break;
} }
}
break; break;
case rtfControl: case rtfControl:
switch(info->rtfMajor) switch(info->rtfMajor)
@ -426,8 +435,10 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
ME_Style *style; ME_Style *style;
int from, to, to2, nUndoMode; int from, to, to2, nUndoMode;
ME_UndoItem *pUI; ME_UndoItem *pUI;
int nEventMask = editor->nEventMask;
TRACE("%p %p\n", stream, editor->hWnd); TRACE("%p %p\n", stream, editor->hWnd);
editor->nEventMask = 0;
ME_GetSelection(editor, &from, &to); ME_GetSelection(editor, &from, &to);
if (format & SFF_SELECTION) { if (format & SFF_SELECTION) {
@ -442,6 +453,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor)); ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor));
from = to = 0; from = to = 0;
ME_ClearTempStyle(editor); ME_ClearTempStyle(editor);
/* FIXME restore default paragraph formatting ! */
} }
nUndoMode = editor->nUndoMode; nUndoMode = editor->nUndoMode;
@ -452,6 +464,8 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
RTFSetEditStream(&parser, stream); RTFSetEditStream(&parser, stream);
parser.rtfFormat = format&(SF_TEXT|SF_RTF); parser.rtfFormat = format&(SF_TEXT|SF_RTF);
parser.hwndEdit = editor->hWnd; parser.hwndEdit = editor->hWnd;
parser.editor = editor;
parser.style = style;
WriterInit(&parser); WriterInit(&parser);
RTFInit(&parser); RTFInit(&parser);
RTFSetReadHook(&parser, ME_RTFReadHook); RTFSetReadHook(&parser, ME_RTFReadHook);
@ -460,6 +474,8 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
/* do the parsing */ /* do the parsing */
RTFRead(&parser); RTFRead(&parser);
RTFFlushOutputBuffer(&parser); RTFFlushOutputBuffer(&parser);
style = parser.style;
} }
else if (format & SF_TEXT) else if (format & SF_TEXT)
ME_StreamInText(editor, format, stream, style); ME_StreamInText(editor, format, stream, style);
@ -484,6 +500,14 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
} }
ME_CommitUndo(editor); ME_CommitUndo(editor);
ME_ReleaseStyle(style); ME_ReleaseStyle(style);
editor->nEventMask = nEventMask;
ME_UpdateRepaint(editor);
if (!(format & SFF_SELECTION)) {
ME_ClearTempStyle(editor);
ME_EnsureVisible(editor, editor->pCursors[0].pRun);
}
ME_MoveCaret(editor);
ME_SendSelChange(editor);
return 0; return 0;
} }
@ -817,6 +841,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
case EM_SETCHARFORMAT: case EM_SETCHARFORMAT:
{ {
CHARFORMAT2W buf, *p; CHARFORMAT2W buf, *p;
BOOL bRepaint = TRUE;
p = ME_ToCF2W(&buf, (CHARFORMAT2W *)lParam); p = ME_ToCF2W(&buf, (CHARFORMAT2W *)lParam);
if (!wParam) if (!wParam)
ME_SetDefaultCharFormat(editor, p); ME_SetDefaultCharFormat(editor, p);
@ -824,9 +849,14 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
FIXME("word selection not supported\n"); FIXME("word selection not supported\n");
else if (wParam == SCF_ALL) else if (wParam == SCF_ALL)
ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), p); ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), p);
else else {
int from, to;
ME_GetSelection(editor, &from, &to);
bRepaint = (from != to);
ME_SetSelectionCharFormat(editor, p); ME_SetSelectionCharFormat(editor, p);
}
ME_CommitUndo(editor); ME_CommitUndo(editor);
if (bRepaint)
ME_UpdateRepaint(editor); ME_UpdateRepaint(editor);
return 0; return 0;
} }
@ -843,6 +873,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
} }
case EM_SETPARAFORMAT: case EM_SETPARAFORMAT:
ME_SetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam); ME_SetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam);
ME_UpdateRepaint(editor);
ME_CommitUndo(editor); ME_CommitUndo(editor);
return 0; return 0;
case EM_GETPARAFORMAT: case EM_GETPARAFORMAT:

View File

@ -85,6 +85,10 @@ void ME_EndToUnicode(HWND hWnd, LPVOID psz);
LPSTR ME_ToAnsi(HWND hWnd, LPVOID psz); LPSTR ME_ToAnsi(HWND hWnd, LPVOID psz);
void ME_EndToAnsi(HWND hWnd, LPVOID psz); void ME_EndToAnsi(HWND hWnd, LPVOID psz);
static inline int ME_IsWSpace(WCHAR ch)
{
return ch > '\0' && ch <= ' ';
}
/* note: those two really return the first matching offset (starting from EOS)+1 /* note: those two really return the first matching offset (starting from EOS)+1
* in other words, an offset of the first trailing white/black */ * in other words, an offset of the first trailing white/black */

View File

@ -146,8 +146,8 @@ void ME_Repaint(ME_TextEditor *editor)
ME_DisplayItem *pRun = NULL; ME_DisplayItem *pRun = NULL;
int nOffset = -1; int nOffset = -1;
HDC hDC; HDC hDC;
int nCharOfs = ME_CharOfsFromRunOfs(editor, pCursor->pRun, pCursor->nOffset); int nCharOfs = ME_CharOfsFromRunOfs(editor, pCursor->pRun, pCursor->nOffset);
ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset); ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset);
assert(pRun == pCursor->pRun); assert(pRun == pCursor->pRun);
assert(nOffset == pCursor->nOffset); assert(nOffset == pCursor->nOffset);
@ -244,6 +244,9 @@ void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph
ME_Run *run = &rundi->member.run; ME_Run *run = &rundi->member.run;
int runofs = run->nCharOfs+para->nCharOfs; int runofs = run->nCharOfs+para->nCharOfs;
/* you can always comment it out if you need visible paragraph marks */
if (run->nFlags & MERF_ENDPARA)
return;
if (run->nFlags & MERF_GRAPHICS) { if (run->nFlags & MERF_GRAPHICS) {
int blfrom, blto; int blfrom, blto;
ME_GetSelection(c->editor, &blfrom, &blto); ME_GetSelection(c->editor, &blfrom, &blto);

View File

@ -310,7 +310,6 @@ void ME_SetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
break; break;
para = para->member.para.next_para; para = para->member.para.next_para;
} while(1); } while(1);
ME_Repaint(editor);
} }
void ME_GetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, PARAFORMAT2 *pFmt) void ME_GetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, PARAFORMAT2 *pFmt)

View File

@ -42,12 +42,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include "rtf.h"
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "editor.h"
#include "rtf.h"
WINE_DEFAULT_DEBUG_CHANNEL(richedit); WINE_DEFAULT_DEBUG_CHANNEL(richedit);
extern HANDLE me_heap; extern HANDLE me_heap;
@ -68,6 +69,7 @@ static int Hash (char*);
static void CharSetInit (RTF_Info *); static void CharSetInit (RTF_Info *);
static void ReadCharSetMaps (RTF_Info *); static void ReadCharSetMaps (RTF_Info *);
static void RTFOutputUnicodeString( RTF_Info *info, WCHAR *str, int len );
/* /*
@ -2452,6 +2454,7 @@ static RTFKey rtfKey[] =
{ rtfSpecialChar, rtfNoWidthNonJoiner, "zwnj", 0 }, { rtfSpecialChar, rtfNoWidthNonJoiner, "zwnj", 0 },
/* is this valid? */ /* is this valid? */
{ rtfSpecialChar, rtfCurHeadPict, "chpict", 0 }, { rtfSpecialChar, rtfCurHeadPict, "chpict", 0 },
{ rtfSpecialChar, rtfUnicode, "u", 0 },
/* /*
* Character formatting attributes * Character formatting attributes
@ -3698,7 +3701,6 @@ Destination (RTF_Info *info)
RTFSkipGroup (info); RTFSkipGroup (info);
} }
/* /*
* The reason these use the rtfSC_xxx thingies instead of just writing * The reason these use the rtfSC_xxx thingies instead of just writing
* out ' ', '-', '"', etc., is so that the mapping for these characters * out ' ', '-', '"', etc., is so that the mapping for these characters
@ -3721,6 +3723,22 @@ void SpecialChar (RTF_Info *info)
else else
RTFRouteToken(info); /* "\*" is ignored with known destinations */ RTFRouteToken(info); /* "\*" is ignored with known destinations */
break; break;
case rtfUnicode:
{
WCHAR buf[2];
buf[0] = info->rtfParam;
buf[1] = 0;
RTFFlushOutputBuffer(info);
RTFOutputUnicodeString(info, buf, 1);
RTFGetToken(info);
if (info->rtfClass != rtfText && info->rtfMajor != '?')
{
ERR("The character behind \\u is not a question mark, but (%d,%d,%d)\n",
info->rtfClass, info->rtfMajor, info->rtfMinor);
}
break;
}
case rtfPage: case rtfPage:
case rtfSect: case rtfSect:
case rtfRow: case rtfRow:
@ -3801,10 +3819,32 @@ void PutLitChar (RTF_Info *info, int c)
info->OutputBuffer[info->dwOutputCount++] = c; info->OutputBuffer[info->dwOutputCount++] = c;
} }
void RTFOutputANSIStringOrig( RTF_Info *info, char *str, int len )
{
assert(str[len] == '\0');
if (len) {
SendMessageA( info->hwndEdit, EM_REPLACESEL, FALSE, (LPARAM) str);
}
}
void RTFOutputANSIString( RTF_Info *info, char *str, int len ) void RTFOutputANSIString( RTF_Info *info, char *str, int len )
{ {
assert(str[len] == '\0'); assert(str[len] == '\0');
if (len) SendMessageA( info->hwndEdit, EM_REPLACESEL, FALSE, (LPARAM) str); if (len) {
WCHAR *buf = ALLOC_N_OBJ(WCHAR, len);
len = MultiByteToWideChar(CP_ACP, 0, str, len, buf, len);
ME_InsertTextFromCursor( info->editor, 0, buf, len, info->style );
FREE_OBJ(buf);
}
}
void RTFOutputUnicodeString( RTF_Info *info, WCHAR *str, int len )
{
assert(str[len] == '\0');
if (len) {
ME_InsertTextFromCursor( info->editor, 0, str, len, info->style );
}
} }
void RTFFlushOutputBuffer( RTF_Info *info ) void RTFFlushOutputBuffer( RTF_Info *info )

View File

@ -64,6 +64,7 @@ IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj)
*ppvObj = (LPVOID) This; *ppvObj = (LPVOID) This;
return S_OK; return S_OK;
} }
FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid) );
return E_NOINTERFACE; return E_NOINTERFACE;
} }
@ -215,7 +216,7 @@ static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me,
LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj) LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
{ {
IRichEditOleImpl *This = (IRichEditOleImpl *)me; IRichEditOleImpl *This = (IRichEditOleImpl *)me;
FIXME("stub %p\n",This); FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
return E_NOTIMPL; return E_NOTIMPL;
} }

View File

@ -625,6 +625,7 @@
# define rtfNoWidthNonJoiner 56 /* new in 1.10 */ # define rtfNoWidthNonJoiner 56 /* new in 1.10 */
# define rtfCurHeadPict 57 /* valid? */ # define rtfCurHeadPict 57 /* valid? */
/*# define rtfCurAnnot 58*/ /* apparently not used */ /*# define rtfCurAnnot 58*/ /* apparently not used */
# define rtfUnicode 58 /* no better category*/
# define rtfStyleAttr 7 # define rtfStyleAttr 7
# define rtfAdditive 0 /* new in 1.10 */ # define rtfAdditive 0 /* new in 1.10 */
@ -1453,6 +1454,9 @@ struct _RTF_Info {
/* edit window to output to */ /* edit window to output to */
HWND hwndEdit; HWND hwndEdit;
ME_TextEditor *editor;
ME_Style *style;
/* /*
* These arrays are used to map RTF input character values onto the standard * These arrays are used to map RTF input character values onto the standard
* character names represented by the values. Input character values are * character names represented by the values. Input character values are

View File

@ -321,11 +321,6 @@ ME_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem
return pDI; return pDI;
} }
static inline int ME_IsWSpace(WCHAR ch)
{
return ch <= ' ';
}
void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run) void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run)
{ {
assert(run->nCharOfs != -1); assert(run->nCharOfs != -1);

View File

@ -112,7 +112,7 @@ int ME_IsWhitespaces(ME_String *s)
{ {
/* FIXME multibyte */ /* FIXME multibyte */
WCHAR *pos = s->szData; WCHAR *pos = s->szData;
while(*pos++ == ' ') while(ME_IsWSpace(*pos++))
; ;
pos--; pos--;
if (*pos) if (*pos)
@ -126,12 +126,12 @@ int ME_IsSplitable(ME_String *s)
/* FIXME multibyte */ /* FIXME multibyte */
WCHAR *pos = s->szData; WCHAR *pos = s->szData;
WCHAR ch; WCHAR ch;
while(*pos++ == L' ') while(ME_IsWSpace(*pos++))
; ;
pos--; pos--;
while((ch = *pos++) != 0) while((ch = *pos++) != 0)
{ {
if (ch == L' ') if (ME_IsWSpace(*pos++))
return 1; return 1;
} }
return 0; return 0;

View File

@ -274,10 +274,6 @@ ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
wc->bOverflown = FALSE; wc->bOverflown = FALSE;
pp = ME_SplitRun(wc->context, p, black); pp = ME_SplitRun(wc->context, p, black);
p->member.run.nFlags |= MERF_SKIPPED; p->member.run.nFlags |= MERF_SKIPPED;
/*
run->pt = wc->pt;
wc->pt.x += run->nWidth;
*/
ME_InsertRowStart(wc, pp); ME_InsertRowStart(wc, pp);
return pp; return pp;
} }