Application for GSoC 2014 - riched20: implement ITextDocument::Range and ITextRange

Jactry Zeng jactry92 at gmail.com
Mon Mar 17 10:24:30 CDT 2014


Hello folks,


I am Jactry Zeng, a junior who majoring in Electronic Science from China.
And also a very
fresh developer of Wine. My nickname in #winehackers is jactry. :)

I would like to apply for this year's GSoC to work for Wine. I have entered
Wine's GSoC last
year. What I have work for is ITextDocument, I implemented some functions
of it. I got some
experience of Wine development and fixed some other bugs[0] of richedit
during that time.

I continued the work of ITextDocument after GSoC, I know there is still a
lot of work worth
to do. Such as ITextDocument::Range[1], which is used to get an ITextRange
object of the
content. And functions of ITextRange[2] are used to operate this range of
text. Now in Wine,
ITextRange was implemented mix with ITextSelection[3][4]. And
ITextDocument::GetSelection[5]
which is used to get an ITextSelection object is similar to ITextRange. In
an easy way, we can
implement ITextDocument::Range using some cast (I have a dirty hack in
attachment). But I
don't think it is a permanent solution.


There are four parts in my plan:

--- Part 0: Do some COM cleanup. ---

Because ITextRange is implemented mix with ITextSelection now, so we should
do some COM
cleanup to create an ITextRange interface independently. And create a
ITextSelection interface
inherits from ITextRange.
This is just the preparatory work for implementing ITextRange and I will
begin this part before
GSoC. ( So it is signed as part zore :b )


--- Part 1: Implement ITextDocument::Range. ---

I will write more tests for ITextDocument::Range and
ITextDocument::GetSelection first. Than try
to implement ITextDocumen::Range.
When this part is finished, bug 12458[6] and bug 18303[7] will benefit from
it.


--- Part 2: Implement functions of ITextRange ---

In this part, I will try my best to implement some functions of ITextRange.
I will write some
tests for them first and than implement them. I think this is the hard part.
And these functions will be implemented preferentially: GetText,
GetDuplicate, GetStar, GetEnd,
Copy, SetText. Because GetDuplicate and GetEnd were needed by bug 18303,
and these
functions seem was depend on the others.
After these functions were implemented, I think bug 18303 will be fixed!
( Oh, this one of my pursues! ;) )


--- Part 3: Imporve all the code for being merged by upstream. ---

This is the last part, I will improve all the patches for being merged by
upstream, including what
I did last year. After this part is finished, Wine will really has an
initial implementation of
ITextDocument and ITextRange. Maybe it will spend a lot of time, and I will
continue this work
after GSoC if I can't finish all of this part during GSoC.


I think after all these are finished not only bug 18303 and bug 12458 will
benefit from it, but
also many other softwares. Because TOM interfaces are so important and be
used frequently in
real world applications.


I appreciate for any comment.
Thank you. :)


attachments:
dirty hack of ITextDocument::Range: dirty_hack.txt
patch 0001: tests for ITextDocument_Range



[0]
http://source.winehq.org/git/wine.git/?a=search&h=HEAD&st=author&s=jactry<http://source.winehq.org/git/wine.git/?a=search&h=HEAD&st=author&s=jactry>
[1]
http://msdn.microsoft.com/en-us/library/windows/desktop/bb774097(v=vs.85).aspx
[2]
http://msdn.microsoft.com/en-us/library/windows/desktop/bb774058(v=vs.85).aspx
[3]
http://msdn.microsoft.com/en-us/library/windows/desktop/bb774060(v=vs.85).aspx
[4]
http://source.winehq.org/git/wine.git/blob/HEAD:/dlls/riched20/richole.c#l779
[5]
http://msdn.microsoft.com/en-us/library/windows/desktop/bb774013(v=vs.85).aspx
[6] http://bugs.winehq.org/show_bug.cgi?id=12458
[7] http://bugs.winehq.org/show_bug.cgi?id=18303

-- 
Regards,
Jactry Zeng
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20140317/d7ab5520/attachment.html>
-------------- next part --------------
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c
index 6805873..982276c 100644
--- a/dlls/riched20/richole.c
+++ b/dlls/riched20/richole.c
@@ -648,8 +648,14 @@ ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2,
     ITextRange** ppRange)
 {
     IRichEditOleImpl *This = impl_from_ITextDocument(me);
-    FIXME("stub %p\n",This);
-    return E_NOTIMPL;
+    FIXME("dirty hack %p\n",This);
+
+    if(!ppRange)
+      return E_INVALIDARG;
+
+    *ppRange = (ITextRange *)&This->txtSel->ITextSelection_iface;
+    ITextSelection_AddRef(*(ITextSelection**)ppRange);
+    return S_OK;
 }
 
 static HRESULT WINAPI
-------------- next part --------------
From fbd912822d267df5427bbba845486557ac80cfe0 Mon Sep 17 00:00:00 2001
From: Jactry Zeng <jactry92 at gmail.com>
Date: Mon, 17 Mar 2014 22:46:25 +0800
Subject: riched20/tests: Add tests for ITextDocument::Range.

---
 dlls/riched20/tests/richole.c | 74 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 72 insertions(+), 2 deletions(-)

diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c
index 5bfb999..1945770 100644
--- a/dlls/riched20/tests/richole.c
+++ b/dlls/riched20/tests/richole.c
@@ -80,7 +80,8 @@ static void create_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txt
   SendMessageA(*w, EM_GETOLEINTERFACE, 0, (LPARAM)reOle);
   IRichEditOle_QueryInterface(*reOle, &IID_ITextDocument,
                                  (void **) txtDoc);
-  ITextDocument_GetSelection(*txtDoc, txtSel);
+  if(txtSel)
+    ITextDocument_GetSelection(*txtDoc, txtSel);
 }
 
 static void release_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc,
@@ -89,7 +90,13 @@ static void release_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **tx
   ITextDocument_Release(*txtDoc);
   IRichEditOle_Release(*reOle);
   DestroyWindow(*w);
-  ITextSelection_Release(*txtSel);
+  if(txtSel)
+    ITextSelection_Release(*txtSel);
+}
+
+static void release_txtrge(ITextRange **txtRge)
+{
+  if(*txtRge) ITextRange_Release(*txtRge);
 }
 
 static void test_Interfaces(void)
@@ -97,6 +104,7 @@ static void test_Interfaces(void)
   IRichEditOle *reOle = NULL;
   ITextDocument *txtDoc = NULL;
   ITextSelection *txtSel = NULL;
+  ITextRange *txtRge = NULL;
   IUnknown *punk;
   HRESULT hres;
   LRESULT res;
@@ -118,6 +126,7 @@ static void test_Interfaces(void)
   ok(txtDoc != NULL, "IRichEditOle_QueryInterface\n");
 
   ITextDocument_GetSelection(txtDoc, &txtSel);
+  ITextDocument_Range(txtDoc, 0, 0, &txtRge);
 
   punk = NULL;
   hres = ITextSelection_QueryInterface(txtSel, &IID_ITextSelection, (void **) &punk);
@@ -129,12 +138,23 @@ static void test_Interfaces(void)
   hres = ITextSelection_QueryInterface(txtSel, &IID_ITextRange, (void **) &punk);
   ok(hres == S_OK, "ITextSelection_QueryInterface\n");
   ok(punk != NULL, "ITextSelection_QueryInterface\n");
+  
+  if(txtRge) {
+    hres = ITextRange_QueryInterface(txtRge, &IID_ITextRange, (void **) &punk);
+    ok(hres == S_OK, "ITextRange_QueryInterface\n");
+    ok(punk != NULL, "ITextRange_QueryInterface\n");
+  } else skip("Couldn't create ITextRange interface.\n");
   IUnknown_Release(punk);
 
   punk = NULL;
   hres = ITextSelection_QueryInterface(txtSel, &IID_IDispatch, (void **) &punk);
   ok(hres == S_OK, "ITextSelection_QueryInterface\n");
   ok(punk != NULL, "ITextSelection_QueryInterface\n");
+  if(txtRge) {
+    hres = ITextRange_QueryInterface(txtRge, &IID_IDispatch, (void **) &punk);
+    ok(hres == S_OK, "ITextRange_QueryInterface\n");
+    ok(punk != NULL, "ITextRange_QueryInterface\n");
+  } else skip("Couldn't create ITextRange interface.\n");
   IUnknown_Release(punk);
 
   ITextDocument_Release(txtDoc);
@@ -147,6 +167,7 @@ static void test_Interfaces(void)
   ok(hres == CO_E_RELEASED, "ITextSelection after ITextDocument destroyed\n");
 
   ITextSelection_Release(txtSel);
+  release_txtrge(&txtRge);
 }
 
 static void test_ITextDocument_Open(void)
@@ -382,6 +403,54 @@ static void test_ITextDocument_Open(void)
   VariantClear(&testfile);
 }
 
+void static test_ITextDocument_Range(void)
+{
+  IRichEditOle *reOle = NULL;
+  ITextDocument *txtDoc = NULL;
+  ITextRange *txtRge = NULL;
+  HRESULT hres;
+  HWND w;
+  WCHAR textW[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
+                   'e', 'T', 'e', 'x', 't', 0};
+  LONG cpFirst = 0, cpLim = 0;
+  BSTR bstr;
+
+
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
+  todo_wine ok(hres == S_OK, "ITextDocument_Range fails: 0x%x.\n", hres);
+  release_txtrge(&txtRge);
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  hres = ITextDocument_Range(txtDoc, 0, 0, NULL);
+  todo_wine ok(hres == E_INVALIDARG, "ITextDocument_Range should return E_INVALIDARG\n");
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+
+  /* The next two tests testify the sequence of pFirst and pLim won't the result. */
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  SendMessageW(w, WM_SETTEXT, 0, (LPARAM)textW);
+  cpFirst = 8;
+  cpLim = 12;
+  ITextDocument_Range(txtDoc, cpFirst, cpLim, &txtRge);
+  if(txtRge) {
+    hres = ITextRange_GetText(txtRge, &bstr);
+    todo_wine ok(hres == S_OK, "ITextRange_GetText fails: 0x%x.\n", hres);
+    todo_wine ok(!lstrcmpW(bstr, &textW[cpFirst]), "ITextDocument_Range get wrong text: %s\n", wine_dbgstr_w(bstr));
+    ITextRange_Release(txtRge);
+  } else skip("Couldn't create ITextRange interface.\n");
+
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  SendMessageW(w, WM_SETTEXT, 0, (LPARAM)textW);
+  ITextDocument_Range(txtDoc, cpLim, cpFirst, &txtRge);
+  if(txtRge) {
+    hres = ITextRange_GetText(txtRge, &bstr);
+    todo_wine ok(hres == S_OK, "ITextRange_GetText fails: 0x%x.\n", hres);
+    todo_wine ok(!lstrcmpW(bstr, &textW[cpFirst]), "ITextDocument_Range get wrong text: %s\n", wine_dbgstr_w(bstr));
+    ITextRange_Release(txtRge);
+  } else skip("Couldn't create ITextRange interface.\n");
+}
+
 START_TEST(richole)
 {
   /* Must explicitly LoadLibrary(). The test has no references to functions in
@@ -391,4 +460,5 @@ START_TEST(richole)
 
   test_Interfaces();
   test_ITextDocument_Open();
+  test_ITextDocument_Range();
 }
-- 
1.8.3.2



More information about the wine-devel mailing list