[Libreoffice-commits] core.git: Branch 'private/jmux/qt5_fixes' - 78 commits - basctl/source basegfx/source bin/find-unneeded-includes chart2/IwyuFilter_chart2.yaml comphelper/source config_host/config_global.h.in configure.ac cui/source dbaccess/qa dbaccess/source dictionaries distro-configs/LibreOfficeLinux.conf distro-configs/LibreOfficeMacOSX.conf distro-configs/LibreOfficeWin32.conf distro-configs/LibreOfficeWin64.conf external/pdfium filter/source helpcontent2 icon-themes/colibre icon-themes/colibre_svg icon-themes/karasa_jaga include/comphelper include/editeng include/filter include/svx include/vcl include/xmloff officecfg/registry sc/CppunitTest_sc_tableconditionalentryobj.mk sc/CppunitTest_sc_tableconditionalformatobj.mk schema/libreoffice sc/inc sc/IwyuFilter_sc.yaml scp2/InstallModule_ooo.mk sc/qa scripting/java sc/sdi sc/source sc/uiconfig sd/IwyuFilter_sd.yaml sd/uiconfig sfx2/source slideshow/source solenv/bin solenv/gbuild svtools/source svx/sdi svx/source svx/uiconfig sw/inc sw/qa sw/source sw/uiconfig translations vcl/inc vcl/qa vcl/qt5 vcl/source vcl/unx vcl/win wizards/source writerfilter/source xmloff/source xmlsecurity/inc xmlsecurity/Library_xsec_xmlsec.mk xmlsecurity/source xmlsecurity/util

Jan-Marek Glogowski glogow at fbihome.de
Fri Jul 6 08:59:36 UTC 2018


Rebased ref, commits from common ancestor:
commit c74e05f6682c237d2b2d589f8833cdad66853b94
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Jul 6 09:44:21 2018 +0200

    loplugin:externandnotdefined + loplugin:unreffun
    
    Change-Id: I364cfdb3b26096d986b651bd3e0673fa3dbf5f83

diff --git a/vcl/qa/cppunit/complextext.cxx b/vcl/qa/cppunit/complextext.cxx
index 97d156d4f8e8..d28d50900eee 100644
--- a/vcl/qa/cppunit/complextext.cxx
+++ b/vcl/qa/cppunit/complextext.cxx
@@ -9,8 +9,8 @@
 
 #include <ostream>
 #include <vector>
-#if !defined(_WIN32)
-std::ostream& operator<<(std::ostream& rStream, const std::vector<long>& rVec);
+#if !defined(_WIN32) && !TEST_FONTS_MISSING
+static std::ostream& operator<<(std::ostream& rStream, const std::vector<long>& rVec);
 #endif
 
 #include <unotest/filters-test.hxx>
@@ -25,8 +25,8 @@ std::ostream& operator<<(std::ostream& rStream, const std::vector<long>& rVec);
 
 #include <config_test.h>
 
-#if !defined(_WIN32)
-std::ostream& operator<<(std::ostream& rStream, const std::vector<long>& rVec)
+#if !defined(_WIN32) && !TEST_FONTS_MISSING
+static std::ostream& operator<<(std::ostream& rStream, const std::vector<long>& rVec)
 {
     rStream << "{ ";
     for (size_t i = 0; i < rVec.size() - 1; i++)
@@ -42,8 +42,10 @@ class VclComplexTextTest : public test::BootstrapFixture
 public:
     VclComplexTextTest() : BootstrapFixture(true, false) {}
 
+#if !TEST_FONTS_MISSING
     /// Play with font measuring etc.
     void testArabic();
+#endif
 #if defined(_WIN32)
     void testTdf95650(); // Windows-only issue
 #endif
commit b3dec406495c5824aad9bdc433f057e9ca171699
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:33:40 2018 +0200

    Qt5 rest
    
    Change-Id: I24b37228321ec38db704c32cd7e5164ad230b695

diff --git a/solenv/bin/create-tags b/solenv/bin/create-tags
index c9fd565b823f..6a6082e72fe8 100755
--- a/solenv/bin/create-tags
+++ b/solenv/bin/create-tags
@@ -11,6 +11,15 @@ ctags="ctags $@"
 saloptions="-ISAL_DELETED_FUNCTION -ISAL_OVERRIDE -ISAL_FINAL"
 omnicppoptions="--c++-kinds=+p --fields=+iaS --extra=+q"
 
+if [ "$1" = "-e" ]; then
+    tagfile="TAGS"
+else
+    tagfile="tags"
+fi
+
+tmpfile=$(mktemp)
+ctags="$ctags -f $tmpfile"
+
 $ctags -h "+.hdl.hrc" --langmap=c:+.hrc.src,c++:+.hdl $saloptions $omnicppoptions \
       --languages=-HTML,Java,JavaScript \
       --langdef=UNOIDL \
@@ -39,3 +48,5 @@ $ctags -h "+.hdl.hrc" --langmap=c:+.hrc.src,c++:+.hdl $saloptions $omnicppoption
       $w/UnoApiHeadersTarget/udkapi/normal \
       $w/UnoApiHeadersTarget/offapi/normal \
       $w/CustomTarget/officecfg/registry
+
+mv "$tmpfile" "$tagfile"
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index c45b678d88a5..bd5a3a50d407 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -446,6 +446,8 @@ void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& /*rSalB
 
     assert(rPosAry.mnSrcWidth == rPosAry.mnDestWidth);
     assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
+
+    assert(false && "Qt5Graphics::drawBitmap");
 }
 
 void Qt5Graphics::drawMask(const SalTwoRect& rPosAry, const SalBitmap& /*rSalBitmap*/,
@@ -457,6 +459,8 @@ void Qt5Graphics::drawMask(const SalTwoRect& rPosAry, const SalBitmap& /*rSalBit
 
     assert(rPosAry.mnSrcWidth == rPosAry.mnDestWidth);
     assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
+
+    assert(false && "Qt5Graphics::drawMask");
 }
 
 std::shared_ptr<SalBitmap> Qt5Graphics::getBitmap(long nX, long nY, long nWidth, long nHeight)
@@ -494,6 +498,7 @@ void Qt5Graphics::invert(long nX, long nY, long nWidth, long nHeight, SalInvert
 
 void Qt5Graphics::invert(sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/, SalInvert /*nFlags*/)
 {
+    assert(false && "Qt5Graphics::invert 2");
 }
 
 bool Qt5Graphics::drawEPS(long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/,
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 92e9a416d74a..65b037db0f67 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -132,6 +132,7 @@ void Qt5Graphics::ClearDevFontCache() {}
 bool Qt5Graphics::AddTempDevFont(PhysicalFontCollection*, const OUString& /*rFileURL*/,
                                  const OUString& /*rFontName*/)
 {
+    assert(false && "Qt5Graphics::AddTempDevFont");
     return false;
 }
 
@@ -148,11 +149,15 @@ const void* Qt5Graphics::GetEmbedFontData(const PhysicalFontFace*, long* /*pData
     return nullptr;
 }
 
-void Qt5Graphics::FreeEmbedFontData(const void* /*pData*/, long /*nDataLen*/) {}
+void Qt5Graphics::FreeEmbedFontData(const void* /*pData*/, long /*nDataLen*/)
+{
+    assert(false && "Qt5Graphics::FreeEmbedFontData");
+}
 
 void Qt5Graphics::GetGlyphWidths(const PhysicalFontFace* /*pPFF*/, bool /*bVertical*/,
                                  std::vector<sal_Int32>& /*rWidths*/, Ucs2UIntMap& /*rUnicodeEnc*/)
 {
+    assert(false && "Qt5Graphics::GetGlyphWidths");
 }
 
 bool Qt5Graphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle& rRect)
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index 318b9ffe116a..a4413defde30 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -199,7 +199,7 @@ bool OutputDevice::GetFontFeatures(std::vector<vcl::font::Feature>& rFontFeature
 FontMetric OutputDevice::GetFontMetric() const
 {
     FontMetric aMetric;
-    if( mbNewFont && !ImplNewFont() )
+    if( !ImplNewFont() )
         return aMetric;
 
     LogicalFontInstance* pFontInstance = mpFontInstance.get();
@@ -262,10 +262,8 @@ bool OutputDevice::GetFontCharMap( FontCharMapRef& rxFontCharMap ) const
     if( !mpGraphics && !AcquireGraphics() )
         return false;
 
-    if( mbNewFont )
-        ImplNewFont();
-    if( mbInitFont )
-        InitFont();
+    ImplNewFont();
+    InitFont();
     if( !mpFontInstance )
         return false;
 
@@ -287,10 +285,8 @@ bool OutputDevice::GetFontCapabilities( vcl::FontCapabilities& rFontCapabilities
     if( !mpGraphics && !AcquireGraphics() )
         return false;
 
-    if( mbNewFont )
-        ImplNewFont();
-    if( mbInitFont )
-        InitFont();
+    ImplNewFont();
+    InitFont();
     if( !mpFontInstance )
         return false;
 
@@ -995,28 +991,25 @@ void OutputDevice::ImplInitFontList() const
 
 void OutputDevice::InitFont() const
 {
-    DBG_TESTSOLARMUTEX();
-
-    if (!mpFontInstance)
+    if (!mpFontInstance || !mbInitFont)
         return;
 
-    if ( mbInitFont )
-    {
-        // decide if antialiasing is appropriate
-        bool bNonAntialiased(GetAntialiasing() & AntialiasingFlags::DisableText);
-        FontSelectPattern aPattern(mpFontInstance->GetFontSelectPattern());
-        if (!utl::ConfigManager::IsFuzzing())
-        {
-            const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
-            bNonAntialiased |= bool(rStyleSettings.GetDisplayOptions() & DisplayOptions::AADisable);
-            bNonAntialiased |= (int(rStyleSettings.GetAntialiasingMinPixelHeight()) > aPattern.mnHeight);
-        }
-        aPattern.mbNonAntialiased = bNonAntialiased;
+    DBG_TESTSOLARMUTEX();
 
-        // select font in the device layers
-        mpGraphics->SetFont(&aPattern, 0);
-        mbInitFont = false;
+    // decide if antialiasing is appropriate
+    bool bNonAntialiased(GetAntialiasing() & AntialiasingFlags::DisableText);
+    FontSelectPattern aPattern(mpFontInstance->GetFontSelectPattern());
+    if (!utl::ConfigManager::IsFuzzing())
+    {
+        const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+        bNonAntialiased |= bool(rStyleSettings.GetDisplayOptions() & DisplayOptions::AADisable);
+        bNonAntialiased |= (int(rStyleSettings.GetAntialiasingMinPixelHeight()) > aPattern.mnHeight);
     }
+    aPattern.mbNonAntialiased = bNonAntialiased;
+
+    // select font in the device layers
+    mpGraphics->SetFont(&aPattern, 0);
+    mbInitFont = false;
 }
 
 bool OutputDevice::ImplNewFont() const
@@ -1055,7 +1048,7 @@ bool OutputDevice::ImplNewFont() const
             aSize.setHeight( 1 );
         else
             aSize.setHeight( (12*mnDPIY)/72 );
-        fExactHeight =  static_cast<float>(aSize.Height());
+        fExactHeight = static_cast<float>(aSize.Height());
     }
 
     // select the default width only when logical width is zero
@@ -1076,8 +1069,9 @@ bool OutputDevice::ImplNewFont() const
         return false;
     }
 
-    // mark when lower layers need to get involved
     mbNewFont = false;
+
+    // mark when lower layers need to get involved
     if( bNewFontInstance )
         mbInitFont = true;
 
@@ -1120,14 +1114,13 @@ bool OutputDevice::ImplNewFont() const
     }
 
     // calculate text offset depending on TextAlignment
-    TextAlign eAlign = maFont.GetAlignment();
-    if ( eAlign == ALIGN_BASELINE )
+    switch (maFont.GetAlignment())
     {
+    case ALIGN_BASELINE:
         mnTextOffX = 0;
         mnTextOffY = 0;
-    }
-    else if ( eAlign == ALIGN_TOP )
-    {
+        break;
+    case ALIGN_TOP:
         mnTextOffX = 0;
         mnTextOffY = +pFontInstance->mxFontMetric->GetAscent() + mnEmphasisAscent;
         if ( pFontInstance->mnOrientation )
@@ -1135,9 +1128,8 @@ bool OutputDevice::ImplNewFont() const
             Point aOriginPt(0, 0);
             aOriginPt.RotateAround( mnTextOffX, mnTextOffY, pFontInstance->mnOrientation );
         }
-    }
-    else // eAlign == ALIGN_BOTTOM
-    {
+        break;
+    case ALIGN_BOTTOM:
         mnTextOffX = 0;
         mnTextOffY = -pFontInstance->mxFontMetric->GetDescent() + mnEmphasisDescent;
         if ( pFontInstance->mnOrientation )
@@ -1145,6 +1137,10 @@ bool OutputDevice::ImplNewFont() const
             Point aOriginPt(0, 0);
             aOriginPt.RotateAround( mnTextOffX, mnTextOffY, pFontInstance->mnOrientation );
         }
+        break;
+    case TextAlign_FORCE_EQUAL_SIZE:
+        assert( false && "TextAlign_FORCE_EQUAL_SIZE not implemented for new fonts" );
+        break;
     }
 
     mbTextLines     = ((maFont.GetUnderline() != LINESTYLE_NONE) && (maFont.GetUnderline() != LINESTYLE_DONTKNOW)) ||
@@ -1427,7 +1423,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_pt
 
 long OutputDevice::GetMinKashida() const
 {
-    if( mbNewFont && !ImplNewFont() )
+    if( !ImplNewFont() )
         return 0;
 
     return ImplDevicePixelToLogicWidth( mpFontInstance->mxFontMetric->GetMinKashida() );
commit dbf206902c270388e3b5a4c07987812e213ffca1
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Thu Mar 1 14:57:58 2018 +0100

    WaE: -Wunused-variable
    
    Change-Id: I58f012ddc2c5030b0e3e215b9cab4e89abf06c2b

diff --git a/vcl/inc/unx/x11_cursors/null_curs.h b/vcl/inc/unx/x11_cursors/null_curs.h
index d74b462cba9b..ebeee4e6ffc5 100644
--- a/vcl/inc/unx/x11_cursors/null_curs.h
+++ b/vcl/inc/unx/x11_cursors/null_curs.h
@@ -20,6 +20,5 @@
 #define nullcurs_height 4
 #define nullcurs_x_hot 2
 #define nullcurs_y_hot 2
-static unsigned char nullcurs_bits[] = { 0x00, 0x00, 0x00, 0x00 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/x11_cursors/null_mask.h b/vcl/inc/unx/x11_cursors/null_mask.h
index bc23e9c9729b..71f08a94afcf 100644
--- a/vcl/inc/unx/x11_cursors/null_mask.h
+++ b/vcl/inc/unx/x11_cursors/null_mask.h
@@ -18,6 +18,5 @@
  */
 #define nullmask_width 4
 #define nullmask_height 4
-static unsigned char nullmask_bits[] = { 0x00, 0x00, 0x00, 0x00 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/app/saldisp.cxx b/vcl/unx/generic/app/saldisp.cxx
index dff49c8e8b7c..ddce3f81da27 100644
--- a/vcl/unx/generic/app/saldisp.cxx
+++ b/vcl/unx/generic/app/saldisp.cxx
@@ -1494,6 +1494,9 @@ KeySym SalDisplay::GetKeySym( XKeyEvent        *pEvent,
 }
 
 // Pointer
+static unsigned char nullmask_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+static unsigned char nullcurs_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+
 #define MAKE_BITMAP( name ) \
     XCreateBitmapFromData( pDisp_, \
                            DefaultRootWindow( pDisp_ ), \
diff --git a/vcl/unx/gtk/gtkdata.cxx b/vcl/unx/gtk/gtkdata.cxx
index 7c9a3d1e0fbc..689fa071ce5b 100644
--- a/vcl/unx/gtk/gtkdata.cxx
+++ b/vcl/unx/gtk/gtkdata.cxx
@@ -245,6 +245,9 @@ GdkCursor* GtkSalDisplay::getFromXBM( const unsigned char *pBitmap,
               &aBlack, &aWhite, nXHot, nYHot);
 }
 
+static unsigned char nullmask_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+static unsigned char nullcurs_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+
 #define MAKE_CURSOR( vcl_name, name ) \
     case vcl_name: \
         pCursor = getFromXBM( name##curs##_bits, name##mask##_bits, \
diff --git a/vcl/unx/gtk3/gtk3gtkdata.cxx b/vcl/unx/gtk3/gtk3gtkdata.cxx
index fd5b47f0b626..024dac2a5014 100644
--- a/vcl/unx/gtk3/gtk3gtkdata.cxx
+++ b/vcl/unx/gtk3/gtk3gtkdata.cxx
@@ -213,7 +213,10 @@ GdkCursor* GtkSalDisplay::getFromXBM( const unsigned char *pBitmap,
     return cursor;
 }
 
-#define MAKE_CURSOR( vcl_name, name ) \
+static unsigned char nullmask_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+static unsigned char nullcurs_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+
+#define MAKE_CURSOR( vcl_name, name )           \
     case vcl_name: \
         pCursor = getFromXBM( name##curs##_bits, name##mask##_bits, \
                               name##curs_width, name##curs_height, \
commit 9a5b1d50806706328404060806bf3ee936b4baaf
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:24:28 2018 +0200

    Qt5 use fontconfig for font substitution
    
    This just shoves all known fonts from the PrintFontManager into
    the QFontDatabase. Can be disabled using SAL_VCL_QT5_NO_FONTCONFIG.
    It already feels slow - don't know.
    
    Running "./bin/run vcldemo --show text" you can see it has some
    pro and cons, regarding the output. Qts' diacrits look definitly
    nicer then the "substitutions". This brings the font support kind
    of on par with the other backends.
    
    And since sensible font substitition is not at all implemented in
    Qt, we have to rely on some platform ssolution anyway. And this
    needs a sensible, platform agnostic interface, so we can reuse the
    code easier.
    
    Change-Id: I4e9d8ee98fc479a7c4bbe4c968116e0a102ebb7a

diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index a9f9175e6d48..c45b678d88a5 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -248,9 +248,31 @@ void Qt5Graphics::drawPolygon(sal_uInt32 nPoints, const SalPoint* pPtAry)
     aPainter.update(aPolygon.boundingRect());
 }
 
-void Qt5Graphics::drawPolyPolygon(sal_uInt32 /*nPoly*/, const sal_uInt32* /*pPoints*/,
-                                  PCONSTSALPOINT* /*pPtAry*/)
+void Qt5Graphics::drawPolyPolygon(sal_uInt32 nPolyCount, const sal_uInt32* pPoints,
+                                  PCONSTSALPOINT* ppPtAry)
 {
+    // ignore invisible polygons
+    if (SALCOLOR_NONE == m_aFillColor && SALCOLOR_NONE == m_aLineColor)
+        return;
+
+    QPainterPath aPath;
+    for (sal_uInt32 nPoly = 0; nPoly < nPolyCount; nPoly++)
+    {
+        const sal_uInt32 nPoints = pPoints[nPoly];
+        if (nPoints > 1)
+        {
+            const SalPoint* pPtAry = ppPtAry[nPoly];
+            aPath.moveTo(pPtAry->mnX, pPtAry->mnY);
+            pPtAry++;
+            for (sal_uInt32 nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++)
+                aPath.lineTo(pPtAry->mnX, pPtAry->mnY);
+            aPath.closeSubpath();
+        }
+    }
+
+    Qt5Painter aPainter(*this, true);
+    aPainter.drawPath(aPath);
+    aPainter.update(aPath.boundingRect());
 }
 
 bool Qt5Graphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency)
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 282432214589..92e9a416d74a 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -23,6 +23,8 @@
 #include <Qt5Painter.hxx>
 
 #include <vcl/fontcharmap.hxx>
+#include <unx/geninst.h>
+#include <unx/fontmanager.hxx>
 
 #include <sallayout.hxx>
 #include <PhysicalFontCollection.hxx>
@@ -89,11 +91,33 @@ bool Qt5Graphics::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities)
 
 void Qt5Graphics::GetDevFontList(PhysicalFontCollection* pPFC)
 {
+    static const bool bUseFontconfig = (nullptr == getenv("SAL_VCL_QT5_NO_FONTCONFIG"));
+
     m_pFontCollection = pPFC;
     if (pPFC->Count())
         return;
 
     QFontDatabase aFDB;
+
+    if (bUseFontconfig)
+    {
+        ::std::vector<psp::fontID> aList;
+        psp::FastPrintFontInfo aInfo;
+
+        psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
+        rMgr.getFontList(aList);
+        for (auto const& elem : aList)
+        {
+            if (!rMgr.getFontFastInfo(elem, aInfo))
+                continue;
+            QString aFilename = toQString(
+                OStringToOUString(rMgr.getFontFileSysPath(aInfo.m_nID), RTL_TEXTENCODING_UTF8));
+            aFDB.addApplicationFont(aFilename);
+        }
+
+        SalGenericInstance::RegisterFontSubstitutors(pPFC);
+    }
+
     for (auto& family : aFDB.families())
         for (auto& style : aFDB.styles(family))
         {
diff --git a/vcl/qt5/Qt5Instance.cxx b/vcl/qt5/Qt5Instance.cxx
index 40c737446c65..6ea2610e03f7 100644
--- a/vcl/qt5/Qt5Instance.cxx
+++ b/vcl/qt5/Qt5Instance.cxx
@@ -283,7 +283,7 @@ VCLPLUG_QT5_PUBLIC SalInstance* create_SalInstance()
 
     QApplication::setQuitOnLastWindowClosed(false);
 
-    const bool bUseCairo = (nullptr != getenv("SAL_VCL_QT5_USE_CAIRO"));
+    static const bool bUseCairo = (nullptr != getenv("SAL_VCL_QT5_USE_CAIRO"));
     Qt5Instance* pInstance = new Qt5Instance(new SalYieldMutex(), bUseCairo);
 
     // initialize SalData
commit 670117dd9659910fe2cbde92356b12ef1ceb8399
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:15:50 2018 +0200

    Qt5 multiple small fixes
    
    * just assert palettes, which are larger then the bitmap support;
      smaller then maximum palettes are ok
    * 1bit images are encoded by the most significant bit (N1BitMsbPal)
      => adapt the alpha mask decoding
    * drawLine update height and width need an additional pixel
    * drawn objects can be filled *and* have an outline
    * show cairo usage in about dialog
    
    Change-Id: I301708386feb3cc1c86b27f47f0e76594a1e7357

diff --git a/vcl/qt5/Qt5Bitmap.cxx b/vcl/qt5/Qt5Bitmap.cxx
index 824bfc28b89a..adc46651fe41 100644
--- a/vcl/qt5/Qt5Bitmap.cxx
+++ b/vcl/qt5/Qt5Bitmap.cxx
@@ -38,11 +38,11 @@ bool Qt5Bitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPale
            && "Unsupported BitCount!");
 
     if (nBitCount == 1)
-        assert(2 == rPal.GetEntryCount());
+        assert(2 >= rPal.GetEntryCount());
     if (nBitCount == 4)
-        assert(16 == rPal.GetEntryCount());
+        assert(16 >= rPal.GetEntryCount());
     if (nBitCount == 8)
-        assert(256 == rPal.GetEntryCount());
+        assert(256 >= rPal.GetEntryCount());
 
     if (nBitCount == 4)
     {
@@ -230,7 +230,7 @@ BitmapBuffer* Qt5Bitmap::AcquireBuffer(BitmapAccessMode /*nMode*/)
     switch (pBuffer->mnBitCount)
     {
         case 1:
-            pBuffer->mnFormat = ScanlineFormat::N1BitLsbPal | ScanlineFormat::TopDown;
+            pBuffer->mnFormat = ScanlineFormat::N1BitMsbPal | ScanlineFormat::TopDown;
             pBuffer->maPalette = m_aPalette;
             break;
         case 4:
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index 146849007035..a9f9175e6d48 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -196,7 +196,7 @@ void Qt5Graphics::drawLine(long nX1, long nY1, long nX2, long nY2)
         nY1 = nY2;
         nY2 = tmp;
     }
-    aPainter.update(nX1, nY1, nX2 - nX1, nY2 - nY1);
+    aPainter.update(nX1, nY1, nX2 - nX1 + 1, nY2 - nY1 + 1);
 }
 
 void Qt5Graphics::drawRect(long nX, long nY, long nWidth, long nHeight)
@@ -207,7 +207,7 @@ void Qt5Graphics::drawRect(long nX, long nY, long nWidth, long nHeight)
     Qt5Painter aPainter(*this, true);
     if (SALCOLOR_NONE != m_aFillColor)
         aPainter.fillRect(nX, nY, nWidth, nHeight, aPainter.brush());
-    else
+    if (SALCOLOR_NONE != m_aLineColor)
         aPainter.drawRect(nX, nY, nWidth, nHeight);
     aPainter.update(nX, nY, nWidth, nHeight);
 }
@@ -527,7 +527,7 @@ static bool getAlphaImage(const SalBitmap& rSourceBitmap, const SalBitmap& rAlph
             {
                 if (x && !(x % 8))
                     ++alpha_line;
-                if (0 == (*alpha_line & (1 << (x % 8))))
+                if (0 != (*alpha_line & (1 << (7 - x % 8))))
                     image_line[3] = 0;
             }
         }
@@ -584,7 +584,7 @@ bool Qt5Graphics::drawAlphaRect(long nX, long nY, long nWidth, long nHeight,
     Qt5Painter aPainter(*this, true, nTransparency);
     if (SALCOLOR_NONE != m_aFillColor)
         aPainter.fillRect(nX, nY, nWidth, nHeight, aPainter.brush());
-    else
+    if (SALCOLOR_NONE != m_aLineColor)
         aPainter.drawRect(nX, nY, nWidth, nHeight);
     aPainter.update(nX, nY, nWidth, nHeight);
     return true;
diff --git a/vcl/qt5/Qt5Instance.cxx b/vcl/qt5/Qt5Instance.cxx
index ef618e18fa7f..40c737446c65 100644
--- a/vcl/qt5/Qt5Instance.cxx
+++ b/vcl/qt5/Qt5Instance.cxx
@@ -50,7 +50,10 @@ Qt5Instance::Qt5Instance(SalYieldMutex* pMutex, bool bUseCairo)
 {
     ImplSVData* pSVData = ImplGetSVData();
     delete pSVData->maAppData.mpToolkitName;
-    pSVData->maAppData.mpToolkitName = new OUString("qt5");
+    if (bUseCairo)
+        pSVData->maAppData.mpToolkitName = new OUString("qt5+cairo");
+    else
+        pSVData->maAppData.mpToolkitName = new OUString("qt5");
 
     m_postUserEventId = QEvent::registerEventType();
 
commit bd39726fe67cad9eb133daf4a8ab8c2b19dddfe1
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:10:27 2018 +0200

    Qt5 implement invert for blinking cursor
    
    The different modes are quite probably not correctly implemented,
    as multiple backends disagree here.
    
    Change-Id: I08fc3096487ca95f4905ae9f0e4b5d3897fca483

diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index 08c620c11796..146849007035 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -444,9 +444,30 @@ std::shared_ptr<SalBitmap> Qt5Graphics::getBitmap(long nX, long nY, long nWidth,
 
 Color Qt5Graphics::getPixel(long nX, long nY) { return m_pQImage->pixel(nX, nY); }
 
-void Qt5Graphics::invert(long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/,
-                         SalInvert /*nFlags*/)
+void Qt5Graphics::invert(long nX, long nY, long nWidth, long nHeight, SalInvert nFlags)
 {
+    Qt5Painter aPainter(*this);
+    if (SalInvert::N50 & nFlags)
+    {
+        aPainter.setCompositionMode(QPainter::RasterOp_SourceXorDestination);
+        aPainter.setBrush(Qt::DiagCrossPattern);
+        aPainter.fillRect(nX, nY, nWidth, nHeight, aPainter.brush());
+    }
+    else
+    {
+        if (SalInvert::TrackFrame & nFlags)
+        {
+            aPainter.setCompositionMode(QPainter::RasterOp_SourceXorDestination);
+            aPainter.setPen(Qt::DashLine);
+            aPainter.drawRect(nX, nY, nWidth, nHeight);
+        }
+        else
+        {
+            aPainter.setCompositionMode(QPainter::RasterOp_SourceXorDestination);
+            aPainter.fillRect(nX, nY, nWidth, nHeight, Qt::white);
+        }
+    }
+    aPainter.update(nX, nY, nWidth, nHeight);
 }
 
 void Qt5Graphics::invert(sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/, SalInvert /*nFlags*/)
commit 30bf6b73178a6cf793cddb9c646560808f5faba7
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:06:54 2018 +0200

    Qt5 implement scaled image draws
    
    If the source and target rects don't match, LO expect the image
    to be scaled.
    
    Change-Id: I337acfa56600eba92c10aed7a70749ad08c03e90

diff --git a/vcl/inc/qt5/Qt5Graphics.hxx b/vcl/inc/qt5/Qt5Graphics.hxx
index 0e9de46818a6..b1ba6ce85d98 100644
--- a/vcl/inc/qt5/Qt5Graphics.hxx
+++ b/vcl/inc/qt5/Qt5Graphics.hxx
@@ -53,6 +53,8 @@ class Qt5Graphics : public SalGraphics
 
     Qt5Graphics(Qt5Frame* pFrame, QImage* pQImage);
 
+    void drawScaledImage(const SalTwoRect& rPosAry, const QImage& rImage);
+
 public:
     Qt5Graphics(Qt5Frame* pFrame)
         : Qt5Graphics(pFrame, nullptr)
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index 971b85f705fe..08c620c11796 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -356,6 +356,15 @@ bool Qt5Graphics::drawPolyLine(const basegfx::B2DPolygon& rPolyLine, double fTra
 
 bool Qt5Graphics::drawGradient(const tools::PolyPolygon&, const Gradient&) { return false; }
 
+void Qt5Graphics::drawScaledImage(const SalTwoRect& rPosAry, const QImage& rImage)
+{
+    Qt5Painter aPainter(*this);
+    QRect aSrcRect(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight);
+    QRect aDestRect(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+    aPainter.drawImage(aDestRect, rImage, aSrcRect);
+    aPainter.update(aDestRect);
+}
+
 void Qt5Graphics::copyArea(long nDestX, long nDestY, long nSrcX, long nSrcY, long nSrcWidth,
                            long nSrcHeight, bool /*bWindowInvalidate*/)
 {
@@ -372,25 +381,21 @@ void Qt5Graphics::copyBits(const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics)
         || rPosAry.mnDestHeight <= 0)
         return;
 
-    assert(rPosAry.mnSrcWidth == rPosAry.mnDestWidth);
-    assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
-
-    QImage aImage, *pImage = &aImage;
+    QImage aImage, *pImage;
+    SalTwoRect aPosAry = rPosAry;
     if (!pSrcGraphics || this == pSrcGraphics)
     {
-        if (rPosAry.mnDestX == rPosAry.mnSrcX && rPosAry.mnDestY == rPosAry.mnSrcY)
-            return;
+        pImage = static_cast<Qt5Graphics*>(this)->m_pQImage;
         aImage
             = pImage->copy(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight);
+        pImage = &aImage;
+        aPosAry.mnSrcX = 0;
+        aPosAry.mnSrcY = 0;
     }
     else
         pImage = static_cast<Qt5Graphics*>(pSrcGraphics)->m_pQImage;
 
-    Qt5Painter aPainter(*this);
-    aPainter.drawImage(
-        QPoint(rPosAry.mnDestX, rPosAry.mnDestY), *pImage,
-        QRect(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
-    aPainter.update(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+    drawScaledImage(aPosAry, *pImage);
 }
 
 void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap)
@@ -399,10 +404,6 @@ void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBit
         || rPosAry.mnDestHeight <= 0)
         return;
 
-    assert(rPosAry.mnSrcWidth == rPosAry.mnDestWidth);
-    assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
-
-    Qt5Painter aPainter(*this);
     Qt5Bitmap aRGBABitmap;
     if (rSalBitmap.GetBitCount() == 4)
         aRGBABitmap.Create(rSalBitmap, 32);
@@ -411,10 +412,7 @@ void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBit
                                : aRGBABitmap.GetQImage();
     assert(pImage);
 
-    aPainter.drawImage(
-        QPoint(rPosAry.mnDestX, rPosAry.mnDestY), *pImage,
-        QRect(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
-    aPainter.update(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+    drawScaledImage(rPosAry, *pImage);
 }
 
 void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& /*rSalBitmap*/,
@@ -523,12 +521,7 @@ bool Qt5Graphics::drawAlphaBitmap(const SalTwoRect& rPosAry, const SalBitmap& rS
     QImage aImage;
     if (!getAlphaImage(rSourceBitmap, rAlphaBitmap, aImage))
         return false;
-
-    Qt5Painter aPainter(*this);
-    aPainter.drawImage(
-        QPoint(rPosAry.mnDestX, rPosAry.mnDestY), aImage,
-        QRect(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
-    aPainter.update(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+    drawScaledImage(rPosAry, aImage);
     return true;
 }
 
commit ef46981023becba0f34a235a3571028dd0ea8838
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 17:45:14 2018 +0200

    Qt5 implement 4bit => 32bit bitmap conversion
    
    Some of the PNG icons are 4bit palette based PNG images.
    This implements the conversation function for the most
    common 4bit case, so we don't rely on some generic handling.
    
    All other non-4bit conversions can be handled by Qt.
    
    Change-Id: I4ddd744fb7166fc3a6992b6be6c250c2adb99ca5

diff --git a/vcl/inc/qt5/Qt5Bitmap.hxx b/vcl/inc/qt5/Qt5Bitmap.hxx
index 6ecdebed5ca1..c89038a28fb7 100644
--- a/vcl/inc/qt5/Qt5Bitmap.hxx
+++ b/vcl/inc/qt5/Qt5Bitmap.hxx
@@ -31,7 +31,7 @@ class VCL_DLLPUBLIC Qt5Bitmap : public SalBitmap
     BitmapPalette m_aPalette;
 
     // for 4bit support
-    std::unique_ptr<sal_uInt8> m_pBuffer;
+    std::unique_ptr<sal_uInt8[]> m_pBuffer;
     Size m_aSize;
     sal_uInt32 m_nScanline;
 
diff --git a/vcl/qt5/Qt5Bitmap.cxx b/vcl/qt5/Qt5Bitmap.cxx
index ff44143a16f2..824bfc28b89a 100644
--- a/vcl/qt5/Qt5Bitmap.cxx
+++ b/vcl/qt5/Qt5Bitmap.cxx
@@ -48,8 +48,17 @@ bool Qt5Bitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPale
     {
         m_pImage.reset();
         m_aSize = rSize;
-        m_nScanline = rSize.Width() / 2 + (rSize.Width() % 2) ? 0 : 1;
-        m_pBuffer.reset(new sal_uInt8[m_nScanline * rSize.Height()]);
+        bool bFail = o3tl::checked_multiply<sal_uInt32>(rSize.Width(), nBitCount, m_nScanline);
+        if (bFail)
+        {
+            SAL_WARN("vcl.gdi", "checked multiply failed");
+            return false;
+        }
+        m_nScanline = AlignedWidth4Bytes(m_nScanline);
+        sal_uInt8* pBuffer = nullptr;
+        if (0 != m_nScanline && 0 != rSize.Height())
+            pBuffer = new sal_uInt8[m_nScanline * rSize.Height()];
+        m_pBuffer.reset(pBuffer);
     }
     else
     {
@@ -59,7 +68,7 @@ bool Qt5Bitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPale
     m_aPalette = rPal;
 
     auto count = rPal.GetEntryCount();
-    if (nBitCount != 4 && count)
+    if (nBitCount != 4 && count && m_pImage.get())
     {
         QVector<QRgb> aColorTable(count);
         for (unsigned i = 0; i < count; ++i)
@@ -81,8 +90,14 @@ bool Qt5Bitmap::Create(const SalBitmap& rSalBmp)
     {
         m_aSize = pBitmap->m_aSize;
         m_nScanline = pBitmap->m_nScanline;
-        m_pBuffer.reset(new sal_uInt8[m_nScanline * m_aSize.Height()]);
-        memcpy(m_pBuffer.get(), pBitmap->m_pBuffer.get(), m_nScanline);
+        sal_uInt8* pBuffer = nullptr;
+        if (0 != m_nScanline && 0 != m_aSize.Height())
+        {
+            sal_uInt32 nSize = m_nScanline * m_aSize.Height();
+            pBuffer = new sal_uInt8[nSize];
+            memcpy(pBuffer, pBitmap->m_pBuffer.get(), nSize);
+        }
+        m_pBuffer.reset(pBuffer);
         m_pImage.reset();
     }
     m_aPalette = pBitmap->m_aPalette;
@@ -107,9 +122,52 @@ bool Qt5Bitmap::Create(const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount)
 
     const Qt5Bitmap* pBitmap = static_cast<const Qt5Bitmap*>(&rSalBmp);
     if (pBitmap->m_pBuffer.get())
-        return false;
+    {
+        if (nNewBitCount != 32)
+            return false;
+
+        // convert 4bit indexed palette to 32bit ARGB
+        m_pImage.reset(new QImage(pBitmap->m_aSize.Width(), pBitmap->m_aSize.Height(),
+                                  getBitFormat(nNewBitCount)));
+        m_pImage->fill(0);
+
+        // prepare a whole palette
+        const BitmapPalette& rPal = pBitmap->m_aPalette;
+        QVector<QRgb> colorTable(16);
+        int i = 0, maxEntry = pBitmap->m_aPalette.GetEntryCount();
+        assert(maxEntry <= 16 && maxEntry >= 0);
+        for (; i < maxEntry; ++i)
+            colorTable[i] = qRgb(rPal[i].GetRed(), rPal[i].GetGreen(), rPal[i].GetBlue());
+        for (; i < 16; ++i)
+            colorTable[i] = qRgb(0, 0, 0);
 
-    m_pImage.reset(new QImage(pBitmap->m_pImage->convertToFormat(getBitFormat(nNewBitCount))));
+        sal_uInt32* image_data = reinterpret_cast<sal_uInt32*>(m_pImage->bits());
+        sal_uInt8* buffer_data_pos = pBitmap->m_pBuffer.get();
+        sal_uInt32 nWidth = pBitmap->m_aSize.Height() / 2;
+        bool isOdd(0 != pBitmap->m_aSize.Height() % 2);
+
+        for (sal_uInt32 h = 0; h < pBitmap->m_aSize.Height(); ++h)
+        {
+            sal_uInt8* buffer_data = buffer_data_pos;
+            buffer_data_pos += pBitmap->m_nScanline;
+            for (sal_uInt32 w = 0; w < nWidth; ++w)
+            {
+                *image_data = reinterpret_cast<sal_uInt32>(colorTable.at(*buffer_data >> 4));
+                ++image_data;
+                *image_data = reinterpret_cast<sal_uInt32>(colorTable.at(*buffer_data & 0xF));
+                ++image_data;
+                ++buffer_data;
+            }
+            if (isOdd)
+            {
+                *image_data = reinterpret_cast<sal_uInt32>(colorTable.at(*buffer_data >> 4));
+                ++image_data;
+            }
+        }
+    }
+    else
+        m_pImage.reset(new QImage(pBitmap->m_pImage->convertToFormat(getBitFormat(nNewBitCount))));
+    m_pBuffer.reset();
     return true;
 }
 
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index b58f18e4b59b..971b85f705fe 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -403,8 +403,12 @@ void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBit
     assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
 
     Qt5Painter aPainter(*this);
-
-    const QImage* pImage = static_cast<const Qt5Bitmap*>(&rSalBitmap)->GetQImage();
+    Qt5Bitmap aRGBABitmap;
+    if (rSalBitmap.GetBitCount() == 4)
+        aRGBABitmap.Create(rSalBitmap, 32);
+    const QImage* pImage = (rSalBitmap.GetBitCount() != 4)
+                               ? static_cast<const Qt5Bitmap*>(&rSalBitmap)->GetQImage()
+                               : aRGBABitmap.GetQImage();
     assert(pImage);
 
     aPainter.drawImage(
@@ -475,7 +479,12 @@ static bool getAlphaImage(const SalBitmap& rSourceBitmap, const SalBitmap& rAlph
         return false;
     }
 
-    const QImage* pBitmap = static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage();
+    Qt5Bitmap aRGBABitmap;
+    if (rSourceBitmap.GetBitCount() == 4)
+        aRGBABitmap.Create(rSourceBitmap, 32);
+    const QImage* pBitmap = (rSourceBitmap.GetBitCount() != 4)
+                                ? static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage()
+                                : aRGBABitmap.GetQImage();
     const QImage* pAlpha = static_cast<const Qt5Bitmap*>(&rAlphaBitmap)->GetQImage();
     rAlphaImage = pBitmap->convertToFormat(Qt5_DefaultFormat32);
 
@@ -532,7 +541,12 @@ bool Qt5Graphics::drawTransformedBitmap(const basegfx::B2DPoint& rNull, const ba
         return false;
     else
     {
-        const QImage* pBitmap = static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage();
+        Qt5Bitmap aRGBABitmap;
+        if (rSourceBitmap.GetBitCount() == 4)
+            aRGBABitmap.Create(rSourceBitmap, 32);
+        const QImage* pBitmap = (rSourceBitmap.GetBitCount() != 4)
+                                    ? static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage()
+                                    : aRGBABitmap.GetQImage();
         aImage = pBitmap->convertToFormat(Qt5_DefaultFormat32);
     }
 
commit ebd1d973eac7ef6f330634a2d2a8ca1bf3c6720e
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:38:07 2018 +0200

    Qt5 flesh out font handling
    
    Fills some more FontAttributes based on the QFont.
    Also implements initial font rotation support.
    
    Something is still strage with the vertical font in Writers
    vertical ruler. Text looks correct in vertical text boxes FWIW.
    
    The toRectangle bug is embarrassing; I was wondering for quite
    some time, which glyphs had strange size rects :-)
    
    While at it, move the Qt5Font header to vcl/inc/qt5.
    
    Change-Id: I67fa400486981035be6f98c5ab56e82d69c42065

diff --git a/vcl/qt5/Qt5Font.hxx b/vcl/inc/qt5/Qt5Font.hxx
similarity index 100%
rename from vcl/qt5/Qt5Font.hxx
rename to vcl/inc/qt5/Qt5Font.hxx
diff --git a/vcl/inc/qt5/Qt5FontFace.hxx b/vcl/inc/qt5/Qt5FontFace.hxx
index 3c94f46777e1..c653b4be6f6e 100644
--- a/vcl/inc/qt5/Qt5FontFace.hxx
+++ b/vcl/inc/qt5/Qt5FontFace.hxx
@@ -37,6 +37,7 @@ public:
     virtual ~Qt5FontFace() override;
 
     static Qt5FontFace* fromQFont(const QFont& rFont);
+    static void fillAttributesFromQFont(const QFont& rFont, FontAttributes& rFA);
 
     sal_IntPtr GetFontId() const override;
 
diff --git a/vcl/inc/qt5/Qt5Tools.hxx b/vcl/inc/qt5/Qt5Tools.hxx
index f075468ca3d3..c919b401e191 100644
--- a/vcl/inc/qt5/Qt5Tools.hxx
+++ b/vcl/inc/qt5/Qt5Tools.hxx
@@ -49,7 +49,7 @@ inline QRect toQRect(const tools::Rectangle& rRect)
 
 inline tools::Rectangle toRectangle(const QRect& rRect)
 {
-    return tools::Rectangle(rRect.left(), rRect.top(), rRect.width(), rRect.height());
+    return tools::Rectangle(rRect.left(), rRect.top(), rRect.right(), rRect.bottom());
 }
 
 inline QSize toQSize(const Size& rSize) { return QSize(rSize.Width(), rSize.Height()); }
diff --git a/vcl/qt5/Qt5Font.cxx b/vcl/qt5/Qt5Font.cxx
index 0164c3b13cd4..dc393dd1cae8 100644
--- a/vcl/qt5/Qt5Font.cxx
+++ b/vcl/qt5/Qt5Font.cxx
@@ -17,14 +17,65 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include "Qt5Font.hxx"
+#include <Qt5Font.hxx>
+#include <Qt5Tools.hxx>
 
 #include <QtGui/QFont>
 #include <QtGui/QRawFont>
 
+static QFont::Weight GetQFontWeight(FontWeight eWeight)
+{
+    switch (eWeight)
+    {
+        case WEIGHT_THIN:
+            return QFont::Thin;
+        case WEIGHT_ULTRALIGHT:
+            return QFont::ExtraLight;
+        case WEIGHT_LIGHT:
+            return QFont::Light;
+        case FontWeight_FORCE_EQUAL_SIZE:
+            assert(false && "FontWeight_FORCE_EQUAL_SIZE not implementable for QFont");
+        case WEIGHT_SEMILIGHT:
+        case WEIGHT_DONTKNOW:
+        case WEIGHT_NORMAL:
+            return QFont::Normal;
+        case WEIGHT_MEDIUM:
+            return QFont::Medium;
+        case WEIGHT_SEMIBOLD:
+            return QFont::DemiBold;
+        case WEIGHT_BOLD:
+            return QFont::Bold;
+        case WEIGHT_ULTRABOLD:
+            return QFont::ExtraBold;
+        case WEIGHT_BLACK:
+            return QFont::Black;
+    }
+
+    // so we would get enum not handled warning
+    return QFont::Normal;
+}
+
 Qt5Font::Qt5Font(const PhysicalFontFace& rPFF, const FontSelectPattern& rFSP)
     : LogicalFontInstance(rPFF, rFSP)
 {
+    setFamily(toQString(rPFF.GetFamilyName()));
+    setWeight(GetQFontWeight(rPFF.GetWeight()));
+    setPixelSize(rFSP.mnHeight);
+    switch (rFSP.GetItalic())
+    {
+        case ITALIC_DONTKNOW:
+        case FontItalic_FORCE_EQUAL_SIZE:
+            break;
+        case ITALIC_NONE:
+            setStyle(Style::StyleNormal);
+            break;
+        case ITALIC_OBLIQUE:
+            setStyle(Style::StyleOblique);
+            break;
+        case ITALIC_NORMAL:
+            setStyle(Style::StyleItalic);
+            break;
+    }
 }
 
 Qt5Font::~Qt5Font() {}
diff --git a/vcl/qt5/Qt5FontFace.cxx b/vcl/qt5/Qt5FontFace.cxx
index 043a9b6e798b..10f79aa559bd 100644
--- a/vcl/qt5/Qt5FontFace.cxx
+++ b/vcl/qt5/Qt5FontFace.cxx
@@ -18,7 +18,7 @@
  */
 
 #include <Qt5FontFace.hxx>
-#include "Qt5Font.hxx"
+#include <Qt5Font.hxx>
 #include <Qt5Tools.hxx>
 
 #include <sft.hxx>
@@ -41,13 +41,67 @@ Qt5FontFace::Qt5FontFace(const Qt5FontFace& rSrc)
         m_xCharMap = rSrc.m_xCharMap;
 }
 
+void Qt5FontFace::fillAttributesFromQFont(const QFont& rFont, FontAttributes& rFA)
+{
+    QFontInfo aFontInfo(rFont);
+
+    rFA.SetFamilyName(toOUString(aFontInfo.family()));
+    if (IsStarSymbol(toOUString(aFontInfo.family())))
+        rFA.SetSymbolFlag(true);
+    rFA.SetStyleName(toOUString(aFontInfo.styleName()));
+    rFA.SetPitch(aFontInfo.fixedPitch() ? PITCH_FIXED : PITCH_VARIABLE);
+
+    FontWeight eWeight = WEIGHT_DONTKNOW;
+    switch (aFontInfo.weight())
+    {
+        case QFont::Thin:
+            eWeight = WEIGHT_THIN;
+            break;
+        case QFont::ExtraLight:
+            eWeight = WEIGHT_ULTRALIGHT;
+            break;
+        case QFont::Light:
+            eWeight = WEIGHT_LIGHT;
+            break;
+        case QFont::Normal:
+            eWeight = WEIGHT_NORMAL;
+            break;
+        case QFont::Medium:
+            eWeight = WEIGHT_MEDIUM;
+            break;
+        case QFont::DemiBold:
+            eWeight = WEIGHT_SEMIBOLD;
+            break;
+        case QFont::Bold:
+            eWeight = WEIGHT_BOLD;
+            break;
+        case QFont::ExtraBold:
+            eWeight = WEIGHT_ULTRABOLD;
+            break;
+        case QFont::Black:
+            eWeight = WEIGHT_BLACK;
+            break;
+    }
+    rFA.SetWeight(eWeight);
+
+    switch (aFontInfo.style())
+    {
+        case QFont::StyleNormal:
+            rFA.SetItalic(ITALIC_NONE);
+            break;
+        case QFont::StyleItalic:
+            rFA.SetItalic(ITALIC_NORMAL);
+            break;
+        case QFont::StyleOblique:
+            rFA.SetItalic(ITALIC_OBLIQUE);
+            break;
+    }
+}
+
 Qt5FontFace* Qt5FontFace::fromQFont(const QFont& rFont)
 {
     FontAttributes aFA;
-    aFA.SetFamilyName(toOUString(rFont.family()));
-    aFA.SetStyleName(toOUString(rFont.styleName()));
-    aFA.SetItalic(rFont.italic() ? ITALIC_NORMAL : ITALIC_NONE);
-
+    fillAttributesFromQFont(rFont, aFA);
     return new Qt5FontFace(aFA, rFont.toString());
 }
 
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index cb7bef853ba8..282432214589 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -19,7 +19,7 @@
 
 #include <Qt5Graphics.hxx>
 #include <Qt5FontFace.hxx>
-#include "Qt5Font.hxx"
+#include <Qt5Font.hxx>
 #include <Qt5Painter.hxx>
 
 #include <vcl/fontcharmap.hxx>
@@ -56,6 +56,7 @@ void Qt5Graphics::SetFont(const FontSelectPattern* pReqFont, int nFallbackLevel)
 void Qt5Graphics::GetFontMetric(ImplFontMetricDataRef& rFMD, int nFallbackLevel)
 {
     QRawFont aRawFont(QRawFont::fromFont(*m_pTextStyle[nFallbackLevel]));
+    Qt5FontFace::fillAttributesFromQFont(*m_pTextStyle[nFallbackLevel], *rFMD);
 
     QByteArray aHheaTable = aRawFont.fontTable("hhea");
     std::vector<uint8_t> rHhea(aHheaTable.data(), aHheaTable.data() + aHheaTable.size());
@@ -65,6 +66,7 @@ void Qt5Graphics::GetFontMetric(ImplFontMetricDataRef& rFMD, int nFallbackLevel)
 
     rFMD->ImplCalcLineSpacing(rHhea, rOS2, aRawFont.unitsPerEm());
 
+    rFMD->SetSlant(0);
     rFMD->SetWidth(aRawFont.averageCharWidth());
 
     rFMD->SetMinKashida(m_pTextStyle[nFallbackLevel]->GetKashidaWidth());
@@ -146,10 +148,21 @@ bool Qt5Graphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle& r
 
 bool Qt5Graphics::GetGlyphOutline(const GlyphItem&, basegfx::B2DPolyPolygon&) { return false; }
 
+class Qt5CommonSalLayout : public GenericSalLayout
+{
+public:
+    Qt5CommonSalLayout(LogicalFontInstance& rLFI)
+        : GenericSalLayout(rLFI)
+    {
+    }
+
+    void SetOrientation(int nOrientation) { mnOrientation = nOrientation; }
+};
+
 std::unique_ptr<SalLayout> Qt5Graphics::GetTextLayout(ImplLayoutArgs&, int nFallbackLevel)
 {
     if (m_pTextStyle[nFallbackLevel])
-        return std::unique_ptr<SalLayout>(new GenericSalLayout(*m_pTextStyle[nFallbackLevel]));
+        return std::unique_ptr<SalLayout>(new Qt5CommonSalLayout(*m_pTextStyle[nFallbackLevel]));
     return std::unique_ptr<SalLayout>();
 }
 
@@ -162,6 +175,14 @@ void Qt5Graphics::DrawTextLayout(const GenericSalLayout& rLayout)
     QVector<quint32> glyphIndexes;
     QVector<QPointF> positions;
 
+    // prevent glyph rotation inside the SalLayout
+    // probably better to add a parameter to GetNextGlyphs?
+    Qt5CommonSalLayout* pQt5Layout
+        = static_cast<Qt5CommonSalLayout*>(const_cast<GenericSalLayout*>(&rLayout));
+    int nOrientation = rLayout.GetOrientation();
+    if (nOrientation)
+        pQt5Layout->SetOrientation(0);
+
     Point aPos;
     const GlyphItem* pGlyph;
     int nStart = 0;
@@ -171,6 +192,9 @@ void Qt5Graphics::DrawTextLayout(const GenericSalLayout& rLayout)
         positions.push_back(QPointF(aPos.X(), aPos.Y()));
     }
 
+    if (nOrientation)
+        pQt5Layout->SetOrientation(nOrientation);
+
     QGlyphRun aGlyphRun;
     aGlyphRun.setPositions(positions);
     aGlyphRun.setGlyphIndexes(glyphIndexes);
@@ -179,6 +203,21 @@ void Qt5Graphics::DrawTextLayout(const GenericSalLayout& rLayout)
     Qt5Painter aPainter(*this);
     QColor aColor = toQColor(m_aTextColor);
     aPainter.setPen(aColor);
+
+    if (nOrientation)
+    {
+        // make text position the center of the rotation
+        // then rotate and move back
+        QRect window = aPainter.window();
+        window.moveTo(-positions[0].x(), -positions[0].y());
+        aPainter.setWindow(window);
+
+        QTransform p;
+        p.rotate(-static_cast<qreal>(nOrientation) / 10.0);
+        p.translate(-positions[0].x(), -positions[0].y());
+        aPainter.setTransform(p);
+    }
+
     aPainter.drawGlyphRun(QPointF(), aGlyphRun);
 }
 
commit d4125bd04bd58972594510bf6ab5614693e25833
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:30:34 2018 +0200

    Add ostream::operator<< for SalTwoRect
    
    Change-Id: I4466ebb154acd8046927db6b945b04c85095b87e

diff --git a/include/vcl/salgtype.hxx b/include/vcl/salgtype.hxx
index 0e37300f3dbd..d920ede00dac 100644
--- a/include/vcl/salgtype.hxx
+++ b/include/vcl/salgtype.hxx
@@ -23,6 +23,8 @@
 #include <sal/types.h>
 #include <o3tl/typed_flags_set.hxx>
 #include <tools/color.hxx>
+#include <tools/gen.hxx>
+#include <ostream>
 
 enum class DeviceFormat {
                             NONE = -1,
@@ -63,6 +65,19 @@ struct SalTwoRect
     }
 };
 
+template <typename charT, typename traits>
+inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
+                                                     const SalTwoRect& rPosAry)
+{
+    tools::Rectangle aSrcRect(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcX + rPosAry.mnSrcWidth,
+                              rPosAry.mnSrcY + rPosAry.mnSrcHeight);
+    tools::Rectangle aDestRect(rPosAry.mnDestX, rPosAry.mnDestY,
+                               rPosAry.mnDestX + rPosAry.mnDestWidth,
+                               rPosAry.mnDestY + rPosAry.mnDestHeight);
+    stream << aSrcRect << " => " << aDestRect;
+    return stream;
+}
+
 enum class SalROPColor {
     N0, N1, Invert
 };
commit e2320955b32595df09c9c4412ccec56a0b273df7
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:37:35 2018 +0200

    Some cleanup and comments
    
    Change-Id: Ic1dda9b0e5d7896703b65d0d43be340196bcb871

diff --git a/basctl/source/basicide/baside2b.cxx b/basctl/source/basicide/baside2b.cxx
index 6b97f30409e7..ae2fb1086d7f 100644
--- a/basctl/source/basicide/baside2b.cxx
+++ b/basctl/source/basicide/baside2b.cxx
@@ -963,6 +963,7 @@ void EditorWindow::CreateEditEngine()
     ImplSetFont();
 
     aSyntaxIdle.SetInvokeHandler( LINK( this, EditorWindow, SyntaxTimerHdl ) );
+    aSyntaxIdle.SetDebugName( "basctl EditorWindow aSyntaxIdle" );
 
     bool bWasDoSyntaxHighlight = bDoSyntaxHighlight;
     bDoSyntaxHighlight = false; // too slow for large texts...
diff --git a/sfx2/source/appl/appdispatchprovider.cxx b/sfx2/source/appl/appdispatchprovider.cxx
index a13cb5312bf6..d13a9009ee0e 100644
--- a/sfx2/source/appl/appdispatchprovider.cxx
+++ b/sfx2/source/appl/appdispatchprovider.cxx
@@ -129,7 +129,10 @@ Reference < XDispatch > SAL_CALL SfxAppDispatchProvider::queryDispatch(
     bool                bMasterCommand( false );
     Reference < XDispatch > xDisp;
     const SfxSlot* pSlot = nullptr;
-    SfxDispatcher* pAppDisp = SfxGetpApp()->GetAppDispatcher_Impl();
+    SfxApplication* pApp = SfxGetpApp();
+    if ( !pApp )
+        return xDisp;
+    SfxDispatcher* pAppDisp = pApp->GetAppDispatcher_Impl();
     if ( aURL.Protocol == "slot:" || aURL.Protocol == "commandId:" )
     {
         nId = static_cast<sal_uInt16>(aURL.Path.toInt32());
diff --git a/vcl/inc/fontselect.hxx b/vcl/inc/fontselect.hxx
index efb88ad74ae1..fd453a0d5f54 100644
--- a/vcl/inc/fontselect.hxx
+++ b/vcl/inc/fontselect.hxx
@@ -59,7 +59,7 @@ public:
     int             mnWidth;                    // width of font in pixel units
     int             mnHeight;                   // height of font in pixel units
     float           mfExactHeight;              // requested height (in pixels with subpixel details)
-    int             mnOrientation;              // text orientation in 3600 system
+    int             mnOrientation;              // text orientation in 1/10 degree (0-3600)
     LanguageType    meLanguage;                 // text language
     bool            mbVertical;                 // vertical mode of requested font
     bool            mbNonAntialiased;           // true if antialiasing is disabled
diff --git a/vcl/source/font/fontcache.cxx b/vcl/source/font/fontcache.cxx
index a58d9b6931f2..333bc8415c08 100644
--- a/vcl/source/font/fontcache.cxx
+++ b/vcl/source/font/fontcache.cxx
@@ -48,7 +48,7 @@ bool ImplFontCache::IFSD_Equal::operator()(const FontSelectPattern& rA, const Fo
         return false;
 
     // check font face attributes
-    if( (rA.GetWeight()       != rB.GetWeight())
+    if( (rA.GetWeight()    != rB.GetWeight())
     ||  (rA.GetItalic()    != rB.GetItalic())
 //  ||  (rA.meFamily       != rB.meFamily) // TODO: remove this mostly obsolete member
     ||  (rA.GetPitch()     != rB.GetPitch()) )
commit df8589bd49d7eb1bb42ae78abcb91d33cf9255ce
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Thu Jul 5 15:01:31 2018 +0200

    loplugin:useuniqueptr in XclExpObjList
    
    Change-Id: Ia7f2be93d6306d72773ab611de2945c8a711a2d9
    Reviewed-on: https://gerrit.libreoffice.org/57010
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx
index 61daa9295ee6..49988ed954a6 100644
--- a/sc/source/filter/excel/excrecds.cxx
+++ b/sc/source/filter/excel/excrecds.cxx
@@ -1013,8 +1013,8 @@ void ExcAutoFilterRecs::AddObjRecs()
         ScAddress aAddr( m_pFilterInfo->GetStartPos() );
         for( SCCOL nObj = 0, nCount = m_pFilterInfo->GetColCount(); nObj < nCount; nObj++ )
         {
-            XclObj* pObjRec = new XclObjDropDown( GetObjectManager(), aAddr, IsFiltered( nObj ) );
-            GetObjectManager().AddObj( pObjRec );
+            std::unique_ptr<XclObj> pObjRec(new XclObjDropDown( GetObjectManager(), aAddr, IsFiltered( nObj ) ));
+            GetObjectManager().AddObj( std::move(pObjRec) );
             aAddr.IncCol();
         }
     }
diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx
index c2e9aba3b175..971eb25998f6 100644
--- a/sc/source/filter/excel/xeescher.cxx
+++ b/sc/source/filter/excel/xeescher.cxx
@@ -39,6 +39,7 @@
 #include <svx/svdocapt.hxx>
 #include <editeng/outlobj.hxx>
 #include <editeng/editobj.hxx>
+#include <o3tl/make_unique.hxx>
 #include <unotools/tempfile.hxx>
 #include <unotools/ucbstreamhelper.hxx>
 #include <svtools/embedhlp.hxx>
@@ -1200,7 +1201,7 @@ XclExpNote::XclExpNote(const XclExpRoot& rRoot, const ScAddress& rScPos,
                 {
                     lcl_GetFromTo( rRoot, pCaption->GetLogicRect(), maScPos.Tab(), maCommentFrom, maCommentTo );
                     if( const OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
-                        mnObjId = rRoot.GetObjectManager().AddObj( new XclObjComment( rRoot.GetObjectManager(), pCaption->GetLogicRect(), pOPO->GetTextObject(), pCaption, mbVisible, maScPos, maCommentFrom, maCommentTo ) );
+                        mnObjId = rRoot.GetObjectManager().AddObj( o3tl::make_unique<XclObjComment>( rRoot.GetObjectManager(), pCaption->GetLogicRect(), pOPO->GetTextObject(), pCaption, mbVisible, maScPos, maCommentFrom, maCommentTo ) );
 
                     SfxItemSet aItemSet = pCaption->GetMergedItemSet();
                     meTVA       = pCaption->GetTextVerticalAdjust();
@@ -1556,16 +1557,14 @@ bool XclExpObjectManager::HasObj() const
     return !mxObjList->empty();
 }
 
-sal_uInt16 XclExpObjectManager::AddObj( XclObj* pObjRec )
+sal_uInt16 XclExpObjectManager::AddObj( std::unique_ptr<XclObj> pObjRec )
 {
-    return mxObjList->Add( pObjRec );
+    return mxObjList->Add( std::move(pObjRec) );
 }
 
-XclObj* XclExpObjectManager::RemoveLastObj()
+std::unique_ptr<XclObj> XclExpObjectManager::RemoveLastObj()
 {
-    XclObj* pLastObj = mxObjList->back();
-    mxObjList->pop_back();
-    return pLastObj;
+    return mxObjList->pop_back();
 }
 
 void XclExpObjectManager::InitStream( bool bTempFile )
diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx
index d078128859b5..8efaf9768ca7 100644
--- a/sc/source/filter/inc/xcl97rec.hxx
+++ b/sc/source/filter/inc/xcl97rec.hxx
@@ -37,24 +37,21 @@ class XclExpObjList : public ExcEmptyRec, protected XclExpRoot
 {
 public:
 
-    typedef std::vector<XclObj*>::iterator iterator;
+    typedef std::vector<std::unique_ptr<XclObj>>::iterator iterator;
 
     explicit            XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx );
     virtual             ~XclExpObjList() override;
 
     /// return: 1-based ObjId
     ///! count>=0xFFFF: Obj will be deleted, return 0
-    sal_uInt16              Add( XclObj* );
+    sal_uInt16              Add( std::unique_ptr<XclObj> );
 
-    XclObj* back () { return maObjs.empty() ? nullptr : maObjs.back(); }
+    XclObj* back () { return maObjs.empty() ? nullptr : maObjs.back().get(); }
 
     /**
-     *
      * @brief Remove last element in the list.
-     *
      */
-
-    void pop_back ();
+    std::unique_ptr<XclObj> pop_back ();
 
     bool empty () const { return maObjs.empty(); }
 
@@ -64,7 +61,7 @@ public:
 
     iterator end () { return maObjs.end(); }
 
-    XclExpMsoDrawing* GetMsodrawingPerSheet() { return pMsodrawingPerSheet; }
+    XclExpMsoDrawing* GetMsodrawingPerSheet() { return pMsodrawingPerSheet.get(); }
 
                                 /// close groups and DgContainer opened in ctor
     void                EndSheet();
@@ -79,10 +76,10 @@ private:
     SCTAB               mnScTab;
 
     XclEscherEx&        mrEscherEx;
-    XclExpMsoDrawing*   pMsodrawingPerSheet;
-    XclExpMsoDrawing*   pSolverContainer;
+    std::unique_ptr<XclExpMsoDrawing> pMsodrawingPerSheet;
+    std::unique_ptr<XclExpMsoDrawing> pSolverContainer;
 
-    std::vector<XclObj*> maObjs;
+    std::vector<std::unique_ptr<XclObj>> maObjs;
 };
 
 // --- class XclObj --------------------------------------------------
diff --git a/sc/source/filter/inc/xeescher.hxx b/sc/source/filter/inc/xeescher.hxx
index 46cc7519fbcc..3f5fa308e261 100644
--- a/sc/source/filter/inc/xeescher.hxx
+++ b/sc/source/filter/inc/xeescher.hxx
@@ -407,8 +407,8 @@ public:
     XclEscherEx& GetEscherEx() { return *mxEscherEx; }
     XclExpMsoDrawing*   GetMsodrawingPerSheet();
     bool                HasObj() const;
-    sal_uInt16          AddObj( XclObj* pObjRec );
-    XclObj*             RemoveLastObj();
+    sal_uInt16          AddObj( std::unique_ptr<XclObj> pObjRec );
+    std::unique_ptr<XclObj> RemoveLastObj();
 
 protected:
     explicit            XclExpObjectManager( const XclExpObjectManager& rParent );
diff --git a/sc/source/filter/xcl97/xcl97esc.cxx b/sc/source/filter/xcl97/xcl97esc.cxx
index 198b23ef5c33..b5030ce78304 100644
--- a/sc/source/filter/xcl97/xcl97esc.cxx
+++ b/sc/source/filter/xcl97/xcl97esc.cxx
@@ -27,6 +27,7 @@
 
 #include <svx/svdpage.hxx>
 #include <editeng/outlobj.hxx>
+#include <o3tl/make_unique.hxx>
 #include <svx/svdotext.hxx>
 #include <svx/svdobj.hxx>
 #include <svx/svdoole2.hxx>
@@ -222,7 +223,7 @@ EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape
                     SvGlobalName aObjClsId( xObj->getClassID() );
                     if ( SotExchange::IsChart( aObjClsId ) )
                     {   // yes, it's a chart diagram
-                        mrObjMgr.AddObj( new XclExpChartObj( mrObjMgr, rxShape, pChildAnchor ) );
+                        mrObjMgr.AddObj( o3tl::make_unique<XclExpChartObj>( mrObjMgr, rxShape, pChildAnchor ) );
                         pCurrXclObj = nullptr;     // no metafile or whatsoever
                     }
                     else    // metafile and OLE object
@@ -265,7 +266,7 @@ EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape
     }
     if ( pCurrXclObj )
     {
-        if ( !mrObjMgr.AddObj( pCurrXclObj ) )
+        if ( !mrObjMgr.AddObj( std::unique_ptr<XclObj>(pCurrXclObj) ) )
         {   // maximum count reached, object got deleted
             pCurrXclObj = nullptr;
         }
@@ -353,9 +354,8 @@ void XclEscherEx::EndShape( sal_uInt16 nShapeType, sal_uInt32 nShapeID )
         // escher data of last shape not written? -> delete it from object list
         if( nShapeID == 0 )
         {
-            XclObj* pLastObj = mrObjMgr.RemoveLastObj();
-            OSL_ENSURE( pLastObj == pCurrXclObj, "XclEscherEx::EndShape - wrong object" );
-            DELETEZ( pLastObj );
+            std::unique_ptr<XclObj> pLastObj = mrObjMgr.RemoveLastObj();
+            OSL_ENSURE( pLastObj.get() == pCurrXclObj, "XclEscherEx::EndShape - wrong object" );
             pCurrXclObj = nullptr;
         }
 
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx
index 2eb32f70f558..b8a9919ca5dd 100644
--- a/sc/source/filter/xcl97/xcl97rec.cxx
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -98,10 +98,9 @@ sal_Int32 XclExpObjList::mnVmlCount;
 XclExpObjList::XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx ) :
     XclExpRoot( rRoot ),
     mnScTab( rRoot.GetCurrScTab() ),
-    mrEscherEx( rEscherEx ),
-    pSolverContainer( nullptr )
+    mrEscherEx( rEscherEx )
 {
-    pMsodrawingPerSheet = new XclExpMsoDrawing( rEscherEx );
+    pMsodrawingPerSheet.reset( new XclExpMsoDrawing( rEscherEx ) );
     // open the DGCONTAINER and the patriarch group shape
     mrEscherEx.OpenContainer( ESCHER_DgContainer );
     tools::Rectangle aRect( 0, 0, 0, 0 );
@@ -111,12 +110,12 @@ XclExpObjList::XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx )
 
 XclExpObjList::~XclExpObjList()
 {
-    std::for_each(maObjs.begin(), maObjs.end(), std::default_delete<XclObj>());
-    delete pMsodrawingPerSheet;
-    delete pSolverContainer;
+    maObjs.clear();
+    pMsodrawingPerSheet.reset();
+    pSolverContainer.reset();
 }
 
-sal_uInt16 XclExpObjList::Add( XclObj* pObj )
+sal_uInt16 XclExpObjList::Add( std::unique_ptr<XclObj> pObj )
 {
     OSL_ENSURE( maObjs.size() < 0xFFFF, "XclExpObjList::Add: too much for Xcl" );
 
@@ -124,30 +123,31 @@ sal_uInt16 XclExpObjList::Add( XclObj* pObj )
 
     if ( nSize < 0xFFFF )
     {
-        maObjs.push_back(pObj);
-        ++nSize;
-        pObj->SetId( nSize );
+        pObj->SetId( nSize+1 );
         pObj->SetTab( mnScTab );
+        maObjs.push_back(std::move(pObj));
+        ++nSize;
     }
     else
     {
-        delete pObj;
         nSize = 0;
     }
 
     return nSize;
 }
 
-void XclExpObjList::pop_back ()
+std::unique_ptr<XclObj> XclExpObjList::pop_back ()
 {
+    auto ret = std::move(maObjs.back());
     maObjs.pop_back();
+    return ret;
 }
 
 void XclExpObjList::EndSheet()
 {
     // Is there still something in the stream? -> The solver container
     if( mrEscherEx.HasPendingDffData() )
-        pSolverContainer = new XclExpMsoDrawing( mrEscherEx );
+        pSolverContainer.reset( new XclExpMsoDrawing( mrEscherEx ) );
 
     // close the DGCONTAINER created by XclExpObjList ctor MSODRAWING
     mrEscherEx.CloseContainer();
@@ -158,8 +158,7 @@ void XclExpObjList::Save( XclExpStream& rStrm )
     //! Escher must be written, even if there are no objects
     pMsodrawingPerSheet->Save( rStrm );
 
-    std::vector<XclObj*>::iterator pIter;
-    for ( pIter = maObjs.begin(); pIter != maObjs.end(); ++pIter )
+    for ( auto pIter = maObjs.begin(); pIter != maObjs.end(); ++pIter )
         (*pIter)->Save( rStrm );
 
     if( pSolverContainer )
@@ -183,9 +182,8 @@ sal_Int32 GetVmlObjectCount( XclExpObjList& rList )
 {
     sal_Int32 nNumVml = 0;
 
-    std::vector<XclObj*>::iterator pIter;
-    for ( pIter = rList.begin(); pIter != rList.end(); ++pIter )
-        if( IsVmlObject( *pIter ) )
+    for ( auto pIter = rList.begin(); pIter != rList.end(); ++pIter )
+        if( IsVmlObject( pIter->get() ) )
             ++nNumVml;
 
     return nNumVml;
@@ -236,13 +234,12 @@ void SaveDrawingMLObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_Int
 {
     std::vector<XclObj*> aList;
     aList.reserve(rList.size());
-    std::vector<XclObj*>::iterator it = rList.begin(), itEnd = rList.end();
-    for (; it != itEnd; ++it)
+    for (auto it = rList.begin(), itEnd = rList.end(); it != itEnd; ++it)
     {
-        if (IsVmlObject(*it) || !IsValidObject(**it))
+        if (IsVmlObject(it->get()) || !IsValidObject(**it))
             continue;
 
-        aList.push_back(*it);
+        aList.push_back(it->get());
     }
 
     if (aList.empty())
@@ -269,7 +266,7 @@ void SaveDrawingMLObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_Int
             FSNS( XML_xmlns, XML_r ),   XclXmlUtils::ToOString(rStrm.getNamespaceURL(OOX_NS(officeRel))).getStr(),
             FSEND );
 
-    for (it = aList.begin(), itEnd = aList.end(); it != itEnd; ++it)
+    for (auto it = aList.begin(), itEnd = aList.end(); it != itEnd; ++it)
         (*it)->SaveXml(rStrm);
 
     pDrawing->endElement( FSNS( XML_xdr, XML_wsDr ) );
@@ -304,10 +301,9 @@ void SaveVmlObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_Int32& nV
             FSNS( XML_xmlns, XML_w10 ), XclXmlUtils::ToOString(rStrm.getNamespaceURL(OOX_NS(vmlWord))).getStr(),
             FSEND );
 
-    std::vector<XclObj*>::iterator pIter;
-    for ( pIter = rList.begin(); pIter != rList.end(); ++pIter )
+    for ( auto pIter = rList.begin(); pIter != rList.end(); ++pIter )
     {
-        if( !IsVmlObject( *pIter ) )
+        if( !IsVmlObject( pIter->get() ) )
             continue;
         (*pIter)->SaveXml( rStrm );
     }
commit a91fe8558b4c8aa163069ebdb117d58239da74f2
Author: Tamas Bunth <tamas.bunth at collabora.co.uk>
Date:   Tue Jun 26 13:15:07 2018 +0200

    dbahsql: Look for properties only after name
    
    Additional properties in SQL string like "DEFAULT" or "NOT NULL" should
    be searched only after column name, because what if a column name is
    "myEvilNOT NULLColumn"
    
    Change-Id: I21f0755ba14c7267243d9999f044db4d16963387
    Reviewed-on: https://gerrit.libreoffice.org/56462
    Tested-by: Jenkins
    Reviewed-by: Tamás Bunth <btomi96 at gmail.com>

diff --git a/dbaccess/qa/extras/hsql_schema_import.cxx b/dbaccess/qa/extras/hsql_schema_import.cxx
index 892be33d15e7..dd75eb2dc38c 100644
--- a/dbaccess/qa/extras/hsql_schema_import.cxx
+++ b/dbaccess/qa/extras/hsql_schema_import.cxx
@@ -42,6 +42,7 @@ public:
     void testIntegerAutoincremental();
     void testTimestampWithParam();
     void testDefaultValueNow();
+    void testEvilNullColumnName();
     // TODO testForeign, testDecomposer
 
     CPPUNIT_TEST_SUITE(HsqlSchemaImportTest);
@@ -53,6 +54,7 @@ public:
     CPPUNIT_TEST(testIntegerAutoincremental);
     CPPUNIT_TEST(testTimestampWithParam);
     CPPUNIT_TEST(testDefaultValueNow);
+    CPPUNIT_TEST(testEvilNullColumnName);
 
     CPPUNIT_TEST_SUITE_END();
 };
@@ -197,6 +199,22 @@ void HsqlSchemaImportTest::testDefaultValueNow()
     CPPUNIT_ASSERT(fbSql.indexOf("\'NOW\'") > 0); // composed 'NOW'
 }
 
+void HsqlSchemaImportTest::testEvilNullColumnName()
+{
+    OUString sql{ "CREATE CACHED TABLE \"myTable\"(\"id\" INTEGER NOT NULL PRIMARY KEY, "
+                  "\"myEvilNOT NULLName\" "
+                  "VARCHAR(20))" };
+
+    FbCreateStmtParser aCreateParser;
+    aCreateParser.parse(sql);
+
+    const auto& columns = aCreateParser.getColumnDef();
+    CPPUNIT_ASSERT_EQUAL(2_z, columns.size());
+    const ColumnDefinition* colVarchar = lcl_findByType(columns, css::sdbc::DataType::VARCHAR);
+    CPPUNIT_ASSERT(colVarchar != nullptr);
+    CPPUNIT_ASSERT(colVarchar->isNullable());
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(HsqlSchemaImportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/dbaccess/source/filter/hsqldb/createparser.cxx b/dbaccess/source/filter/hsqldb/createparser.cxx
index 2344ceb075fe..32abe25a8521 100644
--- a/dbaccess/source/filter/hsqldb/createparser.cxx
+++ b/dbaccess/source/filter/hsqldb/createparser.cxx
@@ -301,10 +301,13 @@ void CreateStmtParser::parseColumnPart(const OUString& sColumnPart)
         if (isPrimaryKey)
             m_PrimaryKeys.push_back(rColumnName);
 
+        const OUString sColumnWithoutName = sColumn.copy(sColumn.indexOf(typeParts.typeName));
+
         ColumnDefinition aColDef(rColumnName, lcl_getDataTypeFromHsql(typeParts.typeName),
                                  typeParts.params, isPrimaryKey,
-                                 lcl_getAutoIncrementDefault(sColumn), lcl_isNullable(sColumn),
-                                 bCaseInsensitive, lcl_getDefaultValue(sColumn));
+                                 lcl_getAutoIncrementDefault(sColumnWithoutName),
+                                 lcl_isNullable(sColumnWithoutName), bCaseInsensitive,
+                                 lcl_getDefaultValue(sColumnWithoutName));
 
         m_aColumns.push_back(aColDef);
     }
commit 815b2130c86d5a0aa07bdddb252fbd6ae5d64a62
Author: Tamas Bunth <tamas.bunth at collabora.co.uk>
Date:   Tue Jun 26 13:08:12 2018 +0200

    dbahsql: refactor, around parseColumnpart
    
    Change-Id: I663da1474d3f1c3bde8a3d3c041e8fd0fe4c7d43
    Reviewed-on: https://gerrit.libreoffice.org/56459
    Tested-by: Jenkins
    Reviewed-by: Tamás Bunth <btomi96 at gmail.com>

diff --git a/dbaccess/source/filter/hsqldb/createparser.cxx b/dbaccess/source/filter/hsqldb/createparser.cxx
index 11443e7b4d37..2344ceb075fe 100644
--- a/dbaccess/source/filter/hsqldb/createparser.cxx
+++ b/dbaccess/source/filter/hsqldb/createparser.cxx
@@ -200,6 +200,39 @@ void lcl_addDefaultParameters(std::vector<sal_Int32>& aParams, sal_Int32 eType)
         aParams.push_back(8000); // from SQL standard
 }
 
+struct ColumnTypeParts
+{
+    OUString typeName;
+    std::vector<sal_Int32> params;
+};
+
+/**
+ * Separates full type descriptions (e.g. NUMERIC(5,4)) to type name (NUMERIC) and
+ * parameters (5,4)
+ */
+ColumnTypeParts lcl_getColumnTypeParts(const OUString& sFullTypeName)
+{
+    ColumnTypeParts parts;
+    auto nParenPos = sFullTypeName.indexOf("(");
+    if (nParenPos > 0)
+    {
+        parts.typeName = sFullTypeName.copy(0, nParenPos).trim();
+        OUString sParamStr
+            = sFullTypeName.copy(nParenPos + 1, sFullTypeName.indexOf(")") - nParenPos - 1);
+        auto sParams = string::split(sParamStr, sal_Unicode(u','));
+        for (auto& sParam : sParams)
+        {
+            parts.params.push_back(sParam.toInt32());
+        }
+    }
+    else
+    {
+        parts.typeName = sFullTypeName.trim();
+        lcl_addDefaultParameters(parts.params, lcl_getDataTypeFromHsql(parts.typeName));
+    }
+    return parts;
+}
+
 } // unnamed namespace
 
 namespace dbahsql
@@ -239,61 +272,39 @@ void CreateStmtParser::parseColumnPart(const OUString& sColumnPart)
         }
 
         bool bIsQuoteUsedForColumnName(sColumn[0] == '\"');
+
         // find next quote after the initial quote
         // or next space if quote isn't used as delimiter
-        // to fetch the whole column name, including quotes
         auto nEndColumnName
-            = bIsQuoteUsedForColumnName ? sColumn.indexOf("\"", 1) : sColumn.indexOf(" ");
-        OUString rColumnName
-            = sColumn.copy(0, bIsQuoteUsedForColumnName ? nEndColumnName + 1 : nEndColumnName);
+            = bIsQuoteUsedForColumnName ? sColumn.indexOf("\"", 1) + 1 : sColumn.indexOf(" ");
+        OUString rColumnName = sColumn.copy(0, nEndColumnName);
 
-        // create a buffer which begins on column type
-        // with extra spaces removed
-        const OUString& buffer
-            = sColumn.copy(bIsQuoteUsedForColumnName ? nEndColumnName + 1 : nEndColumnName).trim();
+        const OUString& sFromTypeName = sColumn.copy(nEndColumnName).trim();
 
         // Now let's manage the column type
         // search next space to get the whole type name
         // eg: INTEGER, VARCHAR(10), DECIMAL(6,3)
-        auto nNextSpace = buffer.indexOf(" ");
+        auto nNextSpace = sFromTypeName.indexOf(" ");
         OUString sFullTypeName;
-        OUString sTypeName;
         if (nNextSpace > 0)
-            sFullTypeName = buffer.copy(0, nNextSpace);
+            sFullTypeName = sFromTypeName.copy(0, nNextSpace);
         // perhaps column type corresponds to the last info here
         else
-            sFullTypeName = buffer;
+            sFullTypeName = sFromTypeName;
 
-        auto nParenPos = sFullTypeName.indexOf("(");
-        std::vector<sal_Int32> aParams;
-        if (nParenPos > 0)
-        {
-            sTypeName = sFullTypeName.copy(0, nParenPos).trim();
-            OUString sParamStr
-                = sFullTypeName.copy(nParenPos + 1, sFullTypeName.indexOf(")") - nParenPos - 1);
-            auto sParams = string::split(sParamStr, sal_Unicode(u','));
-            for (auto& sParam : sParams)
-            {
-                aParams.push_back(sParam.toInt32());
-            }
-        }
-        else
-        {
-            sTypeName = sFullTypeName.trim();
-            lcl_addDefaultParameters(aParams, lcl_getDataTypeFromHsql(sTypeName));
-        }
+        ColumnTypeParts typeParts = lcl_getColumnTypeParts(sFullTypeName);
 
-        bool bCaseInsensitive = sTypeName.indexOf("IGNORECASE") >= 0;
+        bool bCaseInsensitive = typeParts.typeName.indexOf("IGNORECASE") >= 0;
         rColumnName = lcl_ConvertToUTF8(OUStringToOString(rColumnName, RTL_TEXTENCODING_UTF8));
         bool isPrimaryKey = lcl_isPrimaryKey(sColumn);
 
         if (isPrimaryKey)
             m_PrimaryKeys.push_back(rColumnName);
 
-        ColumnDefinition aColDef(rColumnName, lcl_getDataTypeFromHsql(sTypeName), aParams,
-                                 isPrimaryKey, lcl_getAutoIncrementDefault(sColumn),
-                                 lcl_isNullable(sColumn), bCaseInsensitive,
-                                 lcl_getDefaultValue(sColumn));
+        ColumnDefinition aColDef(rColumnName, lcl_getDataTypeFromHsql(typeParts.typeName),
+                                 typeParts.params, isPrimaryKey,
+                                 lcl_getAutoIncrementDefault(sColumn), lcl_isNullable(sColumn),
+                                 bCaseInsensitive, lcl_getDefaultValue(sColumn));
 
         m_aColumns.push_back(aColDef);
     }
commit 8f3d6e67b08ed1bce9bc989e5e3df92c4d9d95d3
Author: Tamas Bunth <tamas.bunth at collabora.co.uk>
Date:   Tue Jun 26 12:27:57 2018 +0200

    tdf#117867 dbahsql: Migrate default values
    
    Default Value "NOW" is a special case, because Firebird likes it with
    single quotes. In contrast, HSQLDB uses the keyword without quotes.
    
    Add unit test for parsing default value "NOW"
    
    Change-Id: I34886f8ae53e98addb52bf5e85030a03721d6a45
    Reviewed-on: https://gerrit.libreoffice.org/56454
    Tested-by: Jenkins
    Reviewed-by: Tamás Bunth <btomi96 at gmail.com>

diff --git a/dbaccess/qa/extras/hsql_schema_import.cxx b/dbaccess/qa/extras/hsql_schema_import.cxx
index a04e3697ecfb..892be33d15e7 100644
--- a/dbaccess/qa/extras/hsql_schema_import.cxx
+++ b/dbaccess/qa/extras/hsql_schema_import.cxx
@@ -41,6 +41,7 @@ public:
     void testNumericWithTwoParam();
     void testIntegerAutoincremental();
     void testTimestampWithParam();
+    void testDefaultValueNow();
     // TODO testForeign, testDecomposer
 
     CPPUNIT_TEST_SUITE(HsqlSchemaImportTest);
@@ -51,6 +52,7 @@ public:
     CPPUNIT_TEST(testNumericWithTwoParam);
     CPPUNIT_TEST(testIntegerAutoincremental);
     CPPUNIT_TEST(testTimestampWithParam);
+    CPPUNIT_TEST(testDefaultValueNow);
 
     CPPUNIT_TEST_SUITE_END();
 };
@@ -174,6 +176,27 @@ void HsqlSchemaImportTest::testTimestampWithParam()
     CPPUNIT_ASSERT(fbSql.indexOf("0") < 0); //does not contain
 }
 
+/**
+ * Special case:
+ * HSQLDB uses keyword NOW without quotes. Firebird uses single quotes 'NOW'
+ */
+void HsqlSchemaImportTest::testDefaultValueNow()
+{
+    OUString sql{ "CREATE CACHED TABLE \"myTable\"(\"id\" INTEGER NOT NULL PRIMARY KEY, \"myDate\" "
+                  "TIMESTAMP DEFAULT NOW)" };
+
+    FbCreateStmtParser aCreateParser;
+    aCreateParser.parse(sql);
+
+    const auto& columns = aCreateParser.getColumnDef();
+    const ColumnDefinition* colTimeStamp = lcl_findByType(columns, css::sdbc::DataType::TIMESTAMP);
+
+    CPPUNIT_ASSERT(colTimeStamp != nullptr);
+    CPPUNIT_ASSERT_EQUAL(OUString{ "NOW" }, colTimeStamp->getDefault()); // parsed NOW
+    OUString fbSql = aCreateParser.compose();
+    CPPUNIT_ASSERT(fbSql.indexOf("\'NOW\'") > 0); // composed 'NOW'
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(HsqlSchemaImportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/dbaccess/source/filter/hsqldb/columndef.cxx b/dbaccess/source/filter/hsqldb/columndef.cxx
index 6e36ee1b8718..dd71e81f28b3 100644
--- a/dbaccess/source/filter/hsqldb/columndef.cxx
+++ b/dbaccess/source/filter/hsqldb/columndef.cxx
@@ -27,7 +27,8 @@ using namespace css::sdbc;
 
 ColumnDefinition::ColumnDefinition(const OUString& sName, sal_Int32 eType,
                                    const std::vector<sal_Int32> aParams, bool bPrimary,
-                                   sal_Int32 nAutoIncr, bool bNullable, bool bCaseInsensitive)
+                                   sal_Int32 nAutoIncr, bool bNullable, bool bCaseInsensitive,
+                                   const OUString& sDefault)
     : m_sName(sName)
     , m_eType(eType)
     , m_aParams(aParams)
@@ -35,6 +36,7 @@ ColumnDefinition::ColumnDefinition(const OUString& sName, sal_Int32 eType,
     , m_nAutoIncrement(nAutoIncr)
     , m_bNullable(bNullable)
     , m_bCaseInsensitive(bCaseInsensitive)
+    , m_sDefaultValue(sDefault)
 {
 }
 }
diff --git a/dbaccess/source/filter/hsqldb/columndef.hxx b/dbaccess/source/filter/hsqldb/columndef.hxx
index b356d3906b37..fd23ed313abb 100644
--- a/dbaccess/source/filter/hsqldb/columndef.hxx
+++ b/dbaccess/source/filter/hsqldb/columndef.hxx
@@ -26,11 +26,12 @@ private:
     sal_Int32 m_nAutoIncrement;
     bool m_bNullable;
     bool m_bCaseInsensitive;
+    OUString m_sDefaultValue;
 
 public:
     ColumnDefinition(const OUString& sName, sal_Int32 eType, const std::vector<sal_Int32> aParams,
                      bool bPrimary = false, sal_Int32 nAutoIncr = -1, bool bNullable = true,
-                     bool bCaseInsensitive = false);
+                     bool bCaseInsensitive = false, const OUString& sDefault = OUString{});
 
     OUString const& getName() const { return m_sName; }
     sal_Int32 getDataType() const { return m_eType; }
@@ -40,6 +41,7 @@ public:
     bool isCaseInsensitive() const { return m_bCaseInsensitive; }
     sal_Int32 getStartValue() const { return m_nAutoIncrement; }
     const std::vector<sal_Int32>& getParams() const { return m_aParams; }
+    OUString const& getDefault() const { return m_sDefaultValue; }
 };
 }
 
diff --git a/dbaccess/source/filter/hsqldb/createparser.cxx b/dbaccess/source/filter/hsqldb/createparser.cxx
index 5b864f4231c6..11443e7b4d37 100644
--- a/dbaccess/source/filter/hsqldb/createparser.cxx
+++ b/dbaccess/source/filter/hsqldb/createparser.cxx
@@ -111,6 +111,21 @@ sal_Int32 lcl_getAutoIncrementDefault(const OUString& sColumnDef)
     return -1;
 }
 
+OUString lcl_getDefaultValue(const OUString& sColumnDef)
+{
+    constexpr char DEFAULT_KW[] = "DEFAULT";
+    auto nDefPos = sColumnDef.indexOf(DEFAULT_KW);
+    if (nDefPos > 0 && lcl_getAutoIncrementDefault(sColumnDef) < 0)
+    {
+        const OUString& fromDefault = sColumnDef.copy(nDefPos + sizeof(DEFAULT_KW)).trim();
+
+        // next word is the value
+        auto nNextSpace = fromDefault.indexOf(" ");
+        return nNextSpace > 0 ? fromDefault.copy(0, fromDefault.indexOf(" ")) : fromDefault;
+    }
+    return OUString{};
+}
+
 bool lcl_isNullable(const OUString& sColumnDef)
 {
     if (sColumnDef.indexOf("NOT NULL") >= 0)
@@ -277,7 +292,8 @@ void CreateStmtParser::parseColumnPart(const OUString& sColumnPart)
 
         ColumnDefinition aColDef(rColumnName, lcl_getDataTypeFromHsql(sTypeName), aParams,
                                  isPrimaryKey, lcl_getAutoIncrementDefault(sColumn),
-                                 lcl_isNullable(sColumn), bCaseInsensitive);
+                                 lcl_isNullable(sColumn), bCaseInsensitive,
+                                 lcl_getDefaultValue(sColumn));
 
         m_aColumns.push_back(aColDef);
     }
diff --git a/dbaccess/source/filter/hsqldb/fbcreateparser.cxx b/dbaccess/source/filter/hsqldb/fbcreateparser.cxx
index 59f41c887368..768c7286185b 100644
--- a/dbaccess/source/filter/hsqldb/fbcreateparser.cxx
+++ b/dbaccess/source/filter/hsqldb/fbcreateparser.cxx
@@ -173,6 +173,16 @@ OUString FbCreateStmtParser::compose() const
         if (columnIter->isCaseInsensitive())
             lcl_appendWithSpace(sSql, "COLLATE UNICODE_CI");
 
+        const OUString& sDefaultVal = columnIter->getDefault();
+        if (!sDefaultVal.isEmpty())
+        {
+            lcl_appendWithSpace(sSql, "DEFAULT");
+            if (sDefaultVal.equalsIgnoreAsciiCase("NOW"))
+                lcl_appendWithSpace(sSql, "\'NOW\'"); // Fb likes it single quoted
+            else
+                lcl_appendWithSpace(sSql, sDefaultVal);
+        }
+
         ++columnIter;
         sSql.append(",");
     }
commit 2b0a7c346f8e3c5823a9e032a4501f20bc712914
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu Jul 5 15:58:05 2018 +0200

    tdf#118414 sw: fix fieldmarks in GetNextAttr()
    
    Apparently this needs to stop both before and after the CH_TXT_ATR_*.
    
    (regression from 3e724847308c0d9cdd727898faaeb347c5f0643a)
    
    Change-Id: Iff3d594d2eec59436ad683b9cc7aca04f7527bd5
    Reviewed-on: https://gerrit.libreoffice.org/57017
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>

diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx
index d1f77e062ee9..b6e53480d6e4 100644
--- a/sw/source/core/text/itratr.cxx
+++ b/sw/source/core/text/itratr.cxx
@@ -674,9 +674,11 @@ static sal_Int32 GetNextAttrImpl(SwTextNode const*const pTextNode,
         }
     }
     assert(p <= nNext);
-    if (p < l && nPosition < p)
+    if (p < l)
     {
-        nNext=p;
+        // found a CH_TXT_ATR_FIELD*: if it's same as current position,
+        // skip behind it so that both before- and after-positions are returned
+        nNext = (nPosition < p) ? p : p + 1;
     }
     return nNext;
 }
commit bf4d4a9cad6664bd5772618e31e998942caef77e
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Wed Jul 4 12:53:56 2018 +0200

    tdf#101856 sw: hidden bookmark portions in SwTextFormatter::NewTextPortion()
    
    All other hidden-text features already have a AUTOFMT hint or a TXTFIELD
    hint, so the SwAttrIter already creates new portions for them.
    
    The bookmarks aren't considered by SwTextFormatter currently, but
    SwScriptInfo already has all of the required info.
    
    Change-Id: I451ce331110aa58df8955e1a3ffa339e6f905b22
    Reviewed-on: https://gerrit.libreoffice.org/56959
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>

diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index aab651e1511d..e3b532783439 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -177,6 +177,7 @@ public:
         assert(nCnt < m_HiddenChg.size());
         return m_HiddenChg[ nCnt ];
     }
+    TextFrameIndex NextHiddenChg(TextFrameIndex nPos) const;
     static void CalcHiddenRanges(const SwTextNode& rNode, MultiSelection& rHiddenMulti);
     static void selectHiddenTextProperty(const SwTextNode& rNode, MultiSelection &rHiddenMulti);
     static void selectRedLineDeleted(const SwTextNode& rNode, MultiSelection &rHiddenMulti, bool bSelect=true);
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 3949fc35bb71..2df29c9e8ff8 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -958,6 +958,10 @@ SwTextPortion *SwTextFormatter::NewTextPortion( SwTextFormatInfo &rInf )
     const TextFrameIndex nNextDir = m_pScriptInfo->NextDirChg(rInf.GetIdx());
     nNextChg = std::min( nNextChg, nNextDir );
 
+    // hidden change (potentially via bookmark):
+    const TextFrameIndex nNextHidden = m_pScriptInfo->NextHiddenChg(rInf.GetIdx());
+    nNextChg = std::min( nNextChg, nNextHidden );
+
     // Turbo boost:
     // We assume that font characters are not larger than twice
     // as wide as height.
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 7d5b87b8437a..a5391aa817a6 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -1450,6 +1450,18 @@ sal_uInt8 SwScriptInfo::DirType(const TextFrameIndex nPos) const
     return 0;
 }
 
+TextFrameIndex SwScriptInfo::NextHiddenChg(TextFrameIndex const nPos) const
+{
+    for (auto const it : m_HiddenChg)
+    {
+        if (nPos < it)
+        {
+            return it;
+        }
+    }
+    return TextFrameIndex(COMPLETE_STRING);
+}
+
 // Takes a string and replaced the hidden ranges with cChar.
 sal_Int32 SwScriptInfo::MaskHiddenRanges( const SwTextNode& rNode, OUStringBuffer & rText,
                                        const sal_Int32 nStt, const sal_Int32 nEnd,
commit 97de51107824b5b3452e5343672c838da4b04b84
Author: Serge Krot <Serge.Krot at cib.de>
Date:   Mon Feb 12 10:19:10 2018 +0100

    tdf#101856: Use bookmark attributes at load
    
    Conflicts:
            sw/source/core/text/porlay.cxx
    
    Change-Id: I935c50f8b3a1d7179121b9230a7f7f25fa6aea22
    (cherry picked from commit f8afdb8ba99074a85b331065b4642081467557ec)
    Reviewed-on: https://gerrit.libreoffice.org/49578
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>

diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index d7d7ad015e77..7d5b87b8437a 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -54,6 +54,7 @@
 #include <IDocumentRedlineAccess.hxx>
 #include <IDocumentSettingAccess.hxx>
 #include <IDocumentContentOperations.hxx>
+#include <IMark.hxx>
 
 using namespace ::com::sun::star;
 using namespace i18n::ScriptType;
@@ -2251,6 +2252,25 @@ void SwScriptInfo::selectHiddenTextProperty(const SwTextNode& rNode, MultiSelect
             }
         }
     }
+
+    for (const SwIndex* pIndex = rNode.GetFirstIndex(); pIndex; pIndex = pIndex->GetNext())
+    {
+        const sw::mark::IMark* pMark = pIndex->GetMark();
+        const sw::mark::IBookmark* pBookmark = dynamic_cast<const sw::mark::IBookmark*>(pMark);
+        if (pBookmark && pBookmark->IsHidden())
+        {
+            // intersect bookmark range with textnode range and add the intersection to rHiddenMulti
+
+            const sal_Int32 nSt =  pBookmark->GetMarkStart().nContent.GetIndex();
+            const sal_Int32 nEnd = pBookmark->GetMarkEnd().nContent.GetIndex();
+
+            if( nEnd > nSt )
+            {
+                Range aTmp( nSt, nEnd - 1 );
+                rHiddenMulti.Select(aTmp, true);
+            }
+        }
+    }
 }
 
 void SwScriptInfo::selectRedLineDeleted(const SwTextNode& rNode, MultiSelection &rHiddenMulti, bool bSelect)
commit 8c2545153572b32ecba202e52aade84b188dac73
Author: Serge Krot <Serge.Krot at cib.de>
Date:   Thu Feb 8 13:19:01 2018 +0100

    tdf#101856 odt: write/read new bookmark attributes: unit test
    
    Change-Id: I094f91c2af2d171067e3c37a8d52276835d36e9c
    (cherry picked from commit 61150f1c37744457e7a1a1c1e684612b6adf0298)
    Reviewed-on: https://gerrit.libreoffice.org/49424
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>

diff --git a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng
index f6561295af84..adae650eafc9 100644
--- a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng
+++ b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng
@@ -2299,6 +2299,20 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
     </rng:optional>
   </rng:define>
 
+  <!-- TODO no proposal -->
+  <rng:define name="text-bookmark-start-attlist" combine="interleave">
+    <rng:optional>
+      <rng:attribute name="loext:hidden">
+        <rng:ref name="boolean"/>
+      </rng:attribute>
+      <rng:optional>
+        <rng:attribute name="loext:condition">
+          <rng:ref name="string"/>
+        </rng:attribute>
+      </rng:optional>
+    </rng:optional>
+  </rng:define>
+
   <!-- just a test-case for user-defined attributes, move along, nothing to see here... -->
   <rng:define name="style-table-cell-properties-attlist" combine="interleave">
     <rng:optional>
diff --git a/sw/qa/extras/odfexport/data/tdf101856.odt b/sw/qa/extras/odfexport/data/tdf101856.odt
new file mode 100755
index 000000000000..bddd1502281c
Binary files /dev/null and b/sw/qa/extras/odfexport/data/tdf101856.odt differ
diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx
index 48ac63b27271..ef48e648661b 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -1996,6 +1996,52 @@ DECLARE_ODFEXPORT_TEST(testSpellOutNumberingTypes, "spellout-numberingtypes.odt"
     }
 }
 
+// MAILMERGE Add conditional to expand / collapse bookmarks
+DECLARE_ODFEXPORT_TEST(tdf101856, "tdf101856.odt")
+{
+    // get bookmark interface
+    uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
+    uno::Reference<container::XNameAccess> xBookmarksByName(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
+
+    // check: we have 2 bookmarks
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5), xBookmarksByIdx->getCount());
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkVisible"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkHidden"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkVisibleWithCondition"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkNotHiddenWithCondition"));
+    CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkHiddenWithCondition"));
+
+    // <text:bookmark-start text:name="BookmarkVisible"/>
+    uno::Reference<beans::XPropertySet> xBookmark1(xBookmarksByName->getByName("BookmarkVisible"), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xBookmark1, UNO_NAME_BOOKMARK_CONDITION));
+    CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xBookmark1, UNO_NAME_BOOKMARK_HIDDEN));
+
+    // <text:bookmark-start text:name="BookmarkHidden" loext:condition="" loext:hidden="true"/>
+    uno::Reference<beans::XPropertySet> xBookmark2(xBookmarksByName->getByName("BookmarkHidden"), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xBookmark2, UNO_NAME_BOOKMARK_CONDITION));
+    CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xBookmark2, UNO_NAME_BOOKMARK_HIDDEN));
+
+    // <text:bookmark-start text:name="BookmarkVisibleWithCondition" loext:condition="0==1" loext:hidden="true"/>
+    uno::Reference<beans::XPropertySet> xBookmark3(xBookmarksByName->getByName("BookmarkVisibleWithCondition"), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("0==1"), getProperty<OUString>(xBookmark3, UNO_NAME_BOOKMARK_CONDITION));
+    CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xBookmark3, UNO_NAME_BOOKMARK_HIDDEN));
+
+    // <text:bookmark-start text:name="BookmarkNotHiddenWithCondition" loext:condition="1==1" loext:hidden="false"/>
+    //
+    // The following test doesn't work, while during output in the case of loext:hidden="false".
+    // no additional parameters are written. Implementation should be reviewed.
+    //
+//    uno::Reference<beans::XPropertySet> xBookmark4(xBookmarksByName->getByName("BookmarkNotHiddenWithCondition"), uno::UNO_QUERY);
+//    CPPUNIT_ASSERT_EQUAL(OUString("1==1"), getProperty<OUString>(xBookmark4, UNO_NAME_BOOKMARK_CONDITION));
+//    CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xBookmark4, UNO_NAME_BOOKMARK_HIDDEN));
+
+    // <text:bookmark-start text:name="BookmarkHiddenWithCondition" loext:condition="1==1" loext:hidden="true"/>
+    uno::Reference<beans::XPropertySet> xBookmark5(xBookmarksByName->getByName("BookmarkHiddenWithCondition"), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("1==1"), getProperty<OUString>(xBookmark5, UNO_NAME_BOOKMARK_CONDITION));
+    CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xBookmark5, UNO_NAME_BOOKMARK_HIDDEN));
+}
+
 #endif
 
 CPPUNIT_PLUGIN_IMPLEMENT();
commit 412b1f8d2b03687a13784e3055c5b0f2507dfef2
Author: Serge Krot <Serge.Krot at cib.de>
Date:   Thu Mar 1 13:00:33 2018 +0100

    tdf#101856 Backport parsing of bookmark properties
    
    Change-Id: I7654aa93d4d86a5d36201832ac3609b9f4c30e03
    Reviewed-on: https://gerrit.libreoffice.org/50565
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit 88b6b1a8c149163d226eb3295930e3407bcb8b5b)
    Reviewed-on: https://gerrit.libreoffice.org/56958
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>

diff --git a/include/xmloff/txtimp.hxx b/include/xmloff/txtimp.hxx
index 287413ba7f5c..c8e060f15d9c 100644
--- a/include/xmloff/txtimp.hxx
+++ b/include/xmloff/txtimp.hxx
@@ -711,6 +711,11 @@ public:
 
     void AddCrossRefHeadingMapping(OUString const& rFrom, OUString const& rTo);
     void MapCrossRefHeadingFieldsHorribly();
+
+    void setBookmarkAttributes(bool hidden, OUString const& condition);
+    bool getBookmarkHidden();
+    const OUString& getBookmarkCondition();
+
 };
 
 #endif
diff --git a/include/xmloff/txtparae.hxx b/include/xmloff/txtparae.hxx
index 8fb299cae511..d06a335f1f83 100644
--- a/include/xmloff/txtparae.hxx
+++ b/include/xmloff/txtparae.hxx
@@ -204,6 +204,8 @@ private:
     const OUString sTextFieldStart;
     const OUString sTextFieldEnd;
     const OUString sTextFieldStartEnd;
+    const OUString m_sBookmarkHidden;
+    const OUString m_sBookmarkCondition;
 
 protected:
     const OUString sFrameStyleName;
diff --git a/xmloff/source/text/XMLTextMarkImportContext.cxx b/xmloff/source/text/XMLTextMarkImportContext.cxx
index 3854f6c7e2da..62695a15c2f1 100644
--- a/xmloff/source/text/XMLTextMarkImportContext.cxx
+++ b/xmloff/source/text/XMLTextMarkImportContext.cxx
@@ -170,6 +170,13 @@ void XMLTextMarkImportContext::StartElement(
         }
         m_rHelper.pushFieldCtx( m_sBookmarkName, m_sFieldName );
     }
+
+    if (IsXMLToken(GetLocalName(), XML_BOOKMARK_START))
+    {
+        OUString sHidden = xAttrList->getValueByName("loext:hidden");
+        OUString sCondition = xAttrList->getValueByName("loext:condition");
+        m_rHelper.setBookmarkAttributes(sHidden == "true", sCondition);
+    }
 }
 
 void XMLTextMarkImportContext::EndElement()
@@ -346,6 +353,12 @@ void XMLTextMarkImportContext::EndElement()
                                     GetImport().GetRDFaImportHelper().AddRDFa(
                                         xMeta, xRDFaAttributes);
                                 }
+                                const Reference<XPropertySet> xPropertySet(xContent, UNO_QUERY);
+                                if (xPropertySet.is())
+                                {
+                                    xPropertySet->setPropertyValue("BookmarkHidden",    uno::Any(m_rHelper.getBookmarkHidden()));
+                                    xPropertySet->setPropertyValue("BookmarkCondition", uno::Any(m_rHelper.getBookmarkCondition()));
+                                }
                             }
 
                             if (nTmp==TypeFieldmarkEnd) {
diff --git a/xmloff/source/text/txtimp.cxx b/xmloff/source/text/txtimp.cxx
index 7dadde85e2a2..bc5aba285195 100644
--- a/xmloff/source/text/txtimp.cxx
+++ b/xmloff/source/text/txtimp.cxx
@@ -547,6 +547,9 @@ struct XMLTextImportHelper::Impl
     // Used for frame deduplication, the name of the last frame imported directly before the current one
     OUString msLastImportedFrameName;
 
+    bool m_bBookmarkHidden;
+    OUString m_sBookmarkCondition;
+
     uno::Reference<text::XText> m_xText;
     uno::Reference<text::XTextCursor> m_xCursor;
     uno::Reference<text::XTextRange> m_xCursorAsRange;
@@ -592,6 +595,7 @@ struct XMLTextImportHelper::Impl
                 bool const bProgress, bool const bBlockMode,
                 bool const bOrganizerMode)
         :   m_xTextListsHelper( new XMLTextListsHelper() )
+        ,   m_bBookmarkHidden( false )
         // XML import: reconstrution of assignment of paragraph style to outline levels (#i69629#)
         ,   m_xServiceFactory( rModel, UNO_QUERY )
         ,   m_rSvXMLImport( rImport )
@@ -2951,4 +2955,20 @@ void XMLTextImportHelper::MapCrossRefHeadingFieldsHorribly()
     }
 }
 
+void XMLTextImportHelper::setBookmarkAttributes(bool hidden, OUString const& condition)
+{
+    m_xImpl->m_bBookmarkHidden = hidden;
+    m_xImpl->m_sBookmarkCondition = condition;
+}
+
+bool XMLTextImportHelper::getBookmarkHidden()
+{
+    return m_xImpl->m_bBookmarkHidden;
+}
+
+const OUString& XMLTextImportHelper::getBookmarkCondition()
+{
+    return m_xImpl->m_sBookmarkCondition;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index 099a7385c1cf..d039682eb856 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -1248,6 +1248,8 @@ XMLTextParagraphExport::XMLTextParagraphExport(
     sTextFieldStart( "TextFieldStart"  ),
     sTextFieldEnd( "TextFieldEnd"  ),
     sTextFieldStartEnd( "TextFieldStartEnd"  ),
+    m_sBookmarkHidden("BookmarkHidden"),
+    m_sBookmarkCondition("BookmarkCondition"),
     sFrameStyleName("FrameStyleName"),
     aCharStyleNamesPropInfoCache( sCharStyleNames )
 {
commit 7a586a9c6bf28088c72f163d724d1cb3259e7920
Author: Bernhard Widl <bernhard.widl at cib.de>
Date:   Wed Nov 15 19:30:28 2017 +0100

    tdf#101856 create bookmarks w/ new hidden/cond attrs, save as odt
    
    Committer's note: this is forward ported from 5.2+backports branch, with
    numerous conflicts.
    
    tdf#101856 add new checkbox/editfield for hidden/condition attrs
    Conflicts:
            sw/uiconfig/swriter/ui/insertbookmark.ui
    Author: Bernhard Widl <bernhard.widl at cib.de>
    (cherry picked from commit c347e00821791377731ab32acd103ea006f3cc1b)
    
    tdf#101856 Fix crash in Insert Bookmark dialog
    Author: Serge Krot <Serge.Krot at cib.de>
    Reviewed-on: https://gerrit.libreoffice.org/50616
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit bcc16920eec647f2a3753d60c4d969862f272942)
    
    Change-Id: Ib1df7a4c1477693aa2d0ec067635cdcbd393cebd
    Reviewed-on: https://gerrit.libreoffice.org/46820
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>

diff --git a/sw/inc/IMark.hxx b/sw/inc/IMark.hxx
index 39ff1d7108eb..3761b0ea08fb 100644
--- a/sw/inc/IMark.hxx
+++ b/sw/inc/IMark.hxx
@@ -90,6 +90,10 @@ namespace sw { namespace mark
             virtual const vcl::KeyCode& GetKeyCode() const =0;
             virtual void SetShortName(const OUString&) =0;
             virtual void SetKeyCode(const vcl::KeyCode&) =0;
+            virtual bool IsHidden() const =0;
+            virtual const OUString& GetHideCondition() const =0;
+            virtual void Hide(bool hide) =0;
+            virtual void SetHideCondition(const OUString&) =0;
         private:
             IBookmark(IBookmark&) = delete;
             IBookmark &operator =(IBookmark const&) = delete;
diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h
index fccfd6c87bb9..377cae2b4121 100644
--- a/sw/inc/cmdid.h
+++ b/sw/inc/cmdid.h
@@ -781,6 +781,8 @@
 #define FN_SHAPE_ENDPOSITION_IN_HORI_L2R   (FN_PARAM2+26)
 #define FN_PARAM_PAM                    (FN_PARAM2+27) /* Point and Mark */
 #define FN_TEXT_BOX                     (FN_PARAM2+28) /* TextBox Property*/
+#define FN_BOOKMARK_HIDDEN              (FN_PARAM2+29) /* Hidden Property of bookmarks*/
+#define FN_BOOKMARK_CONDITION           (FN_PARAM2+30) /* Condition Property of bookmarks*/
 
 // Status: not more than 19!
 #define FN_STAT_PAGE                (FN_STAT + 1)
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index 531452561fe9..e57153609256 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -533,6 +533,11 @@ public:
         const vcl::KeyCode&,
         const OUString& rName,
         IDocumentMarkAccess::MarkType eMark = IDocumentMarkAccess::MarkType::BOOKMARK);
+    ::sw::mark::IMark* SetBookmark2(
+        const vcl::KeyCode&,
+        const OUString& rName,
+        bool bHide,
+        const OUString& rCondition);
     bool GotoMark( const ::sw::mark::IMark* const pMark );    // sets CurrentCursor.SPoint
     bool GotoMark( const ::sw::mark::IMark* const pMark, bool bAtStart );
     bool GoNextBookmark(); // true, if there was one
diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc
index fef14dcc9307..9be1de51bfe9 100644
--- a/sw/inc/strings.hrc
+++ b/sw/inc/strings.hrc
@@ -236,6 +236,8 @@
 #define STR_BOOKMARK_DEF_NAME                   NC_("STR_BOOKMARK_DEF_NAME", "Bookmark")
 #define STR_BOOKMARK_NAME                       NC_("STR_BOOKMARK_NAME", "Name")
 #define STR_BOOKMARK_TEXT                       NC_("STR_BOOKMARK_TEXT", "Text")
+#define STR_BOOKMARK_HIDDEN                     NC_("STR_BOOKMARK_HIDDEN", "Hidden")
+#define STR_BOOKMARK_CONDITION                  NC_("STR_BOOKMARK_CONDITION", "Condition")
 #define SW_STR_NONE                             NC_("SW_STR_NONE", "[None]")
 #define STR_CAPTION_BEGINNING                   NC_("STR_CAPTION_BEGINNING", "Start")
 #define STR_CAPTION_END                         NC_("STR_CAPTION_END", "End")
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 714d221d3712..a168bbc38498 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -343,6 +343,8 @@
 #define UNO_NAME_IS_GLOBAL_DOCUMENT_SECTION "IsGlobalDocumentSection"
 #define UNO_NAME_TEXT_FIELD "TextField"
 #define UNO_NAME_BOOKMARK "Bookmark"
+#define UNO_NAME_BOOKMARK_HIDDEN "BookmarkHidden"
+#define UNO_NAME_BOOKMARK_CONDITION "BookmarkCondition"
 #define UNO_NAME_TEXT_TABLE "TextTable"
 #define UNO_NAME_CELL "Cell"
 #define UNO_NAME_TEXT_FRAME "TextFrame"
diff --git a/sw/qa/uitest/writer_tests2/bookmark.py b/sw/qa/uitest/writer_tests2/bookmark.py
index 33f88d594c7a..9cbf82c29b41 100644
--- a/sw/qa/uitest/writer_tests2/bookmark.py
+++ b/sw/qa/uitest/writer_tests2/bookmark.py

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list