[Libreoffice-commits] core.git: Branch 'libreoffice-6-2' - vcl/inc vcl/qt5

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Dec 14 13:30:10 UTC 2018


 vcl/inc/qt5/Qt5Menu.hxx |    9 +++-
 vcl/qt5/Qt5Menu.cxx     |   94 ++++++++++++++++++++++++++++++------------------
 2 files changed, 67 insertions(+), 36 deletions(-)

New commits:
commit 1a8cb9df631d820ed488cb6faafacbbf11a3f913
Author:     Aleksei Nikiforov <darktemplar at basealt.ru>
AuthorDate: Fri Nov 23 12:08:08 2018 +0300
Commit:     Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Fri Dec 14 14:29:45 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>
    
    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>
    Reviewed-on: https://gerrit.libreoffice.org/65150
    Tested-by: Jenkins
    Reviewed-by: Aleksei Nikiforov <darktemplar at basealt.ru>
    Reviewed-by: Michael Weghorn <m.weghorn at posteo.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 8acaf1e5e410..acb8f957fcf6 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>
 
@@ -47,20 +46,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), nullptr);
+            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,
@@ -74,18 +78,20 @@ QMenu* Qt5Menu::InsertMenuItem(Qt5MenuItem* pSalMenuItem, unsigned nPos)
         if (pSalMenuItem->mpSubMenu)
         {
             // submenu
+            QMenu* pTempQMenu = new QMenu(toQString(aText), nullptr);
+            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,
@@ -95,37 +101,38 @@ QMenu* Qt5Menu::InsertMenuItem(Qt5MenuItem* pSalMenuItem, unsigned nPos)
         }
         else
         {
-            delete pSalMenuItem->mpAction;
-
             if (pSalMenuItem->mnType == MenuItemType::SEPARATOR)
             {
+                QAction* pAction = new QAction(nullptr);
+                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), nullptr);
+                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)
@@ -229,6 +236,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)
         {
@@ -244,8 +252,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;
     }
 }
@@ -255,8 +264,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);
     }
 }
 
@@ -265,8 +275,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;
     }
 }
@@ -274,38 +285,46 @@ void Qt5Menu::EnableItem(unsigned nPos, bool bEnable)
 void Qt5Menu::SetItemText(unsigned, SalMenuItem* pItem, const 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*) {}
@@ -379,14 +398,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: */


More information about the Libreoffice-commits mailing list