[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-6-1+backports' - 301 commits - basegfx/Library_basegfx.mk basegfx/source basegfx/test canvas/source chart2/inc chart2/qa chart2/source comphelper/Library_comphelper.mk comphelper/source compilerplugins/clang configure.ac cppcanvas/source cui/source cui/uiconfig desktop/source drawinglayer/qa drawinglayer/source editeng/source filter/source .gitreview include/basegfx include/comphelper include/drawinglayer include/editeng include/sot include/svl include/svx include/tools include/unotools include/vcl include/xmloff 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 setup_native/scripts sfx2/source slideshow/source solenv/clang-format solenv/sanitizers sot/source svgio/source svl/source svtools/source svx/Library_svxcore.mk svx/source sw/inc sw/qa sw/source sw/uiconfig tools/source unotools/source vcl/backendtest vc l/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
Sat Dec 1 02:15:43 UTC 2018


Rebased ref, commits from common ancestor:
commit ab5b828c862dd6177313035a30fbb7abd1007c6a
Author:     Aleksei Nikiforov <darktemplar at basealt.ru>
AuthorDate: Fri Nov 30 10:42:38 2018 +0300
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Sat Dec 1 03:14:00 2018 +0100

    KDE5: fix build with Qt-5.6
    
    Change-Id: Ic4aef6b22d5b9c7262a534e26363c8f8cef99859
    Reviewed-on: https://gerrit.libreoffice.org/64321
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/vcl/qt5/Qt5Menu.cxx b/vcl/qt5/Qt5Menu.cxx
index c93c1954e54a..8203a30c8112 100644
--- a/vcl/qt5/Qt5Menu.cxx
+++ b/vcl/qt5/Qt5Menu.cxx
@@ -53,7 +53,7 @@ QMenu* Qt5Menu::InsertMenuItem(Qt5MenuItem* pSalMenuItem, unsigned nPos)
         // top-level menu
         if (mpQMenuBar)
         {
-            pQMenu = new QMenu(toQString(aText));
+            pQMenu = new QMenu(toQString(aText), nullptr);
             pSalMenuItem->mpMenu.reset(pQMenu);
 
             if ((nPos != MENU_APPEND)
@@ -77,7 +77,7 @@ QMenu* Qt5Menu::InsertMenuItem(Qt5MenuItem* pSalMenuItem, unsigned nPos)
         if (pSalMenuItem->mpSubMenu)
         {
             // submenu
-            QMenu* pTempQMenu = new QMenu(toQString(aText));
+            QMenu* pTempQMenu = new QMenu(toQString(aText), nullptr);
             pSalMenuItem->mpMenu.reset(pTempQMenu);
 
             if ((nPos != MENU_APPEND)
@@ -102,7 +102,7 @@ QMenu* Qt5Menu::InsertMenuItem(Qt5MenuItem* pSalMenuItem, unsigned nPos)
         {
             if (pSalMenuItem->mnType == MenuItemType::SEPARATOR)
             {
-                QAction* pAction = new QAction();
+                QAction* pAction = new QAction(nullptr);
                 pSalMenuItem->mpAction.reset(pAction);
                 pAction->setSeparator(true);
 
@@ -119,7 +119,7 @@ QMenu* Qt5Menu::InsertMenuItem(Qt5MenuItem* pSalMenuItem, unsigned nPos)
             else
             {
                 // leaf menu
-                QAction* pAction = new QAction(toQString(aText));
+                QAction* pAction = new QAction(toQString(aText), nullptr);
                 pSalMenuItem->mpAction.reset(pAction);
 
                 if ((nPos != MENU_APPEND)
commit 15ca59d3a3bf63093d888c87be99cc059434ce29
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Sun Sep 30 19:38:44 2018 +0000
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Sat Dec 1 03:14:00 2018 +0100

    implicitboolconversion: ignore quint64 bitfield
    
    Change-Id: I97380455b9f526b75c7d3855d188d2f659035ba2
    Reviewed-on: https://gerrit.libreoffice.org/61170
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>

diff --git a/compilerplugins/clang/implicitboolconversion.cxx b/compilerplugins/clang/implicitboolconversion.cxx
index d7e80f56ab36..c3834c8054db 100644
--- a/compilerplugins/clang/implicitboolconversion.cxx
+++ b/compilerplugins/clang/implicitboolconversion.cxx
@@ -641,10 +641,12 @@ bool ImplicitBoolConversion::TraverseBinNE(BinaryOperator * expr) {
 bool ImplicitBoolConversion::TraverseBinAssign(BinaryOperator * expr) {
     nested.push(std::vector<ImplicitCastExpr const *>());
     bool bRet = RecursiveASTVisitor::TraverseBinAssign(expr);
-    // /usr/include/gtk-2.0/gtk/gtktogglebutton.h: struct _GtkToggleButton:
+    // gtk-2.0/gtk/gtktogglebutton.h: struct _GtkToggleButton:
     //  guint GSEAL (active) : 1;
     // even though <http://www.gtk.org/api/2.6/gtk/GtkToggleButton.html>:
     //  "active"               gboolean              : Read / Write
+    // qt5/QtGui/qaccessible.h: struct State:
+    //  quint64 disabled : 1;
     bool bExt = false;
     MemberExpr const * me = dyn_cast<MemberExpr>(expr->getLHS());
     if (me != nullptr) {
@@ -653,7 +655,11 @@ bool ImplicitBoolConversion::TraverseBinAssign(BinaryOperator * expr) {
             && fd->getBitWidthValue(compiler.getASTContext()) == 1)
         {
             TypedefType const * t = fd->getType()->getAs<TypedefType>();
-            bExt = t != nullptr && t->getDecl()->getNameAsString() == "guint";
+            if (t != nullptr)
+            {
+                std::string sTypeName = t->getDecl()->getNameAsString();
+                bExt = (sTypeName == "guint" || sTypeName == "quint64");
+            }
         }
     }
     assert(!nested.empty());
commit 36dd66602a9852ee9364bc6b488617c7b165e7f4
Author:     Aleksei Nikiforov <darktemplar at basealt.ru>
AuthorDate: Fri Nov 23 12:08:08 2018 +0300
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Sat Dec 1 03:14:00 2018 +0100

    tdf#120814 KDE5: Assign images to menu items on first build of menu
    
    Treat submenu items similarly to action items.
    
    Qt5MenuItem controls lifetime of menus and actions instead of QMenu or QMenuBar.
    Qt5MenuItem may need to remove menus, and thus it may need to delete it.
    But if QMenu or QMenuBar owns menu, then on application exit a crash may happen
    due to order of destruction of objects.
    
    Change-Id: I66138c5692bd4955e78a805cc774ff9fc8fefb99
    Reviewed-on: https://gerrit.libreoffice.org/63886
    Tested-by: Jenkins
    Reviewed-by: Katarina Behrens <Katarina.Behrens at cib.de>

diff --git a/vcl/inc/qt5/Qt5Menu.hxx b/vcl/inc/qt5/Qt5Menu.hxx
index 43641f023542..9f7469fa3f78 100644
--- a/vcl/inc/qt5/Qt5Menu.hxx
+++ b/vcl/inc/qt5/Qt5Menu.hxx
@@ -11,6 +11,8 @@
 
 #include <salmenu.hxx>
 
+#include <memory>
+
 class MenuItemList;
 class QActionGroup;
 class QMenu;
@@ -77,15 +79,18 @@ class Qt5MenuItem : public SalMenuItem
 {
 public:
     Qt5MenuItem(const SalItemParams*);
-    virtual ~Qt5MenuItem() override;
+
+    QAction* getAction() const;
 
     Qt5Menu* mpParentMenu; // The menu into which this menu item is inserted
     Qt5Menu* mpSubMenu; // Submenu of this item (if defined)
-    QAction* mpAction; // action corresponding to this item
+    std::unique_ptr<QAction> mpAction; // action corresponding to this item
+    std::unique_ptr<QMenu> mpMenu; // menu corresponding to this item
     sal_uInt16 mnId; // Item ID
     MenuItemType mnType; // Item type
     bool mbVisible; // Item visibility.
     bool mbEnabled; // Item active.
+    Image maImage; // Item image
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Menu.cxx b/vcl/qt5/Qt5Menu.cxx
index 67a58f13996f..c93c1954e54a 100644
--- a/vcl/qt5/Qt5Menu.cxx
+++ b/vcl/qt5/Qt5Menu.cxx
@@ -10,7 +10,6 @@
 #include <Qt5Frame.hxx>
 #include <Qt5MainWindow.hxx>
 #include <Qt5Bitmap.hxx>
-#include <Qt5Tools.hxx>
 #include <Qt5Menu.hxx>
 #include <Qt5Menu.moc>
 
@@ -46,20 +45,25 @@ QMenu* Qt5Menu::InsertMenuItem(Qt5MenuItem* pSalMenuItem, unsigned nPos)
     bool bChecked = mpVCLMenu->IsItemChecked(nId);
     MenuItemBits itemBits = mpVCLMenu->GetItemBits(nId);
 
+    pSalMenuItem->mpAction.reset();
+    pSalMenuItem->mpMenu.reset();
+
     if (mbMenuBar)
     {
         // top-level menu
         if (mpQMenuBar)
         {
+            pQMenu = new QMenu(toQString(aText));
+            pSalMenuItem->mpMenu.reset(pQMenu);
+
             if ((nPos != MENU_APPEND)
                 && (static_cast<size_t>(nPos) < static_cast<size_t>(mpQMenuBar->actions().size())))
             {
-                pQMenu = new QMenu(toQString(aText), mpQMenuBar);
                 mpQMenuBar->insertMenu(mpQMenuBar->actions()[nPos], pQMenu);
             }
             else
             {
-                pQMenu = mpQMenuBar->addMenu(toQString(aText));
+                mpQMenuBar->addMenu(pQMenu);
             }
 
             connect(pQMenu, &QMenu::aboutToShow, this,
@@ -73,18 +77,20 @@ QMenu* Qt5Menu::InsertMenuItem(Qt5MenuItem* pSalMenuItem, unsigned nPos)
         if (pSalMenuItem->mpSubMenu)
         {
             // submenu
+            QMenu* pTempQMenu = new QMenu(toQString(aText));
+            pSalMenuItem->mpMenu.reset(pTempQMenu);
+
             if ((nPos != MENU_APPEND)
                 && (static_cast<size_t>(nPos) < static_cast<size_t>(pQMenu->actions().size())))
             {
-                QMenu* pTempQMenu = new QMenu(toQString(aText), pQMenu);
                 pQMenu->insertMenu(pQMenu->actions()[nPos], pTempQMenu);
-                pQMenu = pTempQMenu;
             }
             else
             {
-                pQMenu = pQMenu->addMenu(toQString(aText));
+                pQMenu->addMenu(pTempQMenu);
             }
 
+            pQMenu = pTempQMenu;
             mpQActionGroup = new QActionGroup(pQMenu);
 
             connect(pQMenu, &QMenu::aboutToShow, this,
@@ -94,37 +100,38 @@ QMenu* Qt5Menu::InsertMenuItem(Qt5MenuItem* pSalMenuItem, unsigned nPos)
         }
         else
         {
-            delete pSalMenuItem->mpAction;
-
             if (pSalMenuItem->mnType == MenuItemType::SEPARATOR)
             {
+                QAction* pAction = new QAction();
+                pSalMenuItem->mpAction.reset(pAction);
+                pAction->setSeparator(true);
+
                 if ((nPos != MENU_APPEND)
                     && (static_cast<size_t>(nPos) < static_cast<size_t>(pQMenu->actions().size())))
                 {
-                    pSalMenuItem->mpAction = pQMenu->insertSeparator(pQMenu->actions()[nPos]);
+                    pQMenu->insertAction(pQMenu->actions()[nPos], pAction);
                 }
                 else
                 {
-                    pSalMenuItem->mpAction = pQMenu->addSeparator();
+                    pQMenu->addAction(pAction);
                 }
             }
             else
             {
                 // leaf menu
-                QAction* pAction = nullptr;
+                QAction* pAction = new QAction(toQString(aText));
+                pSalMenuItem->mpAction.reset(pAction);
 
                 if ((nPos != MENU_APPEND)
                     && (static_cast<size_t>(nPos) < static_cast<size_t>(pQMenu->actions().size())))
                 {
-                    pAction = new QAction(toQString(aText), pQMenu);
                     pQMenu->insertAction(pQMenu->actions()[nPos], pAction);
                 }
                 else
                 {
-                    pAction = pQMenu->addAction(toQString(aText));
+                    pQMenu->addAction(pAction);
                 }
 
-                pSalMenuItem->mpAction = pAction;
                 pAction->setShortcut(toQString(nAccelKey.GetName(GetFrame()->GetWindow())));
 
                 if (itemBits & MenuItemBits::CHECKABLE)
@@ -228,6 +235,7 @@ void Qt5Menu::DoFullMenuUpdate(Menu* pMenuBar, QMenu* pParentMenu)
     {
         Qt5MenuItem* pSalMenuItem = GetItemAtPos(nItem);
         QMenu* pQMenu = InsertMenuItem(pSalMenuItem, MENU_APPEND);
+        SetItemImage(nItem, pSalMenuItem, pSalMenuItem->maImage);
 
         if (pSalMenuItem->mpSubMenu != nullptr)
         {
@@ -243,8 +251,9 @@ void Qt5Menu::ShowItem(unsigned nPos, bool bShow)
     if (nPos < maItems.size())
     {
         Qt5MenuItem* pSalMenuItem = GetItemAtPos(nPos);
-        if (pSalMenuItem->mpAction)
-            pSalMenuItem->mpAction->setVisible(bShow);
+        QAction* pAction = pSalMenuItem->getAction();
+        if (pAction)
+            pAction->setVisible(bShow);
         pSalMenuItem->mbVisible = bShow;
     }
 }
@@ -254,8 +263,9 @@ void Qt5Menu::CheckItem(unsigned nPos, bool bChecked)
     if (nPos < maItems.size())
     {
         Qt5MenuItem* pSalMenuItem = GetItemAtPos(nPos);
-        if (pSalMenuItem->mpAction)
-            pSalMenuItem->mpAction->setChecked(bChecked);
+        QAction* pAction = pSalMenuItem->getAction();
+        if (pAction)
+            pAction->setChecked(bChecked);
     }
 }
 
@@ -264,8 +274,9 @@ void Qt5Menu::EnableItem(unsigned nPos, bool bEnable)
     if (nPos < maItems.size())
     {
         Qt5MenuItem* pSalMenuItem = GetItemAtPos(nPos);
-        if (pSalMenuItem->mpAction)
-            pSalMenuItem->mpAction->setEnabled(bEnable);
+        QAction* pAction = pSalMenuItem->getAction();
+        if (pAction)
+            pAction->setEnabled(bEnable);
         pSalMenuItem->mbEnabled = bEnable;
     }
 }
@@ -273,38 +284,46 @@ void Qt5Menu::EnableItem(unsigned nPos, bool bEnable)
 void Qt5Menu::SetItemText(unsigned, SalMenuItem* pItem, const rtl::OUString& rText)
 {
     Qt5MenuItem* pSalMenuItem = static_cast<Qt5MenuItem*>(pItem);
-    if (pSalMenuItem->mpAction)
-        pSalMenuItem->mpAction->setText(toQString(rText));
+    QAction* pAction = pSalMenuItem->getAction();
+    if (pAction)
+        pAction->setText(toQString(rText));
 }
 
 void Qt5Menu::SetItemImage(unsigned, SalMenuItem* pItem, const Image& rImage)
 {
-    if (!rImage)
+    Qt5MenuItem* pSalMenuItem = static_cast<Qt5MenuItem*>(pItem);
+
+    // Save new image to use it in DoFullMenuUpdate
+    pSalMenuItem->maImage = rImage;
+
+    QAction* pAction = pSalMenuItem->getAction();
+    if (!pAction)
         return;
 
-    Qt5MenuItem* pSalMenuItem = static_cast<Qt5MenuItem*>(pItem);
-    if (pSalMenuItem->mpAction)
+    QImage aImage;
+
+    if (!!rImage)
     {
         SvMemoryStream aMemStm;
         vcl::PNGWriter aWriter(rImage.GetBitmapEx());
         aWriter.Write(aMemStm);
 
-        QImage aImage;
-
-        if (aImage.loadFromData(static_cast<const uchar*>(aMemStm.GetData()), aMemStm.TellEnd()))
+        if (!aImage.loadFromData(static_cast<const uchar*>(aMemStm.GetData()), aMemStm.TellEnd()))
         {
-            pSalMenuItem->mpAction->setIcon(QPixmap::fromImage(aImage));
+            return;
         }
     }
+
+    pAction->setIcon(QPixmap::fromImage(aImage));
 }
 
 void Qt5Menu::SetAccelerator(unsigned, SalMenuItem* pItem, const vcl::KeyCode&,
                              const OUString& rText)
 {
     Qt5MenuItem* pSalMenuItem = static_cast<Qt5MenuItem*>(pItem);
-    if (pSalMenuItem->mpAction)
-        pSalMenuItem->mpAction->setShortcut(
-            QKeySequence(toQString(rText), QKeySequence::PortableText));
+    QAction* pAction = pSalMenuItem->getAction();
+    if (pAction)
+        pAction->setShortcut(QKeySequence(toQString(rText), QKeySequence::PortableText));
 }
 
 void Qt5Menu::GetSystemMenuData(SystemMenuData*) {}
@@ -378,14 +397,21 @@ void Qt5Menu::NativeItemText(OUString& rItemText)
 Qt5MenuItem::Qt5MenuItem(const SalItemParams* pItemData)
     : mpParentMenu(nullptr)
     , mpSubMenu(nullptr)
-    , mpAction(nullptr)
     , mnId(pItemData->nId)
     , mnType(pItemData->eType)
     , mbVisible(true)
     , mbEnabled(true)
+    , maImage(pItemData->aImage)
 {
 }
 
-Qt5MenuItem::~Qt5MenuItem() { delete mpAction; }
+QAction* Qt5MenuItem::getAction() const
+{
+    if (mpMenu)
+        return mpMenu->menuAction();
+    if (mpAction)
+        return mpAction.get();
+    return nullptr;
+}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit f37a7e178b61dfb3872c4474ec37e1b25c0cc0b7
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Wed Nov 28 12:23:38 2018 +0000
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Sat Dec 1 03:14:00 2018 +0100

    Resolves: tdf#112215 null deref on missing optional ppd value
    
    Change-Id: Iba45437332df963e1aa213c587071ab293f36390
    Reviewed-on: https://gerrit.libreoffice.org/64163
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/unx/generic/printer/ppdparser.cxx b/vcl/unx/generic/printer/ppdparser.cxx
index af2dfbe0e249..7668701f91cb 100644
--- a/vcl/unx/generic/printer/ppdparser.cxx
+++ b/vcl/unx/generic/printer/ppdparser.cxx
@@ -852,13 +852,22 @@ PPDParser::PPDParser( const OUString& rFile ) :
     }
 
     // fill in direct values
-    if( (pKey = getKey( OUString( "ColorDevice" ) )) )
-        m_bColorDevice = pKey->getValue( 0 )->m_aValue.startsWithIgnoreAsciiCase( "true" );
+    if ((pKey = getKey(OUString("ColorDevice"))))
+    {
+        if (const PPDValue* pValue = pKey->getValue(0))
+            m_bColorDevice = pValue->m_aValue.startsWithIgnoreAsciiCase("true");
+    }
 
-    if( (pKey = getKey( OUString( "LanguageLevel" ) )) )
-        m_nLanguageLevel = pKey->getValue( 0 )->m_aValue.toInt32();
-    if( (pKey = getKey( OUString( "TTRasterizer" ) )) )
-        m_bType42Capable = pKey->getValue( 0 )->m_aValue.equalsIgnoreAsciiCase( "Type42" );
+    if ((pKey = getKey(OUString("LanguageLevel"))))
+    {
+        if (const PPDValue* pValue = pKey->getValue(0))
+            m_nLanguageLevel = pValue->m_aValue.toInt32();
+    }
+    if ((pKey = getKey(OUString("TTRasterizer"))))
+    {
+        if (const PPDValue* pValue = pKey->getValue(0))
+            m_bType42Capable = pValue->m_aValue.equalsIgnoreAsciiCase( "Type42" );
+    }
 }
 
 PPDParser::~PPDParser()
commit 656df86cbcdd35c6db09dd5e43652f5ec4b2cddd
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Nov 26 16:34:10 2018 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Sat Dec 1 03:13:59 2018 +0100

    tdf#121723 vcl: leave popup mode on focus loss of toplevel windows
    
    This way it can't happen that we open a menu or context menu, the user
    switches away (loosing focus) and a leftover floating window is still
    there.
    
    Handle this at the same place where we stop blinking the cursor on focus
    loss.
    
    Change-Id: I4321e8e3fa1d3f8976c0a1fa29c6a182972023bf
    Reviewed-on: https://gerrit.libreoffice.org/64053
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
index 45b01a01f8fa..c3c0272a4012 100644
--- a/vcl/source/window/winproc.cxx
+++ b/vcl/source/window/winproc.cxx
@@ -1843,6 +1843,11 @@ static void ImplHandleLoseFocus( vcl::Window* pWindow )
     vcl::Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
     if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
         pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
+
+    // Make sure that no menu is visible when a toplevel window loses focus.
+    VclPtr<FloatingWindow> pFirstFloat = pSVData->maWinData.mpFirstFloat;
+    if (pFirstFloat && !pWindow->GetParent())
+        pFirstFloat->EndPopupMode(FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll);
 }
 
 struct DelayedCloseEvent
commit 22d366cf81edcfcba3e31334d974cee1ad9f8249
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Mon Nov 26 10:43:11 2018 +0000
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Sat Dec 1 03:13:59 2018 +0100

    like keypress does, on mouse press create a cursor if missing
    
    Change-Id: I57cd718ed03846dbff164acb5cd3c329d9eee615
    Reviewed-on: https://gerrit.libreoffice.org/64036
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/svtools/source/contnr/svimpbox.cxx b/svtools/source/contnr/svimpbox.cxx
index 52d1f9a47f59..7eb013d651d9 100644
--- a/svtools/source/contnr/svimpbox.cxx
+++ b/svtools/source/contnr/svimpbox.cxx
@@ -1982,6 +1982,8 @@ void SvImpLBox::MouseButtonDown( const MouseEvent& rMEvt )
     if( aPos.X() > aOutputSize.Width() || aPos.Y() > aOutputSize.Height() )
         return;
 
+    if( !pCursor )
+        pCursor = pStartEntry;
     SvTreeListEntry* pEntry = GetEntry( aPos );
     if ( pEntry != pCursor )
         // new entry selected -> reset current tab position to first tab
commit ff25cdb191210cd012f3fef46c46725e8689a686
Author:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
AuthorDate: Wed Nov 28 18:53:54 2018 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Sat Dec 1 03:13:59 2018 +0100

    fix the .gitreview to point to the 6.1 distro/lhm/... branch
    
    Change-Id: I0c66fe18c6fa74d6619179eb0425a7ac40a647eb

diff --git a/.gitreview b/.gitreview
index 040bbce83108..65b6d0d4116e 100644
--- a/.gitreview
+++ b/.gitreview
@@ -3,5 +3,5 @@ host=logerrit
 port=29418
 project=core
 defaultremote=logerrit
-defaultbranch=libreoffice-6-1
+defaultbranch=distro/lhm/libreoffice-6-1+backports
 
commit 920c0afbede3c3d15842fb29dc8787d6ff04cf3b
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: Sat Dec 1 03:13:59 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 550e089164d92e0b64cdee79339edf183ef2bf5d
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: Sat Dec 1 03:13:59 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 4978fe015bc64aa740648a72603921583e0c792c
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: Sat Dec 1 03:13:59 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 74654162c0d848421a56f19c7cd4251a2451354d
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: Sat Dec 1 03:13:58 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 fa8413a5bd26004fab0d71b78900f1e9a8ec74e4
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: Sat Dec 1 03:13:58 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 8f51363a1da1e57b330495d97a97ca165285a833
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: Sat Dec 1 03:13:58 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 5c3b187098cb815d6b72ee04464ebbac5e8f4a90
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: Sat Dec 1 03:13:58 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 60b143e9aab5a3aca87b4d9e84424cb3b6813fe1
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: Sat Dec 1 03:13:58 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 2a110667189120a4a88d54466397f6bff17b48fc
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: Sat Dec 1 03:13:58 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 729839ea7ba115953557a6998739afb5086ced9e
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: Sat Dec 1 03:13:57 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 9fec64d168384a6d710e9a1c0805ca27dae68cd6
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: Sat Dec 1 03:13:57 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 aae090736059658a5790d4049f60e4e681e42c26
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: Sat Dec 1 03:13:57 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

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list