Module: wine
Branch: master
Commit: 9116d73c63256e7318e0a74bb80f7ecdf0c7f2f5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9116d73c63256e7318e0a74bb…
Author: Rob Shearman <robertshearman(a)gmail.com>
Date: Sun Aug 10 11:14:07 2008 +0100
rpcrt4: Factorise conformant array NDR functions and use them to fix the wire-representation of complex structures with conformant arrays.
Factorise each conformant array function into the part that deals with
reading, writing or sizing the conformance and another part that deals
with reading, writing or sizing the variance and the element data.
This allows complex structures to use the right wire format where the
conformance appears before the structure data starts.
---
dlls/rpcrt4/ndr_marshall.c | 425 +++++++++++++++++++++++++++++++++++--------
1 files changed, 346 insertions(+), 79 deletions(-)
Diff: http://source.winehq.org/git/wine.git/?a=commitdiff;h=9116d73c63256e7318e0a…
Module: wine
Branch: master
Commit: bf5ccefc4cf6ecdb2c15bf0eb70dfadee241ad65
URL: http://source.winehq.org/git/wine.git/?a=commit;h=bf5ccefc4cf6ecdb2c15bf0eb…
Author: Dylan Smith <dylan.ah.smith(a)gmail.com>
Date: Tue Aug 5 12:10:47 2008 -0400
richedit: Handle tab key properly within table cells.
Within table cells the tab key moves to the next cell in the table, or creates
a new table row when at the end of the table.
---
dlls/riched20/Makefile.in | 1 +
dlls/riched20/caret.c | 1 -
dlls/riched20/editor.c | 24 ++++++-
dlls/riched20/editor.h | 4 +
dlls/riched20/table.c | 173 +++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 200 insertions(+), 3 deletions(-)
diff --git a/dlls/riched20/Makefile.in b/dlls/riched20/Makefile.in
index 4e443a1..8bcf8ed 100644
--- a/dlls/riched20/Makefile.in
+++ b/dlls/riched20/Makefile.in
@@ -20,6 +20,7 @@ C_SRCS = \
run.c \
string.c \
style.c \
+ table.c \
txtsrv.c \
undo.c \
wrap.c \
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c
index 93fa77b..99ad947 100644
--- a/dlls/riched20/caret.c
+++ b/dlls/riched20/caret.c
@@ -781,7 +781,6 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
editor->pCursors[3] = editor->pCursors[1];
}
-
int ME_GetCursorOfs(ME_TextEditor *editor, int nCursor)
{
ME_Cursor *pCursor = &editor->pCursors[nCursor];
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index e3f91f1..732797a 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -3286,10 +3286,30 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
if (((unsigned)wstr)>=' '
|| (wstr=='\r' && (GetWindowLongW(hWnd, GWL_STYLE) & ES_MULTILINE))
|| wstr=='\t') {
- /* FIXME maybe it would make sense to call EM_REPLACESEL instead ? */
- /* WM_CHAR is restricted to nTextLimit */
int from, to;
ME_GetSelection(editor, &from, &to);
+ if (wstr=='\t') {
+ ME_Cursor cursor = editor->pCursors[0];
+ ME_DisplayItem *para;
+ BOOL bSelectedRow = FALSE;
+
+ para = ME_GetParagraph(cursor.pRun);
+ if (ME_IsSelection(editor) &&
+ cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
+ para->member.para.prev_para->type == diParagraph)
+ {
+ para = para->member.para.prev_para;
+ bSelectedRow = TRUE;
+ }
+ if (ME_IsInTable(para))
+ {
+ ME_TabPressedInTable(editor, bSelectedRow);
+ ME_CommitUndo(editor);
+ return 0;
+ }
+ }
+ /* FIXME maybe it would make sense to call EM_REPLACESEL instead ? */
+ /* WM_CHAR is restricted to nTextLimit */
if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from))
{
ME_Style *style = ME_GetInsertStyle(editor, 0);
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index a32811c..869a2ce 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -285,6 +285,10 @@ extern BOOL ME_IsCandidateAnURL(ME_TextEditor *editor, int sel_min, int sel_max)
BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, int sel_min, int sel_max);
void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor);
+/* table.c */
+BOOL ME_IsInTable(ME_DisplayItem *pItem);
+void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow);
+
/* undo.c */
ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_DisplayItem *pdi);
void ME_CommitUndo(ME_TextEditor *editor);
diff --git a/dlls/riched20/table.c b/dlls/riched20/table.c
new file mode 100644
index 0000000..ace36d0
--- /dev/null
+++ b/dlls/riched20/table.c
@@ -0,0 +1,173 @@
+/*
+ * RichEdit functions dealing with on tables
+ *
+ * Copyright 2008 by Dylan Smith
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * The implementation of tables differs greatly between version 3.0
+ * (in riched20.dll) and version 4.1 (in msftedit.dll) of richedit controls.
+ * Currently Wine is not implementing table support as done in version 4.1.
+ *
+ * Richedit version 1.0 - 3.0:
+ * Tables are implemented in these versions using tabs at the end of cells,
+ * and tab stops to position the cells. The paragraph format flag PFE_TABLE
+ * will indicate the the paragraph is a table row. Note that in this
+ * implementation there is one paragraph per table row.
+ */
+
+#include "editor.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(richedit);
+
+BOOL ME_IsInTable(ME_DisplayItem *pItem)
+{
+ PARAFORMAT2 *pFmt;
+ if (!pItem)
+ return FALSE;
+ if (pItem->type == diRun)
+ pItem = ME_GetParagraph(pItem);
+ if (pItem->type != diParagraph)
+ return FALSE;
+ pFmt = pItem->member.para.pFmt;
+ return pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE;
+}
+
+static ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor,
+ ME_DisplayItem *table_row)
+{
+ WCHAR endl = '\r', tab = '\t';
+ ME_DisplayItem *run;
+ PARAFORMAT2 *pFmt;
+ int i;
+
+ assert(table_row);
+ run = ME_FindItemBack(table_row->member.para.next_para, diRun);
+ pFmt = table_row->member.para.pFmt;
+ assert(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE);
+ editor->pCursors[0].pRun = run;
+ editor->pCursors[0].nOffset = 0;
+ editor->pCursors[1] = editor->pCursors[0];
+ ME_InsertTextFromCursor(editor, 0, &endl, 1, run->member.run.style);
+ run = editor->pCursors[0].pRun;
+ for (i = 0; i < pFmt->cTabCount; i++) {
+ ME_InsertTextFromCursor(editor, 0, &tab, 1, run->member.run.style);
+ }
+ return table_row->member.para.next_para;
+}
+
+/* Selects the next table cell or appends a new table row if at end of table */
+static void ME_SelectOrInsertNextCell(ME_TextEditor *editor,
+ ME_DisplayItem *run)
+{
+ ME_DisplayItem *para = ME_GetParagraph(run);
+ int i;
+
+ assert(run && run->type == diRun);
+ assert(ME_IsInTable(run));
+ if (run->member.run.nFlags & MERF_ENDPARA &&
+ ME_IsInTable(ME_FindItemFwd(run, diParagraphOrEnd)))
+ {
+ run = ME_FindItemFwd(run, diRun);
+ assert(run);
+ }
+ for (i = 0; i < 2; i++)
+ {
+ while (!(run->member.run.nFlags & MERF_TAB))
+ {
+ run = ME_FindItemFwd(run, diRunOrParagraphOrEnd);
+ if (run->type != diRun)
+ {
+ para = run;
+ if (ME_IsInTable(para))
+ {
+ run = ME_FindItemFwd(para, diRun);
+ assert(run);
+ editor->pCursors[0].pRun = run;
+ editor->pCursors[0].nOffset = 0;
+ i = 1;
+ } else {
+ /* Insert table row */
+ para = ME_AppendTableRow(editor, para->member.para.prev_para);
+ /* Put cursor at the start of the new table row */
+ editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+ editor->pCursors[0].nOffset = 0;
+ editor->pCursors[1] = editor->pCursors[0];
+ ME_WrapMarkedParagraphs(editor);
+ return;
+ }
+ }
+ }
+ if (i == 0)
+ run = ME_FindItemFwd(run, diRun);
+ editor->pCursors[i].pRun = run;
+ editor->pCursors[i].nOffset = 0;
+ }
+}
+
+
+void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow)
+{
+ /* FIXME: Shift tab should move to the previous cell. */
+ ME_Cursor fromCursor, toCursor;
+ ME_InvalidateSelection(editor);
+ {
+ int from, to;
+ from = ME_GetCursorOfs(editor, 0);
+ to = ME_GetCursorOfs(editor, 1);
+ if (from <= to)
+ {
+ fromCursor = editor->pCursors[0];
+ toCursor = editor->pCursors[1];
+ } else {
+ fromCursor = editor->pCursors[1];
+ toCursor = editor->pCursors[0];
+ }
+ }
+ if (!ME_IsInTable(fromCursor.pRun))
+ {
+ editor->pCursors[0] = fromCursor;
+ editor->pCursors[1] = fromCursor;
+ /* FIXME: For some reason the caret is shown at the start of the
+ * previous paragraph in v1.0 to v3.0, and bCaretAtEnd only works
+ * within the paragraph for wrapped lines. */
+ if (ME_FindItemBack(fromCursor.pRun, diRun))
+ editor->bCaretAtEnd = TRUE;
+ } else {
+ if (bSelectedRow || !ME_IsInTable(toCursor.pRun))
+ {
+ ME_SelectOrInsertNextCell(editor, fromCursor.pRun);
+ } else {
+ if (ME_IsSelection(editor) && !toCursor.nOffset)
+ {
+ ME_DisplayItem *run;
+ run = ME_FindItemBack(toCursor.pRun, diRunOrParagraphOrEnd);
+ if (run->type == diRun && run->member.run.nFlags & MERF_TAB)
+ ME_SelectOrInsertNextCell(editor, run);
+ else
+ ME_SelectOrInsertNextCell(editor, toCursor.pRun);
+ } else {
+ ME_SelectOrInsertNextCell(editor, toCursor.pRun);
+ }
+ }
+ }
+ ME_InvalidateSelection(editor);
+ ME_Repaint(editor);
+ HideCaret(editor->hWnd);
+ ME_ShowCaret(editor);
+ ME_SendSelChange(editor);
+}