[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-6-1+backports' - 4 commits - svtools/source vcl/inc vcl/qt5 vcl/source vcl/unx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Thu Nov 29 18:13:57 UTC 2018


 svtools/source/contnr/svimpbox.cxx    |    2 
 vcl/inc/qt5/Qt5Menu.hxx               |    9 ++-
 vcl/qt5/Qt5Menu.cxx                   |   94 +++++++++++++++++++++-------------
 vcl/source/window/winproc.cxx         |    5 +
 vcl/unx/generic/printer/ppdparser.cxx |   21 +++++--
 5 files changed, 89 insertions(+), 42 deletions(-)

New commits:
commit 305cc93aa168517efe4701f807b5be71c765a8d6
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: Thu Nov 29 18:58:23 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 04e04bafea03795ed89dd0133f4aba2c37ca3c4e
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: Thu Nov 29 18:58:17 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 55d8ed2e1b9a73af83b60ea1d44e37f77499f60a
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: Thu Nov 29 18:58:09 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 8a4658a1c3c4392fddc907dd0918d9180c4961ab
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: Thu Nov 29 18:57:58 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


More information about the Libreoffice-commits mailing list