diff options
Diffstat (limited to 'sfx2/source')
-rw-r--r-- | sfx2/source/control/dispatch.cxx | 126 |
1 files changed, 123 insertions, 3 deletions
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx index b6e3600d56d6..7782459d5186 100644 --- a/sfx2/source/control/dispatch.cxx +++ b/sfx2/source/control/dispatch.cxx @@ -26,11 +26,14 @@ #include <stdarg.h> #include <stdlib.h> +#include <boost/property_tree/json_parser.hpp> + #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> #include <com/sun/star/frame/XPopupMenuController.hpp> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <comphelper/lok.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/propertyvalue.hxx> @@ -144,6 +147,107 @@ struct SfxDispatcher_Impl std::deque< std::deque<SfxToDo_Impl> > aToDoCopyStack; }; +namespace { + + boost::property_tree::ptree fillPopupMenu(Menu* pMenu) + { + // Activate this menu first + pMenu->HandleMenuActivateEvent(pMenu); + pMenu->HandleMenuDeActivateEvent(pMenu); + + boost::property_tree::ptree aTree; + // If last item inserted is some valid text + bool bIsLastItemText = false; + sal_uInt16 nCount = pMenu->GetItemCount(); + for (sal_uInt16 nPos = 0; nPos < nCount; nPos++) + { + boost::property_tree::ptree aItemTree; + const MenuItemType aItemType = pMenu->GetItemType(nPos); + + if (aItemType == MenuItemType::DONTKNOW) + continue; + + if (aItemType == MenuItemType::SEPARATOR) + { + if (bIsLastItemText) + aItemTree.put("type", "separator"); + bIsLastItemText = false; + } + else + { + const sal_uInt16 nItemId = pMenu->GetItemId(nPos); + const OUString aCommandURL = pMenu->GetItemCommand(nItemId); + + const OUString aItemText = pMenu->GetItemText(nItemId); + Menu* pPopupSubmenu = pMenu->GetPopupMenu(nItemId); + + if (!pMenu->IsItemEnabled(nItemId)) + continue; + + if (!aItemText.isEmpty()) + aItemTree.put("text", std::string(aItemText.toUtf8().getStr())); + + if (pPopupSubmenu) + { + boost::property_tree::ptree aSubmenu = fillPopupMenu(pPopupSubmenu); + if (!aSubmenu.empty()) + { + aItemTree.put("type", "menu"); + aItemTree.push_back(std::make_pair("menu", aSubmenu)); + } + else + aItemTree.clear(); + } + else + { + if (!aCommandURL.isEmpty()) + { + aItemTree.put("type", "command"); + aItemTree.put("command", std::string(aCommandURL.toUtf8().getStr())); + } + } + + MenuItemBits aItemBits = pMenu->GetItemBits(nItemId); + bool bHasChecks = false; + if (aItemBits & MenuItemBits::CHECKABLE) + { + aItemTree.put("checktype", "checkmark"); + bHasChecks = true; + } + else if (aItemBits & MenuItemBits::RADIOCHECK) + { + aItemTree.put("checktype", "radio"); + bHasChecks = true; + } + else if (aItemBits & MenuItemBits::AUTOCHECK) + { + aItemTree.put("checktype", "auto"); + bHasChecks = true; + } + + if (bHasChecks) + { + if (pMenu->IsItemChecked(nItemId)) + aItemTree.put("checked", "true"); + else + aItemTree.put("checked", "false"); + } + } + + if (!aItemTree.empty()) + { + aTree.push_back(std::make_pair("", aItemTree)); + if (aItemType != MenuItemType::SEPARATOR) + bIsLastItemText = true; + } + } + + return aTree; + } + +} // end anonymous namespace + + /** This method checks if the stack of the SfxDispatchers is flushed, or if push- or pop- commands are pending. */ @@ -1884,9 +1988,25 @@ void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window *pWin, c xPopupController->setPopupMenu( xPopupMenu ); VCLXMenu* pAwtMenu = VCLXMenu::GetImplementation( xPopupMenu ); PopupMenu* pVCLMenu = static_cast< PopupMenu* >( pAwtMenu->GetMenu() ); - OUString aMenuURL = "private:resource/popupmenu/" + rResName; - if ( pVCLMenu && GetFrame()->GetViewShell()->TryContextMenuInterception( *pVCLMenu, aMenuURL, aEvent ) ) - pVCLMenu->Execute( pWindow, aPos ); + if (comphelper::LibreOfficeKit::isActive()) + { + boost::property_tree::ptree aMenu = fillPopupMenu(pVCLMenu); + boost::property_tree::ptree aRoot; + aRoot.add_child("menu", aMenu); + + std::stringstream aStream; + boost::property_tree::write_json(aStream, aRoot, true); + const SfxObjectShell* objSh = xImp->pFrame->GetObjectShell(); + objSh->libreOfficeKitCallback(LOK_CALLBACK_CONTEXT_MENU, aStream.str().c_str()); + } + else + { + OUString aMenuURL = "private:resource/popupmenu/" + rResName; + if (pVCLMenu && GetFrame()->GetViewShell()->TryContextMenuInterception(*pVCLMenu, aMenuURL, aEvent)) + { + pVCLMenu->Execute(pWindow, aPos); + } + } css::uno::Reference< css::lang::XComponent > xComponent( xPopupController, css::uno::UNO_QUERY ); if ( xComponent.is() ) |