[Libreoffice-commits] core.git: 4 commits - shell/source solenv/gdb sw/qa sw/source vcl/unx

Jan-Marek Glogowski glogow at fbihome.de
Fri Jan 1 19:21:19 PST 2016


 shell/source/backends/kde4be/kde4access.cxx   |   10 +-
 shell/source/backends/kde4be/kde4backend.cxx  |    2 
 solenv/gdb/libreoffice/sw.py                  |   17 ++--
 sw/qa/extras/mailmerge/data/tdf92623.odt      |binary
 sw/qa/extras/mailmerge/mailmerge.cxx          |   51 +++++++++++++
 sw/qa/extras/uiwriter/uiwriter.cxx            |   97 ++++++++++++++++++++++++++
 sw/source/core/txtnode/thints.cxx             |    7 -
 vcl/unx/kde4/KDE4FilePicker.cxx               |   13 +--
 vcl/unx/kde4/KDE4FilePicker.hxx               |    6 -
 vcl/unx/kde4/KDEData.cxx                      |    2 
 vcl/unx/kde4/KDESalFrame.cxx                  |    8 +-
 vcl/unx/kde4/KDESalGraphics.cxx               |   10 +-
 vcl/unx/kde4/KDESalGraphics.hxx               |    2 
 vcl/unx/kde4/KDEXLib.cxx                      |   24 ++----
 vcl/unx/kde4/KDEXLib.hxx                      |    6 -
 vcl/unx/kde4/VCLKDEApplication.cxx            |    4 -
 vcl/unx/kde4/main.cxx                         |    2 
 vcl/unx/kde4/tst_exclude_posted_events.hxx    |    4 -
 vcl/unx/kde4/tst_exclude_socket_notifiers.hxx |    6 -
 19 files changed, 209 insertions(+), 62 deletions(-)

New commits:
commit d9bceb34310f05acce886fe28e9e42433fd488c2
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Dec 11 21:57:02 2015 +0100

    tdf#84263 KDE4: unify includes
    
    Use Qt submodule notation for Qt includes and also "correct"
    some KDE headers AKA use <> notation for external headers.
    
    Change-Id: I9457f75baae56514989800b016a11348a72a242b

diff --git a/shell/source/backends/kde4be/kde4access.cxx b/shell/source/backends/kde4be/kde4access.cxx
index bebb528..5d962b7 100644
--- a/shell/source/backends/kde4be/kde4access.cxx
+++ b/shell/source/backends/kde4be/kde4access.cxx
@@ -19,11 +19,11 @@
 
 #include "sal/config.h"
 
-#include "QFont"
-#include "QString"
-#include "kemailsettings.h"
-#include "kglobalsettings.h"
-#include "kprotocolmanager.h"
+#include <QtGui/QFont>
+#include <QtCore/QString>
+#include <kemailsettings.h>
+#include <kglobalsettings.h>
+#include <kprotocolmanager.h>
 
 #include "com/sun/star/uno/Any.hxx"
 #include "cppu/unotype.hxx"
diff --git a/shell/source/backends/kde4be/kde4backend.cxx b/shell/source/backends/kde4be/kde4backend.cxx
index fadd5ae..d15f2d2 100644
--- a/shell/source/backends/kde4be/kde4backend.cxx
+++ b/shell/source/backends/kde4be/kde4backend.cxx
@@ -19,7 +19,7 @@
 
 #include "sal/config.h"
 
-#include "kapplication.h"
+#include <kapplication.h>
 
 #include "boost/noncopyable.hpp"
 #include "com/sun/star/beans/Optional.hpp"
diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index d1c718d..9aa4817 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -17,6 +17,8 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include "KDE4FilePicker.hxx"
+
 #include <com/sun/star/lang/DisposedException.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <cppuhelper/interfacecontainer.h>
@@ -36,7 +38,6 @@
 
 #include "osl/file.h"
 
-#include "KDE4FilePicker.hxx"
 #include "FPServiceInfo.hxx"
 #include "VCLKDEApplication.hxx"
 
@@ -49,10 +50,10 @@
 #include <kservicetypetrader.h>
 #include <kmessagebox.h>
 
-#include <qclipboard.h>
-#include <QWidget>
-#include <QCheckBox>
-#include <QGridLayout>
+#include <QtGui/QClipboard>
+#include <QtGui/QWidget>
+#include <QtGui/QCheckBox>
+#include <QtGui/QGridLayout>
 
 #undef Region
 
@@ -82,7 +83,7 @@ using namespace ::com::sun::star::uno;
 
 // helper functions
 
-#include <QDebug>
+#include <QtCore/QDebug>
 
 namespace
 {
diff --git a/vcl/unx/kde4/KDE4FilePicker.hxx b/vcl/unx/kde4/KDE4FilePicker.hxx
index 65cb01a..ebc7a60 100644
--- a/vcl/unx/kde4/KDE4FilePicker.hxx
+++ b/vcl/unx/kde4/KDE4FilePicker.hxx
@@ -32,9 +32,9 @@
 
 #include <rtl/ustrbuf.hxx>
 
-#include <QObject>
-#include <QString>
-#include <QHash>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QHash>
 
 class KFileDialog;
 class QWidget;
diff --git a/vcl/unx/kde4/KDEData.cxx b/vcl/unx/kde4/KDEData.cxx
index b180695..71267a0 100644
--- a/vcl/unx/kde4/KDEData.cxx
+++ b/vcl/unx/kde4/KDEData.cxx
@@ -17,7 +17,7 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <QStyle>
+#include <QtGui/QStyle>
 #include <kapplication.h>
 
 #undef Region
diff --git a/vcl/unx/kde4/KDESalFrame.cxx b/vcl/unx/kde4/KDESalFrame.cxx
index 25a401f..d02779a 100644
--- a/vcl/unx/kde4/KDESalFrame.cxx
+++ b/vcl/unx/kde4/KDESalFrame.cxx
@@ -17,8 +17,10 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <QColor>
-#include <QStyle>
+#include <QtGui/QColor>
+#include <QtGui/QStyle>
+#include <QtCore/QDebug>
+#include <QtGui/QToolTip>
 
 #include <kconfig.h>
 #include <kglobal.h>
@@ -27,8 +29,6 @@
 #include <kmainwindow.h>
 #include <kapplication.h>
 #include <ktoolbar.h>
-#include <qdebug.h>
-#include <qtooltip.h>
 
 #undef Region
 
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index b8c98c3..a05f358 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -17,11 +17,11 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <QStyle>
-#include <QStyleOption>
-#include <QPainter>
-#include <QFrame>
-#include <QLabel>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
+#include <QtGui/QPainter>
+#include <QtGui/QFrame>
+#include <QtGui/QLabel>
 
 #include <kapplication.h>
 #include <kdebug.h>
diff --git a/vcl/unx/kde4/KDESalGraphics.hxx b/vcl/unx/kde4/KDESalGraphics.hxx
index b803c60..38dd169 100644
--- a/vcl/unx/kde4/KDESalGraphics.hxx
+++ b/vcl/unx/kde4/KDESalGraphics.hxx
@@ -25,7 +25,7 @@
 #include <unx/saldisp.hxx>
 #include <unx/salgdi.h>
 
-#include <QImage>
+#include <QtGui/QImage>
 
 /** handles graphics drawings requests and performs the needed drawing operations */
 class KDESalGraphics : public X11SalGraphics
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 8060fb5..3ae9745 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -17,8 +17,10 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include "VCLKDEApplication.hxx"
+#include "config_kde4.h"
 
+#include "KDEXLib.hxx"
+#include "VCLKDEApplication.hxx"
 #include "KDESalInstance.hxx"
 
 #include <kapplication.h>
@@ -26,22 +28,18 @@
 #include <kaboutdata.h>
 #include <kcmdlineargs.h>
 #include <kstartupinfo.h>
-#include <qabstracteventdispatcher.h>
-#include <qclipboard.h>
-#include <qthread.h>
 
-#include "KDEXLib.hxx"
-
-#include <unx/i18n_im.hxx>
-#include <unx/i18n_xkb.hxx>
+#include <QtCore/QAbstractEventDispatcher>
+#include <QtGui/QClipboard>
+#include <QtCore/QThread>
 
-#include <unx/saldata.hxx>
-#include <osl/process.h>
+#include "unx/i18n_im.hxx"
+#include "unx/i18n_xkb.hxx"
+#include "unx/saldata.hxx"
+#include "osl/process.h"
 
 #include "KDESalDisplay.hxx"
 
-#include <config_kde4.h>
-
 #if KDE_HAVE_GLIB
 #include "KDE4FilePicker.hxx"
 #include "tst_exclude_socket_notifiers.moc"
@@ -428,7 +426,7 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
 #endif
 }
 
-#include <qframe.h>
+#include <QtGui/QFrame>
 
 int KDEXLib::getFrameWidth()
 {
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index 60a4cd1..f607508 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -25,9 +25,9 @@
 
 #include <fixx11h.h>
 
-#include <qhash.h>
-#include <qsocketnotifier.h>
-#include <qtimer.h>
+#include <QtCore/QHash>
+#include <QtCore/QSocketNotifier>
+#include <QtCore/QTimer>
 
 #include <unx/salinst.h>
 
diff --git a/vcl/unx/kde4/VCLKDEApplication.cxx b/vcl/unx/kde4/VCLKDEApplication.cxx
index 17dcdd6..78181b2 100644
--- a/vcl/unx/kde4/VCLKDEApplication.cxx
+++ b/vcl/unx/kde4/VCLKDEApplication.cxx
@@ -19,8 +19,8 @@
 
 #include "VCLKDEApplication.hxx"
 
-#include <QClipboard>
-#include <QEvent>
+#include <QtGui/QClipboard>
+#include <QtCore/QEvent>
 
 #include "KDESalDisplay.hxx"
 
diff --git a/vcl/unx/kde4/main.cxx b/vcl/unx/kde4/main.cxx
index 3b318eb44..13b0d46 100644
--- a/vcl/unx/kde4/main.cxx
+++ b/vcl/unx/kde4/main.cxx
@@ -17,7 +17,7 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <QApplication>
+#include <QtGui/QApplication>
 
 #include "KDEData.hxx"
 #include "KDESalInstance.hxx"
diff --git a/vcl/unx/kde4/tst_exclude_posted_events.hxx b/vcl/unx/kde4/tst_exclude_posted_events.hxx
index a840523..0830cd5 100644
--- a/vcl/unx/kde4/tst_exclude_posted_events.hxx
+++ b/vcl/unx/kde4/tst_exclude_posted_events.hxx
@@ -21,8 +21,8 @@
 
 #pragma once
 
-#include <qcoreapplication.h>
-#include <qeventloop.h>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QEventLoop>
 
 namespace
 {
diff --git a/vcl/unx/kde4/tst_exclude_socket_notifiers.hxx b/vcl/unx/kde4/tst_exclude_socket_notifiers.hxx
index 3adb956..9df67c2 100644
--- a/vcl/unx/kde4/tst_exclude_socket_notifiers.hxx
+++ b/vcl/unx/kde4/tst_exclude_socket_notifiers.hxx
@@ -21,9 +21,9 @@
 
 #pragma once
 
-#include <qcoreapplication.h>
-#include <qeventloop.h>
-#include <qsocketnotifier.h>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QEventLoop>
+#include <QtCore/QSocketNotifier>
 #include <unistd.h>
 
 namespace
commit 615cd2637a1c7be897ad4b7d86a4495b0720183e
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sat Jan 2 02:09:28 2016 +0100

    GDB: pretty-print more sw::mark::MarkBase classes
    
    Generalize the UnoMark pretty printer to actually print many
    objects inheriting from sw::mark::MarkBase.
    
    Also adds the mark name to the output.
    
    Change-Id: Idaec06ba448702ee3a47b474736df954646c0300

diff --git a/solenv/gdb/libreoffice/sw.py b/solenv/gdb/libreoffice/sw.py
index ddbbb42..8ccdbf4 100644
--- a/solenv/gdb/libreoffice/sw.py
+++ b/solenv/gdb/libreoffice/sw.py
@@ -89,8 +89,8 @@ class SwRectPrinter(object):
         children = [ ( 'point', point), ( 'size', size ) ]
         return children.__iter__()
 
-class SwUnoMarkPrinter(object):
-    '''Prints sw::mark::UnoMark.'''
+class MarkBasePrinter(object):
+    '''Prints sw::mark::MarkBase.'''
 
     def __init__(self, typename, value):
         self.typename = typename
@@ -100,11 +100,9 @@ class SwUnoMarkPrinter(object):
         return "%s" % (self.typename)
 
     def children(self):
-        unoMark = self.value.cast(self.value.dynamic_type)
-        pos1 = unoMark['m_pPos1']
-        pos2 = unoMark['m_pPos2']
-        children = [ ( 'pos1', pos1), ( 'pos2', pos2 ) ]
-        return children.__iter__()
+        m = self.value.cast(self.value.dynamic_type)
+        return [ ( v, m[ v ] )
+            for v in ( 'm_aName', 'm_pPos1', 'm_pPos2' ) ].__iter__()
 
 class SwXTextRangeImplPrinter(object):
     '''Prints SwXTextRange::Impl.'''
@@ -293,7 +291,10 @@ def build_pretty_printers():
     printer.add('SwPaM', SwPaMPrinter)
     printer.add('SwUnoCrsr', SwUnoCrsrPrinter)
     printer.add('SwRect', SwRectPrinter)
-    printer.add('sw::mark::UnoMark', SwUnoMarkPrinter)
+    printer.add('sw::mark::Bookmark', MarkBasePrinter)
+    printer.add('sw::mark::MarkBase', MarkBasePrinter)
+    printer.add('sw::mark::UnoMark', MarkBasePrinter)
+    printer.add('sw::mark::IMark', MarkBasePrinter)
     printer.add('SwXTextRange::Impl', SwXTextRangeImplPrinter)
     printer.add('sw::UnoImplPtr', SwUnoImplPtrPrinter)
     printer.add('SwXTextRange', SwXTextRangePrinter)
commit 480e943f0100154fa82942db092ed1f66b76ef66
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sat Jan 2 02:07:24 2016 +0100

    tdf#92623 MM: add unit test
    
    Adds the missing unit test to the bugfix.
    
    Actually the original bug was a crash, so this just
    does some test on the resulting MM document.
    
    Change-Id: I4c9f031e57157fe5744aa8290b7503b7e1990fc7

diff --git a/sw/qa/extras/mailmerge/data/tdf92623.odt b/sw/qa/extras/mailmerge/data/tdf92623.odt
new file mode 100644
index 0000000..3dea831
Binary files /dev/null and b/sw/qa/extras/mailmerge/data/tdf92623.odt differ
diff --git a/sw/qa/extras/mailmerge/mailmerge.cxx b/sw/qa/extras/mailmerge/mailmerge.cxx
index 992ddd5..f359809 100644
--- a/sw/qa/extras/mailmerge/mailmerge.cxx
+++ b/sw/qa/extras/mailmerge/mailmerge.cxx
@@ -412,5 +412,56 @@ DECLARE_SHELL_MAILMERGE_TEST(testTdf90230, "empty.odt", "10-testing-addresses.od
     executeMailMerge();
 }
 
+DECLARE_SHELL_MAILMERGE_TEST(testTdf92623, "tdf92623.odt", "10-testing-addresses.ods", "testing-addresses")
+{
+    // Copying bookmarks for MM was broken because of the StartOfContent node copy
+    // copyied marks were off by one
+    executeMailMerge();
+
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+    IDocumentMarkAccess const *pIDMA = pTextDoc->GetDocShell()->GetDoc()->getIDocumentMarkAccess();
+    // There is just one mark...
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pIDMA->getAllMarksCount());
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pIDMA->getBookmarksCount());
+    IDocumentMarkAccess::const_iterator_t mark = pIDMA->getAllMarksBegin();
+    // and it's a TEXT_FIELDMARK
+    CPPUNIT_ASSERT_EQUAL( sal_Int32(IDocumentMarkAccess::GetType( **mark )),
+                          sal_Int32(IDocumentMarkAccess::MarkType::TEXT_FIELDMARK ) );
+    sal_uLong src_pos = (*mark)->GetMarkPos().nNode.GetIndex();
+
+    // Get the size of the document in nodes
+    SwDoc *doc = pTextDoc->GetDocShell()->GetDoc();
+    sal_uLong size = doc->GetNodes().GetEndOfContent().GetIndex() - doc->GetNodes().GetEndOfExtras().GetIndex();
+    CPPUNIT_ASSERT_EQUAL( sal_uLong(13), size );
+    size -= 2; // For common start and end nodes
+
+    // Iterate over all field marks in the target document and check that they
+    // are positioned at a multitude of the document size
+    SwXTextDocument* pMMTextDoc = dynamic_cast<SwXTextDocument *>(mxMMComponent.get());
+    CPPUNIT_ASSERT(pMMTextDoc);
+    pIDMA = pMMTextDoc->GetDocShell()->GetDoc()->getIDocumentMarkAccess();
+    // The target document has the duplicated amount of bookmarks
+    // as the helping uno bookmark from the mail merge is left in the doc
+    // TODO should be fixed!
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(20), pIDMA->getAllMarksCount());
+    std::set<sal_uLong> pages;
+    sal_Int32 countFieldMarks = 0;
+    for( mark = pIDMA->getAllMarksBegin(); mark != pIDMA->getAllMarksEnd(); ++mark )
+    {
+        IDocumentMarkAccess::MarkType markType = IDocumentMarkAccess::GetType( **mark );
+        if( markType == IDocumentMarkAccess::MarkType::TEXT_FIELDMARK )
+        {
+            sal_uLong pos = (*mark)->GetMarkPos().nNode.GetIndex() - src_pos;
+            CPPUNIT_ASSERT_EQUAL(sal_uLong(0), pos % size);
+            CPPUNIT_ASSERT(pages.insert(pos).second);
+            countFieldMarks++;
+        }
+        else // see previous TODO
+            CPPUNIT_ASSERT_EQUAL( sal_Int32(markType), sal_Int32(IDocumentMarkAccess::MarkType::UNO_BOOKMARK) );
+    }
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(10), countFieldMarks);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit c91024891ff10c2ae01e11a28a9aecca2f36b6c3
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Wed Dec 30 01:20:23 2015 +0100

    tdf#96479 workaround bookmark end pos handling...
    
    ... when inserting text into a text node.
    
    Seems SwTextNode::InsertText doesn't handle bookmark end
    positions correctly. This is just handled correctly, if it
    also contains the bookmark start.
    
    This workaround simply concats the three strings to be
    inserted in advance, so we just have to call
    SwTextNode::InsertText once for the whole string.
    
    Change-Id: Iab7708b4cc4df406bdbc3a685c7410e0e797fdc4

diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 4ea139e..50a70ee 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -178,6 +178,7 @@ public:
     void testTdf92648();
     void testTdf96515();
     void testTdf96536();
+    void testTdf96479();
 
     CPPUNIT_TEST_SUITE(SwUiWriterTest);
     CPPUNIT_TEST(testReplaceForward);
@@ -262,6 +263,7 @@ public:
     CPPUNIT_TEST(testTdf92648);
     CPPUNIT_TEST(testTdf96515);
     CPPUNIT_TEST(testTdf96536);
+    CPPUNIT_TEST(testTdf96479);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2966,6 +2968,101 @@ void SwUiWriterTest::testTdf96536()
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(276), parseDump("/root/infos/bounds", "height").toInt32());
 }
 
+void SwUiWriterTest::testTdf96479()
+{
+    // We want to verify the empty input text field in the bookmark
+    static const OUString emptyInputTextField =
+        OUString(CH_TXT_ATR_INPUTFIELDSTART) + OUString(CH_TXT_ATR_INPUTFIELDEND);
+
+    SwDoc* pDoc = createDoc();
+    SwXTextDocument *xTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
+    CPPUNIT_ASSERT(xTextDoc);
+
+    // So we can clean up all references for reload
+    {
+        // Append bookmark
+        SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
+        SwPaM aPaM(aIdx);
+        IDocumentMarkAccess &rIDMA = *pDoc->getIDocumentMarkAccess();
+        sw::mark::IMark *pMark =
+            rIDMA.makeMark(aPaM, "original", IDocumentMarkAccess::MarkType::BOOKMARK);
+        CPPUNIT_ASSERT(!pMark->IsExpanded());
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());
+
+        // Get helper objects
+        uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
+        uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+
+        // Create cursor from bookmark
+        uno::Reference<text::XTextContent> xTextContent(xBookmarksSupplier->getBookmarks()->getByName("original"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xTextContent->getAnchor(), uno::UNO_QUERY);
+        uno::Reference<text::XTextCursor> xCursor(xRange->getText()->createTextCursorByRange(xRange), uno::UNO_QUERY);
+        CPPUNIT_ASSERT(xCursor->isCollapsed());
+
+        // Remove bookmark
+        xRange->getText()->removeTextContent(xTextContent);
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rIDMA.getBookmarksCount());
+
+        // Insert replacement bookmark
+        uno::Reference<text::XTextContent> xBookmarkNew(xFactory->createInstance("com.sun.star.text.Bookmark"), uno::UNO_QUERY);
+        uno::Reference<container::XNamed> xBookmarkName(xBookmarkNew, uno::UNO_QUERY);
+        xBookmarkName->setName("replacement");
+        CPPUNIT_ASSERT(xCursor->isCollapsed());
+        // Force bookmark expansion
+        xCursor->getText()->insertString(xCursor, ".", true);
+        xCursor->getText()->insertTextContent(xCursor, xBookmarkNew, true);
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());
+        auto mark = *(rIDMA.getBookmarksBegin());
+        CPPUNIT_ASSERT(mark->IsExpanded());
+
+        // Create and insert input textfield with some content
+        uno::Reference<text::XTextField> xTextField(xFactory->createInstance("com.sun.star.text.TextField.Input"), uno::UNO_QUERY);
+        uno::Reference<text::XTextCursor> xCursorNew(xBookmarkNew->getAnchor()->getText()->createTextCursorByRange(xBookmarkNew->getAnchor()));
+        CPPUNIT_ASSERT(!xCursorNew->isCollapsed());
+        xCursorNew->getText()->insertTextContent(xCursorNew, xTextField, true);
+        xBookmarkNew = uno::Reference<text::XTextContent>(xBookmarksSupplier->getBookmarks()->getByName("replacement"), uno::UNO_QUERY);
+        xCursorNew = uno::Reference<text::XTextCursor>(xBookmarkNew->getAnchor()->getText()->createTextCursorByRange(xBookmarkNew->getAnchor()));
+        CPPUNIT_ASSERT(!xCursorNew->isCollapsed());
+
+        // Can't check the actual content of the text node via UNO
+        mark = *(rIDMA.getBookmarksBegin());
+        CPPUNIT_ASSERT(mark->IsExpanded());
+        SwPaM pam(mark->GetMarkStart(), mark->GetMarkEnd());
+        // Check for the actual bug, which didn't include CH_TXT_ATR_INPUTFIELDEND in the bookmark
+        CPPUNIT_ASSERT_EQUAL(emptyInputTextField, pam.GetText());
+    }
+
+    {
+        // Save and load cycle
+        // Actually not needed, but the bug symptom of a missing bookmark
+        // occured because a broken bookmar was saved and loading silently
+        // dropped the broken bookmark!
+        utl::TempFile aTempFile;
+        save("writer8", aTempFile);
+        loadURL(aTempFile.GetURL(), nullptr);
+        xTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
+        CPPUNIT_ASSERT(xTextDoc);
+        pDoc = xTextDoc->GetDocShell()->GetDoc();
+
+        // Lookup "replacement" bookmark
+        IDocumentMarkAccess &rIDMA = *pDoc->getIDocumentMarkAccess();
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());
+        uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
+        CPPUNIT_ASSERT(xBookmarksSupplier->getBookmarks()->hasByName("replacement"));
+
+        uno::Reference<text::XTextContent> xTextContent(xBookmarksSupplier->getBookmarks()->getByName("replacement"), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> xRange(xTextContent->getAnchor(), uno::UNO_QUERY);
+        uno::Reference<text::XTextCursor> xCursor(xRange->getText()->createTextCursorByRange(xRange), uno::UNO_QUERY);
+        CPPUNIT_ASSERT(!xCursor->isCollapsed());
+
+        // Verify bookmark content via text node / PaM
+        auto mark = *(rIDMA.getBookmarksBegin());
+        CPPUNIT_ASSERT(mark->IsExpanded());
+        SwPaM pam(mark->GetMarkStart(), mark->GetMarkEnd());
+        CPPUNIT_ASSERT_EQUAL(emptyInputTextField, pam.GetText());
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index 986a985..0cbdd5e 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1507,16 +1507,15 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, const SetAttrMode nMode )
                     if( !(SetAttrMode::NOTXTATRCHR & nMode) )
                     {
                         SwIndex aIdx( this, pAttr->GetStart() );
-                        InsertText( OUString(CH_TXT_ATR_INPUTFIELDSTART), aIdx, nInsertFlags );
-                        const OUString aContent = pTextInputField->GetFieldContent();
+                        const OUString aContent = OUString(CH_TXT_ATR_INPUTFIELDSTART)
+                            + pTextInputField->GetFieldContent() + OUString(CH_TXT_ATR_INPUTFIELDEND);
                         InsertText( aContent, aIdx, nInsertFlags );
-                        InsertText( OUString(CH_TXT_ATR_INPUTFIELDEND), aIdx, nInsertFlags );
 
                         sal_Int32* const pEnd(pAttr->GetEnd());
                         OSL_ENSURE( pEnd != nullptr, "<SwTextNode::InsertHint(..)> - missing end of RES_TXTATR_INPUTFIELD!" );
                         if ( pEnd != nullptr )
                         {
-                            *pEnd = *pEnd + 2 + aContent.getLength();
+                            *pEnd = *pEnd + aContent.getLength();
                             nEnd = *pEnd;
                         }
                     }


More information about the Libreoffice-commits mailing list