[Libreoffice-commits] core.git: Branch 'feature/tiled-editing' - 656 commits - accessibility/inc accessibility/source android/Bootstrap android/CustomTarget_lo_android.mk android/experimental basctl/inc basctl/source basegfx/inc basic/inc basic/source bin/get-bugzilla-attachments-by-mimetype bridges/inc bridges/source canvas/source chart2/inc chart2/source cli_ure/source codemaker/source comphelper/inc comphelper/source compilerplugins/clang config_host/config_global.h.in config_host.mk.in configmgr/inc configmgr/source configure.ac connectivity/inc connectivity/Module_connectivity.mk connectivity/qa connectivity/source cppcanvas/inc cppcanvas/source cppuhelper/inc cppuhelper/source cppu/source cui/inc cui/source cui/uiconfig dbaccess/inc dbaccess/Module_dbaccess.mk dbaccess/PythonTest_dbaccess_python.mk dbaccess/qa dbaccess/source dbaccess/util desktop/inc desktop/Library_sofficeapp.mk desktop/source desktop/test distro-configs/LibreOfficeCoverity.conf drawinglayer/inc drawinglayer/source dtrans /source editeng/inc editeng/source embeddedobj/source extensions/inc extensions/source external/boost external/coinmp external/cppunit external/graphite external/harfbuzz external/icu external/jpeg-turbo external/lcms2 external/libodfgen external/lpsolve external/python3 external/redland filter/source forms/source forms/util formula/source fpicker/source framework/inc framework/source helpcompiler/source helpcontent2 hwpfilter/inc hwpfilter/source i18npool/inc i18npool/source i18npool/util icon-themes/breeze icon-themes/crystal icon-themes/galaxy icon-themes/hicontrast icon-themes/human icon-themes/industrial icon-themes/oxygen icon-themes/sifr icon-themes/tango icon-themes/tango_testing idlc/inc idl/inc include/avmedia include/basebmp include/basegfx include/basic include/canvas include/codemaker include/com include/comphelper include/connectivity include/cppcanvas include/cppu include/cppuhelper include/drawinglayer include/editeng include/filter include/formula include/framework include/jvmaccess include/LibreOfficeKit include/linguistic include/oox include/opencl include/osl include/registry include/rtl include/sal include/salhelper include/sfx2 include/sot include/svl include/svtools include/svx include/toolkit include/tools include/typelib include/ucbhelper include/uno include/unotools include/vcl include/xmloff instsetoo_native/util ios/CustomTarget_TiledLibreOffice_app.mk ios/experimental ios/shared jvmfwk/source libreofficekit/qa libreofficekit/source lingucomponent/source linguistic/inc linguistic/source lotuswordpro/source odk/config offapi/com offapi/UnoApi_offapi.mk officecfg/registry oox/inc oox/source opencl/source package/inc package/source pyuno/inc qadevOOo/tests readlicense_oo/license registry/source registry/tools reportdesign/inc reportdesign/source RepositoryExternal.mk Repository.mk RepositoryModule_host.mk rsc/source sal/cppunittester sal/CppunitTest_sal_rtl_oustringbuffer.mk sal/inc sal/osl sal/qa sal/rtl sal/textenc sax/qa sax/source sc/CppunitTest_sc_bugfix_test.mk sc/inc sc/Module_sc.mk scp2/InstallModule_impress.mk scp2/source sc/qa scripting/source sc/source sc/uiconfig sdext/inc sdext/source sd/inc sd/qa sd/source sd/uiconfig sfx2/inc sfx2/source sfx2/uiconfig shell/inc shell/source slideshow/source solenv/bin solenv/gdb sot/inc sot/source starmath/inc starmath/source stoc/source stoc/test store/source svgio/inc svgio/source svl/inc svl/qa svl/source svl/unx svtools/inc svtools/qa svtools/source svx/Executable_gengal.mk svx/inc svx/source sw/inc sw/Library_swui.mk sw/Module_sw.mk sw/qa sw/source sw/uiconfig testtools/source toolkit/qa toolkit/source tools/inc tools/source translations ucb/source udkapi/com unotest/source unotools/inc unotools/qa unotools/source unoxml/inc unoxml/source unusedcode.easy uui/inc uui/source vbahelper/inc vbahelper/source vcl/Executable_icontest.mk vcl/generic vcl/headless vcl/inc vcl/Module_vcl.mk vcl/null vcl/opengl vcl/osx vcl/quartz vcl/source vcl/unx vcl/win vcl/workben win accessibility/source wizards/source writerfilter/inc writerfilter/source writerperfect/Library_wpftimpress.mk writerperfect/source xmlhelp/source xmloff/inc xmloff/source xmlscript/dtd xmlscript/inc xmlscript/source xmlsecurity/inc xmlsecurity/source

Miklos Vajna vmiklos at collabora.co.uk
Mon Feb 9 00:48:50 PST 2015


Rebased ref, commits from common ancestor:
commit e8fe1582372983c6e3ca5b9cbead097ed670f504
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon Feb 9 08:02:46 2015 +0100

    lokdocview: fix Linux baseline build
    
    Baseline is only used for releases, while lokdocview is a tool to
    helpdevelopment for now, so don't bother with full compatiblity, just add
    enough to not break the build.
    
    Change-Id: I52e312d3c3ae80636448bf42d5f277184fb9ca7b

diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index 03d6448..a7cf3ec 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -184,6 +184,7 @@ static gboolean lcl_handleTimeout(gpointer pData)
 
 static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpointer pData)
 {
+#if GTK_CHECK_VERSION(2,14,0) // we need gtk_widget_get_window()
     LOKDocView* pDocView = pData;
     cairo_t* pCairo;
 
@@ -220,6 +221,7 @@ static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpoint
     }
 
     cairo_destroy(pCairo);
+#endif
     return FALSE;
 }
 
@@ -390,6 +392,7 @@ static GList* lcl_payloadToRectangles(const char* pPayload)
 /// Invoked on the main thread if lok_docview_callback_worker() requests so.
 static gboolean lok_docview_callback(gpointer pData)
 {
+#if GLIB_CHECK_VERSION(2,28,0) // we need g_list_free_full()
     LOKDocViewCallbackData* pCallback = pData;
 
     switch (pCallback->m_nType)
@@ -427,6 +430,7 @@ static gboolean lok_docview_callback(gpointer pData)
 
     g_free(pCallback->m_pPayload);
     g_free(pCallback);
+#endif
     return G_SOURCE_REMOVE;
 }
 
commit c0a185ed1d535b49e20b6ed7ca52bacdb7a457aa
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Feb 6 12:12:44 2015 +0100

    lokdocview: implement selection overlay using LOK_CALLBACK_TEXT_SELECTION
    
    Change-Id: I59cb870973ea4e2fda816b15ae7d9a53a4624e8d

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index 934d55a..def92f9 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -50,6 +50,8 @@ struct _LOKDocView
     guint32 m_nLastButtonPressTime;
     /// Time of the last button release.
     guint32 m_nLastButtonReleaseTime;
+    /// Rectangles of the current text selection.
+    GList* m_pTextSelectionRectangles;
 };
 
 struct _LOKDocViewClass
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index c5f8dab..03d6448 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -130,6 +130,7 @@ static void lok_docview_init( LOKDocView* pDocView )
     pDocView->m_bCursorVisible = FALSE;
     pDocView->m_nLastButtonPressTime = 0;
     pDocView->m_nLastButtonReleaseTime = 0;
+    pDocView->m_pTextSelectionRectangles = NULL;
 
     gtk_signal_connect( GTK_OBJECT(pDocView), "destroy",
                         GTK_SIGNAL_FUNC(lcl_onDestroy), NULL );
@@ -204,6 +205,20 @@ static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpoint
         cairo_fill(pCairo);
     }
 
+    if (pDocView->m_pTextSelectionRectangles)
+    {
+        GList* i;
+
+        for (i = pDocView->m_pTextSelectionRectangles; i != NULL; i = i->next)
+        {
+            GdkRectangle* pRectangle = i->data;
+            // Blue with 75% transparency.
+            cairo_set_source_rgba(pCairo, ((double)0x43)/255, ((double)0xac)/255, ((double)0xe8)/255, 0.25);
+            cairo_rectangle(pCairo, twipToPixel(pRectangle->x), twipToPixel(pRectangle->y), twipToPixel(pRectangle->width), twipToPixel(pRectangle->height));
+            cairo_fill(pCairo);
+        }
+    }
+
     cairo_destroy(pCairo);
     return FALSE;
 }
@@ -354,6 +369,24 @@ static GdkRectangle lcl_payloadToRectangle(const char* pPayload)
     return aRet;
 }
 
+/// Returns the GdkRectangle list of a w,h,x,y;w2,h2,x2,y2;... string.
+static GList* lcl_payloadToRectangles(const char* pPayload)
+{
+    GList* pRet = NULL;
+    gchar** ppRectangles;
+    gchar** ppRectangle;
+
+    ppRectangles = g_strsplit(pPayload, "; ", 0);
+    for (ppRectangle = ppRectangles; *ppRectangle; ++ppRectangle)
+    {
+        GdkRectangle aRect = lcl_payloadToRectangle(*ppRectangle);
+        GdkRectangle* pRect = g_new0(GdkRectangle, 1);
+        *pRect = aRect;
+        pRet = g_list_prepend(pRet, pRect);
+    }
+    g_strfreev(ppRectangles);
+    return pRet;
+}
 /// Invoked on the main thread if lok_docview_callback_worker() requests so.
 static gboolean lok_docview_callback(gpointer pData)
 {
@@ -379,6 +412,15 @@ static gboolean lok_docview_callback(gpointer pData)
         gtk_widget_queue_draw(GTK_WIDGET(pCallback->m_pDocView->pEventBox));
     }
     break;
+    case LOK_CALLBACK_TEXT_SELECTION:
+    {
+        GList* pRectangles = lcl_payloadToRectangles(pCallback->m_pPayload);
+        if (pCallback->m_pDocView->m_pTextSelectionRectangles)
+            g_list_free_full(pCallback->m_pDocView->m_pTextSelectionRectangles, g_free);
+        pCallback->m_pDocView->m_pTextSelectionRectangles = pRectangles;
+        gtk_widget_queue_draw(GTK_WIDGET(pCallback->m_pDocView->pEventBox));
+    }
+    break;
     default:
         break;
     }
commit 1b15f4863e6d4b0a280ccd61713cbb1209ffe33e
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Feb 6 12:12:02 2015 +0100

    LOK: add LOK_CALLBACK_TEXT_SELECTION and implement it in sw
    
    Change-Id: I31662cb06add0d1a1c517b5f5416703aeaae1e77

diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 0ee2883..1ef70e5 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -57,7 +57,7 @@ typedef enum
      * Any tiles which are over the rectangle described in the payload are no
      * longer valid.
      *
-     * Rectangle format: "width,height,x,y", where all numbers are document
+     * Rectangle format: "width, height, x, y", where all numbers are document
      * coordinates, in twips.
      */
     LOK_CALLBACK_INVALIDATE_TILES,
@@ -66,7 +66,16 @@ typedef enum
      *
      * Rectangle format is the same as LOK_CALLBACK_INVALIDATE_TILES.
      */
-    LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR
+    LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
+    /**
+     * The list of rectangles representing the current text selection changed.
+     *
+     * List format is "rectangle1[; rectangle2[; ...]]" (without quotes and
+     * brackets), where rectangleN has the same format as
+     * LOK_CALLBACK_INVALIDATE_TILES. When there is no selection, an empty
+     * string is provided.
+     */
+    LOK_CALLBACK_TEXT_SELECTION
 }
 LibreOfficeKitCallbackType;
 
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index bb8f6d6..6d7a961 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -314,6 +314,20 @@ void SwSelPaintRects::Show()
             }
         }
 
+        if (GetShell()->isTiledRendering())
+        {
+            std::stringstream ss;
+            for (size_type i = 0; i < size(); ++i)
+            {
+                const SwRect& rRect = (*this)[i];
+                if (i)
+                    ss << "; ";
+                ss << rRect.Width() << ", " << rRect.Height() << ", " << rRect.Left() << ", " << rRect.Top();
+            }
+            OString sRect = ss.str().c_str();
+            GetShell()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr());
+        }
+
         HighlightInputFld();
 #else
 
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index d2f9418..1bb9176 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -2007,8 +2007,12 @@ void SwRootFrm::CalcFrmRects(SwShellCrsr &rCrsr)
 
     SwViewShell *pSh = GetCurrShell();
 
+    bool bIgnoreVisArea = false;
+    if (pSh)
+        bIgnoreVisArea = pSh->GetViewOptions()->IsPDFExport() || pSh->isTiledRendering();
+
     // #i12836# enhanced pdf
-    SwRegionRects aRegion( pSh && !pSh->GetViewOptions()->IsPDFExport() ?
+    SwRegionRects aRegion( !bIgnoreVisArea ?
                            pSh->VisArea() :
                            Frm() );
     if( !pStartPos->nNode.GetNode().IsCntntNode() ||
commit 17be6dab4a349944448e06a2b71df312899b3351
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Thu Feb 5 18:07:05 2015 +0100

    native-code.py: Add libfrmlo.a + some constructors around controls.
    
    Fixes loading of ooo108922-1.doc, hope this does not blow the .apk size too
    much...
    
    Change-Id: Ifbaa6fa5a7467e516fd1020e941c7a125d1a6437

diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index 45f80a8..c6d52b3 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -119,8 +119,12 @@ core_constructor_list = [
 # stoc/source/inspect/introspection.component
     "com_sun_star_comp_stoc_Introspection_get_implementation",
 # toolkit/util/tk.component
+    "stardiv_Toolkit_UnoComboBoxControl_get_implementation",
+    "stardiv_Toolkit_UnoControlComboBoxModel_get_implementation",
     "stardiv_Toolkit_UnoControlContainer_get_implementation",
     "stardiv_Toolkit_UnoControlContainerModel_get_implementation",
+    "stardiv_Toolkit_UnoDateFieldControl_get_implementation",
+    "stardiv_Toolkit_UnoControlDateFieldModel_get_implementation",
     "stardiv_Toolkit_VCLXPointer_get_implementation",
     "stardiv_Toolkit_VCLXToolkit_get_implementation",
 # uui/util/uui.component
@@ -166,6 +170,7 @@ draw_constructor_list = [
     ]
 
 writer_factory_list = [
+    ("libfrmlo.a", "frm_component_getFactory"),
     ("libsblo.a", "sb_component_getFactory"),
     ("libswdlo.a", "swd_component_getFactory"),
     ("libswlo.a", "sw_component_getFactory"),
commit 9fc47fb27136af527872b03523b4f5f765c876a8
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Thu Feb 5 16:35:56 2015 +0100

    native-code.py: Add libxolo.a.
    
    Fixes loading of ooo10504-1.doc.
    
    Change-Id: Ib82ac9938c755ec5fa9ccd93e44d92b744dc0ff4

diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index e64e27a..45f80a8 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -52,6 +52,7 @@ core_factory_list = [
     ("libunoxmllo.a", "unoxml_component_getFactory"),
     ("libutllo.a", "utl_component_getFactory"),
     ("libxmlsecurity.a", "xmlsecurity_component_getFactory"),
+    ("libxoflo.a", "xof_component_getFactory"),
     ("libxolo.a", "xo_component_getFactory"),
     ("libxsec_xmlsec.a", "xsec_xmlsec_component_getFactory", "#ifndef ANDROID"),
     ("libxstor.a", "xstor_component_getFactory"),
commit 5d483a6751afd6f524a5c154c1be2a8a60ba0328
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Feb 5 18:09:30 2015 +0100

    lokdocview: fix memory leak in lcl_payloadToRectangle()
    
    Change-Id: I2894c693d11b025d23ebbf0ae75f67532efe315f

diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index 3e791a7..c5f8dab 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -330,24 +330,27 @@ static GdkRectangle lcl_payloadToRectangle(const char* pPayload)
 {
     GdkRectangle aRet;
     gchar** ppCoordinates;
+    gchar** ppCoordinate;
 
     aRet.width = aRet.height = aRet.x = aRet.y = 0;
     ppCoordinates = g_strsplit(pPayload, ", ", 4);
-    if (!*ppCoordinates)
+    ppCoordinate = ppCoordinates;
+    if (!*ppCoordinate)
         return aRet;
-    aRet.width = atoi(*ppCoordinates);
-    ++ppCoordinates;
-    if (!*ppCoordinates)
+    aRet.width = atoi(*ppCoordinate);
+    ++ppCoordinate;
+    if (!*ppCoordinate)
         return aRet;
-    aRet.height = atoi(*ppCoordinates);
-    ++ppCoordinates;
-    if (!*ppCoordinates)
+    aRet.height = atoi(*ppCoordinate);
+    ++ppCoordinate;
+    if (!*ppCoordinate)
         return aRet;
-    aRet.x = atoi(*ppCoordinates);
-    ++ppCoordinates;
-    if (!*ppCoordinates)
+    aRet.x = atoi(*ppCoordinate);
+    ++ppCoordinate;
+    if (!*ppCoordinate)
         return aRet;
-    aRet.y = atoi(*ppCoordinates);
+    aRet.y = atoi(*ppCoordinate);
+    g_strfreev(ppCoordinates);
     return aRet;
 }
 
commit 4b707104207e96d4e6666be7ad6e00ac4c6a10bc
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Feb 5 14:19:35 2015 +0100

    lok::Document::postMouseEvent(): allow double-click
    
    Change-Id: Idaddd28d906e7508d4d2c5aab916b06fbe021beb

diff --git a/android/Bootstrap/src/org/libreoffice/kit/Document.java b/android/Bootstrap/src/org/libreoffice/kit/Document.java
index 6966d29..cb798b5 100644
--- a/android/Bootstrap/src/org/libreoffice/kit/Document.java
+++ b/android/Bootstrap/src/org/libreoffice/kit/Document.java
@@ -103,8 +103,9 @@ public class Document {
      * @param type - mouse event type
      * @param x - x coordinate
      * @param y - y coordinate
+     * @param count - number of events
      */
-    public native void postMouseEvent(int type, int x, int y);
+    public native void postMouseEvent(int type, int x, int y, int count);
 
     /**
      * Callback to retrieve messages from LOK
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 20fce27..78af14b 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -316,7 +316,7 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
         int x = (int) pixelToTwip(inDocument.x, mDPI);
         int y = (int) pixelToTwip(inDocument.y, mDPI);
 
-        mDocument.postMouseEvent(type, x, y);
+        mDocument.postMouseEvent(type, x, y, 1);
     }
 
     @Override
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 940f413..6443019 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -205,7 +205,8 @@ static void doc_registerCallback(LibreOfficeKitDocument* pThis,
 static void doc_postMouseEvent (LibreOfficeKitDocument* pThis,
                                 int nType,
                                 int nX,
-                                int nY);
+                                int nY,
+                                int nCount);
 
 struct LibLODocument_Impl : public _LibreOfficeKitDocument
 {
@@ -659,7 +660,7 @@ static void doc_registerCallback(LibreOfficeKitDocument* pThis,
     pDoc->registerCallback(pCallback, pData);
 }
 
-static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX, int nY)
+static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX, int nY, int nCount)
 {
     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     if (!pDoc)
@@ -668,7 +669,7 @@ static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX,
         return;
     }
 
-    pDoc->postMouseEvent(nType, nX, nY);
+    pDoc->postMouseEvent(nType, nX, nY, nCount);
 }
 
 
diff --git a/desktop/source/lib/lokandroid.cxx b/desktop/source/lib/lokandroid.cxx
index 9ea5107..d253cfe 100644
--- a/desktop/source/lib/lokandroid.cxx
+++ b/desktop/source/lib/lokandroid.cxx
@@ -278,10 +278,10 @@ extern "C" SAL_JNI_EXPORT jint JNICALL Java_org_libreoffice_kit_Office_saveAs
 }
 
 extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Document_postMouseEvent
-    (JNIEnv* pEnv, jobject aObject, jint type, jint x, jint y)
+    (JNIEnv* pEnv, jobject aObject, jint type, jint x, jint y, jint count)
 {
     LibreOfficeKitDocument* pDocument = getHandle<LibreOfficeKitDocument>(pEnv, aObject);
-    pDocument->pClass->postMouseEvent(pDocument, type, x, y);
+    pDocument->pClass->postMouseEvent(pDocument, type, x, y, count);
 }
 
 /* DirectBufferAllocator */
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index e4852e4..0ee2883 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -175,7 +175,8 @@ struct _LibreOfficeKitDocumentClass
   void (*postMouseEvent)(LibreOfficeKitDocument* pThis,
                          int nType,
                          int nX,
-                         int nY);
+                         int nY,
+                         int nCount);
 #endif // LOK_USE_UNSTABLE_API
 };
 
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 9891d49..8448fcd 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -111,10 +111,11 @@ public:
      * @param nType Event type, like down, move or up.
      * @param nX horizontal position in document coordinates
      * @param nY vertical position in document coordinates
+     * @param nCount number of clicks: 1 for single click, 2 for double click
      */
-    inline void postMouseEvent(int nType, int nX, int nY)
+    inline void postMouseEvent(int nType, int nX, int nY, int nCount)
     {
-        mpDoc->pClass->postMouseEvent(mpDoc, nType, nX, nY);
+        mpDoc->pClass->postMouseEvent(mpDoc, nType, nX, nY, nCount);
     }
 #endif // LOK_USE_UNSTABLE_API
 };
diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index 7313215..934d55a 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -46,6 +46,10 @@ struct _LOKDocView
     GdkRectangle m_aVisibleCursor;
     /// Cursor is visible or hidden (for blinking).
     gboolean m_bCursorVisible;
+    /// Time of the last button press.
+    guint32 m_nLastButtonPressTime;
+    /// Time of the last button release.
+    guint32 m_nLastButtonReleaseTime;
 };
 
 struct _LOKDocViewClass
diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index b231e98..9edd7a1 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -106,7 +106,7 @@ public:
      *
      * @see lok::Document::postMouseEvent().
      */
-    virtual void postMouseEvent(int /*nType*/, int /*nX*/, int /*nY*/) { }
+    virtual void postMouseEvent(int /*nType*/, int /*nX*/, int /*nY*/, int /*nCount*/) { }
 };
 
 } // namespace vcl
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index d0c5cfb..3e791a7 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -50,11 +50,23 @@ void lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView*
     switch (pEvent->type)
     {
     case GDK_BUTTON_PRESS:
-        pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(pEvent->x), pixelToTwip(pEvent->y));
+    {
+        int nCount = 1;
+        if ((pEvent->time - pDocView->m_nLastButtonPressTime) < 250)
+            nCount++;
+        pDocView->m_nLastButtonPressTime = pEvent->time;
+        pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(pEvent->x), pixelToTwip(pEvent->y), nCount);
         break;
+    }
     case GDK_BUTTON_RELEASE:
-        pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(pEvent->x), pixelToTwip(pEvent->y));
+    {
+        int nCount = 1;
+        if ((pEvent->time - pDocView->m_nLastButtonReleaseTime) < 250)
+            nCount++;
+        pDocView->m_nLastButtonReleaseTime = pEvent->time;
+        pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(pEvent->x), pixelToTwip(pEvent->y), nCount);
         break;
+    }
     default:
         break;
     }
@@ -116,6 +128,8 @@ static void lok_docview_init( LOKDocView* pDocView )
     pDocView->m_bEdit = FALSE;
     memset(&pDocView->m_aVisibleCursor, 0, sizeof(pDocView->m_aVisibleCursor));
     pDocView->m_bCursorVisible = FALSE;
+    pDocView->m_nLastButtonPressTime = 0;
+    pDocView->m_nLastButtonReleaseTime = 0;
 
     gtk_signal_connect( GTK_OBJECT(pDocView), "destroy",
                         GTK_SIGNAL_FUNC(lcl_onDestroy), NULL );
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index 2d5161e..894a127 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -414,7 +414,7 @@ public:
      */
     virtual void registerCallback(LibreOfficeKitCallback pCallback, void* pData) SAL_OVERRIDE;
     /// @see vcl::ITiledRenderable::postMouseEvent().
-    virtual void postMouseEvent(int nType, int nX, int nY) SAL_OVERRIDE;
+    virtual void postMouseEvent(int nType, int nX, int nY, int nCount) SAL_OVERRIDE;
 
     void                        Invalidate();
     void                        Reactivate(SwDocShell* pNewDocShell);
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index e0de39b..70abbac 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3173,12 +3173,12 @@ void SwXTextDocument::registerCallback(LibreOfficeKitCallback pCallback, void* p
     pViewShell->registerLibreOfficeKitCallback(pCallback, pData);
 }
 
-void SwXTextDocument::postMouseEvent(int nType, int nX, int nY)
+void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount)
 {
     SolarMutexGuard aGuard;
 
     SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
-    MouseEvent aEvent(Point(nX, nY), 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT);
+    MouseEvent aEvent(Point(nX, nY), nCount, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT);
 
     switch (nType)
     {
commit 768dea15b4c5c50367e40af45fc2265478ec154b
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Feb 5 19:05:05 2015 +0900

    android: copy document to temp file when using content scheme
    
    We get the data from Intent, which has data identified by an uri.
    An uri can use many schemes but we support file (loading directly
    from a file) or content (used by GMail App). When loading from
    content, the document is available through a stream and has to be
    stored into a temporary file locally first, and then that file is
    should be used as input for loading the document.
    
    Change-Id: Ia4ffa8ff02b9737b91a41c03c2eb335d28fe1d61

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 56e3889..17fa867 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -2,6 +2,7 @@ package org.libreoffice;
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
@@ -26,6 +27,13 @@ import org.mozilla.gecko.ZoomConstraints;
 import org.mozilla.gecko.gfx.GeckoLayerClient;
 import org.mozilla.gecko.gfx.LayerView;
 
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -49,6 +57,7 @@ public class LibreOfficeMainActivity extends LOAbout {
     private String mInputFile;
     private TextSelection mTextSelection;
     private TextCursorLayer mTextCursorLayer;
+    private File mTempFile = null;
 
     public LibreOfficeMainActivity() {
         super(/*newActivity=*/false);
@@ -98,7 +107,15 @@ public class LibreOfficeMainActivity extends LOAbout {
         mMainHandler = new Handler();
 
         if (getIntent().getData() != null) {
-            mInputFile = getIntent().getData().getPath();
+            if (getIntent().getData().getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
+                if (copyFileToTemp() && mTempFile != null) {
+                    mInputFile = mTempFile.getPath();
+                } else {
+                    // TODO: can't open the file
+                }
+            } else if (getIntent().getData().getScheme().equals(ContentResolver.SCHEME_FILE)) {
+                mInputFile = getIntent().getData().getPath();
+            }
         } else {
             mInputFile = DEFAULT_DOC_PATH;
         }
@@ -137,6 +154,35 @@ public class LibreOfficeMainActivity extends LOAbout {
         mLayerClient.notifyReady();
     }
 
+    private boolean copyFileToTemp() {
+        ContentResolver contentResolver = getContentResolver();
+        InputStream inputStream = null;
+        try {
+            inputStream = contentResolver.openInputStream(getIntent().getData());
+            mTempFile = File.createTempFile("LibreOffice", null, this.getCacheDir());
+
+            OutputStream outputStream = new FileOutputStream(mTempFile);
+            byte[] buffer = new byte[4096];
+            int len = 0;
+            while ((len = inputStream.read(buffer)) != -1) {
+                outputStream.write(buffer, 0, len);
+            }
+            inputStream.close();
+            outputStream.close();
+            return true;
+        } catch (FileNotFoundException e) {
+        } catch (IOException e) {
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        return false;
+    }
+
     @Override
     protected void onResume() {
         super.onResume();
@@ -168,6 +214,12 @@ public class LibreOfficeMainActivity extends LOAbout {
         Log.i(LOGTAG, "onDestroy..");
         mLayerClient.destroy();
         super.onDestroy();
+
+        if (isFinishing()) { // Not an orientation change
+            if (mTempFile != null) {
+                mTempFile.delete();
+            }
+        }
     }
 
     public LOKitThread getLOKitThread() {
commit 24b28151c8b89043b0d75bf61d839a629ca3bf70
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Feb 5 19:03:06 2015 +0900

    android: allow only "file" and "content" URI scheme
    
    Content scheme is used by GMail App for example.
    
    Change-Id: I3583d38c42b9ad96209f0cd178ea6957a7aec86c

diff --git a/android/experimental/LOAndroid3/AndroidManifest.xml.in b/android/experimental/LOAndroid3/AndroidManifest.xml.in
index 3a17f62..244c6db 100644
--- a/android/experimental/LOAndroid3/AndroidManifest.xml.in
+++ b/android/experimental/LOAndroid3/AndroidManifest.xml.in
@@ -16,7 +16,9 @@
         android:icon="@drawable/main"
         android:label="@string/app_name"
         android:hardwareAccelerated="true"
-        android:theme="@style/AppTheme">
+        android:theme="@style/AppTheme"
+        android:largeHeap="false">
+
         <!-- Viewer Activity -->
         <activity
             android:name=".LibreOfficeMainActivity"
@@ -28,6 +30,9 @@
                 <action android:name="android.intent.action.PICK" />
                 <category android:name="android.intent.category.DEFAULT" />
 
+                <data android:scheme="file"/>
+                <data android:scheme="content"/>
+
                 <!-- Please keep this in sync with FileUtilities.java. -->
 
                 <!-- ODF -->
@@ -83,6 +88,7 @@
 
             </intent-filter>
         </activity>
+
         <!-- Document Browser Activity -->
         <activity android:name=".ui.LibreOfficeUIActivity"
                   android:label="@string/app_name">
@@ -91,6 +97,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+
     </application>
 
 </manifest>
commit 0059a213c1e52911d92702af269a296f5ece913a
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Wed Feb 4 23:31:01 2015 +0100

    android: When loading fails, make sure we don't crash the next time.
    
    Until now, when the loading failed, the next attempt to open a document
    lead to a crash; fixed.
    
    Change-Id: Ibb55b4799169e1521f076cf38380e429a50258a3

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index 7e99da3..3536256 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -29,6 +29,9 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
     }
 
     private void tileRequest(ComposedTileLayer composedTileLayer, TileIdentifier tileId, boolean forceRedraw) {
+        if (mTileProvider == null)
+            return;
+
         if (composedTileLayer.isStillValid(tileId)) {
             CairoImage image = mTileProvider.createTile(tileId.x, tileId.y, tileId.size, tileId.zoom);
             if (image != null) {
@@ -44,6 +47,9 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
     }
 
     private void tileRerender(ComposedTileLayer composedTileLayer, SubTile tile) {
+        if (mTileProvider == null)
+            return;
+
         if (composedTileLayer.isStillValid(tile.id) && !tile.markedForRemoval) {
             mLayerClient.beginDrawing();
             mTileProvider.rerenderTile(tile.getImage(), tile.id.x, tile.id.y, tile.id.size, tile.id.zoom);
@@ -102,7 +108,7 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
         LOKitShell.hideProgressSpinner();
     }
 
-    private boolean loadDocument(String filename) {
+    private void loadDocument(String filename) {
         if (mApplication == null) {
             mApplication = LibreOfficeMainActivity.mAppContext;
         }
@@ -110,19 +116,21 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
         mLayerClient = mApplication.getLayerClient();
 
         mTileProvider = TileProviderFactory.create(mLayerClient, filename);
-        boolean isReady = mTileProvider.isReady();
-        if (isReady) {
+
+        if (mTileProvider.isReady()) {
             LOKitShell.showProgressSpinner();
             mTileProvider.registerInvalidationCallback(this);
             refresh();
             LOKitShell.hideProgressSpinner();
+        } else {
+            closeDocument();
         }
-        return isReady;
     }
 
     public void closeDocument() {
         if (mTileProvider != null) {
             mTileProvider.close();
+            mTileProvider = null;
         }
     }
 
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 60e57e6..20fce27 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -78,6 +78,9 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
             postLoad();
             mIsReady = true;
         }
+        else {
+            mIsReady = false;
+        }
     }
 
     public void postLoad() {
@@ -152,7 +155,7 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
         } else {
             ret = resetDocumentSize();
             if (!ret) {
-                error = "Document returned an invalid size or the document is empty!";
+                error = "Document returned an invalid size or the document is empty.";
             }
         }
 
commit 9b482b325baaae4a456073476b5edc68bc62e184
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Wed Feb 4 20:33:52 2015 +0100

    android: Initialize for tiled rendering earlier.
    
    We need to prepare the document ASAP, otherwise we will get zero size when eg.
    presentation is switched to Notes view.
    
    Change-Id: I0d3ccea18058052994d91868ec1346c5de25faff

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 60c3e9c..60e57e6 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -71,6 +71,9 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
 
         Log.i(LOGTAG, "====> mDocument = " + mDocument);
 
+        if (mDocument != null)
+            mDocument.initializeForRendering();
+
         if (checkDocument()) {
             postLoad();
             mIsReady = true;
@@ -78,7 +81,6 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
     }
 
     public void postLoad() {
-        mDocument.initializeForRendering();
         mDocument.setMessageCallback(this);
 
         int parts = mDocument.getParts();
commit b25dd857b42352cce6174744a5350ab2c0566c16
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Wed Feb 4 14:48:57 2015 +0100

    android: In Impress, switch to the 'Normal' (slides) view.
    
    Other modes are not fit for the tiled rendering, and crash the viewer.
    
    Change-Id: I6fb17663203d9eb298bba2b9bd143fdd28ffb470

diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index 8711611..b231e98 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -84,6 +84,10 @@ public:
         (void) ePartMode;
     }
 
+    /**
+     * Setup various document properties that are needed for the document to
+     * be renderable via tiled rendering.
+     */
     virtual void initializeForTiledRendering()
     {
     }
diff --git a/sd/source/ui/inc/unomodel.hxx b/sd/source/ui/inc/unomodel.hxx
index f62d2f7..043d742 100644
--- a/sd/source/ui/inc/unomodel.hxx
+++ b/sd/source/ui/inc/unomodel.hxx
@@ -240,6 +240,9 @@ public:
     virtual OUString getPartName( int nPart ) SAL_OVERRIDE;
     virtual void setPartMode( LibreOfficeKitPartMode ePartMode ) SAL_OVERRIDE;
 
+    /// @see ITiledRenderable::initializeForTiledRendering().
+    virtual void initializeForTiledRendering() SAL_OVERRIDE;
+
     // XComponent
 
     /** This dispose implementation releases the resources held by the
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index e92f328..431e4c6 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -2347,6 +2347,11 @@ Size SdXImpressDocument::getDocumentSize()
     return Size(convertMm100ToTwip(aSize.getWidth()), convertMm100ToTwip(aSize.getHeight()));
 }
 
+void SdXImpressDocument::initializeForTiledRendering()
+{
+    // tiled rendering works only when we are in the 'Normal' view, switch to that
+    mpDocShell->GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_VIEWSHELL0, SfxCallMode::SYNCHRON | SfxCallMode::RECORD);
+}
 
 uno::Reference< i18n::XForbiddenCharacters > SdXImpressDocument::getForbiddenCharsTable()
 {
commit 36e701b1db76557121edc7bed46e4c1e694856ed
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Feb 4 17:45:00 2015 +0100

    android: fix missing drawingML preset shapes
    
    Change-Id: I7a22b9bcacd26b837c00bb09743ab2e176d60746

diff --git a/android/Bootstrap/Makefile.shared b/android/Bootstrap/Makefile.shared
index 77d2bcf..12b4774 100644
--- a/android/Bootstrap/Makefile.shared
+++ b/android/Bootstrap/Makefile.shared
@@ -138,6 +138,8 @@ copy-stuff:
 	rm -Rf assets/share # pre-clean it
 	mkdir -p assets/share/config
 	cp -R $(INSTDIR)/share/registry assets/share
+# Filter data is needed by e.g. the drawingML preset shape import.
+	cp -R $(INSTDIR)/share/filter assets/share
 # Make sure the soffice.cfg directory is always created, it's not possible to hit any keys without it.
 	if ! test z$(DISABLE_UI) = zTRUE; then \
 		echo "Copying UI files into the apk"; \
commit 2f018339be2791a6a4d6b29bd369af840e8aa5fa
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Wed Feb 4 21:13:45 2015 +0900

    android: blinking cursor
    
    Change-Id: I1e2d5df7917ec0f8e780e3e3481dadd10b1b76ed

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java
index d9e51fc..1aed2f0 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java
@@ -29,9 +29,11 @@ public class TextCursorView extends ImageView {
 
     private int mWidth;
     private int mHeight;
+    private int mAlpha = 0;
 
     public TextCursorView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        postDelayed(cursorAnimation, 500);
     }
 
     public void changePosition(RectF position) {
@@ -57,7 +59,6 @@ public class TextCursorView extends ImageView {
         mTop = Math.round(scaled.centerY() - y);
 
         setScaleY(scaled.height());
-
         setLayoutPosition();
     }
 
@@ -76,4 +77,13 @@ public class TextCursorView extends ImageView {
 
         setLayoutParams(mLayoutParams);
     }
+
+    private Runnable cursorAnimation = new Runnable() {
+        public void run() {
+            mAlpha = mAlpha == 0 ? 0xFF : 0;
+            getDrawable().setAlpha(mAlpha);
+            invalidate();
+            postDelayed(cursorAnimation, 500);
+        }
+    };
 }
\ No newline at end of file
commit e2d4cfa425a9cecb31ef8aa74722083dca004b3c
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Wed Feb 4 16:02:15 2015 +0900

    android: show text cursor in place suggested by invalid. event
    
    Text cursor is a simple line (currently implemented as a drawable
    and streched), which height is adaptable. It is drawn in a different
    layer than the document.
    
    Change-Id: I40509a866e3a3173e3efcb88e73066565a1619ae

diff --git a/android/experimental/LOAndroid3/res/drawable/text_cursor.xml b/android/experimental/LOAndroid3/res/drawable/text_cursor.xml
new file mode 100644
index 0000000..f39e6e8
--- /dev/null
+++ b/android/experimental/LOAndroid3/res/drawable/text_cursor.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
+    <size android:width="2px" />
+    <size android:height="1px" />
+    <solid android:color="#000000"/>
+</shape>
\ No newline at end of file
diff --git a/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml b/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml
index c876b28..8d8d014 100644
--- a/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml
+++ b/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml
@@ -26,4 +26,11 @@
                                            android:src="@drawable/handle_end_level"
                                            android:visibility="gone"
                                            gecko:handleType="end"/>
+
+    <org.libreoffice.TextCursorView android:id="@+id/text_cursor_view"
+                                    android:layout_width="wrap_content"
+                                    android:layout_height="wrap_content"
+                                    android:src="@drawable/text_cursor"
+                                    android:visibility="gone"/>
+
 </merge>
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 48868f9..60c3e9c 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -395,6 +395,10 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
                     TextSelection textSelection = LibreOfficeMainActivity.mAppContext.getTextSelection();
                     textSelection.positionHandle(TextSelectionHandle.HandleType.MIDDLE, underSelection);
                     textSelection.showHandle(TextSelectionHandle.HandleType.MIDDLE);
+
+                    TextCursorLayer textCursorLayer = LibreOfficeMainActivity.mAppContext.getTextCursorLayer();
+                    textCursorLayer.positionCursor(rect);
+                    textCursorLayer.showCursor();
                 }
                 break;
             }
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 42ffac8..56e3889 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -48,6 +48,7 @@ public class LibreOfficeMainActivity extends LOAbout {
     private DocumentPartViewListAdapter mDocumentPartViewListAdapter;
     private String mInputFile;
     private TextSelection mTextSelection;
+    private TextCursorLayer mTextCursorLayer;
 
     public LibreOfficeMainActivity() {
         super(/*newActivity=*/false);
@@ -126,6 +127,7 @@ public class LibreOfficeMainActivity extends LOAbout {
         }
 
         mTextSelection = new TextSelection(mAppContext);
+        mTextCursorLayer = new TextCursorLayer(mAppContext);
 
         mLayerClient = new GeckoLayerClient(this);
         mLayerClient.setZoomConstraints(new ZoomConstraints(true));
@@ -238,6 +240,10 @@ public class LibreOfficeMainActivity extends LOAbout {
         return mTextSelection;
     }
 
+    public TextCursorLayer getTextCursorLayer() {
+        return mTextCursorLayer;
+    }
+
     private class DocumentPartClickListener implements android.widget.AdapterView.OnItemClickListener {
         @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorLayer.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorLayer.java
new file mode 100644
index 0000000..e83a56c
--- /dev/null
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorLayer.java
@@ -0,0 +1,82 @@
+package org.libreoffice;
+
+import android.app.Activity;
+import android.graphics.RectF;
+import android.util.Log;
+import android.view.View;
+
+import org.mozilla.gecko.TextSelectionHandle;
+import org.mozilla.gecko.gfx.Layer;
+import org.mozilla.gecko.gfx.LayerView;
+import org.mozilla.gecko.util.FloatUtils;
+
+/**
+ * The TextCursorLayer is a layer which is responsible for showing the cursor and
+ * controls its position, height and visibility.
+ */
+public class TextCursorLayer extends Layer {
+    private static final String LOGTAG = TextCursorLayer.class.getSimpleName();
+
+    private final TextCursorView mCursorView;
+    private float mViewLeft;
+    private float mViewTop;
+    private float mViewZoom;
+
+    public TextCursorLayer(Activity context) {
+        mCursorView = (TextCursorView) context.findViewById(R.id.text_cursor_view);
+        if (mCursorView == null) {
+            Log.e(LOGTAG, "Failed to initialize TextCursorLayer - CursorView is null");
+        }
+    }
+
+    @Override
+    public void draw(final RenderContext context) {
+        if (FloatUtils.fuzzyEquals(mViewLeft, context.viewport.left)
+                && FloatUtils.fuzzyEquals(mViewTop, context.viewport.top)
+                && FloatUtils.fuzzyEquals(mViewZoom, context.zoomFactor)) {
+            return;
+        }
+
+        mViewLeft = context.viewport.left;
+        mViewTop = context.viewport.top;
+        mViewZoom = context.zoomFactor;
+
+        LOKitShell.getMainHandler().post(new Runnable() {
+            public void run() {
+                mCursorView.repositionWithViewport(context.viewport.left, context.viewport.top, context.zoomFactor);
+            }
+        });
+    }
+
+    public void showCursor() {
+        LOKitShell.getMainHandler().post(new Runnable() {
+            public void run() {
+                mCursorView.setVisibility(View.VISIBLE);
+
+                mViewLeft = 0.0f;
+                mViewTop = 0.0f;
+                mViewZoom = 0.0f;
+                LayerView layerView = LOKitShell.getLayerView();
+                if (layerView != null) {
+                    layerView.addLayer(TextCursorLayer.this);
+                }
+            }
+        });
+    }
+
+    public void hideCursor() {
+        LOKitShell.getMainHandler().post(new Runnable() {
+            public void run() {
+                mCursorView.setVisibility(View.GONE);
+            }
+        });
+    }
+
+    public void positionCursor(final RectF position) {
+        LOKitShell.getMainHandler().post(new Runnable() {
+            public void run() {
+                mCursorView.changePosition(position);
+            }
+        });
+    }
+}
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java
new file mode 100644
index 0000000..d9e51fc
--- /dev/null
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java
@@ -0,0 +1,79 @@
+package org.libreoffice;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+
+import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
+import org.mozilla.gecko.gfx.LayerView;
+import org.mozilla.gecko.gfx.RectUtils;
+
+/**
+ * Text cursor view responsible to show the cursor drawable on the screen.
+ */
+public class TextCursorView extends ImageView {
+    private static final String LOGTAG = TextCursorView.class.getSimpleName();
+
+    private RectF mPosition;
+    private RelativeLayout.LayoutParams mLayoutParams;
+
+    private int mLeft;
+    private int mTop;
+
+    private int mWidth;
+    private int mHeight;
+
+    public TextCursorView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void changePosition(RectF position) {
+        LayerView layerView = LOKitShell.getLayerView();
+        if (layerView == null) {
+            Log.e(LOGTAG, "Can't position handle because layerView is null");
+            return;
+        }
+
+        mPosition = position;
+
+        mWidth = Math.round(position.width());
+        mHeight = Math.round(position.height());
+
+        ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
+        repositionWithViewport(metrics.viewportRectLeft, metrics.viewportRectTop, metrics.zoomFactor);
+    }
+
+    public void repositionWithViewport(float x, float y, float zoom) {
+        RectF scaled = RectUtils.scale(mPosition, zoom);
+
+        mLeft = Math.round(scaled.centerX() - x);
+        mTop = Math.round(scaled.centerY() - y);
+
+        setScaleY(scaled.height());
+
+        setLayoutPosition();
+    }
+
+    private void setLayoutPosition() {
+        if (mLayoutParams == null) {
+            mLayoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
+            // Set negative right/bottom margins so that the handles can be dragged outside of
+            // the content area (if they are dragged to the left/top, the dyanmic margins set
+            // below will take care of that).
+            mLayoutParams.rightMargin = 0 - mWidth;
+            mLayoutParams.bottomMargin = 0 - mHeight;
+        }
+
+        mLayoutParams.leftMargin = mLeft;
+        mLayoutParams.topMargin = mTop;
+
+        setLayoutParams(mLayoutParams);
+    }
+}
\ No newline at end of file
commit 48ae33bd8513678c898c5ba692351be2e95a7e83
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Jan 30 22:15:03 2015 +0900

    android: gather text selection handles inside TextSelection
    
    Change-Id: I7bd13bea6aa58f7a1be4b9cfbc32f9d59c0b9e14

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index f1eb759..42ffac8 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -125,11 +125,7 @@ public class LibreOfficeMainActivity extends LOAbout {
             sLOKitThread.clearQueue();
         }
 
-        TextSelectionHandle startHandle = (TextSelectionHandle) findViewById(R.id.start_handle);
-        TextSelectionHandle middleHandle = (TextSelectionHandle) findViewById(R.id.middle_handle);
-        TextSelectionHandle endHandle = (TextSelectionHandle) findViewById(R.id.end_handle);
-
-        mTextSelection = new TextSelection(startHandle, middleHandle, endHandle);
+        mTextSelection = new TextSelection(mAppContext);
 
         mLayerClient = new GeckoLayerClient(this);
         mLayerClient.setZoomConstraints(new ZoomConstraints(true));
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelection.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelection.java
index 241ce14..2ae1539 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelection.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelection.java
@@ -4,6 +4,7 @@
 
 package org.mozilla.gecko;
 
+import android.app.Activity;
 import android.graphics.RectF;
 import android.util.Log;
 import android.view.View;
@@ -12,6 +13,7 @@ import org.json.JSONArray;
 import org.json.JSONObject;
 import org.libreoffice.LOKitShell;
 import org.libreoffice.LibreOfficeMainActivity;
+import org.libreoffice.R;
 import org.mozilla.gecko.gfx.Layer;
 import org.mozilla.gecko.gfx.LayerView;
 import org.mozilla.gecko.util.FloatUtils;
@@ -29,12 +31,10 @@ public class TextSelection extends Layer {
     private float mViewTop;
     private float mViewZoom;
 
-    public TextSelection(TextSelectionHandle startHandle,
-                         TextSelectionHandle middleHandle,
-                         TextSelectionHandle endHandle) {
-        mStartHandle = startHandle;
-        mMiddleHandle = middleHandle;
-        mEndHandle = endHandle;
+    public TextSelection(Activity context) {
+        mStartHandle = (TextSelectionHandle) context.findViewById(R.id.start_handle);
+        mMiddleHandle = (TextSelectionHandle) context.findViewById(R.id.middle_handle);
+        mEndHandle = (TextSelectionHandle) context.findViewById(R.id.end_handle);
 
         // Only register listeners if we have valid start/middle/end handles
         if (mStartHandle == null || mMiddleHandle == null || mEndHandle == null) {
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelectionHandle.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelectionHandle.java
index b554465..6f85db9 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelectionHandle.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelectionHandle.java
@@ -22,7 +22,7 @@ import android.widget.ImageView;
 import android.widget.RelativeLayout;
 
 public class TextSelectionHandle extends ImageView implements View.OnTouchListener {
-    private static final String LOGTAG = "GeckoTextSelectionHandle";
+    private static final String LOGTAG = TextSelectionHandle.class.getSimpleName();
 
     public enum HandleType { START, MIDDLE, END };
 
commit 1eb411480643cbba748b268e5c760552253b2f8a
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Tue Feb 3 11:44:54 2015 +0100

    android: Always log the SAL_WARN's.
    
    Change-Id: Iab470097cc09835efd5ab3c13a0defb267c985a0

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index f416b45..48868f9 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -46,7 +46,7 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
         mTileWidth = pixelToTwip(TILE_SIZE, mDPI);
         mTileHeight = pixelToTwip(TILE_SIZE, mDPI);
 
-        LibreOfficeKit.putenv("SAL_LOG=-WARN+INFO.lok");
+        LibreOfficeKit.putenv("SAL_LOG=+WARN+INFO.lok");
         LibreOfficeKit.init(LibreOfficeMainActivity.mAppContext);
 
         mOffice = new Office(LibreOfficeKit.getLibreOfficeKitHandle());
@@ -66,7 +66,7 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
             mOffice = new Office(handle);
             Log.i(LOGTAG, "====> new Office created");
             mDocument = mOffice.documentLoad(input);
-            LibreOfficeKit.putenv("SAL_LOG=-WARN+INFO.lok");
+            LibreOfficeKit.putenv("SAL_LOG=+WARN+INFO.lok");
         }
 
         Log.i(LOGTAG, "====> mDocument = " + mDocument);
commit 8e58af2c7f9a865f3cb8e24eb3318db36d973bad
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Mon Feb 2 23:34:16 2015 +0100

    Add slideshow-related services.
    
    Fixes loading of .pps presentations.
    
    Change-Id: I739d15793110fc55cbaa556e1c91d666c6f81c70

diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index dda7581..e64e27a 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -38,6 +38,7 @@ core_factory_list = [
     ("liblocalebe1lo.a", "localebe1_component_getFactory"),
     ("libooxlo.a", "oox_component_getFactory"),
     ("libpackage2.a", "package2_component_getFactory"),
+    ("libslideshowlo.a", "slideshow_component_getFactory"),
     ("libsmlo.a", "sm_component_getFactory"),
     ("libsotlo.a", "sot_component_getFactory"),
     ("libspelllo.a", "spell_component_getFactory"),
@@ -119,6 +120,7 @@ core_constructor_list = [
 # toolkit/util/tk.component
     "stardiv_Toolkit_UnoControlContainer_get_implementation",
     "stardiv_Toolkit_UnoControlContainerModel_get_implementation",
+    "stardiv_Toolkit_VCLXPointer_get_implementation",
     "stardiv_Toolkit_VCLXToolkit_get_implementation",
 # uui/util/uui.component
     "com_sun_star_comp_uui_UUIInteractionHandler_get_implementation",
commit 72e7e945d09d028cedabaf7f80d5ec96b833e76e
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Jan 30 20:59:05 2015 +0900

    android: TextSelection improvements
    
    Change-Id: I485976edda5e2bb41381ad3a90b8d2139ca7d5f4

diff --git a/android/experimental/LOAndroid3/res/drawable/handle_end_level.xml b/android/experimental/LOAndroid3/res/drawable/handle_end_level.xml
new file mode 100644
index 0000000..40a512b
--- /dev/null
+++ b/android/experimental/LOAndroid3/res/drawable/handle_end_level.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!-- LTR -->
+    <item android:maxLevel="0" android:drawable="@drawable/handle_end"/>
+
+    <!-- RTL -->
+    <item android:maxLevel="1" android:drawable="@drawable/handle_start"/>
+
+</level-list>
diff --git a/android/experimental/LOAndroid3/res/drawable/handle_start_level.xml b/android/experimental/LOAndroid3/res/drawable/handle_start_level.xml
new file mode 100644
index 0000000..2294513
--- /dev/null
+++ b/android/experimental/LOAndroid3/res/drawable/handle_start_level.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!-- LTR -->
+    <item android:maxLevel="0" android:drawable="@drawable/handle_start"/>
+
+    <!-- RTL -->
+    <item android:maxLevel="1" android:drawable="@drawable/handle_end"/>
+
+</level-list>
diff --git a/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml b/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml
index 1f0d816..c876b28 100644
--- a/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml
+++ b/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml
@@ -9,7 +9,7 @@
     <org.mozilla.gecko.TextSelectionHandle android:id="@+id/start_handle"
                                            android:layout_width="@dimen/text_selection_handle_width"
                                            android:layout_height="@dimen/text_selection_handle_height"
-                                           android:src="@drawable/handle_start"
+                                           android:src="@drawable/handle_start_level"
                                            android:visibility="gone"
                                            gecko:handleType="start"/>
 
@@ -23,7 +23,7 @@
     <org.mozilla.gecko.TextSelectionHandle android:id="@+id/end_handle"
                                            android:layout_width="@dimen/text_selection_handle_width"
                                            android:layout_height="@dimen/text_selection_handle_height"
-                                           android:src="@drawable/handle_end"
+                                           android:src="@drawable/handle_end_level"
                                            android:visibility="gone"
                                            gecko:handleType="end"/>
 </merge>
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 0bf9f1f..f416b45 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -11,6 +11,7 @@ import org.libreoffice.kit.Document;
 import org.libreoffice.kit.LibreOfficeKit;
 import org.libreoffice.kit.Office;
 import org.mozilla.gecko.TextSelection;
+import org.mozilla.gecko.TextSelectionHandle;
 import org.mozilla.gecko.gfx.BufferedCairoImage;
 import org.mozilla.gecko.gfx.CairoImage;
 import org.mozilla.gecko.gfx.GeckoLayerClient;
@@ -390,9 +391,10 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
                 Log.i(LOGTAG, "Invalidate visible cursor: " + payload);
                 RectF rect = convertCallbackMessageStringToRectF(payload);
                 if (rect != null) {
+                    RectF underSelection = new RectF(rect.centerX(), rect.bottom, rect.centerX(), rect.bottom);
                     TextSelection textSelection = LibreOfficeMainActivity.mAppContext.getTextSelection();
-                    textSelection.positionHandle("MIDDLE", new RectF(rect.right,rect.bottom, rect.right, rect.bottom));
-                    textSelection.showHandle("MIDDLE");
+                    textSelection.positionHandle(TextSelectionHandle.HandleType.MIDDLE, underSelection);
+                    textSelection.showHandle(TextSelectionHandle.HandleType.MIDDLE);
                 }
                 break;
             }
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelection.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelection.java
index f09e93a..241ce14 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelection.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelection.java
@@ -16,6 +16,8 @@ import org.mozilla.gecko.gfx.Layer;
 import org.mozilla.gecko.gfx.LayerView;
 import org.mozilla.gecko.util.FloatUtils;
 
+import static org.mozilla.gecko.TextSelectionHandle.HandleType.*;
+
 public class TextSelection extends Layer {
     private static final String LOGTAG = "GeckoTextSelection";
 
@@ -43,84 +45,6 @@ public class TextSelection extends Layer {
     void destroy() {
     }
 
-    public void handleMessage(String event, JSONObject message) {
-        try {
-            if (event.equals("TextSelection:ShowHandles")) {
-                final JSONArray handles = message.getJSONArray("handles");
-                LibreOfficeMainActivity.mAppContext.mMainHandler.post(new Runnable() {
-                    public void run() {
-                        try {
-                            for (int i=0; i < handles.length(); i++) {
-                                String handle = handles.getString(i);
-
-                                if (handle.equals("START"))
-                                    mStartHandle.setVisibility(View.VISIBLE);
-                                else if (handle.equals("MIDDLE"))
-                                    mMiddleHandle.setVisibility(View.VISIBLE);
-                                else
-                                    mEndHandle.setVisibility(View.VISIBLE);
-                            }
-
-                            mViewLeft = 0.0f;
-                            mViewTop = 0.0f;
-                            mViewZoom = 0.0f;
-                            LayerView layerView = LOKitShell.getLayerView();
-                            if (layerView != null) {
-                                layerView.addLayer(TextSelection.this);
-                            }
-                        } catch(Exception e) {}
-                    }
-                });
-            } else if (event.equals("TextSelection:HideHandles")) {
-                final JSONArray handles = message.getJSONArray("handles");
-                LibreOfficeMainActivity.mAppContext.mMainHandler.post(new Runnable() {
-                    public void run() {
-                        try {
-                            LayerView layerView = LOKitShell.getLayerView();
-                            if (layerView != null) {
-                                layerView.removeLayer(TextSelection.this);
-                            }
-
-                            for (int i=0; i < handles.length(); i++) {
-                                String handle = handles.getString(i);
-                                if (handle.equals("START"))
-                                    mStartHandle.setVisibility(View.GONE);
-                                else if (handle.equals("MIDDLE"))
-                                    mMiddleHandle.setVisibility(View.GONE);
-                                else
-                                    mEndHandle.setVisibility(View.GONE);
-                            }
-
-                        } catch(Exception e) {}
-                    }
-                });
-            } else if (event.equals("TextSelection:PositionHandles")) {
-                final JSONArray positions = message.getJSONArray("positions");
-                LibreOfficeMainActivity.mAppContext.mMainHandler.post(new Runnable() {
-                    public void run() {
-                        try {
-                            for (int i=0; i < positions.length(); i++) {
-                                JSONObject position = positions.getJSONObject(i);
-                                String handle = position.getString("handle");
-                                int left = position.getInt("left");
-                                int top = position.getInt("top");
-
-                                if (handle.equals("START"))
-                                    mStartHandle.positionFromGecko(left, top);
-                                else if (handle.equals("MIDDLE"))
-                                    mMiddleHandle.positionFromGecko(left, top);
-                                else
-                                    mEndHandle.positionFromGecko(left, top);
-                            }
-                        } catch (Exception e) { }
-                    }
-                });
-            }
-        } catch (Exception e) {
-            Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
-        }
-    }
-
     @Override
     public void draw(final RenderContext context) {
         // cache the relevant values from the context and bail out if they are the same. we do this
@@ -144,47 +68,49 @@ public class TextSelection extends Layer {
         });
     }
 
-    public void showHandle(final String handleType) {
+    public void showHandle(final TextSelectionHandle.HandleType handleType) {
         LOKitShell.getMainHandler().post(new Runnable() {
             public void run() {
-                try {
-                    TextSelectionHandle handle;
-                    if (handleType.equals("START"))
-                        handle = mStartHandle;
-                    else if (handleType.equals("MIDDLE"))
-                        handle = mMiddleHandle;
-                    else
-                        handle = mEndHandle;
-
-                    handle.setVisibility(View.VISIBLE);
-
-                    mViewLeft = 0.0f;
-                    mViewTop = 0.0f;
-                    mViewZoom = 0.0f;
-                    LayerView layerView = LOKitShell.getLayerView();
-                    if (layerView != null) {
-                        layerView.addLayer(TextSelection.this);
-                    }
-                } catch (Exception e) {
+                TextSelectionHandle handle = getHandle(handleType);
+
+                handle.setVisibility(View.VISIBLE);
+
+                mViewLeft = 0.0f;
+                mViewTop = 0.0f;
+                mViewZoom = 0.0f;
+                LayerView layerView = LOKitShell.getLayerView();
+                if (layerView != null) {
+                    layerView.addLayer(TextSelection.this);
                 }
             }
         });
     }
 
-    public void positionHandle(final String handleType, final RectF position) {
+    private TextSelectionHandle getHandle(TextSelectionHandle.HandleType handleType) {
+        if (handleType == START) {
+            return mStartHandle;
+        } else if (handleType == MIDDLE) {
+            return mMiddleHandle;
+        } else {
+            return mEndHandle;
+        }
+    }
+
+    public void hideHandle(final TextSelectionHandle.HandleType handleType) {
+        LOKitShell.getMainHandler().post(new Runnable() {
+            public void run() {
+                TextSelectionHandle handle = getHandle(handleType);
+                handle.setVisibility(View.GONE);
+            }
+        });
+    }
+
+
+    public void positionHandle(final TextSelectionHandle.HandleType handleType, final RectF position) {
         LOKitShell.getMainHandler().post(new Runnable() {
             public void run() {
-                try {
-                    TextSelectionHandle handle;
-                    if (handleType.equals("START"))
-                        handle = mStartHandle;
-                    else if (handleType.equals("MIDDLE"))
-                        handle = mMiddleHandle;
-                    else
-                        handle = mEndHandle;
-
-                    handle.positionFromGecko((int) position.left, (int) position.top);
-                } catch (Exception e) { }
+                TextSelectionHandle handle = getHandle(handleType);
+                handle.positionFromGecko((int) position.left, (int) position.top, false);
             }
         });
     }
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelectionHandle.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelectionHandle.java
index 92ca9d4..b554465 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelectionHandle.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/TextSelectionHandle.java
@@ -24,7 +24,7 @@ import android.widget.RelativeLayout;
 public class TextSelectionHandle extends ImageView implements View.OnTouchListener {
     private static final String LOGTAG = "GeckoTextSelectionHandle";
 
-    private enum HandleType { START, MIDDLE, END };
+    public enum HandleType { START, MIDDLE, END };
 
     private final HandleType mHandleType;
     private final int mWidth;
@@ -33,12 +33,16 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen
 
     private int mLeft;
     private int mTop;
+    private boolean mIsRTL;
     private PointF mGeckoPoint;
     private int mTouchStartX;
     private int mTouchStartY;
 
     private RelativeLayout.LayoutParams mLayoutParams;
 
+    private static final int IMAGE_LEVEL_LTR = 0;
+    private static final int IMAGE_LEVEL_RTL = 1;
+
     public TextSelectionHandle(Context context, AttributeSet attrs) {
         super(context, attrs);
         setOnTouchListener(this);
@@ -53,6 +57,7 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen
         else
             mHandleType = HandleType.END;
 
+        mIsRTL = false;
         mGeckoPoint = new PointF(0.0f, 0.0f);
 
         mWidth = getResources().getDimensionPixelSize(R.dimen.text_selection_handle_width);
@@ -99,13 +104,7 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen
             return;
         }
         // Send x coordinate on the right side of the start handle, left side of the end handle.
-        float left = (float) mLeft;
-        if (mHandleType.equals(HandleType.START))
-            left +=  mWidth - mShadow;
-        else if (mHandleType.equals(HandleType.MIDDLE))
-            left +=  (float) ((mWidth - mShadow) / 2);
-        else
-            left += mShadow;
+        float left = (float) mLeft + adjustLeftForHandle();
 
         PointF geckoPoint = new PointF(left, (float) mTop);
         geckoPoint = layerView.getLayerClient().convertViewPointToLayerPoint(geckoPoint);
@@ -123,8 +122,7 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen
         setLayoutPosition();
     }
 
-    void positionFromGecko(int left, int top) {
-        Log.i(LOGTAG, "positionFromGecko: " + left + " " + top);
+    void positionFromGecko(int left, int top, boolean rtl) {
         LayerView layerView = LOKitShell.getLayerView();
         if (layerView == null) {
             Log.e(LOGTAG, "Can't position handle because layerView is null");
@@ -132,27 +130,34 @@ public class TextSelectionHandle extends ImageView implements View.OnTouchListen
         }
 
         mGeckoPoint = new PointF((float) left, (float) top);
+        if (mIsRTL != rtl) {
+            mIsRTL = rtl;
+            setImageLevel(mIsRTL ? IMAGE_LEVEL_RTL : IMAGE_LEVEL_LTR);
+        }
+
         ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
         repositionWithViewport(metrics.viewportRectLeft, metrics.viewportRectTop, metrics.zoomFactor);
     }
 
     void repositionWithViewport(float x, float y, float zoom) {
         PointF viewPoint = new PointF((mGeckoPoint.x * zoom) - x,
-                (mGeckoPoint.y * zoom) - y);
-
-        mLeft = Math.round(viewPoint.x);
-        if (mHandleType.equals(HandleType.START))
-            mLeft -=  mWidth - mShadow;
-        else if (mHandleType.equals(HandleType.MIDDLE))
-            mLeft -=  (float) ((mWidth - mShadow) / 2);
-        else
-            mLeft -= mShadow;
+                                      (mGeckoPoint.y * zoom) - y);
 
+        mLeft = Math.round(viewPoint.x) - (int) adjustLeftForHandle();
         mTop = Math.round(viewPoint.y);
 
         setLayoutPosition();
     }
 
+    private float adjustLeftForHandle() {
+        if (mHandleType.equals(HandleType.START))
+            return mIsRTL ? mShadow : mWidth - mShadow;
+        else if (mHandleType.equals(HandleType.MIDDLE))
+            return (float) ((mWidth - mShadow) / 2);
+        else
+            return mIsRTL ? mWidth - mShadow : mShadow;
+    }
+
     private void setLayoutPosition() {
         if (mLayoutParams == null) {
             mLayoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
commit c9893aa85887c108431c59d29feeeea8bef5f4ef
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Jan 30 14:17:47 2015 +0900

    android: make back button work again - return false in OnKeyDown
    
    Change-Id: I8340e5f27475f38f8384d883ac0bb7fccf1135f1

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitInputConnectionHandler.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitInputConnectionHandler.java
index a63b28d..6a5837b 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitInputConnectionHandler.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitInputConnectionHandler.java
@@ -20,7 +20,7 @@ public class LOKitInputConnectionHandler implements InputConnectionHandler {
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         LOKitShell.sendKeyPressEvent(event);
-        return true;
+        return false;
     }
 
     @Override
commit a6ae67d897550a52c8b2b4f710a8ef4a88cf45f0
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Jan 30 13:42:58 2015 +0900

    android: mute invalid. if not editing, don't show handle on touch
    
    Change-Id: I551af3849f9b0a10106bf02fff220fa4600eb07f

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index 354404c..7e99da3 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -4,6 +4,7 @@ import android.graphics.Bitmap;
 import android.graphics.PointF;
 import android.graphics.RectF;
 import android.util.Log;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 import org.mozilla.gecko.gfx.CairoImage;
@@ -159,25 +160,35 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
                 createThumbnail(event.mTask);
                 break;
             case LOEvent.TOUCH:
-                if (!LOKitShell.isEditingEnabled()) {
-                    return;
-                }
                 touch(event.mTouchType, event.mMotionEvent, event.mDocumentTouchCoordinate);
                 break;
             case LOEvent.KEY_EVENT:
-                if (!LOKitShell.isEditingEnabled()) {
-                    return;
-                }
-                if (event.mKeyEventType == "KeyPress") {
-                    mTileProvider.keyPress(event.mKeyEvent);
-                } else if (event.mKeyEventType.equals("KeyRelease")) {
-                    mTileProvider.keyRelease(event.mKeyEvent);
-                }
+                keyEvent(event.mKeyEventType, event.mKeyEvent);
                 break;
         }
     }
 
+    /**
+     * Processes key events.
+     */
+    private void keyEvent(String keyEventType, KeyEvent keyEvent) {
+        if (!LOKitShell.isEditingEnabled()) {
+            return;
+        }
+        if (keyEventType == "KeyPress") {
+            mTileProvider.keyPress(keyEvent);
+        } else if (keyEventType.equals("KeyRelease")) {
+            mTileProvider.keyRelease(keyEvent);
+        }
+    }
+
+    /**
+     * Processes touch events.
+     */
     private void touch(String touchType, MotionEvent motionEvent, PointF mDocumentTouchCoordinate) {
+        if (!LOKitShell.isEditingEnabled()) {
+            return;
+        }
         LibreOfficeMainActivity.mAppContext.showSoftKeyboard();
         mTileProvider.mouseButtonDown(mDocumentTouchCoordinate);
     }
@@ -197,10 +208,6 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
 
     @Override
     public void invalidate(RectF rect) {
-        if (!LOKitShell.isEditingEnabled()) {
-            return;
-        }
-
         Log.i(LOGTAG, "Invalidate request: " + rect);
 
         mLayerClient = mApplication.getLayerClient();
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index c5f31b3..0bf9f1f 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -310,10 +310,6 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
         int x = (int) pixelToTwip(inDocument.x, mDPI);
         int y = (int) pixelToTwip(inDocument.y, mDPI);
 
-        TextSelection textSelection = LibreOfficeMainActivity.mAppContext.getTextSelection();
-        textSelection.positionHandle("MIDDLE", new RectF(inDocument.x, inDocument.y, inDocument.x, inDocument.y));
-        textSelection.showHandle("MIDDLE");
-
         mDocument.postMouseEvent(type, x, y);
     }
 
@@ -378,6 +374,10 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
      */
     @Override
     public void messageRetrieved(int signalNumber, String payload) {
+        if (!LOKitShell.isEditingEnabled()) {
+            return;
+        }
+
         switch (signalNumber) {
             case Document.CALLBACK_INVALIDATE_TILES: {
                 RectF rect = convertCallbackMessageStringToRectF(payload);
@@ -391,7 +391,7 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
                 RectF rect = convertCallbackMessageStringToRectF(payload);
                 if (rect != null) {
                     TextSelection textSelection = LibreOfficeMainActivity.mAppContext.getTextSelection();
-                    textSelection.positionHandle("MIDDLE", rect);
+                    textSelection.positionHandle("MIDDLE", new RectF(rect.right,rect.bottom, rect.right, rect.bottom));
                     textSelection.showHandle("MIDDLE");
                 }
                 break;
commit e71b15ccc55b8e4bc4b105a664abfd5eb72da2de
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 29 19:03:07 2015 +0900

    tdf#87098 don't adjust zoom/position for spreadsheets
    
    Change-Id: Ieb908980a931b123e2c48fe3ecdc7830b48810ed

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index 5cb8f31..354404c 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -63,16 +63,27 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
         mViewportMetrics = mLayerClient.getViewportMetrics();
         mLayerClient.setViewportMetrics(mViewportMetrics);
 
-        if (mTileProvider.isTextDocument()) {
+        zoomAndRepositionTheDocument();
+
+        mLayerClient.forceRedraw();
+    }
+
+    private void zoomAndRepositionTheDocument() {
+        if (mTileProvider.isSpreadsheet()) {
+            // Don't do anything for spreadsheets - show at 100%
+        } else if (mTileProvider.isTextDocument()) {
+            // Always zoom text document to the beginning of the document and centered by width
             float centerY = mViewportMetrics.getCssViewport().centerY();
-            mLayerClient.zoomTo(new RectF (0, centerY, mTileProvider.getPageWidth(), centerY));
-        } else if (mViewportMetrics.getViewport().width() < mViewportMetrics.getViewport().height()) {
-            mLayerClient.zoomTo(mTileProvider.getPageWidth(), 0);
+            mLayerClient.zoomTo(new RectF(0, centerY, mTileProvider.getPageWidth(), centerY));
         } else {
-            mLayerClient.zoomTo(0, mTileProvider.getPageHeight());
+            // Other documents - always show the whole document on the screen,
+            // regardless of document shape and orientation.
+            if (mViewportMetrics.getViewport().width() < mViewportMetrics.getViewport().height()) {
+                mLayerClient.zoomTo(mTileProvider.getPageWidth(), 0);
+            } else {
+                mLayerClient.zoomTo(0, mTileProvider.getPageHeight());
+            }
         }
-
-        mLayerClient.forceRedraw();
     }
 
     /** Invalidate everything + handle the geometry change */
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 5539450..c5f31b3 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -270,6 +270,11 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
         return mDocument != null && mDocument.getDocumentType() == Document.DOCTYPE_TEXT;
     }
 
+    @Override
+    public boolean isSpreadsheet() {
+        return mDocument != null && mDocument.getDocumentType() == Document.DOCTYPE_SPREADSHEET;
+    }
+
     /**
      * Register the tile invalidation callback.
      */
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
index 006ae90..34347bb 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
@@ -85,6 +85,11 @@ public class MockTileProvider implements TileProvider {
     }
 
     @Override
+    public boolean isSpreadsheet() {
+        return false;
+    }
+
+    @Override
     public void registerInvalidationCallback(TileInvalidationCallback tileInvalidationCallback) {
     }
 
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java
index 759ecad..c983c62 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java
@@ -54,6 +54,11 @@ public interface TileProvider {
     boolean isTextDocument();
 
     /**
+     * Returns true if the current open document is a spreadsheet.
+     */
+    boolean isSpreadsheet();
+
+    /**
      * Register a callback that is invoked when a tile invalidation is
      * required.
      *
commit 576973408d88c9bf6100c09cb10b84edcdc88094
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 29 18:07:06 2015 +0900

    Don't hide cursor for Android anymore - makes cursor events work
    
    Change-Id: I97caadf079c9a5e38c00c80fdc8185aee997f632

diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index a8cd152..982a2ac 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -63,7 +63,7 @@
 #include <comcore.hrc>
 #include <IDocumentLayoutAccess.hxx>
 
-#if defined(ANDROID) || defined(IOS)
+#if defined(IOS)
 #include <touch/touch.h>
 #endif
 
@@ -2119,7 +2119,7 @@ void SwCrsrShell::ShowCrsr()
     {
         m_bSVCrsrVis = true;
         m_pCurCrsr->SetShowTxtInputFldOverlay( true );
-#if defined(ANDROID) || defined(IOS)
+#if defined(IOS)
         // This was dummied out both for Android and for TiledLibreOffice (iOS) anyway
         // touch_ui_show_keyboard();
 #endif
@@ -2136,7 +2136,7 @@ void SwCrsrShell::HideCrsr()
         SET_CURR_SHELL( this );
         m_pCurCrsr->SetShowTxtInputFldOverlay( false );
         m_pVisCrsr->Hide();
-#if defined(ANDROID) || defined(IOS)
+#if defined(IOS)
         // This was dummied out both for Android and for TiledLibreOffice (iOS) anyway
         // touch_ui_hide_keyboard();
 #endif
@@ -2634,7 +2634,7 @@ SwCrsrShell::SwCrsrShell( SwCrsrShell& rShell, vcl::Window *pInitWin )
     m_pVisCrsr = new SwVisCrsr( this );
     m_bMacroExecAllowed = rShell.IsMacroExecAllowed();
 
-#if defined(ANDROID) || defined(IOS)
+#if defined(IOS)
     HideCrsr();
 #endif
 }
@@ -2685,7 +2685,7 @@ SwCrsrShell::SwCrsrShell( SwDoc& rDoc, vcl::Window *pInitWin,
     m_pVisCrsr = new SwVisCrsr( this );
     m_bMacroExecAllowed = true;
 
-#if defined(ANDROID) || defined(IOS)
+#if defined(IOS)
     HideCrsr();
 #endif
 }
commit 9288a3c6b0d07a763a227e8fd97d0ece0eee96b9
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 29 17:46:23 2015 +0900

    Combine DBG_UTIL and header version of Stt{End}CrsrMove
    
    Having 2 versions (debug and release) of one method (on top of
    that in different places - one implemented in header) which are
    mostly the same is a recipe for disaster.
    
    Change-Id: Ia38f900ac076d1c1765fea2c7326147b115e343d

diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index d57520c..13489ce 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -447,14 +447,8 @@ public:
      */
     void Combine();
 
-#ifdef DBG_UTIL
     void SttCrsrMove();
     void EndCrsrMove( const bool bIdleEnd = false );
-#else
-    void SttCrsrMove() { ++m_nCrsrMove; StartAction(); }
-    void EndCrsrMove( const bool bIdleEnd = false )
-            { EndAction( bIdleEnd, true ); --m_nCrsrMove; }
-#endif
 
     /*
      * When the focus is lost the selected ranges are not displayed anymore.
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 2e63da7..a8cd152 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -314,22 +314,27 @@ void SwCrsrShell::EndAction( const bool bIdleEnd, const bool DoSetPosX )
     }
 }
 
-#ifdef DBG_UTIL
 void SwCrsrShell::SttCrsrMove()
 {
+#ifdef DBG_UTIL
     OSL_ENSURE( m_nCrsrMove < USHRT_MAX, "To many nested CrsrMoves." );
+#endif
     ++m_nCrsrMove;
     StartAction();
 }
 
 void SwCrsrShell::EndCrsrMove( const bool bIdleEnd )
 {
+#ifdef DBG_UTIL
     OSL_ENSURE( m_nCrsrMove, "EndCrsrMove() without SttCrsrMove()." );
+#endif
     EndAction( bIdleEnd, true );
-    if( !--m_nCrsrMove )
+    --m_nCrsrMove;
+#ifdef DBG_UTIL
+    if( !m_nCrsrMove )
         m_bInCMvVisportChgd = false;
-}
 #endif
+}
 
 bool SwCrsrShell::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
                              bool bVisualAllowed )
commit e1f9b5394b7cf512a0bcbbb4f1ae2a96e9b8b248
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 29 14:40:29 2015 +0900

    android: Actually we don't need ViewFactory
    
    Change-Id: I2d1ccafefe9c52d0536601ba7ff219e6547ceb20

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 362fb78..f1eb759 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -96,8 +96,6 @@ public class LibreOfficeMainActivity extends LOAbout {
 
         mMainHandler = new Handler();
 
-        LayoutInflater.from(this).setFactory(ViewFactory.getInstance());
-
         if (getIntent().getData() != null) {
             mInputFile = getIntent().getData().getPath();
         } else {
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/ViewFactory.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/ViewFactory.java
deleted file mode 100644
index 68f88d9..0000000
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/ViewFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.libreoffice;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-
-import org.mozilla.gecko.TextSelectionHandle;
-import org.mozilla.gecko.gfx.LayerView;
-
-public class ViewFactory implements LayoutInflater.Factory {
-    private static final String LOGTAG = ViewFactory.class.getSimpleName();
-    private static final String LAYER_VIEW_ID = "org.mozilla.gecko.gfx.LayerView";
-    private static final String TEXT_SELECTION_HANDLE_ID = "org.mozilla.gecko.TextSelectionHandle";
-    private static final ViewFactory INSTANCE = new ViewFactory();
-
-    private ViewFactory() {
-    }
-
-    public static LayoutInflater.Factory getInstance() {
-        return INSTANCE;
-    }
-
-    @Override
-    public View onCreateView(String name, Context context, AttributeSet attrs) {
-        if (name.equals(LAYER_VIEW_ID)) {
-            Log.i(LOGTAG, "Creating custom Gecko view: " + name);
-            return new LayerView(context, attrs);
-        } else if (name.equals(TEXT_SELECTION_HANDLE_ID)) {
-            Log.i(LOGTAG, "Creating custom Gecko view: " + name);
-            return new TextSelectionHandle(context, attrs);
-        }
-        return null;
-    }
-}
\ No newline at end of file
commit aecce900af9e9d216cd1039c775556b6ff683ce6
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 29 11:26:24 2015 +0900

    android: integrate text selection handles from Fennec
    
    Integrate text selection handles from Fennec and insert middle
    handle when a cursor invalidation event is recieved from LO.
    
    Change-Id: I6ba31d46bf89555bdbca9ce4be666039e8bc9041

diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/handle_end.png b/android/experimental/LOAndroid3/res/drawable-hdpi/handle_end.png
new file mode 100644
index 0000000..d5e2044
Binary files /dev/null and b/android/experimental/LOAndroid3/res/drawable-hdpi/handle_end.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/handle_middle.png b/android/experimental/LOAndroid3/res/drawable-hdpi/handle_middle.png
new file mode 100644
index 0000000..5dcee14
Binary files /dev/null and b/android/experimental/LOAndroid3/res/drawable-hdpi/handle_middle.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/handle_start.png b/android/experimental/LOAndroid3/res/drawable-hdpi/handle_start.png
new file mode 100644
index 0000000..b6a8ce7
Binary files /dev/null and b/android/experimental/LOAndroid3/res/drawable-hdpi/handle_start.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/handle_end.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/handle_end.png
new file mode 100644
index 0000000..c83b7b6
Binary files /dev/null and b/android/experimental/LOAndroid3/res/drawable-xhdpi/handle_end.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/handle_middle.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/handle_middle.png
new file mode 100644
index 0000000..2a1774f
Binary files /dev/null and b/android/experimental/LOAndroid3/res/drawable-xhdpi/handle_middle.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/handle_start.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/handle_start.png
new file mode 100644
index 0000000..9af7654
Binary files /dev/null and b/android/experimental/LOAndroid3/res/drawable-xhdpi/handle_start.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable/handle_end.png b/android/experimental/LOAndroid3/res/drawable/handle_end.png
new file mode 100644
index 0000000..32b77df
Binary files /dev/null and b/android/experimental/LOAndroid3/res/drawable/handle_end.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable/handle_middle.png b/android/experimental/LOAndroid3/res/drawable/handle_middle.png
new file mode 100644
index 0000000..751eb89
Binary files /dev/null and b/android/experimental/LOAndroid3/res/drawable/handle_middle.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable/handle_start.png b/android/experimental/LOAndroid3/res/drawable/handle_start.png
new file mode 100644
index 0000000..cf12a0d
Binary files /dev/null and b/android/experimental/LOAndroid3/res/drawable/handle_start.png differ
diff --git a/android/experimental/LOAndroid3/res/layout/activity_main.xml b/android/experimental/LOAndroid3/res/layout/activity_main.xml
index 1b1bb07..e9a946f 100644
--- a/android/experimental/LOAndroid3/res/layout/activity_main.xml
+++ b/android/experimental/LOAndroid3/res/layout/activity_main.xml
@@ -22,6 +22,9 @@
                 android:id="@+id/layer_view"
                 android:layout_width="fill_parent"
                 android:layout_height="fill_parent"/>
+
+            <include layout="@layout/text_selection_handles"/>
+
         </RelativeLayout>
 
         <RelativeLayout
diff --git a/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml b/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml
new file mode 100644
index 0000000..1f0d816
--- /dev/null
+++ b/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+       xmlns:gecko="http://schemas.android.com/apk/res-auto">
+
+    <org.mozilla.gecko.TextSelectionHandle android:id="@+id/start_handle"
+                                           android:layout_width="@dimen/text_selection_handle_width"
+                                           android:layout_height="@dimen/text_selection_handle_height"
+                                           android:src="@drawable/handle_start"
+                                           android:visibility="gone"
+                                           gecko:handleType="start"/>
+
+    <org.mozilla.gecko.TextSelectionHandle android:id="@+id/middle_handle"
+                                           android:layout_width="@dimen/text_selection_handle_width"
+                                           android:layout_height="@dimen/text_selection_handle_height"
+                                           android:src="@drawable/handle_middle"
+                                           android:visibility="gone"
+                                           gecko:handleType="middle"/>
+
+    <org.mozilla.gecko.TextSelectionHandle android:id="@+id/end_handle"
+                                           android:layout_width="@dimen/text_selection_handle_width"
+                                           android:layout_height="@dimen/text_selection_handle_height"
+                                           android:src="@drawable/handle_end"
+                                           android:visibility="gone"
+                                           gecko:handleType="end"/>
+</merge>
diff --git a/android/experimental/LOAndroid3/res/values/attrs.xml b/android/experimental/LOAndroid3/res/values/attrs.xml
new file mode 100644
index 0000000..ed73978
--- /dev/null
+++ b/android/experimental/LOAndroid3/res/values/attrs.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<resources>
+
+    <declare-styleable name="TextSelectionHandle">
+        <attr name="handleType">
+            <flag name="start" value="0x01"/>
+            <flag name="middle" value="0x02"/>
+            <flag name="end" value="0x03"/>
+        </attr>
+    </declare-styleable>
+
+</resources>
+
diff --git a/android/experimental/LOAndroid3/res/values/dimens.xml b/android/experimental/LOAndroid3/res/values/dimens.xml
index 47c8224..1e5d771 100644
--- a/android/experimental/LOAndroid3/res/values/dimens.xml
+++ b/android/experimental/LOAndroid3/res/values/dimens.xml
@@ -2,4 +2,7 @@
     <!-- Default screen margins, per the Android Design guidelines. -->
     <dimen name="activity_horizontal_margin">16dp</dimen>
     <dimen name="activity_vertical_margin">16dp</dimen>
+    <dimen name="text_selection_handle_width">30dp</dimen>
+    <dimen name="text_selection_handle_height">44dp</dimen>
+    <dimen name="text_selection_handle_shadow">2dp</dimen>
 </resources>
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index c8bcc23..5cb8f31 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -168,8 +168,6 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
 
     private void touch(String touchType, MotionEvent motionEvent, PointF mDocumentTouchCoordinate) {
         LibreOfficeMainActivity.mAppContext.showSoftKeyboard();
-        float x = motionEvent.getX();
-        float y = motionEvent.getY();
         mTileProvider.mouseButtonDown(mDocumentTouchCoordinate);
     }
 
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 3e3412a7..5539450 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -10,6 +10,7 @@ import org.libreoffice.kit.DirectBufferAllocator;
 import org.libreoffice.kit.Document;
 import org.libreoffice.kit.LibreOfficeKit;
 import org.libreoffice.kit.Office;
+import org.mozilla.gecko.TextSelection;
 import org.mozilla.gecko.gfx.BufferedCairoImage;
 import org.mozilla.gecko.gfx.CairoImage;
 import org.mozilla.gecko.gfx.GeckoLayerClient;
@@ -303,6 +304,11 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
     private void mouseButton(int type, PointF inDocument) {
         int x = (int) pixelToTwip(inDocument.x, mDPI);
         int y = (int) pixelToTwip(inDocument.y, mDPI);
+
+        TextSelection textSelection = LibreOfficeMainActivity.mAppContext.getTextSelection();
+        textSelection.positionHandle("MIDDLE", new RectF(inDocument.x, inDocument.y, inDocument.x, inDocument.y));
+        textSelection.showHandle("MIDDLE");
+
         mDocument.postMouseEvent(type, x, y);
     }
 
@@ -376,9 +382,12 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
                 break;
             }
             case Document.CALLBACK_INVALIDATE_VISIBLE_CURSOR: {
+                Log.i(LOGTAG, "Invalidate visible cursor: " + payload);
                 RectF rect = convertCallbackMessageStringToRectF(payload);
                 if (rect != null) {
-                    //tileInvalidationCallback.invalidate(rect);
+                    TextSelection textSelection = LibreOfficeMainActivity.mAppContext.getTextSelection();
+                    textSelection.positionHandle("MIDDLE", rect);
+                    textSelection.showHandle("MIDDLE");
                 }
                 break;
             }
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index bca8230..362fb78 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list