Rebased ref, commits from common ancestor:
commit 4283337b509b471acb018c9daeb97b41dde67c8d
Author:     Thorsten Behrens <thorsten.behr...@cib.de>
AuthorDate: Wed Nov 28 00:38:40 2018 +0100
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:02 2018 +0100

    Disable the GL based 3D charts
    
    KDE5 currently does not support GL windows properly, so lets disable
    that - this is the gist of 026e2623f7f498432e6dc970fb06145dfc77dc45
    but with minimal footprint for easier branch maintenance.
    
    Change-Id: I88113596e460c6300a826f821d918a761632047e

diff --git a/chart2/inc/ChartModel.hxx b/chart2/inc/ChartModel.hxx
index 83dca2872772..44e873b02912 100644
--- a/chart2/inc/ChartModel.hxx
+++ b/chart2/inc/ChartModel.hxx
@@ -476,16 +476,9 @@ public:
 
     void removeDataProviders();
 
-#if HAVE_FEATURE_OPENGL
-    OpenGLWindow* getOpenGLWindow() { return mpOpenGLWindow;}
-#endif
-
 private:
     sal_Int32 mnStart;
     sal_Int32 mnEnd;
-#if HAVE_FEATURE_OPENGL
-    VclPtr<OpenGLWindow> mpOpenGLWindow;
-#endif
 };
 
 }  // namespace chart
diff --git a/chart2/source/controller/main/ChartWindow.cxx 
b/chart2/source/controller/main/ChartWindow.cxx
index a0f7c31de47d..a5080383d9c9 100644
--- a/chart2/source/controller/main/ChartWindow.cxx
+++ b/chart2/source/controller/main/ChartWindow.cxx
@@ -58,11 +58,7 @@ ChartWindow::ChartWindow( ChartController* pController, 
vcl::Window* pParent, Wi
         , m_pWindowController( pController )
         , m_bInPaint(false)
         , m_pViewShellWindow( nullptr )
-#if HAVE_FEATURE_OPENGL
-        , m_pOpenGLWindow(VclPtr<OpenGLWindow>::Create(this, false))
-#else
         , m_pOpenGLWindow(nullptr)
-#endif
 {
     set_id("chart_window");
     SetHelpId( HID_SCH_WIN_DOCUMENT );
diff --git a/chart2/source/model/main/ChartModel.cxx 
b/chart2/source/model/main/ChartModel.cxx
index d0ceb73b88e7..c917f4d64a65 100644
--- a/chart2/source/model/main/ChartModel.cxx
+++ b/chart2/source/model/main/ChartModel.cxx
@@ -112,9 +112,6 @@ 
ChartModel::ChartModel(uno::Reference<uno::XComponentContext > const & xContext)
                 "com.sun.star.xml.NamespaceMap", 
"com.sun.star.comp.chart.XMLNameSpaceMap" ), uno::UNO_QUERY)
     , mnStart(0)
     , mnEnd(0)
-#if HAVE_FEATURE_OPENGL
-    , mpOpenGLWindow(nullptr)
-#endif
 {
     osl_atomic_increment(&m_refCount);
     {
@@ -156,9 +153,6 @@ ChartModel::ChartModel( const ChartModel & rOther )
     , m_xInternalDataProvider( rOther.m_xInternalDataProvider )
     , mnStart(rOther.mnStart)
     , mnEnd(rOther.mnEnd)
-#if HAVE_FEATURE_OPENGL
-    , mpOpenGLWindow(nullptr)
-#endif
 {
     osl_atomic_increment(&m_refCount);
     {
@@ -1309,12 +1303,7 @@ void ChartModel::setTimeBasedRange(sal_Int32 nStart, 
sal_Int32 nEnd)
 
 void ChartModel::setWindow( const sal_uInt64 nWindowPtr )
 {
-#if HAVE_FEATURE_OPENGL
-    OpenGLWindow* pWindow = reinterpret_cast<OpenGLWindow*>(nWindowPtr);
-    mpOpenGLWindow = pWindow;
-#else
     (void)nWindowPtr;
-#endif
 }
 
 void ChartModel::update()
@@ -1325,9 +1314,6 @@ void ChartModel::update()
     }
     mxChartView->setViewDirty();
     mxChartView->update();
-#if HAVE_FEATURE_OPENGL
-    mxChartView->updateOpenGLWindow();
-#endif
 }
 
 bool ChartModel::isDataFromSpreadsheet()
diff --git a/chart2/source/model/template/ChartTypeManager.cxx 
b/chart2/source/model/template/ChartTypeManager.cxx
index bb9656f76692..1b81327efd1b 100644
--- a/chart2/source/model/template/ChartTypeManager.cxx
+++ b/chart2/source/model/template/ChartTypeManager.cxx
@@ -32,9 +32,6 @@
 #include "NetChartTypeTemplate.hxx"
 #include "BubbleChartTypeTemplate.hxx"
 #include <config_features.h>
-#if HAVE_FEATURE_OPENGL
-#include "GL3DBarChartTypeTemplate.hxx"
-#endif
 #include <cppuhelper/component_context.hxx>
 #include <cppuhelper/supportsservice.hxx>
 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
@@ -529,16 +526,7 @@ uno::Reference< uno::XInterface > SAL_CALL 
ChartTypeManager::createInstance(
             case TEMPLATE_BUBBLE:
                 xTemplate.set( new BubbleChartTypeTemplate( m_xContext, 
aServiceSpecifier ));
                 break;
-#if HAVE_FEATURE_OPENGL
-            case TEMPLATE_GL3DBAR:
-                xTemplate.set(new GL3DBarChartTypeTemplate(m_xContext, 
aServiceSpecifier));
-                break;
-            case TEMPLATE_GL3DBAR_ROUNDED_RECTANGLE:
-                xTemplate.set(new GL3DBarChartTypeTemplate(m_xContext, 
aServiceSpecifier));
-                break;
-#else
             default: break;
-#endif
 //            case TEMPLATE_SURFACE:
 //            case TEMPLATE_ADDIN:
 //               break;
diff --git a/chart2/source/view/main/ChartView.cxx 
b/chart2/source/view/main/ChartView.cxx
index 22f268b19a4a..9b8e157afc28 100644
--- a/chart2/source/view/main/ChartView.cxx
+++ b/chart2/source/view/main/ChartView.cxx
@@ -50,9 +50,6 @@
 #include <DateHelper.hxx>
 #include <defines.hxx>
 #include <unonames.hxx>
-#if HAVE_FEATURE_OPENGL
-#include <GL3DBarChart.hxx>
-#endif
 #include <editeng/frmdiritem.hxx>
 #include <rtl/uuid.h>
 #include <tools/globname.hxx>
@@ -70,9 +67,6 @@
 #include <osl/mutex.hxx>
 #include <svx/unofill.hxx>
 #include <vcl/openglwin.hxx>
-#if HAVE_FEATURE_OPENGL
-#include <vcl/opengl/OpenGLContext.hxx>
-#endif
 #include <drawinglayer/XShapeDumper.hxx>
 
 #include <time.h>
@@ -1066,35 +1060,19 @@ public:
     virtual void scroll(long nDelta) override;
     virtual void contextDestroyed() override;
 
-#if HAVE_FEATURE_OPENGL
-    const OpenGLWindow* getOpenGLWindow() const;
-    void updateOpenGLWindow();
-#endif
 private:
     ChartView* mpView;
     bool mbContextDestroyed;
-#if HAVE_FEATURE_OPENGL
-    VclPtr<OpenGLWindow> mpWindow;
-#endif
 };
 
 GL2DRenderer::GL2DRenderer(ChartView* pView)
     : mpView(pView)
     , mbContextDestroyed(false)
-#if HAVE_FEATURE_OPENGL
-    , mpWindow(mpView->mrChartModel.getOpenGLWindow())
-#endif
 {
 }
 
 GL2DRenderer::~GL2DRenderer()
 {
-#if HAVE_FEATURE_OPENGL
-    SolarMutexGuard g;
-    if(!mbContextDestroyed && mpWindow)
-        mpWindow->setRenderer(nullptr);
-    mpWindow.reset();
-#endif
 }
 
 void GL2DRenderer::update()
@@ -1120,36 +1098,6 @@ void GL2DRenderer::contextDestroyed()
     mbContextDestroyed = true;
 }
 
-#if HAVE_FEATURE_OPENGL
-
-const OpenGLWindow* GL2DRenderer::getOpenGLWindow() const
-{
-    return mpWindow;
-}
-
-void GL2DRenderer::updateOpenGLWindow()
-{
-    if(mbContextDestroyed)
-        return;
-
-    OpenGLWindow* pWindow = mpView->mrChartModel.getOpenGLWindow();
-    if(pWindow != mpWindow)
-    {
-        if(mpWindow)
-        {
-            mpWindow->setRenderer(nullptr);
-        }
-
-        if(pWindow)
-        {
-            pWindow->setRenderer(this);
-        }
-    }
-    mpWindow = pWindow;
-}
-
-#endif
-
 const uno::Sequence<sal_Int8>& ExplicitValueProvider::getUnoTunnelId()
 {
     return theExplicitValueProviderUnoTunnelId::get().getSeq();
@@ -2582,11 +2530,7 @@ void ChartView::impl_refreshAddIn()
 bool ChartView::isReal3DChart()
 {
     uno::Reference< XDiagram > xDiagram( mrChartModel.getFirstDiagram() );
-#if HAVE_FEATURE_OPENGL
-    return ChartHelper::isGL3DDiagram(xDiagram);
-#else
     return false;
-#endif
 }
 
 static const char* envChartDummyFactory = getenv("CHART_DUMMY_FACTORY");
@@ -2629,24 +2573,6 @@ void ChartView::createShapes()
     }
     pShapeFactory->setPageSize(mxRootShape, aPageSize);
     pShapeFactory->clearPage(mxRootShape);
-#if HAVE_FEATURE_OPENGL
-#if HAVE_FEATURE_DESKTOP
-    if(isReal3DChart())
-    {
-        createShapes3D();
-        return;
-    }
-    else
-    {
-        m_pGL3DPlotter.reset();
-
-        // hide OpenGL window for now in normal charts
-        OpenGLWindow* pWindow = mrChartModel.getOpenGLWindow();
-        if(pWindow && !envChartDummyFactory)
-            pWindow->Show(false);
-    }
-#endif
-#endif
 
     createShapes2D(aPageSize);
 
@@ -2665,23 +2591,7 @@ void ChartView::createShapes()
 
 void ChartView::render()
 {
-#if HAVE_FEATURE_OPENGL
-    if(!isReal3DChart())
-    {
-        AbstractShapeFactory* pShapeFactory = 
AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory);
-        OpenGLWindow* pWindow = mrChartModel.getOpenGLWindow();
-        if(pWindow)
-            pWindow->setRenderer(mp2DRenderer.get());
-        bool bRender = pShapeFactory->preRender(mxRootShape, pWindow);
-        if(bRender)
-        {
-            pShapeFactory->render(mxRootShape, pWindow != 
mp2DRenderer->getOpenGLWindow());
-            pShapeFactory->postRender(pWindow);
-        }
-    }
-#else
     (void) this;
-#endif
 }
 
 // util::XEventListener (base of XCloseListener)
@@ -2720,11 +2630,6 @@ void ChartView::impl_updateView( bool bCheckLockedCtrler 
)
 
             //create chart view
             {
-#if HAVE_FEATURE_OPENGL
-                OpenGLWindow* pWindow = mrChartModel.getOpenGLWindow();
-                if (pWindow && 
ChartHelper::isGL3DDiagram(mrChartModel.getFirstDiagram()))
-                    pWindow->Initialize();
-#endif
                 m_bViewDirty = false;
                 m_bViewUpdatePending = false;
                 createShapes();
@@ -3310,91 +3215,8 @@ bool ChartView::createAxisTitleShapes2D( 
CreateShapeParam2D& rParam, const css::
 
 void ChartView::createShapes3D()
 {
-#if HAVE_FEATURE_OPENGL
-    OpenGLWindow* pWindow = mrChartModel.getOpenGLWindow();
-    if(!pWindow)
-        return;
-
-    if( pWindow->GetSizePixel().Width() == 0 || 
pWindow->GetSizePixel().Height() == 0 )
-    {
-        awt::Size aPageSize = mrChartModel.getVisualAreaSize( 
embed::Aspects::MSOLE_CONTENT );
-        Size aSize = pWindow->LogicToPixel(Size(aPageSize.Width, 
aPageSize.Height), MapMode(MapUnit::Map100thMM));
-        pWindow->SetSizePixel(aSize);
-    }
-    pWindow->Show();
-    uno::Reference< XDiagram > xDiagram( mrChartModel.getFirstDiagram() );
-    uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, 
uno::UNO_QUERY );
-    if( !xCooSysContainer.is())
-        return;
-
-    uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( 
xCooSysContainer->getCoordinateSystems() );
-
-    if (aCooSysList.getLength() != 1)
-        // Supporting multiple coordinates in a truly 3D chart (which implies
-        // it's a Cartesian coordinate system) is a bit of a challenge, if not
-        // impossible.
-        return;
-
-    uno::Reference<XCoordinateSystem> xCooSys( aCooSysList[0] );
-
-    //iterate through all chart types in the current coordinate system
-    uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, 
uno::UNO_QUERY );
-    OSL_ASSERT( xChartTypeContainer.is());
-    if( !xChartTypeContainer.is() )
-        return;
-
-    uno::Sequence< uno::Reference< XChartType > > aChartTypeList( 
xChartTypeContainer->getChartTypes() );
-    if (aChartTypeList.getLength() != 1)
-        // Likewise, we can't really support multiple chart types here.
-        return;
-
-    uno::Reference< XChartType > xChartType( aChartTypeList[0] );
-
-    if (!m_pGL3DPlotter)
-    {
-        m_pGL3DPlotter.reset(new GL3DBarChart(xChartType, pWindow));
-    }
-    else
-    {
-        GL3DBarChart* pChart = 
dynamic_cast<GL3DBarChart*>(m_pGL3DPlotter.get());
-        if (pChart)
-            pChart->setOpenGLWindow(pWindow);
-    }
-
-    uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, 
uno::UNO_QUERY );
-    OSL_ASSERT( xDataSeriesContainer.is());
-    if( !xDataSeriesContainer.is() )
-        return;
-
-    std::vector<std::unique_ptr<VDataSeries> > aDataSeries;
-    uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( 
xDataSeriesContainer->getDataSeries() );
-    for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
-    {
-        uno::Reference< XDataSeries > xDataSeries( aSeriesList[nS], 
uno::UNO_QUERY );
-        if(!xDataSeries.is())
-            continue;
-
-        aDataSeries.push_back(o3tl::make_unique<VDataSeries>(xDataSeries));
-    }
-
-    std::unique_ptr<ExplicitCategoriesProvider> pCatProvider(new 
ExplicitCategoriesProvider(xCooSys, mrChartModel));
-
-    m_pGL3DPlotter->create3DShapes(aDataSeries, *pCatProvider);
-
-    m_pGL3DPlotter->render();
-#endif
-}
-
-#if HAVE_FEATURE_OPENGL
-
-void ChartView::updateOpenGLWindow()
-{
-    if(!isReal3DChart())
-        mp2DRenderer->updateOpenGLWindow();
 }
 
-#endif
-
 } //namespace chart
 
 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
commit 4f68a133f70f8b86de73774518fe932e06edcc2a
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Thu Nov 22 21:37:52 2018 +0100
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:02 2018 +0100

    Check isEmptyStringQuery() early to avoid call ..., tdf#121052 follow-up
    
    ... and comparison of lcl_getPrevRowWithEmptyValueLookup() result.
    
    Change-Id: Ie4b848f30a0696cc40b04376c352a530b99190b9
    Reviewed-on: https://gerrit.libreoffice.org/63840
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins

diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 194d8aa94522..3d08ccfca5de 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -9603,9 +9603,10 @@ static bool lcl_LookupQuery( ScAddress & o_rResultPos, 
ScDocument * pDoc, const
 //  [RangeArray] is the reference, which is to comprise at least two columns.
 //  [Index] is the number of the column in the array that contains the value 
to be returned. The first column has the number 1.
 //
+// Prerequisite of lcl_getPrevRowWithEmptyValueLookup():
+//      Value referenced by [SearchCriterion] is empty.
 // lcl_getPrevRowWithEmptyValueLookup() performs following checks:
-// - if value referenced by [SearchCriterion] is empty
-// - and if we run query with "exact match" mode (i.e. VLOOKUP)
+// - if we run query with "exact match" mode (i.e. VLOOKUP)
 // - and if we already have the same lookup done before but for another row
 //   which is also had empty [SearchCriterion]
 //
@@ -9620,12 +9621,9 @@ static bool lcl_LookupQuery( ScAddress & o_rResultPos, 
ScDocument * pDoc, const
 // This method was added only for speed up to avoid several useless complete
 // lookups inside [RangeArray] for searching empty strings.
 //
-static SCROW lcl_getPrevRowWithEmptyValueLookup(const ScLookupCache& rCache, 
const ScLookupCache::QueryCriteria& aCriteria, const ScQueryParam & rParam)
+static SCROW lcl_getPrevRowWithEmptyValueLookup( const ScLookupCache& rCache,
+        const ScLookupCache::QueryCriteria& rCriteria, const ScQueryParam & 
rParam)
 {
-    // is search with equal match?
-    if (! aCriteria.isEmptyStringQuery())
-        return -1; // not found
-
     // is lookup value empty?
     const ScQueryEntry& rEntry = rParam.GetEntry(0);
     const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
@@ -9634,7 +9632,7 @@ static SCROW lcl_getPrevRowWithEmptyValueLookup(const 
ScLookupCache& rCache, con
 
     // try to find the row index for which we have already performed lookup
     // and have some result of it inside cache
-    return rCache.lookup( aCriteria );
+    return rCache.lookup( rCriteria );
 }
 
 bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos,
@@ -9664,7 +9662,7 @@ bool ScInterpreter::LookupQueryWithCache( ScAddress & 
o_rResultPos,
         // tdf#121052: Slow load of cells with VLOOKUP with references to 
empty cells
         // This check was added only for speed up to avoid several useless 
complete
         // lookups inside [RangeArray] for searching empty strings.
-        if (eCacheResult == ScLookupCache::NOT_CACHED)
+        if (eCacheResult == ScLookupCache::NOT_CACHED && 
aCriteria.isEmptyStringQuery())
         {
             const SCROW nPrevRowWithEmptyValueLookup = 
lcl_getPrevRowWithEmptyValueLookup(rCache, aCriteria, rParam);
             if (nPrevRowWithEmptyValueLookup >= 0)
commit 6847e16e904603cff7911e3b224746dd9efc7aad
Author:     Serge Krot <serge.k...@cib.de>
AuthorDate: Wed Oct 31 22:11:31 2018 +0100
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:02 2018 +0100

    tdf#121052 sc: avoid multiple empty value lookups in ranges
    
    Change-Id: I7759aef51af2f400f3f5ec69854fd9133e845f49
    Reviewed-on: https://gerrit.libreoffice.org/62712
    Tested-by: Jenkins
    Reviewed-by: Eike Rathke <er...@redhat.com>

diff --git a/sc/inc/lookupcache.hxx b/sc/inc/lookupcache.hxx
index fa55c2bcbced..08df364b1be6 100644
--- a/sc/inc/lookupcache.hxx
+++ b/sc/inc/lookupcache.hxx
@@ -102,6 +102,10 @@ public:
                 (mbString ? (*mpStr == *r.mpStr) : (mfVal == r.mfVal));
         }
 
+        bool isEmptyStringQuery() const
+        {
+            return (getQueryOp() == QueryOp::EQUAL) && mbString && mpStr && 
mpStr->isEmpty();
+        }
     };
 
     /// MUST be new'd because Notify() deletes.
@@ -110,11 +114,13 @@ public:
     /// Remove from document structure and delete (!) cache on modify hint.
     virtual void Notify( const SfxHint& rHint ) override;
 
-    /// @returns document address in o_rAddress if Result==FOUND
+    /// @returns document address in o_rResultAddress if Result==FOUND
             Result          lookup( ScAddress & o_rResultAddress,
                                     const QueryCriteria & rCriteria,
                                     const ScAddress & rQueryAddress ) const;
 
+            SCROW           lookup( const QueryCriteria & rCriteria ) const;
+
     /** Insert query and result.
         @param bAvailable
             Pass sal_False if the search didn't deliver a result. A subsequent
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 260978ca0559..194d8aa94522 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -9597,6 +9597,46 @@ static bool lcl_LookupQuery( ScAddress & o_rResultPos, 
ScDocument * pDoc, const
     return bFound;
 }
 
+// tdf#121052:
+// =VLOOKUP(SearchCriterion; RangeArray; Index; Sorted)
+//  [SearchCriterion] is the value searched for in the first column of the 
array.
+//  [RangeArray] is the reference, which is to comprise at least two columns.
+//  [Index] is the number of the column in the array that contains the value 
to be returned. The first column has the number 1.
+//
+// lcl_getPrevRowWithEmptyValueLookup() performs following checks:
+// - if value referenced by [SearchCriterion] is empty
+// - and if we run query with "exact match" mode (i.e. VLOOKUP)
+// - and if we already have the same lookup done before but for another row
+//   which is also had empty [SearchCriterion]
+//
+// then
+//   we could say, that for current row we could reuse results of the cached 
call which was done for the row2
+//   In this case we return row index, which is >= 0.
+//
+// Elsewhere
+//   -1 is returned, which will lead to default behavior =>
+//   complete lookup will be done in RangeArray inside lcl_LookupQuery() 
method.
+//
+// This method was added only for speed up to avoid several useless complete
+// lookups inside [RangeArray] for searching empty strings.
+//
+static SCROW lcl_getPrevRowWithEmptyValueLookup(const ScLookupCache& rCache, 
const ScLookupCache::QueryCriteria& aCriteria, const ScQueryParam & rParam)
+{
+    // is search with equal match?
+    if (! aCriteria.isEmptyStringQuery())
+        return -1; // not found
+
+    // is lookup value empty?
+    const ScQueryEntry& rEntry = rParam.GetEntry(0);
+    const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+    if (! rItem.maString.getString().isEmpty())
+        return -1; // not found
+
+    // try to find the row index for which we have already performed lookup
+    // and have some result of it inside cache
+    return rCache.lookup( aCriteria );
+}
+
 bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos,
         const ScQueryParam & rParam ) const
 {
@@ -9620,6 +9660,24 @@ bool ScInterpreter::LookupQueryWithCache( ScAddress & 
o_rResultPos,
         ScLookupCache::QueryCriteria aCriteria( rEntry);
         ScLookupCache::Result eCacheResult = rCache.lookup( o_rResultPos,
                 aCriteria, aPos);
+
+        // tdf#121052: Slow load of cells with VLOOKUP with references to 
empty cells
+        // This check was added only for speed up to avoid several useless 
complete
+        // lookups inside [RangeArray] for searching empty strings.
+        if (eCacheResult == ScLookupCache::NOT_CACHED)
+        {
+            const SCROW nPrevRowWithEmptyValueLookup = 
lcl_getPrevRowWithEmptyValueLookup(rCache, aCriteria, rParam);
+            if (nPrevRowWithEmptyValueLookup >= 0)
+            {
+                // make the same lookup using cache with different row index
+                // (this lookup was already cached)
+                ScAddress aPosPrev(aPos);
+                aPosPrev.SetRow(nPrevRowWithEmptyValueLookup);
+
+                eCacheResult = rCache.lookup( o_rResultPos, aCriteria, 
aPosPrev );
+            }
+        }
+
         switch (eCacheResult)
         {
             case ScLookupCache::NOT_CACHED :
diff --git a/sc/source/core/tool/lookupcache.cxx 
b/sc/source/core/tool/lookupcache.cxx
index 95a6d196287f..bde3c9d82ae8 100644
--- a/sc/source/core/tool/lookupcache.cxx
+++ b/sc/source/core/tool/lookupcache.cxx
@@ -92,6 +92,19 @@ ScLookupCache::Result ScLookupCache::lookup( ScAddress & 
o_rResultAddress,
     return FOUND;
 }
 
+SCROW ScLookupCache::lookup( const QueryCriteria & rCriteria ) const
+{
+    // try to find the row index for which we have already performed lookup
+    for (auto it = maQueryMap.begin(); it != maQueryMap.end(); ++it)
+    {
+        if (it->second.maCriteria == rCriteria)
+            return it->first.mnRow;
+    }
+
+    // not found
+    return -1;
+}
+
 bool ScLookupCache::insert( const ScAddress & rResultAddress,
         const QueryCriteria & rCriteria, const ScAddress & rQueryAddress,
         const bool bAvailable )
commit c3fa0a0057199093952935525ed8cf353a1fa285
Author:     Vasily Melenchuk <vasily.melenc...@cib.de>
AuthorDate: Thu Aug 9 23:42:35 2018 +0300
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:01 2018 +0100

    tdf#119178: use current range as a range for conditional format
    
    During addition of new conditional format it is possible to select
    different range, not one used initially. And new range should be
    used for correct relative reference in formula evaluation.`
    
    Change-Id: If73a0ddbb268c86e8c99f0703db1a5a97fb6ca66
    Reviewed-on: https://gerrit.libreoffice.org/58800
    Tested-by: Jenkins
    Reviewed-by: Eike Rathke <er...@redhat.com>

diff --git a/sc/source/ui/condformat/condformatdlg.cxx 
b/sc/source/ui/condformat/condformatdlg.cxx
index 7776ea958f86..f5296aef037d 100644
--- a/sc/source/ui/condformat/condformatdlg.cxx
+++ b/sc/source/ui/condformat/condformatdlg.cxx
@@ -37,6 +37,7 @@ ScCondFormatList::ScCondFormatList(vcl::Window* pParent, 
WinBits nStyle)
     : Control(pParent, nStyle | WB_DIALOGCONTROL)
     , mbHasScrollBar(false)
     , mbFrozen(false)
+    , mbNewEntry(false)
     , mpScrollBar(VclPtr<ScrollBar>::Create(this, WB_VERT ))
     , mpDoc(nullptr)
     , mpDialogParent(nullptr)
@@ -137,6 +138,7 @@ void ScCondFormatList::init(ScDocument* pDoc, 
ScCondFormatDlg* pDialogParent,
             case condformat::dialog::NONE:
                 break;
         }
+        mbNewEntry = true;
     }
     Thaw();
     RecalcAll();
@@ -149,6 +151,11 @@ void ScCondFormatList::init(ScDocument* pDoc, 
ScCondFormatDlg* pDialogParent,
     RecalcAll();
 }
 
+void ScCondFormatList::SetRange(const ScRangeList& rRange)
+{
+    maRanges = rRange;
+}
+
 VCL_BUILDER_FACTORY_CONSTRUCTOR(ScCondFormatList, 0)
 
 Size ScCondFormatList::GetOptimalSize() const
@@ -178,9 +185,20 @@ ScConditionalFormat* 
ScCondFormatList::GetConditionalFormat() const
     ScConditionalFormat* pFormat = new ScConditionalFormat(0, mpDoc);
     pFormat->SetRange(maRanges);
 
-    for(EntryContainer::const_iterator itr = maEntries.begin(); itr != 
maEntries.end(); ++itr)
+    for(auto & rEntry: maEntries)
     {
-        ScFormatEntry* pEntry = (*itr)->GetEntry();
+        // tdf#119178: Sometimes initial apply-to range (the one this dialog
+        // was opened with) is different from the final apply-to range
+        // (as edited by the user)
+
+        // If this format entry is new, take top-left corner of the final range
+        // and use it to create the initial entry (token array therein, if 
applicable)
+        if (mbNewEntry)
+            rEntry->SetPos(maRanges.GetTopLeftCorner());
+        // else do nothing: setting new position when editing recompiles 
formulas
+        // in entries and nobody wants that
+
+        ScFormatEntry* pEntry = rEntry->GetEntry();
         if(pEntry)
             pFormat->AddEntry(pEntry);
     }
@@ -671,6 +689,7 @@ ScConditionalFormat* 
ScCondFormatDlg::GetConditionalFormat() const
     ScRangeList aRange;
     ScRefFlags nFlags = aRange.Parse(aRangeStr, mpViewData->GetDocument(),
         mpViewData->GetDocument()->GetAddressConvention(), maPos.Tab());
+    mpCondFormList->SetRange(aRange);
     ScConditionalFormat* pFormat = mpCondFormList->GetConditionalFormat();
 
     if((nFlags & ScRefFlags::VALID) && !aRange.empty() && pFormat)
diff --git a/sc/source/ui/inc/condformatdlg.hxx 
b/sc/source/ui/inc/condformatdlg.hxx
index 374b4611cf2c..017587fd5a9e 100644
--- a/sc/source/ui/inc/condformatdlg.hxx
+++ b/sc/source/ui/inc/condformatdlg.hxx
@@ -48,6 +48,7 @@ private:
 
     bool mbHasScrollBar;
     bool mbFrozen;
+    bool mbNewEntry;
     VclPtr<ScrollBar> mpScrollBar;
 
     ScDocument* mpDoc;
@@ -66,6 +67,8 @@ public:
         const ScRangeList& rRanges, const ScAddress& rPos,
         condformat::dialog::ScCondFormatDialogType eType);
 
+    void SetRange(const ScRangeList& rRange);
+
     virtual Size GetOptimalSize() const override;
     virtual void queue_resize(StateChangedType eReason = 
StateChangedType::Layout) override;
     virtual void Resize() override;
diff --git a/sc/source/ui/inc/condformatdlgentry.hxx 
b/sc/source/ui/inc/condformatdlgentry.hxx
index 086c7c7ee6ed..748378ba8764 100644
--- a/sc/source/ui/inc/condformatdlgentry.hxx
+++ b/sc/source/ui/inc/condformatdlgentry.hxx
@@ -74,6 +74,7 @@ public:
 
     virtual bool EventNotify( NotifyEvent& rNEvt ) override;
 
+    virtual void SetPos(const ScAddress& rPos) { maPos = rPos; };
     bool IsSelected() const { return mbActive;}
     void SetIndex(sal_Int32 nIndex);
     void SetHeight();
commit dd832ac4a3735feb3d5e7efdd2b98049c5219c34
Author:     Vasily Melenchuk <vasily.melenc...@cib.de>
AuthorDate: Fri Nov 2 13:53:16 2018 +0100
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:01 2018 +0100

    presentation minimizer: fixed problem with default filename
    
    According to code, it is expected that minimized copy of
    presentation is proposed with ".mini" suffix as default,
    but this does not works right now. As a solution a new
    localized prefix "(minimized)" is added to filename.
    
    Change-Id: If869c70a5885a9c917fc7254aa8b0d164a6f5a50
    Reviewed-on: https://gerrit.libreoffice.org/62781
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de>

diff --git 
a/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu 
b/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu
index 1a2bbe315267..c5ea67d39c2b 100644
--- a/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu
@@ -196,6 +196,9 @@ The current presentation contains no OLE objects.</value>
         <prop oor:name="STR_FILESIZESEPARATOR">
             <value xml:lang="en-US">.</value>
         </prop>
+        <prop oor:name="STR_FILENAME_SUFFIX">
+            <value xml:lang="en-US">(minimized)</value>
+        </prop>
     </node>
     <node oor:name="LastUsedSettings">
         <prop oor:name="Name">
diff --git 
a/officecfg/registry/schema/org/openoffice/Office/PresentationMinimizer.xcs 
b/officecfg/registry/schema/org/openoffice/Office/PresentationMinimizer.xcs
index 5a9758139b1f..f57c1ad42837 100644
--- a/officecfg/registry/schema/org/openoffice/Office/PresentationMinimizer.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/PresentationMinimizer.xcs
@@ -361,6 +361,10 @@ The current presentation contains no OLE objects.</value>
                <info><desc>String STR_FILESIZESEPARATOR.</desc></info>
                                <value>.</value>
                        </prop>
+                       <prop oor:name="STR_FILENAME_SUFFIX" 
oor:type="xs:string" oor:localized="true">
+               <info><desc>String STR_FILENAME_SUFFIX.</desc></info>
+                               <value>(minimized)</value>
+                       </prop>
                </group>
                <node-ref oor:name="LastUsedSettings" 
oor:node-type="OptimizerSettings">
                        <info>
diff --git a/sdext/source/minimizer/optimizerdialog.cxx 
b/sdext/source/minimizer/optimizerdialog.cxx
index 17eb90630715..9185f8e4f327 100644
--- a/sdext/source/minimizer/optimizerdialog.cxx
+++ b/sdext/source/minimizer/optimizerdialog.cxx
@@ -508,12 +508,15 @@ void ActionListener::actionPerformed( const ActionEvent& 
rEvent )
                 if ( xStorable.is() && xStorable->hasLocation() )
                 {
                     INetURLObject aURLObj( xStorable->getLocation() );
-                    if ( !aURLObj.hasFinalSlash() &&
-                         aURLObj.setExtension( "mini", 
INetURLObject::LAST_SEGMENT, false ) ) {
+                    if ( !aURLObj.hasFinalSlash() ) {
                         // tdf#105382 uri-decode file name
+                        aURLObj.removeExtension(INetURLObject::LAST_SEGMENT, 
false);
                         auto aName( aURLObj.getName( 
INetURLObject::LAST_SEGMENT,
                                                      false,
                                                      
INetURLObject::DecodeMechanism::WithCharset ) );
+                        // Add "(minimized)"
+                        aName += " ";
+                        aName += 
mrOptimizerDialog.getString(STR_FILENAME_SUFFIX);
                         aFileOpenDialog.setDefaultName( aName );
                     }
                 }
diff --git a/sdext/source/minimizer/pppoptimizertoken.cxx 
b/sdext/source/minimizer/pppoptimizertoken.cxx
index 79303918e775..b32bbc1a2a6e 100644
--- a/sdext/source/minimizer/pppoptimizertoken.cxx
+++ b/sdext/source/minimizer/pppoptimizertoken.cxx
@@ -152,6 +152,8 @@ static const TokenTable pTokenTableArray[] =
     { "STR_OPTIMIZING_GRAPHICS",    STR_OPTIMIZING_GRAPHICS },
     { "STR_CREATING_OLE_REPLACEMENTS",STR_CREATING_OLE_REPLACEMENTS },
     { "STR_FileSizeSeparator",      STR_FILESIZESEPARATOR },
+    { "STR_FILENAME_SUFFIX",        STR_FILENAME_SUFFIX },
+
 
     { "NotFound",           TK_NotFound }
 };
diff --git a/sdext/source/minimizer/pppoptimizertoken.hxx 
b/sdext/source/minimizer/pppoptimizertoken.hxx
index e458da0d3181..a72afd3ef83d 100644
--- a/sdext/source/minimizer/pppoptimizertoken.hxx
+++ b/sdext/source/minimizer/pppoptimizertoken.hxx
@@ -135,6 +135,7 @@ enum PPPOptimizerTokenEnum
     STR_OPTIMIZING_GRAPHICS,
     STR_CREATING_OLE_REPLACEMENTS,
     STR_FILESIZESEPARATOR,
+    STR_FILENAME_SUFFIX,
 
     TK_NotFound
 };
commit 4e75b8c038bf3d352fa79f8cbf171ad8caf03f04
Author:     Vasily Melenchuk <vasily.melenc...@cib.de>
AuthorDate: Fri Nov 2 11:20:14 2018 +0100
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:01 2018 +0100

    presentation minimizer: use standard error reporting
    
    Insead of custom error dialogs try to use standard LO error
    reporting & localization
    
    Change-Id: I199c7770dd884a6c5d9b22075d22ab9a9f2037a8
    Reviewed-on: https://gerrit.libreoffice.org/62779
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de>

diff --git 
a/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu 
b/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu
index 5e0b723cf53d..1a2bbe315267 100644
--- a/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu
@@ -196,9 +196,6 @@ The current presentation contains no OLE objects.</value>
         <prop oor:name="STR_FILESIZESEPARATOR">
             <value xml:lang="en-US">.</value>
         </prop>
-        <prop oor:name="STR_ERROR_IO">
-            <value xml:lang="en-US">Writing output file failed.</value>
-        </prop>
     </node>
     <node oor:name="LastUsedSettings">
         <prop oor:name="Name">
diff --git 
a/officecfg/registry/schema/org/openoffice/Office/PresentationMinimizer.xcs 
b/officecfg/registry/schema/org/openoffice/Office/PresentationMinimizer.xcs
index b74cf38d883e..5a9758139b1f 100644
--- a/officecfg/registry/schema/org/openoffice/Office/PresentationMinimizer.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/PresentationMinimizer.xcs
@@ -361,10 +361,6 @@ The current presentation contains no OLE objects.</value>
                <info><desc>String STR_FILESIZESEPARATOR.</desc></info>
                                <value>.</value>
                        </prop>
-                       <prop oor:name="STR_ERROR_IO" oor:type="xs:string" 
oor:localized="true">
-               <info><desc>String STR_ERROR_IO.</desc></info>
-                               <value>Writing output file failed.</value>
-                       </prop>
                </group>
                <node-ref oor:name="LastUsedSettings" 
oor:node-type="OptimizerSettings">
                        <info>
diff --git a/sdext/Library_PresentationMinimizer.mk 
b/sdext/Library_PresentationMinimizer.mk
index 884d4ee7310e..c1f2a00a49b5 100644
--- a/sdext/Library_PresentationMinimizer.mk
+++ b/sdext/Library_PresentationMinimizer.mk
@@ -33,6 +33,9 @@ $(eval $(call gb_Library_use_libraries,PresentationMinimizer,\
     cppu \
     cppuhelper \
     sal \
+       sfx \
+       svt \
+       vcl \
     tl \
 ))
 
@@ -51,7 +54,6 @@ $(eval $(call 
gb_Library_add_exception_objects,PresentationMinimizer,\
     sdext/source/minimizer/pppoptimizertoken \
     sdext/source/minimizer/pppoptimizeruno \
     sdext/source/minimizer/unodialog \
-    sdext/source/minimizer/errordialog \
 ))
 
 # vim:set noet sw=4 ts=4:
diff --git a/sdext/source/minimizer/errordialog.cxx 
b/sdext/source/minimizer/errordialog.cxx
deleted file mode 100644
index d4b67675069b..000000000000
--- a/sdext/source/minimizer/errordialog.cxx
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include "errordialog.hxx"
-#include "informationdialog.hxx"
-#include "optimizationstats.hxx"
-#include <com/sun/star/graphic/GraphicProvider.hpp>
-#include <com/sun/star/graphic/XGraphicProvider.hpp>
-#include <com/sun/star/graphic/XGraphic.hpp>
-#include <com/sun/star/io/TempFile.hpp>
-#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
-#include <com/sun/star/util/URL.hpp>
-#include <com/sun/star/util/URLTransformer.hpp>
-#include <com/sun/star/util/XURLTransformer.hpp>
-#include <rtl/ustrbuf.hxx>
-#include <sal/macros.h>
-
-#define DIALOG_WIDTH 240
-#define DIALOG_HEIGHT 60
-#define PAGE_POS_X 35
-#define PAGE_WIDTH (DIALOG_WIDTH - PAGE_POS_X) - 6
-
-using namespace ::com::sun::star;
-using namespace ::com::sun::star::io;
-using namespace ::com::sun::star::ui;
-using namespace ::com::sun::star::awt;
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::util;
-using namespace ::com::sun::star::lang;
-using namespace ::com::sun::star::frame;
-using namespace ::com::sun::star::beans;
-using namespace ::com::sun::star::container;
-
-void ErrorDialog::InitDialog()
-{
-    // setting the dialog properties
-    OUString pNames[]
-        = { OUString("Closeable"), OUString("Height"), OUString("Moveable"), 
OUString("PositionX"),
-            OUString("PositionY"), OUString("Title"),  OUString("Width") };
-
-    Any pValues[] = { Any(true),
-                      Any(sal_Int32(DIALOG_HEIGHT)),
-                      Any(true),
-                      Any(sal_Int32(245)),
-                      Any(sal_Int32(115)),
-                      Any(getString(STR_SUN_OPTIMIZATION_WIZARD2)),
-                      Any(sal_Int32(DIALOG_WIDTH)) };
-
-    sal_Int32 nCount = SAL_N_ELEMENTS(pNames);
-
-    Sequence<OUString> aNames(pNames, nCount);
-    Sequence<Any> aValues(pValues, nCount);
-
-    mxDialogModelMultiPropertySet->setPropertyValues(aNames, aValues);
-
-    css::uno::Reference<css::awt::XItemListener> xItemListener;
-    InsertImage(*this, "aboutimage", "private:standardimage/error", 5, 5, 25, 
25, false);
-    InsertFixedText(*this, "fixedtext", maText, PAGE_POS_X, 6, PAGE_WIDTH, 24, 
true, 0);
-    InsertButton(*this, "button", mxActionListener, DIALOG_WIDTH / 2 - 25, 
DIALOG_HEIGHT - 20, 50,
-                 2, getString(STR_OK));
-}
-
-ErrorDialog::ErrorDialog(const Reference<XComponentContext>& rxContext,
-                         Reference<XFrame> const& rxFrame, const OUString& 
rText)
-    : UnoDialog(rxContext, rxFrame)
-    , ConfigurationAccess(rxContext)
-    , mxActionListener(new OKActionListener(*this))
-    , maText(rText)
-{
-    Reference<XFrame> xFrame(mxController->getFrame());
-    Reference<XWindow> xContainerWindow(xFrame->getContainerWindow());
-    Reference<XWindowPeer> xWindowPeer(xContainerWindow, UNO_QUERY_THROW);
-    createWindowPeer(xWindowPeer);
-
-    InitDialog();
-}
-
-ErrorDialog::~ErrorDialog() {}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/errordialog.hxx 
b/sdext/source/minimizer/errordialog.hxx
deleted file mode 100644
index cc2eecb34d43..000000000000
--- a/sdext/source/minimizer/errordialog.hxx
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_ERRORDIALOG_HXX
-#define INCLUDED_SDEXT_SOURCE_MINIMIZER_ERRORDIALOG_HXX
-
-#include "unodialog.hxx"
-#include "configurationaccess.hxx"
-#include "pppoptimizertoken.hxx"
-#include <com/sun/star/lang/XServiceInfo.hpp>
-#include <com/sun/star/awt/XItemListener.hpp>
-#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/text/XTextRange.hpp>
-#include <com/sun/star/drawing/XShapes.hpp>
-#include <com/sun/star/container/XIndexAccess.hpp>
-#include <com/sun/star/view/XSelectionSupplier.hpp>
-#include <com/sun/star/uno/XComponentContext.hpp>
-#include <com/sun/star/awt/XItemEventBroadcaster.hpp>
-#include <com/sun/star/awt/PushButtonType.hpp>
-#include <com/sun/star/io/XStream.hpp>
-#include <cppuhelper/implbase.hxx>
-
-class ErrorDialog : public UnoDialog, public ConfigurationAccess
-{
-public:
-    ErrorDialog(const css::uno::Reference<css::uno::XComponentContext>& 
rxContext,
-                css::uno::Reference<css::frame::XFrame> const& rxFrame, const 
OUString& rText);
-    ~ErrorDialog();
-
-private:
-    css::uno::Reference<css::awt::XActionListener> mxActionListener;
-
-    void InitDialog();
-
-    const OUString& maText;
-};
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/optimizerdialog.cxx 
b/sdext/source/minimizer/optimizerdialog.cxx
index 62b364345674..17eb90630715 100644
--- a/sdext/source/minimizer/optimizerdialog.cxx
+++ b/sdext/source/minimizer/optimizerdialog.cxx
@@ -21,7 +21,6 @@
 #include "optimizerdialog.hxx"
 #include "impoptimizer.hxx"
 #include "fileopendialog.hxx"
-#include "errordialog.hxx"
 #include <com/sun/star/frame/XStorable.hpp>
 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
@@ -30,6 +29,9 @@
 #include <com/sun/star/util/XCloseBroadcaster.hpp>
 #include <sal/macros.h>
 #include <osl/time.h>
+#include <vcl/errinf.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
 #include <tools/urlobj.hxx>
 #include <bitmaps.hlst>
 
@@ -568,6 +570,8 @@ void ActionListener::actionPerformed( const ActionEvent& 
rEvent )
                 lArguments[ 2 ].Name = "InformationDialog";
                 lArguments[ 2 ].Value <<= mrOptimizerDialog.GetFrame();
 
+
+                ErrCode errorCode;
                 try
                 {
                     ImpOptimizer aOptimizer(
@@ -577,15 +581,30 @@ void ActionListener::actionPerformed( const ActionEvent& 
rEvent )
                 }
                 catch (css::io::IOException&)
                 {
-                    mrOptimizerDialog.maStats.SetStatusValue(TK_Progress, 
Any(static_cast<sal_Int32>(0)));
+                    // We always receive just ERRCODE_IO_CANTWRITE in case of 
problems, so no need to bother
+                    // about extracting error code from exception text
+                    errorCode = ERRCODE_IO_CANTWRITE;
+                }
+                catch (css::uno::Exception&)
+                {
+                    // Other general exception
+                    errorCode = ERRCODE_IO_GENERAL;
+                }
+
+                if (errorCode != ERRCODE_NONE)
+                {
+                    // Restore wizard controls
+                    mrOptimizerDialog.maStats.SetStatusValue(TK_Progress,
+                                                             
Any(static_cast<sal_Int32>(0)));
                     mrOptimizerDialog.setControlProperty("btnNavBack", 
"Enabled", Any(true));
                     mrOptimizerDialog.setControlProperty("btnNavNext", 
"Enabled", Any(false));
                     mrOptimizerDialog.setControlProperty("btnNavFinish", 
"Enabled", Any(true));
                     mrOptimizerDialog.setControlProperty("btnNavCancel", 
"Enabled", Any(true));
-                    ErrorDialog aInformationDialog(
-                        mrOptimizerDialog.UnoDialog::mxContext, 
mrOptimizerDialog.GetFrame(),
-                        mrOptimizerDialog.getString(STR_ERROR_IO));
-                    aInformationDialog.execute();
+
+                    OUString aFileName;
+                    mrOptimizerDialog.GetConfigProperty(TK_SaveAsURL) >>= 
aFileName;
+                    SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC, aFileName);
+                    ErrorHandler::HandleError(errorCode);
                     break;
                 }
 
diff --git a/sdext/source/minimizer/pppoptimizertoken.cxx 
b/sdext/source/minimizer/pppoptimizertoken.cxx
index 0551ba294a25..79303918e775 100644
--- a/sdext/source/minimizer/pppoptimizertoken.cxx
+++ b/sdext/source/minimizer/pppoptimizertoken.cxx
@@ -152,7 +152,6 @@ static const TokenTable pTokenTableArray[] =
     { "STR_OPTIMIZING_GRAPHICS",    STR_OPTIMIZING_GRAPHICS },
     { "STR_CREATING_OLE_REPLACEMENTS",STR_CREATING_OLE_REPLACEMENTS },
     { "STR_FileSizeSeparator",      STR_FILESIZESEPARATOR },
-    { "STR_ERROR_IO",               STR_ERROR_IO },
 
     { "NotFound",           TK_NotFound }
 };
diff --git a/sdext/source/minimizer/pppoptimizertoken.hxx 
b/sdext/source/minimizer/pppoptimizertoken.hxx
index 3562e8b0ca89..e458da0d3181 100644
--- a/sdext/source/minimizer/pppoptimizertoken.hxx
+++ b/sdext/source/minimizer/pppoptimizertoken.hxx
@@ -135,7 +135,6 @@ enum PPPOptimizerTokenEnum
     STR_OPTIMIZING_GRAPHICS,
     STR_CREATING_OLE_REPLACEMENTS,
     STR_FILESIZESEPARATOR,
-    STR_ERROR_IO,
 
     TK_NotFound
 };
commit 3a9270c3026add68ab6aad0ffefd7cd7db3751f9
Author:     Serge Krot <serge.k...@cib.de>
AuthorDate: Wed Oct 24 15:38:17 2018 +0200
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:01 2018 +0100

    sc: fix: range/step calculation for progress bar
    
    Change-Id: I733e4003b65b410d44d9a1132be4e9e10ac24c3e
    Reviewed-on: https://gerrit.libreoffice.org/62305
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de>
    
    Conflicts:
            sc/source/core/data/table1.cxx

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 5076e70b0eb8..e5a596e7c26b 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -369,7 +369,8 @@ public:
     ScFormulaCell * const * GetFormulaCellBlockAddress( SCROW nRow, size_t& 
rBlockSize ) const;
     CellType    GetCellType( SCROW nRow ) const;
     SCSIZE      GetCellCount() const;
-    sal_uInt32 GetWeightedCount() const;
+    sal_uLong GetWeightedCount() const;
+    sal_uLong GetWeightedCount(SCROW nStartRow, SCROW nEndRow) const;
     sal_uInt32 GetCodeCount() const;       // RPN-Code in formulas
     FormulaError  GetErrCode( SCROW nRow ) const;
 
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index dae1f6f36eaf..61a6cff077d4 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -294,6 +294,7 @@ public:
     }
     sal_uLong       GetCellCount() const;
     sal_uLong       GetWeightedCount() const;
+    sal_uLong       GetWeightedCount(SCROW nStartRow, SCROW nEndRow) const;
     sal_uLong       GetCodeCount() const;       // RPN code in formula
 
     sal_uInt16 GetTextWidth(SCCOL nCol, SCROW nRow) const;
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 912428f688e1..89ac4e47fe53 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -3460,48 +3460,91 @@ namespace {
 
 class WeightedCounter
 {
-    size_t mnCount;
+    sal_uLong mnCount;
 public:
     WeightedCounter() : mnCount(0) {}
 
     void operator() (const sc::CellStoreType::value_type& node)
     {
+        mnCount += getWeight(node);
+    }
+
+    static sal_uLong getWeight(const sc::CellStoreType::value_type& node)
+    {
         switch (node.type)
         {
             case sc::element_type_numeric:
             case sc::element_type_string:
-                mnCount += node.size;
+                return node.size;
             break;
             case sc::element_type_formula:
             {
+                size_t nCount = 0;
                 // Each formula cell is worth its code length plus 5.
                 sc::formula_block::const_iterator it = 
sc::formula_block::begin(*node.data);
                 sc::formula_block::const_iterator itEnd = 
sc::formula_block::end(*node.data);
                 for (; it != itEnd; ++it)
                 {
                     const ScFormulaCell* p = *it;
-                    mnCount += 5 + p->GetCode()->GetCodeLen();
+                    nCount += 5 + p->GetCode()->GetCodeLen();
                 }
+
+                return nCount;
             }
             break;
             case sc::element_type_edittext:
                 // each edit-text cell is worth 50.
-                mnCount += node.size * 50;
+                return node.size * 50;
             break;
             default:
-                ;
+                return 0;
         }
     }
 
-    size_t getCount() const { return mnCount; }
+    sal_uLong getCount() const { return mnCount; }
 };
 
+class WeightedCounterWithRows
+{
+    const SCROW mnStartRow;
+    const SCROW mnEndRow;
+    sal_uLong mnCount;
+
+public:
+    WeightedCounterWithRows(SCROW nStartRow, SCROW nEndRow)
+        : mnStartRow(nStartRow)
+        , mnEndRow(nEndRow)
+        , mnCount(0)
+    {
+    }
+
+    void operator() (const sc::CellStoreType::value_type& node)
+    {
+        const SCROW nRow1 = node.position;
+        const SCROW nRow2 = nRow1 + 1;
+
+        if (! ((nRow2 < mnStartRow) || (nRow1 > mnEndRow)))
+        {
+            mnCount += WeightedCounter::getWeight(node);
+        }
+    }
+
+    sal_uLong getCount() const { return mnCount; }
+};
+
+}
+
+sal_uLong ScColumn::GetWeightedCount() const
+{
+    const WeightedCounter aFunc = std::for_each(maCells.begin(), maCells.end(),
+        WeightedCounter());
+    return aFunc.getCount();
 }
 
-sal_uInt32 ScColumn::GetWeightedCount() const
+sal_uLong ScColumn::GetWeightedCount(SCROW nStartRow, SCROW nEndRow) const
 {
-    WeightedCounter aFunc;
-    std::for_each(maCells.begin(), maCells.end(), aFunc);
+    const WeightedCounterWithRows aFunc = std::for_each(maCells.begin(), 
maCells.end(),
+        WeightedCounterWithRows(nStartRow, nEndRow));
     return aFunc.getCount();
 }
 
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index 3f76513cb8d1..43b2ed89506c 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -2556,10 +2556,14 @@ void ScDocRowHeightUpdater::update()
         return;
     }
 
-    sal_uInt32 nCellCount = 0;
+    sal_uLong nCellCount = 0;
     vector<TabRanges>::const_iterator itr = mpTabRangesArray->begin(), itrEnd 
= mpTabRangesArray->end();
     for (; itr != itrEnd; ++itr)
     {
+        const SCTAB nTab = itr->mnTab;
+        if (!ValidTab(nTab) || nTab >= mrDoc.GetTableCount() || 
!mrDoc.maTabs[nTab])
+            continue;
+
         ScFlatBoolRowSegments::RangeData aData;
         ScFlatBoolRowSegments::RangeIterator aRangeItr(*itr->mpRanges);
         for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = 
aRangeItr.getNext(aData))
@@ -2567,7 +2571,7 @@ void ScDocRowHeightUpdater::update()
             if (!aData.mbValue)
                 continue;
 
-            nCellCount += aData.mnRow2 - aData.mnRow1 + 1;
+            nCellCount += mrDoc.maTabs[nTab]->GetWeightedCount(aData.mnRow1, 
aData.mnRow2);
         }
     }
 
@@ -2575,10 +2579,10 @@ void ScDocRowHeightUpdater::update()
 
     Fraction aZoom(1, 1);
     itr = mpTabRangesArray->begin();
-    sal_uInt32 nProgressStart = 0;
+    sal_uLong nProgressStart = 0;
     for (; itr != itrEnd; ++itr)
     {
-        SCTAB nTab = itr->mnTab;
+        const SCTAB nTab = itr->mnTab;
         if (!ValidTab(nTab) || nTab >= mrDoc.GetTableCount() || 
!mrDoc.maTabs[nTab])
             continue;
 
@@ -2593,7 +2597,7 @@ void ScDocRowHeightUpdater::update()
             mrDoc.maTabs[nTab]->SetOptimalHeight(
                 aCxt, aData.mnRow1, aData.mnRow2, &aProgress, nProgressStart);
 
-            nProgressStart += aData.mnRow2 - aData.mnRow1 + 1;
+            nProgressStart += 
mrDoc.maTabs[nTab]->GetWeightedCount(aData.mnRow1, aData.mnRow2);
         }
     }
 }
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index a4ff71ee3036..3062de5a3dca 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -50,6 +50,7 @@
 #include <scmatrix.hxx>
 #include <refupdatecontext.hxx>
 #include <rowheightcontext.hxx>
+#include <vcl/svapp.hxx>
 
 #include <formula/vectortoken.hxx>
 #include <token.hxx>
@@ -84,7 +85,7 @@ ScProgress* GetProgressBar(
 
 void GetOptimalHeightsInColumn(
     sc::RowHeightContext& rCxt, ScColContainer& rCol, SCROW nStartRow, SCROW 
nEndRow,
-    ScProgress* pProgress, sal_uInt32 nProgressStart )
+    ScProgress* pProgress, sal_uLong nProgressStart )
 {
     assert(nStartRow <= nEndRow);
 
@@ -109,20 +110,24 @@ void GetOptimalHeightsInColumn(
             break;
     }
 
-    SCROW nMinStart = nPos;
+    const SCROW nMinStart = nPos;
 
-    sal_uLong nWeightedCount = 0;
-    for (SCCOL nCol=0; nCol<(rCol.size()-1); nCol++)     // last col done 
already above
+    sal_uLong nWeightedCount = nProgressStart + 
rCol.back().GetWeightedCount(nStartRow, nEndRow);
+    const SCCOL maxCol = (rCol.size() - 1); // last col done already above
+    const SCCOL progressUpdateStep = rCol.size() / 10;
+    for (SCCOL nCol=0; nCol<maxCol; nCol++)
     {
         rCol[nCol].GetOptimalHeight(rCxt, nStartRow, nEndRow, nMinHeight, 
nMinStart);
 
         if (pProgress)
         {
-            sal_uLong nWeight = rCol[nCol].GetWeightedCount();
-            if (nWeight)        // does not have to be the same Status
+            nWeightedCount += rCol[nCol].GetWeightedCount(nStartRow, nEndRow);
+            pProgress->SetState( nWeightedCount );
+
+            if ((nCol % progressUpdateStep) == 0)
             {
-                nWeightedCount += nWeight;
-                pProgress->SetState( nWeightedCount + nProgressStart );
+                // try to make sure the progress dialog is painted before 
continuing
+                Application::Reschedule(true);
             }
         }
     }
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index e59475ff3514..776ca2e3c51a 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -3546,8 +3546,17 @@ sal_uLong ScTable::GetWeightedCount() const
     sal_uLong nCellCount = 0;
 
     for ( SCCOL nCol=0; nCol < aCol.size(); nCol++ )
-        if ( aCol[nCol].GetCellCount() )
-            nCellCount += aCol[nCol].GetWeightedCount();
+        nCellCount += aCol[nCol].GetWeightedCount();
+
+    return nCellCount;
+}
+
+sal_uLong ScTable::GetWeightedCount(SCROW nStartRow, SCROW nEndRow) const
+{
+    sal_uLong nCellCount = 0;
+
+    for ( SCCOL nCol=0; nCol < aCol.size(); nCol++ )
+        nCellCount += aCol[nCol].GetWeightedCount(nStartRow, nEndRow);
 
     return nCellCount;
 }
commit f54fb9562212915b89505fa417354dfbdab5e76c
Author:     Serge Krot <serge.k...@cib.de>
AuthorDate: Tue Oct 9 10:16:18 2018 +0200
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:01 2018 +0100

    sc: speed-up: avoid usage of svl::SharedString where it is possible
    
    Change-Id: I55a1a634927cb1d7a04267d02322fcfa41d390d0
    Reviewed-on: https://gerrit.libreoffice.org/61572
    Tested-by: Jenkins
    Reviewed-by: Eike Rathke <er...@redhat.com>

diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 07c4030382c2..e59475ff3514 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -2473,28 +2473,22 @@ public:
         return std::pair<bool,bool>(bOk, bTestEqual);
     }
 
-    std::pair<bool,bool> compareByString(
+   std::pair<bool,bool> compareByString(
         ScRefCellValue& rCell, SCROW nRow, const ScQueryEntry& rEntry, const 
ScQueryEntry::Item& rItem,
         const ScInterpreterContext* pContext)
     {
-        bool bOk = false;
-        bool bTestEqual = false;
-        bool bMatchWholeCell = mbMatchWholeCell;
-        svl::SharedString aCellStr;
-        const svl::SharedString* pCellSharedStr = &aCellStr;
-        if (isPartialTextMatchOp(rEntry))
-            // may have to do partial textural comparison.
-            bMatchWholeCell = false;
-
         if (!rCell.isEmpty())
         {
             if (rCell.meType == CELLTYPE_FORMULA && 
rCell.mpFormula->GetErrCode() != FormulaError::NONE)
             {
                 // Error cell is evaluated as string (for now).
-                aCellStr = 
mrStrPool.intern(ScGlobal::GetErrorString(rCell.mpFormula->GetErrCode()));
+                const svl::SharedString aCellStr = 
mrStrPool.intern(ScGlobal::GetErrorString(rCell.mpFormula->GetErrCode()));
+                return compareByStringComparator(rEntry, rItem, &aCellStr, 
nullptr);
             }
             else if (rCell.meType == CELLTYPE_STRING)
-                pCellSharedStr = rCell.mpString;
+            {
+                return compareByStringComparator(rEntry, rItem, 
rCell.mpString, nullptr);
+            }
             else
             {
                 sal_uInt32 nFormat = pContext ? mrTab.GetNumberFormat( 
*pContext, ScAddress(static_cast<SCCOL>(rEntry.nField), nRow, mrTab.GetTab()) ) 
:
@@ -2502,41 +2496,58 @@ public:
                 OUString aStr;
                 SvNumberFormatter* pFormatter = pContext ? 
pContext->mpFormatter : mrDoc.GetFormatTable();
                 ScCellFormat::GetInputString(rCell, nFormat, aStr, 
*pFormatter, &mrDoc);
-                aCellStr = mrStrPool.intern(aStr);
+                return compareByStringComparator(rEntry, rItem, nullptr, 
&aStr);
             }
         }
         else
         {
             OUString aStr;
             mrTab.GetInputString(static_cast<SCCOL>(rEntry.nField), nRow, 
aStr);
-            aCellStr = mrStrPool.intern(aStr);
+            return compareByStringComparator(rEntry, rItem, nullptr, &aStr);
         }
+    }
+
+    // Called from compareByString() method, where different sources of 
strings are checked.
+    // The value is placed inside one parameter: [pValueSource1] or 
[pValueSource2] but never in both.
+    std::pair<bool,bool> compareByStringComparator(const ScQueryEntry& rEntry, 
const ScQueryEntry::Item& rItem,
+        const svl::SharedString* pValueSource1, OUString * pValueSource2)
+    {
+        bool bOk = false;
+        bool bTestEqual = false;
+        bool bMatchWholeCell = mbMatchWholeCell;
+        if (isPartialTextMatchOp(rEntry))
+            // may have to do partial textural comparison.
+            bMatchWholeCell = false;
+
+        const bool bRealWildOrRegExp = isRealWildOrRegExp(rEntry);
+        const bool bTestWildOrRegExp = isTestWildOrRegExp(rEntry);
 
-        const svl::SharedString& rCellStr(*pCellSharedStr);
-        bool bRealWildOrRegExp = isRealWildOrRegExp(rEntry);
-        bool bTestWildOrRegExp = isTestWildOrRegExp(rEntry);
+        // [pValueSource1] or [pValueSource2] but never both of them or none 
of them
+        assert((pValueSource1 != nullptr) != (pValueSource2 != nullptr));
 
         if ( bRealWildOrRegExp || bTestWildOrRegExp )
         {
+            const OUString & rValue = pValueSource1 ? 
pValueSource1->getString() : *pValueSource2;
+
             sal_Int32 nStart = 0;
-            sal_Int32 nEnd   = rCellStr.getLength();
+            sal_Int32 nEnd   = rValue.getLength();
 
             // from 614 on, nEnd is behind the found text
             bool bMatch = false;
             if ( rEntry.eOp == SC_ENDS_WITH || rEntry.eOp == 
SC_DOES_NOT_END_WITH )
             {
                 nEnd = 0;
-                nStart = rCellStr.getLength();
+                nStart = rValue.getLength();
                 bMatch = rEntry.GetSearchTextPtr( mrParam.eSearchType, 
mrParam.bCaseSens, bMatchWholeCell )
-                    ->SearchBackward(rCellStr.getString(), &nStart, &nEnd);
+                    ->SearchBackward(rValue, &nStart, &nEnd);
             }
             else
             {
                 bMatch = rEntry.GetSearchTextPtr( mrParam.eSearchType, 
mrParam.bCaseSens, bMatchWholeCell )
-                    ->SearchForward(rCellStr.getString(), &nStart, &nEnd);
+                    ->SearchForward(rValue, &nStart, &nEnd);
             }
             if ( bMatch && bMatchWholeCell
-                    && (nStart != 0 || nEnd != rCellStr.getLength()) )
+                    && (nStart != 0 || nEnd != rValue.getLength()) )
                 bMatch = false;    // RegExp must match entire cell string
             if ( bRealWildOrRegExp )
             {
@@ -2557,10 +2568,10 @@ public:
                         bOk = !( bMatch && (nStart == 0) );
                         break;
                     case SC_ENDS_WITH:
-                        bOk = ( bMatch && (nEnd == rCellStr.getLength()) );
+                        bOk = ( bMatch && (nEnd == rValue.getLength()) );
                         break;
                     case SC_DOES_NOT_END_WITH:
-                        bOk = !( bMatch && (nEnd == rCellStr.getLength()) );
+                        bOk = !( bMatch && (nEnd == rValue.getLength()) );
                         break;
                     default:
                         {
@@ -2587,11 +2598,32 @@ public:
                 }
                 else if ( bMatchWholeCell )
                 {
-                    // Fast string equality check by comparing string 
identifiers.
-                    if (mrParam.bCaseSens)
-                        bOk = rCellStr.getData() == rItem.maString.getData();
-                    else
-                        bOk = rCellStr.getDataIgnoreCase() == 
rItem.maString.getDataIgnoreCase();
+                    if (pValueSource1)
+                    {
+                        // Fast string equality check by comparing string 
identifiers.
+                        if (mrParam.bCaseSens)
+                        {
+                            bOk = pValueSource1->getData() == 
rItem.maString.getData();
+                        }
+                        else
+                        {
+                            bOk = pValueSource1->getDataIgnoreCase() == 
rItem.maString.getDataIgnoreCase();
+                        }
+                    }
+                    else // if (pValueSource2)
+                    {
+                        if (mrParam.bCaseSens)
+                        {
+                            bOk = (*pValueSource2 == 
rItem.maString.getString());
+                        }
+                        else
+                        {
+                            // fallback
+                            const svl::SharedString 
rSource2(mrStrPool.intern(*pValueSource2));
+                            // Fast string equality check by comparing string 
identifiers.
+                            bOk = rSource2.getDataIgnoreCase() == 
rItem.maString.getDataIgnoreCase();
+                        }
+                    }
 
                     if ( rEntry.eOp == SC_NOT_EQUAL )
                         bOk = !bOk;
@@ -2603,12 +2635,15 @@ public:
 
                     if (!mbCaseSensitive)
                     { // Common case for vlookup etc.
+                        const svl::SharedString rSource(pValueSource1? 
*pValueSource1 : mrStrPool.intern(*pValueSource2));
+
                         const rtl_uString *pQuer = 
rItem.maString.getDataIgnoreCase();
-                        const rtl_uString *pCellStr = 
rCellStr.getDataIgnoreCase();
+                        const rtl_uString *pCellStr = 
rSource.getDataIgnoreCase();
+
                         assert(pQuer != nullptr);
                         assert(pCellStr != nullptr);
 
-                        sal_Int32 nIndex = (rEntry.eOp == SC_ENDS_WITH ||
+                        const sal_Int32 nIndex = (rEntry.eOp == SC_ENDS_WITH ||
                                             rEntry.eOp == 
SC_DOES_NOT_END_WITH) ?
                             (pCellStr->length - pQuer->length) : 0;
 
@@ -2631,18 +2666,19 @@ public:
                     }
                     else
                     {
-                        OUString aQueryStr = rItem.maString.getString();
+                        const OUString & rValue = pValueSource1 ? 
pValueSource1->getString() : *pValueSource2;
+                        const OUString aQueryStr = rItem.maString.getString();
                         const LanguageType nLang = 
ScGlobal::pSysLocale->GetLanguageTag().getLanguageType();
                         setupTransliteratorIfNeeded();
-                        OUString aCell( mpTransliteration->transliterate(
-                                            rCellStr.getString(), nLang, 0, 
rCellStr.getLength(),
+                        const OUString aCell( mpTransliteration->transliterate(
+                                            rValue, nLang, 0, 
rValue.getLength(),
                                             nullptr ) );
 
-                        OUString aQuer( mpTransliteration->transliterate(
+                        const OUString aQuer( mpTransliteration->transliterate(
                                             aQueryStr, nLang, 0, 
aQueryStr.getLength(),
                                             nullptr ) );
 
-                        sal_Int32 nIndex = (rEntry.eOp == SC_ENDS_WITH || 
rEntry.eOp == SC_DOES_NOT_END_WITH) ?
+                        const sal_Int32 nIndex = (rEntry.eOp == SC_ENDS_WITH 
|| rEntry.eOp == SC_DOES_NOT_END_WITH) ?
                             (aCell.getLength() - aQuer.getLength()) : 0;
                         nStrPos = ((nIndex < 0) ? -1 : aCell.indexOf( aQuer, 
nIndex ));
                     }
@@ -2681,9 +2717,10 @@ public:
             }
             else
             {   // use collator here because data was probably sorted
+                const OUString & rValue = pValueSource1 ? 
pValueSource1->getString() : *pValueSource2;
                 setupCollatorIfNeeded();
                 sal_Int32 nCompare = mpCollator->compareString(
-                    rCellStr.getString(), rItem.maString.getString());
+                    rValue, rItem.maString.getString());
                 switch (rEntry.eOp)
                 {
                     case SC_LESS :
commit 18a7f24910a81ea27f0808dcd22a26427d3a84a0
Author:     Serge Krot <serge.k...@cib.de>
AuthorDate: Fri Oct 5 21:17:44 2018 +0200
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:01 2018 +0100

    sc: avoid checking for time formats in case of SvNumFormatType::NUMBER
    
    Change-Id: I565506d58f2dd94a6c2c5e1c4a2000ce1f9752cf
    Reviewed-on: https://gerrit.libreoffice.org/61445
    Tested-by: Jenkins
    Reviewed-by: Katarina Behrens <katarina.behr...@cib.de>

diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index 9d4a630df51b..6f1987cd09c4 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -1492,6 +1492,9 @@ sal_uInt32 SvNumberFormatter::GetEditFormat( double 
fNumber, sal_uInt32 nFIndex,
         else
             nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang );
         break;
+    case SvNumFormatType::NUMBER:
+        nKey = GetStandardFormat( eType, eLang );
+        break;
     default:
         nKey = GetStandardFormat( fNumber, nFIndex, eType, eLang );
     }
commit 77f0a29eb72a6c01b2a4828a0db0261be742f62f
Author:     Serge Krot <serge.k...@cib.de>
AuthorDate: Mon Oct 8 10:29:30 2018 +0200
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:01 2018 +0100

    sc: Enhance binary search for ScAttrArray
    
    Change-Id: Idf417c452dbbadbede0e3f0860cce7a8a6fd308e
    Reviewed-on: https://gerrit.libreoffice.org/61517
    Tested-by: Jenkins
    Reviewed-by: Katarina Behrens <katarina.behr...@cib.de>

diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index 3330cf14c10e..813cc6562543 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -190,6 +190,9 @@ bool ScAttrArray::Concat(SCSIZE nPos)
  * no attribute in a column => nCount==1, one attribute somewhere => nCount == 
3
  * (ie. one run with no attribute + one attribute + another run with no 
attribute)
  * so a range of identical attributes is only one entry in ScAttrArray.
+ *
+ * Iterative implementation of Binary Search
+ * The same implementation was used inside ScMarkArray::Search().
  */
 
 bool ScAttrArray::Search( SCROW nRow, SCSIZE& nIndex ) const
@@ -201,33 +204,40 @@ bool ScAttrArray::Search( SCROW nRow, SCSIZE& nIndex ) 
const
         nIndex = it - mvData.begin();
     return it != mvData.end(); */
 
+    if (mvData.size() == 1)
+    {
+        nIndex = 0;
+        return true;
+    }
+
     long nHi = static_cast<long>(mvData.size()) - 1;
     long i = 0;
-    bool bFound = (mvData.size() == 1);
     long nLo = 0;
-    long nStartRow = 0;
-    while ( !bFound && nLo <= nHi )
+
+    while ( nLo <= nHi )
     {
         i = (nLo + nHi) / 2;
-        if (i > 0)
-            nStartRow = static_cast<long>(mvData[i - 1].nEndRow);
-        else
-            nStartRow = -1;
-        const long nEndRow = static_cast<long>(mvData[i].nEndRow);
-        if (nEndRow < static_cast<long>(nRow))
-            nLo = ++i;
+
+        if (mvData[i].nEndRow < nRow)
+        {
+            // If [nRow] greater, ignore left half
+            nLo = i + 1;
+        }
+        else  if ((i > 0) && (mvData[i - 1].nEndRow >= nRow))
+        {
+            // If [nRow] is smaller, ignore right half
+            nHi = i - 1;
+        }
         else
-            if (nStartRow >= static_cast<long>(nRow))
-                nHi = --i;
-            else
-                bFound = true;
+        {
+            // found
+            nIndex=static_cast<SCSIZE>(i);
+            return true;
+        }
     }
 
-    if (bFound)
-        nIndex=static_cast<SCSIZE>(i);
-    else
-        nIndex=0;
-    return bFound;
+    nIndex=0;
+    return false;
 }
 
 const ScPatternAttr* ScAttrArray::GetPattern( SCROW nRow ) const
commit 1e108e8b373ab03a627d595532922295a721ce59
Author:     Serge Krot <serge.k...@cib.de>
AuthorDate: Fri Oct 5 21:21:58 2018 +0200
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:00 2018 +0100

    sc: speed-up: no usage of temp strings objects
    
    Change-Id: I7d9812672e4cbefd7e422b5c70b54ee3ea50df2d
    Reviewed-on: https://gerrit.libreoffice.org/61446
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de>

diff --git a/sc/source/core/tool/cellform.cxx b/sc/source/core/tool/cellform.cxx
index ce40a1daefe4..858097ed8357 100644
--- a/sc/source/core/tool/cellform.cxx
+++ b/sc/source/core/tool/cellform.cxx
@@ -46,7 +46,7 @@ void ScCellFormat::GetString( ScRefCellValue& rCell, 
sal_uInt32 nFormat, OUStrin
         break;
         case CELLTYPE_VALUE:
         {
-            double nValue = rCell.mfValue;
+            const double & nValue = rCell.mfValue;
             if (!bNullVals && nValue == 0.0)
                 rString.clear();
             else
@@ -76,7 +76,7 @@ void ScCellFormat::GetString( ScRefCellValue& rCell, 
sal_uInt32 nFormat, OUStrin
                 }
                 else
                 {
-                    FormulaError nErrCode = pFCell->GetErrCode();
+                    const FormulaError nErrCode = pFCell->GetErrCode();
 
                     if (nErrCode != FormulaError::NONE)
                         rString = ScGlobal::GetErrorString(nErrCode);
@@ -120,36 +120,34 @@ OUString ScCellFormat::GetString(
 void ScCellFormat::GetInputString(
     ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString, 
SvNumberFormatter& rFormatter, const ScDocument* pDoc )
 {
-    OUString aString = rString;
     switch (rCell.meType)
     {
         case CELLTYPE_STRING:
         case CELLTYPE_EDIT:
-            aString = rCell.getString(pDoc);
+            rString = rCell.getString(pDoc);
         break;
         case CELLTYPE_VALUE:
-            rFormatter.GetInputLineString(rCell.mfValue, nFormat, aString );
+            rFormatter.GetInputLineString(rCell.mfValue, nFormat, rString );
         break;
         case CELLTYPE_FORMULA:
         {
             ScFormulaCell* pFC = rCell.mpFormula;
             if (pFC->IsEmptyDisplayedAsString())
-                aString = EMPTY_OUSTRING;
+                rString = EMPTY_OUSTRING;
             else if (pFC->IsValue())
-                rFormatter.GetInputLineString(pFC->GetValue(), nFormat, 
aString);
+                rFormatter.GetInputLineString(pFC->GetValue(), nFormat, 
rString);
             else
-                aString = pFC->GetString().getString();
+                rString = pFC->GetString().getString();
 
-            FormulaError nErrCode = pFC->GetErrCode();
+            const FormulaError nErrCode = pFC->GetErrCode();
             if (nErrCode != FormulaError::NONE)
-                aString = EMPTY_OUSTRING;
+                rString = EMPTY_OUSTRING;
         }
         break;
         default:
-            aString = EMPTY_OUSTRING;
+            rString = EMPTY_OUSTRING;
             break;
     }
-    rString = aString;
 }
 
 OUString ScCellFormat::GetOutputString( ScDocument& rDoc, const ScAddress& 
rPos, ScRefCellValue& rCell )
commit 3f666d9e03aadbfc830ea78324e66c8428d7e4ff
Author:     Serge Krot <serge.k...@cib.de>
AuthorDate: Thu Oct 4 15:20:05 2018 +0200
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:00 2018 +0100

    sc: Enhance binary search for ScMarkArray
    
    Change-Id: I0fe6a0b8987fb3c3229c5aabcbf056cfb365650c
    Reviewed-on: https://gerrit.libreoffice.org/61373
    Tested-by: Jenkins
    Reviewed-by: Katarina Behrens <katarina.behr...@cib.de>

diff --git a/sc/inc/markmulti.hxx b/sc/inc/markmulti.hxx
index cf68a403fb21..5d8d7a48d4ae 100644
--- a/sc/inc/markmulti.hxx
+++ b/sc/inc/markmulti.hxx
@@ -58,7 +58,7 @@ public:
     void SetMarkArea( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW 
nEndRow, bool bMark );
     bool IsRowMarked( SCROW nRow ) const;
     bool IsRowRangeMarked( SCROW nStartRow, SCROW nEndRow ) const;
-    bool IsEmpty() const { return ( !aMultiSelContainer.size() && 
!aRowSel.HasMarks() ); }
+    bool IsEmpty() const { return ( aMultiSelContainer.empty() && 
!aRowSel.HasMarks() ); }
     ScMarkArray GetMarkArray( SCCOL nCol ) const;
     void Clear();
     void MarkAllCols( SCROW nStartRow, SCROW nEndRow );
diff --git a/sc/qa/unit/mark_test.cxx b/sc/qa/unit/mark_test.cxx
index 0c393e934b77..6e00e4bf163d 100644
--- a/sc/qa/unit/mark_test.cxx
+++ b/sc/qa/unit/mark_test.cxx
@@ -97,6 +97,8 @@ public:
     void testDeleteTabBeforeSelected();
     void testDeleteTabAfterSelected();
 
+    void testScMarkArraySearch();
+
     CPPUNIT_TEST_SUITE(Test);
     CPPUNIT_TEST(testSimpleMark_Simple);
     CPPUNIT_TEST(testSimpleMark_Column);
@@ -107,10 +109,11 @@ public:
     CPPUNIT_TEST(testInsertTabAfterSelected);
     CPPUNIT_TEST(testDeleteTabBeforeSelected);
     CPPUNIT_TEST(testDeleteTabAfterSelected);
+    CPPUNIT_TEST(testScMarkArraySearch);
     CPPUNIT_TEST_SUITE_END();
 
 private:
-
+    void testScMarkArraySearch_check(ScMarkArray & ar, SCROW nRow, bool 
expectStatus, SCSIZE nIndexExpect);
 };
 
 static void lcl_GetSortedRanges( const ScRangeList& rRangeList, ScRangeList& 
rRangeListOut )
@@ -846,6 +849,106 @@ void Test::testDeleteTabAfterSelected()
     CPPUNIT_ASSERT_EQUAL(SCTAB(0), aMark.GetFirstSelected());
 }
 
+void Test::testScMarkArraySearch_check(ScMarkArray & ar, SCROW nRow, bool 
expectStatus, SCSIZE nIndexExpect)
+{
+    SCSIZE nIndex = 0;
+    bool status = ar.Search(nRow, nIndex);
+    CPPUNIT_ASSERT_EQUAL(expectStatus, status);
+    CPPUNIT_ASSERT_EQUAL(nIndexExpect, nIndex);
+}
+
+void Test::testScMarkArraySearch()
+{
+    // empty
+    {
+        ScMarkArray ar;
+        testScMarkArraySearch_check(ar, -1, false, 0);
+        testScMarkArraySearch_check(ar, 100, false, 0);
+    }
+
+    // one range
+    {
+        ScMarkArray ar;
+        ar.SetMarkArea(10, 20, true);
+
+        // 0-9,10-20,21+
+
+        testScMarkArraySearch_check(ar, -100, true, 0);
+        testScMarkArraySearch_check(ar, -1, true, 0);
+
+        testScMarkArraySearch_check(ar, 0,  true, 0);
+        testScMarkArraySearch_check(ar, 5,  true, 0);
+        testScMarkArraySearch_check(ar, 9,  true, 0);
+        testScMarkArraySearch_check(ar, 10, true, 1);
+        testScMarkArraySearch_check(ar, 11, true, 1);
+        testScMarkArraySearch_check(ar, 19, true, 1);
+        testScMarkArraySearch_check(ar, 20, true, 1);
+        testScMarkArraySearch_check(ar, 21, true, 2);
+        testScMarkArraySearch_check(ar, 22, true, 2);
+    }
+
+    // three ranges
+    {
+        ScMarkArray ar;
+        ar.SetMarkArea(10, 20, true);
+        ar.SetMarkArea(21, 30, true);
+        ar.SetMarkArea(50, 100, true);
+
+        // 0-9,10-30,31-49,50-100,101+
+
+        testScMarkArraySearch_check(ar, -100, true, 0);
+        testScMarkArraySearch_check(ar, -1, true, 0);
+
+        testScMarkArraySearch_check(ar, 5,  true, 0);
+        testScMarkArraySearch_check(ar, 15, true, 1);
+        testScMarkArraySearch_check(ar, 25, true, 1);
+        testScMarkArraySearch_check(ar, 35, true, 2);
+        testScMarkArraySearch_check(ar, 55, true, 3);
+        testScMarkArraySearch_check(ar, 20, true, 1);
+        testScMarkArraySearch_check(ar, 21, true, 1);
+    }
+
+    // three single-row ranges
+    {
+        ScMarkArray ar;
+        ar.SetMarkArea(4, 4, true);
+        ar.SetMarkArea(6, 6, true);
+        ar.SetMarkArea(8, 8, true);
+
+        testScMarkArraySearch_check(ar, -100, true, 0);
+        testScMarkArraySearch_check(ar, -1, true, 0);
+
+        testScMarkArraySearch_check(ar, 3,  true, 0);
+        testScMarkArraySearch_check(ar, 4, true, 1);
+        testScMarkArraySearch_check(ar, 5, true, 2);
+        testScMarkArraySearch_check(ar, 6, true, 3);
+        testScMarkArraySearch_check(ar, 7, true, 4);
+        testScMarkArraySearch_check(ar, 8, true, 5);
+        testScMarkArraySearch_check(ar, 9, true, 6);
+        testScMarkArraySearch_check(ar, 10, true, 6);
+    }
+
+    // one range
+    {
+        ScMarkArray ar;
+        ar.SetMarkArea(10, MAXROW, true);
+
+        // 0-10,11+
+
+        testScMarkArraySearch_check(ar, -100, true, 0);
+        testScMarkArraySearch_check(ar, -1, true, 0);
+
+        testScMarkArraySearch_check(ar, 0,  true, 0);
+        testScMarkArraySearch_check(ar, 5,  true, 0);
+        testScMarkArraySearch_check(ar, 9,  true, 0);
+        testScMarkArraySearch_check(ar, 10, true, 1);
+        testScMarkArraySearch_check(ar, 11, true, 1);
+        testScMarkArraySearch_check(ar, 12, true, 1);
+        testScMarkArraySearch_check(ar, 200, true, 1);
+        testScMarkArraySearch_check(ar, MAXROW, true, 1);
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/core/data/markarr.cxx b/sc/source/core/data/markarr.cxx
index d296ad05b7cb..8f051ae37f03 100644
--- a/sc/source/core/data/markarr.cxx
+++ b/sc/source/core/data/markarr.cxx
@@ -58,40 +58,41 @@ void ScMarkArray::Reset( bool bMarked, SCSIZE nNeeded )
     pData[0].bMarked = bMarked;
 }
 
+// Iterative implementation of Binary Search
 bool ScMarkArray::Search( SCROW nRow, SCSIZE& nIndex ) const
 {
-    long    nHi         = static_cast<long>(nCount) - 1;
-    long    i           = 0;
-    bool    bFound      = (nCount == 1);
     if (pData)
     {
+        long    nHi         = static_cast<long>(nCount) - 1;
+        long    i           = 0;
         long    nLo         = 0;
-        long    nStartRow   = 0;
-        while ( !bFound && nLo <= nHi )
+
+        while ( nLo <= nHi )
         {
             i = (nLo + nHi) / 2;
-            if (i > 0)
-                nStartRow = static_cast<long>(pData[i - 1].nRow);
-            else
-                nStartRow = -1;
-            long nEndRow = static_cast<long>(pData[i].nRow);
-            if (nEndRow < static_cast<long>(nRow))
-                nLo = ++i;
+
+            if (pData[i].nRow < nRow)
+            {
+                // If [nRow] greater, ignore left half
+                nLo = i + 1;
+            }
+            else if ((i > 0) && (pData[i - 1].nRow >= nRow))
+            {
+                // If [nRow] is smaller, ignore right half
+                nHi = i - 1;
+            }
             else
-                if (nStartRow >= static_cast<long>(nRow))
-                    nHi = --i;
-                else
-                    bFound = true;
+            {
+                // found
+                nIndex=static_cast<SCSIZE>(i);
+                return true;
+            }
         }
     }
-    else
-        bFound = false;
 
-    if (bFound)
-        nIndex=static_cast<SCSIZE>(i);
-    else
-        nIndex=0;
-    return bFound;
+    // not found
+    nIndex=0;
+    return false;
 }
 
 bool ScMarkArray::GetMark( SCROW nRow ) const
commit 1ae96934e2ae748fc1dbde2b4e7ddab2c87d6e2e
Author:     Armin Le Grand <armin.le.gr...@cib.de>
AuthorDate: Thu Oct 25 10:06:05 2018 +0200
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Nov 28 16:24:00 2018 +0100

    Reorganize FrameBorderPrimitive creation (II)
    
    Step5: Move the view-dependent decomposition from
    BorderLinePrimitive2D to SdrFrameBorderPrimitive2D.
    
    It is now possible to use discrete sizes before the
    line and edge matching is done what will look much
    better. When it was done at BorderLinePrimitive2D
    and the matching was already done, that match was
    'displaced' with the adapted forced scale to discrete
    units.
    
    The space and size used when zooming out for a single
    discrete unit (pixel) can heavily vary - it just covers
    a much larger logical area than the 'real' line/poly
    would do. All this needs to be handled (also for bound
    ranges) and can only be in a good way using primitives.
    
    Adapted to no longer do view-dependent changes in
    BorderLinePrimitive2D. Adapted to do these now at
    SdrFrameBorderPrimitive2D. Currently used to force
    the existing border partial lines (up to three) to
    not get taller than one logical unit.
    
    Adapted to no longer switch off AntiAliased rendering
    in VclPixelProcessor2D for processBorderLinePrimitive2D,
    this is problematic with various renderers on various
    systems (e.g. vcl still falls back to render multiple
    one-pixel-lines when taller than 3.5 pixels which looks
    horrible combined with other parts like filled polygons)
    
    All this needs fine balancing on
    - all systems
    - all renderers
    - all apps (which all have their own table implementation)
    - all render targets (pixel/PDF/print/slideshow/...)
    
    Done as thorough as possible, but may need additional
    finetuning. May also be a motivation to move away from
    vcl and implement these urgetly needed system-dependent
    primitive renderers...
    
    Adapted UnitTest testDoublePixelProcessing with the needed
    comments.
    
    Change-Id: Ie88bb76c2474b6ab3764d45a9cd1669264492acd
    Reviewed-on: https://gerrit.libreoffice.org/62344
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@cib.de>
    
    Conflicts:
            drawinglayer/source/processor2d/vclpixelprocessor2d.cxx

diff --git a/drawinglayer/qa/unit/border.cxx b/drawinglayer/qa/unit/border.cxx
index 365c90d1691f..30d278a91560 100644
--- a/drawinglayer/qa/unit/border.cxx
+++ b/drawinglayer/qa/unit/border.cxx
@@ -189,7 +189,7 @@ void DrawinglayerBorderTest::testDoublePixelProcessing()
         {
             auto pMPLAction = static_cast<MetaPolyLineAction*>(pAction);
 
-            if (0 == pMPLAction->GetLineInfo().GetWidth() && LineStyle::Solid 
== pMPLAction->GetLineInfo().GetStyle())
+            if (0 != pMPLAction->GetLineInfo().GetWidth() && LineStyle::Solid 
== pMPLAction->GetLineInfo().GetStyle())
             {
                 nPolyLineActionCount++;
             }
@@ -198,7 +198,16 @@ void DrawinglayerBorderTest::testDoublePixelProcessing()
 
     // Check if all eight (2x four) simple lines with width == 0 and
     // solid were created
-    const sal_uInt32 nExpectedNumPolyLineActions = 8;
+    //
+    // This has changed: Now, just the needed 'real' lines get created
+    // which have a width of 1. This are two lines. The former multiple
+    // lines were a combination of view-dependent force to a single-pixel
+    // line width (0 == lineWidth -> hairline) and vcl rendering this
+    // using a (insane) combination of single non-AAed lines. All the
+    // system-dependent part of the BorderLine stuff is now done in
+    // SdrFrameBorderPrimitive2D and svx.
+    // Adapted this test - still useful, breaking it may be a hint :-)
+    const sal_uInt32 nExpectedNumPolyLineActions = 2;
 
     CPPUNIT_ASSERT_EQUAL(nExpectedNumPolyLineActions, nPolyLineActionCount);
 }
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx 
b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 56a85cd65038..edebb6394222 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -76,18 +76,6 @@ namespace drawinglayer
                 && isGap() == rBorderLine.isGap();
         }
 
-        double BorderLine::getAdaptedWidth(double fMinWidth) const
-        {
-            if(isGap())
-            {
-                return std::max(getLineAttribute().getWidth(), fMinWidth);
-            }
-            else
-            {
-                return getLineAttribute().getWidth();
-            }
-        }
-
         // helper to add a centered, maybe stroked line primitive to rContainer
         void addPolygonStrokePrimitive2D(
             Primitive2DContainer& rContainer,
@@ -124,7 +112,7 @@ namespace drawinglayer
 
             for(const auto& candidate : maBorderLines)
             {
-                fRetval += 
candidate.getAdaptedWidth(mfSmallestAllowedDiscreteGapDistance);
+                fRetval += candidate.getLineAttribute().getWidth();
             }
 
             return fRetval;
@@ -143,7 +131,7 @@ namespace drawinglayer
 
                 for(const auto& candidate : maBorderLines)
                 {
-                    const double 
fWidth(candidate.getAdaptedWidth(mfSmallestAllowedDiscreteGapDistance));
+                    const double 
fWidth(candidate.getLineAttribute().getWidth());
 
                     if(!candidate.isGap())
                     {
@@ -289,8 +277,7 @@ namespace drawinglayer
             maStart(rStart),
             maEnd(rEnd),
             maBorderLines(rBorderLines),
-            maStrokeAttribute(rStrokeAttribute),
-            mfSmallestAllowedDiscreteGapDistance(0.0)
+            maStrokeAttribute(rStrokeAttribute)
         {
         }
 
@@ -320,71 +307,6 @@ namespace drawinglayer
             return false;
         }
 
-        bool BorderLinePrimitive2D::getSmallestGap(double& rfSmallestGap) const
-        {
-            bool bGapFound(false);
-
-            for(const auto& candidate : maBorderLines)
-            {
-                if(candidate.isGap())
-                {
-                    if(bGapFound)
-                    {
-                        rfSmallestGap = std::min(rfSmallestGap, 
candidate.getLineAttribute().getWidth());
-                    }
-                    else
-                    {
-                        bGapFound = true;
-                        rfSmallestGap = 
candidate.getLineAttribute().getWidth();
-                    }
-                }
-            }
-
-            return bGapFound;
-        }
-
-        void 
BorderLinePrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& 
rVisitor, const geometry::ViewInformation2D& rViewInformation) const
-        {
-            ::osl::MutexGuard aGuard(m_aMutex);
-
-            if (!getStart().equal(getEnd()) && getBorderLines().size() > 1)
-            {
-                // Line with potential gap. In this case, we want to be 
view-dependent.
-                // get the smallest gap
-                double fSmallestGap(0.0);
-
-                if(getSmallestGap(fSmallestGap))
-                {
-                    // Get the current DiscreteUnit, look at X and Y and use 
the maximum
-                    const basegfx::B2DVector 
aDiscreteVector(rViewInformation.getInverseObjectToViewTransformation() * 
basegfx::B2DVector(1.0, 1.0));
-                    const double 
fDiscreteUnit(std::min(fabs(aDiscreteVector.getX()), 
fabs(aDiscreteVector.getY())));
-
-                    // When discrete unit is bigger than distance (distance is 
less than one pixel),
-                    // force distance to one pixel. Or expressed different, do 
not let the distance
-                    // get smaller than one pixel. This is done for screen 
rendering and compatibility.
-                    // This can also be done using 
DiscreteMetricDependentPrimitive2D as base class
-                    // for this class, but specialization is better here for 
later buffering (only
-                    // do this when 'double line with gap')
-                    const double fNewDiscreteDistance(std::max(fDiscreteUnit, 
fSmallestGap));
-
-                    if (!rtl::math::approxEqual(fNewDiscreteDistance, 
mfSmallestAllowedDiscreteGapDistance))
-                    {
-                        if (!getBuffered2DDecomposition().empty())
-                        {
-                            // conditions of last local decomposition have 
changed, delete
-                            const_cast< BorderLinePrimitive2D* 
>(this)->setBuffered2DDecomposition(Primitive2DContainer());
-                        }
-
-                        // remember value for usage in create2DDecomposition
-                        const_cast< BorderLinePrimitive2D* 
>(this)->mfSmallestAllowedDiscreteGapDistance = fNewDiscreteDistance;
-                    }
-                }
-            }
-
-            // call base implementation
-            BufferedDecompositionPrimitive2D::get2DDecomposition(rVisitor, 
rViewInformation);
-        }
-
         // provide unique ID
         ImplPrimitive2DIDBlock(BorderLinePrimitive2D, 
PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D)
 
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index b8920ab850e6..6fb39f0da6fb 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -858,7 +858,27 @@ namespace drawinglayer
                     const drawinglayer::primitive2d::BorderLinePrimitive2D& 
rBorder =
                         static_cast<const 
drawinglayer::primitive2d::BorderLinePrimitive2D&>(rCandidate);
 
-                    if (rBorder.isHorizontalOrVertical(getViewInformation2D()))
+                    // It has shown that there are quite some problems here:
+                    // - vcl OutDev renderer methods stuill use fallbacks to 
paint
+                    //   multiple single lines between discrete sizes of < 3.5 
what
+                    //   looks bad and does not matzch
+                    // - mix of filled Polygons and Lines is bad when AA 
switched off
+                    // - Alignment of AA with non-AA may be bad in diverse 
different
+                    //   renderers
+                    //
+                    // Due to these reasons I change the strategy: Always draw 
AAed, but
+                    // allow fallback to test/check and if needed. The normal 
case
+                    // where BorderLines will be system-depenently snapped to 
have at
+                    // least a single discrete width per partial line (there 
may be up to
+                    // three) works well nowadays due to most renderers moving 
the AA stuff
+                    // by 0.5 pixels (discrete units) to match well with the 
non-AAed parts.
+                    //
+                    // Env-Switch for steering this, default is off.
+                    // Enable by setting at all (and to something)
+                    static const char* 
pSwitchOffAntiAliasingForHorVerBorderlines(getenv("SAL_SWITCH_OFF_ANTIALIASING_FOR_HOR_VER_BORTDERLINES"));
+                    static bool 
bSwitchOffAntiAliasingForHorVerBorderlines(nullptr != 
pSwitchOffAntiAliasingForHorVerBorderlines);
+
+                    if (bSwitchOffAntiAliasingForHorVerBorderlines && 
rBorder.isHorizontalOrVertical(getViewInformation2D()))
                     {
                         AntialiasingFlags nAntiAliasing = 
mpOutputDevice->GetAntialiasing();
                         mpOutputDevice->SetAntialiasing(nAntiAliasing & 
~AntialiasingFlags::EnableB2dDraw);
diff --git a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx 
b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
index cb57e40fbe8a..a3f41985061e 100644
--- a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
@@ -38,7 +38,9 @@ namespace drawinglayer
         /** BorderLine class
         Helper class holding the style definition for a single part of a full 
BorderLine definition.
         Line extends are for start/end and for Left/Right, seen in vector 
direction. If
-        Left != Right that means the line has a diagonal start/end
+        Left != Right that means the line has a diagonal start/end.
+        Think about it similar to a trapezoid, but not aligned to X-Axis and 
using the
+        perpendicular vector to the given one in a right-handed coordinate 
system.
         */
         class DRAWINGLAYER_DLLPUBLIC BorderLine
         {
@@ -76,9 +78,6 @@ namespace drawinglayer
             double getEndRight() const { return mfEndRight; }
             bool isGap() const { return mbIsGap; }
 
-            /// helper to get adapted width (maximum)
-            double getAdaptedWidth(double fMinWidth) const;
-
             /// compare operator
             bool operator==(const BorderLine& rBorderLine) const;
         };
@@ -111,18 +110,10 @@ namespace drawinglayer
             /// common style definitions
             const drawinglayer::attribute::StrokeAttribute  maStrokeAttribute;
 
-            // for view dependent decomposition in the case with existing gaps,
-            // remember the smallest allowed concrete gap distance, see 
get2DDecomposition
-            // implementation
-            double                                          
mfSmallestAllowedDiscreteGapDistance;
-
             /// create local decomposition
             virtual void create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const override;
 
-            /// helper to find smallest defined gap in maBorderLines
-            bool getSmallestGap(double& rfSmallestGap) const;
-
-            /// helper to get the full width taking 
mfSmallestAllowedDiscreteGapDistance into account
+            /// helper to get the full width from maBorderLines
             double getFullWidth() const;
 
         public:
@@ -145,9 +136,6 @@ namespace drawinglayer
             /// compare operator
             virtual bool operator==(const BasePrimitive2D& rPrimitive) const 
override;
 
-            /// Override standard getDecomposition to be view-dependent here
-            virtual void get2DDecomposition(Primitive2DDecompositionVisitor& 
rVisitor, const geometry::ViewInformation2D& rViewInformation) const override;
-
             /// provide unique ID
             DeclPrimitive2DIDBlock()
         };
diff --git a/include/svx/sdr/primitive2d/sdrframeborderprimitive2d.hxx 
b/include/svx/sdr/primitive2d/sdrframeborderprimitive2d.hxx
index 29afb3584538..58f3b94cfd01 100755
--- a/include/svx/sdr/primitive2d/sdrframeborderprimitive2d.hxx
+++ b/include/svx/sdr/primitive2d/sdrframeborderprimitive2d.hxx
@@ -72,7 +72,11 @@ namespace drawinglayer
                 const basegfx::B2DVector& rNormalizedPerpendicular,
                 bool bStyleMirrored);
 
-            void create2DDecomposition(Primitive2DContainer& rContainer) const;
+            void create2DDecomposition(
+                Primitive2DContainer& rContainer,
+                double fMinDiscreteUnit) const;
+
+            double getMinimalNonZeroBorderWidth() const;
         };
 
         typedef std::vector<SdrFrameBorderData> SdrFrameBorderDataVector;
@@ -88,7 +92,10 @@ namespace drawinglayer
         {
         private:
             std::shared_ptr<SdrFrameBorderDataVector>   maFrameBorders;
+            double                                      
mfMinimalNonZeroBorderWidth;
+            double                                      
mfMinimalNonZeroBorderWidthUsedForDecompose;
             bool                                        mbMergeResult;
+            bool                                        
mbForceToSingleDiscreteUnit;
 
         protected:
             // local decomposition.
@@ -99,14 +106,21 @@ namespace drawinglayer
         public:
             SdrFrameBorderPrimitive2D(
                 std::shared_ptr<SdrFrameBorderDataVector>& rFrameBorders,
-                bool bMergeResult);
+                bool bMergeResult,
+                bool bForceToSingleDiscreteUnit);
 
             // compare operator
             virtual bool operator==(const BasePrimitive2D& rPrimitive) const 
override;
 
+            // override to get view-dependent
+            virtual void get2DDecomposition(
+                Primitive2DDecompositionVisitor& rVisitor,
+                const geometry::ViewInformation2D& rViewInformation) const 
override;
+
             // data access
-            const SdrFrameBorderDataVector& getFrameBorders() const { return 
*maFrameBorders.get(); }
-            bool getMergeResult() const { return mbMergeResult; }
+            const std::shared_ptr<SdrFrameBorderDataVector>& getFrameBorders() 
const { return maFrameBorders; }
+            bool doMergeResult() const { return mbMergeResult; }
+            bool doForceToSingleDiscreteUnit() const { return 
mbForceToSingleDiscreteUnit; }
 
             // provide unique ID
             DeclPrimitive2DIDBlock()
diff --git a/svx/source/dialog/framelinkarray.cxx 
b/svx/source/dialog/framelinkarray.cxx
index 9d73ebb38827..476864e7747b 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -1232,7 +1232,8 @@ drawinglayer::primitive2d::Primitive2DContainer 
Array::CreateB2DPrimitiveRange(
             drawinglayer::primitive2d::Primitive2DReference(
                 new drawinglayer::primitive2d::SdrFrameBorderPrimitive2D(
                     aData,
-                    true)));
+                    true,       // try to merge results to have less 
primitivbes
+                    true)));    // force visualization to minimal one discrete 
unit (pixel)
     }
 
     return aSequence;
diff --git a/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx 
b/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx
index 146650eeaf78..ce608b58daa7 100755
--- a/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx
+++ b/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx
@@ -19,12 +19,25 @@
 
 #include <svx/sdr/primitive2d/sdrframeborderprimitive2d.hxx>
 #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
 #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
 #include <basegfx/polygon/b2dpolygontools.hxx>
 #include <svtools/borderhelper.hxx>
 
 namespace
 {
+    double snapToDiscreteUnit(
+        double fValue,
+        double fMinimalDiscreteUnit)
+    {
+        if(0.0 != fValue)
+        {
+            fValue = std::max(fValue, fMinimalDiscreteUnit);
+        }
+
+        return fValue;
+    }
+
     class StyleVectorCombination
     {
     private:
@@ -52,7 +65,8 @@ namespace
             const basegfx::B2DVector& rB2DVector,
             double fAngle,
             bool bMirrored,
-            const Color* pForceColor)
+            const Color* pForceColor,
+            double fMinimalDiscreteUnit)
         :   mfRefModeOffset(0.0),
             maB2DVector(rB2DVector),
             mfAngle(fAngle),
@@ -63,9 +77,18 @@ namespace
                 svx::frame::RefMode aRefMode(rStyle.GetRefMode());
                 Color aPrim(rStyle.GetColorPrim());
                 Color aSecn(rStyle.GetColorSecn());
-                double fPrim(rStyle.Prim());
-                double fSecn(rStyle.Secn());
-                const bool bSecnUsed(0.0 != fSecn);
+                const bool bSecnUsed(0.0 != rStyle.Secn());
+

... etc. - the rest is truncated
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to