[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-6-1+backports' - 344 commits - basegfx/Library_basegfx.mk basegfx/source basegfx/test basic/qa basic/source canvas/source chart2/inc chart2/qa chart2/source comphelper/Library_comphelper.mk comphelper/source compilerplugins/clang configure.ac cppcanvas/source cui/source cui/uiconfig drawinglayer/qa drawinglayer/source emfio/qa filter/source helpcontent2 include/basegfx include/comphelper include/drawinglayer include/editeng include/sfx2 include/sot include/svl include/svx include/tools include/unotools include/vcl include/xmloff l10ntools/inc l10ntools/source offapi/com officecfg/registry oox/source sax/source schema/libreoffice sc/inc sc/qa sc/sdi sc/source sc/uiconfig sdext/Library_PresentationMinimizer.mk sdext/source sd/source sd/uiconfig setup_native/scripts sfx2/source slideshow/source solenv/clang-format solenv/sanitizers sot/source svgio/source svl/source svx/Library_svxcore.mk svx/source sw/inc sw/qa sw/source sw/uiconfig too ls/source translations unotools/source vcl/backendtest vcl/CustomTarget_kde5_moc.mk vcl/CustomTarget_qt5_moc.mk vcl/headless vcl/inc vcl/ios vcl/Library_vclplug_kde5.mk vcl/Library_vclplug_qt5.mk vcl/opengl vcl/osx vcl/qt5 vcl/quartz vcl/source vcl/unx vcl/win vcl/workben winaccessibility/source writerfilter/source xmloff/source xmlsecurity/inc xmlsecurity/Library_xmlsecurity.mk xmlsecurity/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Wed Nov 28 15:25:39 UTC 2018
Rebased ref, commits from common ancestor:
commit 4283337b509b471acb018c9daeb97b41dde67c8d
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
AuthorDate: Wed Nov 28 00:38:40 2018 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at 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 <erack at redhat.com>
AuthorDate: Thu Nov 22 21:37:52 2018 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at 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 <erack at 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.Krot at cib.de>
AuthorDate: Wed Oct 31 22:11:31 2018 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at 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 <erack at 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.melenchuk at cib.de>
AuthorDate: Thu Aug 9 23:42:35 2018 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at 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 <erack at 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.melenchuk at cib.de>
AuthorDate: Fri Nov 2 13:53:16 2018 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at 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.Behrens at 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.melenchuk at cib.de>
AuthorDate: Fri Nov 2 11:20:14 2018 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at 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.Behrens at 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.Krot at cib.de>
AuthorDate: Wed Oct 24 15:38:17 2018 +0200
Commit: Thorsten Behrens <Thorsten.Behrens at 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.Behrens at 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.Krot at cib.de>
AuthorDate: Tue Oct 9 10:16:18 2018 +0200
Commit: Thorsten Behrens <Thorsten.Behrens at 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 <erack at 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.Krot at cib.de>
AuthorDate: Fri Oct 5 21:17:44 2018 +0200
Commit: Thorsten Behrens <Thorsten.Behrens at 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.Behrens at 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.Krot at cib.de>
AuthorDate: Mon Oct 8 10:29:30 2018 +0200
Commit: Thorsten Behrens <Thorsten.Behrens at 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.Behrens at 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.Krot at cib.de>
AuthorDate: Fri Oct 5 21:21:58 2018 +0200
Commit: Thorsten Behrens <Thorsten.Behrens at 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.Behrens at 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.Krot at cib.de>
AuthorDate: Thu Oct 4 15:20:05 2018 +0200
Commit: Thorsten Behrens <Thorsten.Behrens at 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.Behrens at 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.Grand at cib.de>
AuthorDate: Thu Oct 25 10:06:05 2018 +0200
Commit: Thorsten Behrens <Thorsten.Behrens at 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.Grand at 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
More information about the Libreoffice-commits
mailing list