mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 02:46:32 +00:00
- 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:
parent
48061e6899
commit
f089de1f4d
11 changed files with 107 additions and 47 deletions
|
@ -300,12 +300,6 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
|
|||
assert(style);
|
||||
editor->bCaretAtEnd = FALSE;
|
||||
|
||||
/*
|
||||
if (!style)
|
||||
style = ME_GetInsertStyle(editor, nCursor);
|
||||
else
|
||||
ME_AddRefStyle(style);
|
||||
*/
|
||||
ME_AddRefStyle(style);
|
||||
|
||||
/* FIXME really HERE ? */
|
||||
|
@ -800,8 +794,6 @@ BOOL ME_CancelSelection(ME_TextEditor *editor, int dir)
|
|||
editor->pCursors[1] = editor->pCursors[0];
|
||||
else
|
||||
editor->pCursors[0] = editor->pCursors[1];
|
||||
/* FIXME optimize */
|
||||
ME_MarkAllForWrapping(editor);
|
||||
ME_Repaint(editor);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -809,14 +801,6 @@ BOOL ME_CancelSelection(ME_TextEditor *editor, int dir)
|
|||
void ME_RepaintSelection(ME_TextEditor *editor, ME_Cursor *pTempCursor)
|
||||
{
|
||||
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 */
|
||||
{
|
||||
|
@ -915,6 +899,7 @@ BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, int nCtrl)
|
|||
}
|
||||
if (ME_ArrowLeft(editor, p)) {
|
||||
editor->bCaretAtEnd = FALSE; /* FIXME or maybe not */
|
||||
ME_ClearTempStyle(editor);
|
||||
ME_MoveCaret(editor);
|
||||
ME_DeleteTextAtCursor(editor, nCursor, 1);
|
||||
ME_UpdateRepaint(editor);
|
||||
|
@ -928,10 +913,12 @@ BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, int nCtrl)
|
|||
if (ME_IsSelection(editor))
|
||||
{
|
||||
ME_DeleteSelection(editor);
|
||||
ME_ClearTempStyle(editor);
|
||||
ME_UpdateRepaint(editor);
|
||||
return TRUE;
|
||||
}
|
||||
ME_DeleteTextAtCursor(editor, nCursor, 1);
|
||||
ME_ClearTempStyle(editor);
|
||||
ME_UpdateRepaint(editor);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -277,7 +277,7 @@ static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM
|
|||
|
||||
void ME_RTFCharAttrHook(RTF_Info *info)
|
||||
{
|
||||
CHARFORMAT2A fmt;
|
||||
CHARFORMAT2W fmt;
|
||||
fmt.cbSize = sizeof(fmt);
|
||||
fmt.dwMask = 0;
|
||||
|
||||
|
@ -334,8 +334,8 @@ void ME_RTFCharAttrHook(RTF_Info *info)
|
|||
RTFFont *f = RTFGetFont(info, info->rtfParam);
|
||||
if (f)
|
||||
{
|
||||
strncpy(fmt.szFaceName, f->rtfFName, sizeof(fmt.szFaceName)-1);
|
||||
fmt.szFaceName[sizeof(fmt.szFaceName)-1] = '\0';
|
||||
MultiByteToWideChar(CP_ACP, 0, f->rtfFName, -1, fmt.szFaceName, sizeof(fmt.szFaceName)/sizeof(WCHAR));
|
||||
fmt.szFaceName[sizeof(fmt.szFaceName)/sizeof(WCHAR)-1] = '\0';
|
||||
fmt.dwMask = CFM_FACE;
|
||||
}
|
||||
}
|
||||
|
@ -347,8 +347,12 @@ void ME_RTFCharAttrHook(RTF_Info *info)
|
|||
break;
|
||||
}
|
||||
if (fmt.dwMask) {
|
||||
ME_Style *style2;
|
||||
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) {
|
||||
RTFFlushOutputBuffer(info);
|
||||
SendMessageW(info->hwndEdit, EM_SETPARAFORMAT, 0, (LPARAM)&fmt);
|
||||
/* FIXME too slow ? how come ?*/
|
||||
ME_SetSelectionParaFormat(info->editor, &fmt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,17 +398,21 @@ void ME_RTFReadHook(RTF_Info *info) {
|
|||
case rtfBeginGroup:
|
||||
if (info->formatStackTop < maxCharFormatStack) {
|
||||
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++;
|
||||
break;
|
||||
case rtfEndGroup:
|
||||
{
|
||||
ME_Style *s;
|
||||
RTFFlushOutputBuffer(info);
|
||||
info->formatStackTop--;
|
||||
if (info->formatStackTop < maxCharFormatStack) {
|
||||
SendMessageW(info->hwndEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&info->formatStack[info->formatStackTop]);
|
||||
}
|
||||
/* FIXME too slow ? how come ? */
|
||||
s = ME_ApplyStyle(info->style, &info->formatStack[info->formatStackTop]);
|
||||
ME_ReleaseStyle(info->style);
|
||||
info->style = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case rtfControl:
|
||||
|
@ -426,8 +435,10 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
|||
ME_Style *style;
|
||||
int from, to, to2, nUndoMode;
|
||||
ME_UndoItem *pUI;
|
||||
int nEventMask = editor->nEventMask;
|
||||
|
||||
TRACE("%p %p\n", stream, editor->hWnd);
|
||||
editor->nEventMask = 0;
|
||||
|
||||
ME_GetSelection(editor, &from, &to);
|
||||
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));
|
||||
from = to = 0;
|
||||
ME_ClearTempStyle(editor);
|
||||
/* FIXME restore default paragraph formatting ! */
|
||||
}
|
||||
|
||||
nUndoMode = editor->nUndoMode;
|
||||
|
@ -452,6 +464,8 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
|||
RTFSetEditStream(&parser, stream);
|
||||
parser.rtfFormat = format&(SF_TEXT|SF_RTF);
|
||||
parser.hwndEdit = editor->hWnd;
|
||||
parser.editor = editor;
|
||||
parser.style = style;
|
||||
WriterInit(&parser);
|
||||
RTFInit(&parser);
|
||||
RTFSetReadHook(&parser, ME_RTFReadHook);
|
||||
|
@ -460,6 +474,8 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
|||
/* do the parsing */
|
||||
RTFRead(&parser);
|
||||
RTFFlushOutputBuffer(&parser);
|
||||
|
||||
style = parser.style;
|
||||
}
|
||||
else if (format & SF_TEXT)
|
||||
ME_StreamInText(editor, format, stream, style);
|
||||
|
@ -483,7 +499,15 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
|||
pUI->nLen = to-from;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -817,6 +841,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
case EM_SETCHARFORMAT:
|
||||
{
|
||||
CHARFORMAT2W buf, *p;
|
||||
BOOL bRepaint = TRUE;
|
||||
p = ME_ToCF2W(&buf, (CHARFORMAT2W *)lParam);
|
||||
if (!wParam)
|
||||
ME_SetDefaultCharFormat(editor, p);
|
||||
|
@ -824,10 +849,15 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
FIXME("word selection not supported\n");
|
||||
else if (wParam == SCF_ALL)
|
||||
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_CommitUndo(editor);
|
||||
ME_UpdateRepaint(editor);
|
||||
if (bRepaint)
|
||||
ME_UpdateRepaint(editor);
|
||||
return 0;
|
||||
}
|
||||
case EM_GETCHARFORMAT:
|
||||
|
@ -843,6 +873,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
}
|
||||
case EM_SETPARAFORMAT:
|
||||
ME_SetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam);
|
||||
ME_UpdateRepaint(editor);
|
||||
ME_CommitUndo(editor);
|
||||
return 0;
|
||||
case EM_GETPARAFORMAT:
|
||||
|
|
|
@ -85,6 +85,10 @@ void ME_EndToUnicode(HWND hWnd, LPVOID psz);
|
|||
LPSTR ME_ToAnsi(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
|
||||
* in other words, an offset of the first trailing white/black */
|
||||
|
|
|
@ -146,8 +146,8 @@ void ME_Repaint(ME_TextEditor *editor)
|
|||
ME_DisplayItem *pRun = NULL;
|
||||
int nOffset = -1;
|
||||
HDC hDC;
|
||||
|
||||
int nCharOfs = ME_CharOfsFromRunOfs(editor, pCursor->pRun, pCursor->nOffset);
|
||||
|
||||
ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset);
|
||||
assert(pRun == pCursor->pRun);
|
||||
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;
|
||||
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) {
|
||||
int blfrom, blto;
|
||||
ME_GetSelection(c->editor, &blfrom, &blto);
|
||||
|
|
|
@ -310,7 +310,6 @@ void ME_SetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
|
|||
break;
|
||||
para = para->member.para.next_para;
|
||||
} while(1);
|
||||
ME_Repaint(editor);
|
||||
}
|
||||
|
||||
void ME_GetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, PARAFORMAT2 *pFmt)
|
||||
|
|
|
@ -42,12 +42,13 @@
|
|||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "rtf.h"
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "editor.h"
|
||||
#include "rtf.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
|
||||
|
||||
extern HANDLE me_heap;
|
||||
|
@ -68,6 +69,7 @@ static int Hash (char*);
|
|||
|
||||
static void CharSetInit (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 },
|
||||
/* is this valid? */
|
||||
{ rtfSpecialChar, rtfCurHeadPict, "chpict", 0 },
|
||||
{ rtfSpecialChar, rtfUnicode, "u", 0 },
|
||||
|
||||
/*
|
||||
* Character formatting attributes
|
||||
|
@ -3698,7 +3701,6 @@ Destination (RTF_Info *info)
|
|||
RTFSkipGroup (info);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The reason these use the rtfSC_xxx thingies instead of just writing
|
||||
* out ' ', '-', '"', etc., is so that the mapping for these characters
|
||||
|
@ -3721,6 +3723,22 @@ void SpecialChar (RTF_Info *info)
|
|||
else
|
||||
RTFRouteToken(info); /* "\*" is ignored with known destinations */
|
||||
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 rtfSect:
|
||||
case rtfRow:
|
||||
|
@ -3801,10 +3819,32 @@ void PutLitChar (RTF_Info *info, int 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 )
|
||||
{
|
||||
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 )
|
||||
|
|
|
@ -64,6 +64,7 @@ IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj)
|
|||
*ppvObj = (LPVOID) This;
|
||||
return S_OK;
|
||||
}
|
||||
FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid) );
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
@ -215,7 +216,7 @@ static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me,
|
|||
LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
|
||||
{
|
||||
IRichEditOleImpl *This = (IRichEditOleImpl *)me;
|
||||
FIXME("stub %p\n",This);
|
||||
FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
|
|
@ -625,6 +625,7 @@
|
|||
# define rtfNoWidthNonJoiner 56 /* new in 1.10 */
|
||||
# define rtfCurHeadPict 57 /* valid? */
|
||||
/*# define rtfCurAnnot 58*/ /* apparently not used */
|
||||
# define rtfUnicode 58 /* no better category*/
|
||||
|
||||
# define rtfStyleAttr 7
|
||||
# define rtfAdditive 0 /* new in 1.10 */
|
||||
|
@ -1452,6 +1453,9 @@ struct _RTF_Info {
|
|||
|
||||
/* edit window to output to */
|
||||
HWND hwndEdit;
|
||||
|
||||
ME_TextEditor *editor;
|
||||
ME_Style *style;
|
||||
|
||||
/*
|
||||
* These arrays are used to map RTF input character values onto the standard
|
||||
|
|
|
@ -321,11 +321,6 @@ ME_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem
|
|||
return pDI;
|
||||
}
|
||||
|
||||
static inline int ME_IsWSpace(WCHAR ch)
|
||||
{
|
||||
return ch <= ' ';
|
||||
}
|
||||
|
||||
void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run)
|
||||
{
|
||||
assert(run->nCharOfs != -1);
|
||||
|
|
|
@ -112,7 +112,7 @@ int ME_IsWhitespaces(ME_String *s)
|
|||
{
|
||||
/* FIXME multibyte */
|
||||
WCHAR *pos = s->szData;
|
||||
while(*pos++ == ' ')
|
||||
while(ME_IsWSpace(*pos++))
|
||||
;
|
||||
pos--;
|
||||
if (*pos)
|
||||
|
@ -126,12 +126,12 @@ int ME_IsSplitable(ME_String *s)
|
|||
/* FIXME multibyte */
|
||||
WCHAR *pos = s->szData;
|
||||
WCHAR ch;
|
||||
while(*pos++ == L' ')
|
||||
while(ME_IsWSpace(*pos++))
|
||||
;
|
||||
pos--;
|
||||
while((ch = *pos++) != 0)
|
||||
{
|
||||
if (ch == L' ')
|
||||
if (ME_IsWSpace(*pos++))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -274,10 +274,6 @@ ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
|
|||
wc->bOverflown = FALSE;
|
||||
pp = ME_SplitRun(wc->context, p, black);
|
||||
p->member.run.nFlags |= MERF_SKIPPED;
|
||||
/*
|
||||
run->pt = wc->pt;
|
||||
wc->pt.x += run->nWidth;
|
||||
*/
|
||||
ME_InsertRowStart(wc, pp);
|
||||
return pp;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue