/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Defines using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::util; using namespace ::com::sun::star::container; using namespace ::com::sun::star::ui; namespace framework { // XInterface, XTypeProvider, XServiceInfo OUString SAL_CALL ToolbarModeMenuController::getImplementationName() { return "com.sun.star.comp.framework.ToolbarModeMenuController"; } sal_Bool SAL_CALL ToolbarModeMenuController::supportsService( const OUString& sServiceName ) { return cppu::supportsService(this, sServiceName); } css::uno::Sequence< OUString > SAL_CALL ToolbarModeMenuController::getSupportedServiceNames() { return { SERVICENAME_POPUPMENUCONTROLLER }; } ToolbarModeMenuController::ToolbarModeMenuController( const css::uno::Reference< css::uno::XComponentContext >& xContext ) : svt::PopupMenuControllerBase( xContext ), m_xContext( xContext ) { } ToolbarModeMenuController::~ToolbarModeMenuController() { } void ToolbarModeMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu > const & rPopupMenu ) { if ( officecfg::Office::Common::Misc::DisableUICustomization::get() ) return; SolarMutexGuard aSolarMutexGuard; resetPopupMenu( rPopupMenu ); const Reference xContext (::comphelper::getProcessComponentContext() ); const Reference xModuleManager = frame::ModuleManager::create( xContext ); vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(m_xFrame)); OUStringBuffer aPath("org.openoffice.Office.UI.ToolbarMode/Applications/"); switch ( eApp ) { case vcl::EnumContext::Application::Writer: aPath.append("Writer"); break; case vcl::EnumContext::Application::Calc: aPath.append("Calc"); break; case vcl::EnumContext::Application::Impress: aPath.append("Impress"); break; case vcl::EnumContext::Application::Draw: aPath.append("Draw"); break; case vcl::EnumContext::Application::Formula: aPath.append("Formula"); break; case vcl::EnumContext::Application::Base: aPath.append("Base"); break; default: break; } aPath.append("/Modes"); const utl::OConfigurationTreeRoot aModesNode( m_xContext, aPath.makeStringAndClear(), false); if ( !aModesNode.isValid() ) return; const Sequence aModeNodeNames (aModesNode.getNodeNames()); const sal_Int32 nCount(aModeNodeNames.getLength()); tools::Long nCountToolbar = 0; for ( sal_Int32 nReadIndex = 0; nReadIndex < nCount; ++nReadIndex ) { const utl::OConfigurationNode aModeNode(aModesNode.openNode(aModeNodeNames[nReadIndex])); if ( !aModeNode.isValid() ) continue; OUString aLabel = comphelper::getString( aModeNode.getNodeValue( "Label" ) ); OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( "CommandArg" ) ); tools::Long nPosition = comphelper::getINT32( aModeNode.getNodeValue( "MenuPosition" ) ); bool isExperimental = comphelper::getBOOL( aModeNode.getNodeValue( "IsExperimental" ) ); bool hasNotebookbar = comphelper::getBOOL( aModeNode.getNodeValue( "HasNotebookbar" ) ); // Allow Notebookbar only in experimental mode if ( isExperimental && !officecfg::Office::Common::Misc::ExperimentalMode::get() ) continue; if (!hasNotebookbar) nCountToolbar++; m_xPopupMenu->insertItem( nReadIndex+1, aLabel, css::awt::MenuItemStyle::RADIOCHECK, nPosition ); rPopupMenu->setCommand( nReadIndex+1, aCommandArg ); } rPopupMenu->insertSeparator(nCountToolbar); } // XEventListener void SAL_CALL ToolbarModeMenuController::disposing( const EventObject& ) { Reference< css::awt::XMenuListener > xHolder(this); osl::MutexGuard aLock( m_aMutex ); m_xFrame.clear(); m_xDispatch.clear(); if ( m_xPopupMenu.is() ) m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(this) ); m_xPopupMenu.clear(); } // XStatusListener void SAL_CALL ToolbarModeMenuController::statusChanged( const FeatureStateEvent& Event ) { OUString aFeatureURL( Event.FeatureURL.Complete ); // All other status events will be processed here osl::ClearableMutexGuard aLock( m_aMutex ); Reference< css::awt::XPopupMenu > xPopupMenu( m_xPopupMenu ); aLock.clear(); if ( !xPopupMenu.is() ) return; SolarMutexGuard aGuard; bool bSetCheckmark = false; bool bCheckmark = false; for (sal_Int16 i = 0, nCount = xPopupMenu->getItemCount(); i < nCount; ++i) { sal_Int16 nId = xPopupMenu->getItemId(i); if ( nId == 0 ) continue; OUString aCmd = xPopupMenu->getCommand(nId); if ( aCmd == aFeatureURL ) { // Enable/disable item xPopupMenu->enableItem(nId, Event.IsEnabled); // Checkmark if ( Event.State >>= bCheckmark ) bSetCheckmark = true; if ( bSetCheckmark ) xPopupMenu->checkItem(nId, bCheckmark); else { OUString aItemText; if ( Event.State >>= aItemText ) xPopupMenu->setItemText(nId, aItemText); } } } } // XMenuListener void SAL_CALL ToolbarModeMenuController::itemSelected( const css::awt::MenuEvent& rEvent ) { auto aArgs(comphelper::InitPropertySequence({{"Mode", Any(m_xPopupMenu->getCommand(rEvent.MenuId))}})); dispatchCommand(m_aCommandURL, aArgs); } void SAL_CALL ToolbarModeMenuController::itemActivated( const css::awt::MenuEvent& ) { const Reference xModuleManager = frame::ModuleManager::create( m_xContext ); vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(m_xFrame)); OUStringBuffer aPath("org.openoffice.Office.UI.ToolbarMode/Applications/"); switch ( eApp ) { case vcl::EnumContext::Application::Writer: aPath.append("Writer"); break; case vcl::EnumContext::Application::Calc: aPath.append("Calc"); break; case vcl::EnumContext::Application::Impress: aPath.append("Impress"); break; case vcl::EnumContext::Application::Draw: aPath.append("Draw"); break; case vcl::EnumContext::Application::Formula: aPath.append("Formula"); break; case vcl::EnumContext::Application::Base: aPath.append("Base"); break; default: break; } const utl::OConfigurationTreeRoot aModesNode( m_xContext, aPath.makeStringAndClear(), false); if ( !aModesNode.isValid() ) return; OUString aMode = comphelper::getString( aModesNode.getNodeValue( "Active" ) ); for ( int i = 0; i < m_xPopupMenu->getItemCount(); ++i ) { sal_Int16 nItemId(m_xPopupMenu->getItemId(i)); m_xPopupMenu->checkItem(nItemId, aMode == m_xPopupMenu->getCommand(nItemId)); } } // XPopupMenuController void SAL_CALL ToolbarModeMenuController::setPopupMenu( const Reference< css::awt::XPopupMenu >& xPopupMenu ) { osl::MutexGuard aLock( m_aMutex ); throwIfDisposed(); if ( m_xFrame.is() && !m_xPopupMenu.is() ) { // Create popup menu on demand SolarMutexGuard aSolarMutexGuard; m_xPopupMenu = dynamic_cast(xPopupMenu.get()); assert(bool(xPopupMenu) == bool(m_xPopupMenu) && "we only support VCLXPopupMenu"); m_xPopupMenu->addMenuListener( Reference< css::awt::XMenuListener >(this) ); fillPopupMenu( m_xPopupMenu ); } } } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* framework_ToolbarModeMenuController_get_implementation( css::uno::XComponentContext* context, css::uno::Sequence const& ) { return cppu::acquire(new framework::ToolbarModeMenuController(context)); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ nt LibreOffice 核心代码仓库文档基金会
summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2023-12-27tdf#144124 Detect if ownership has been lostPatrick Luby
The shortcut assumes that lost ownership notifications from the system clipboard will happen elsewhere. They do under normal conditions, but do not when some clipboard managers are running. So, explicitly check ownership to catch such cases. Change-Id: If54ca8c9908650c23c348e08231820ee7c2483e1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161337 Tested-by: Jenkins Reviewed-by: Patrick Luby <plubius@libreoffice.org>
2023-12-26tdf#151679 Do not push FLAVOR_LINK to macOS general pasteboardPatrick Luby
When copying text from a Writer document and the FLAVOR_LINK flavor is pasted, Writer will edit the copied text in order to create a bookmark for DDE. The problem is that many macOS clipboard managers fetch *all* available flavors that are available in the macOS general pasteboard instead of just one flavor and this triggers the FLAVOR_LINK flavor's unusual editing behavor in Writer every time the user copies Writer text. Users have reported in tdf#1515679 that on macOS, Microsoft Writer, Excel, and PowerPoint do not recognize this flavor like is done on Windows so, in theory, we can just filter out this flavor when adding flavors to the macOS general pasteboard. With this change, the FLAVOR_LINK flavor will still be visible when copying and pasting within a single LibreOffice instance as well as when dragging from LibreOffice to other applications. Change-Id: Ia391398286fa8795ac65b4702a15caf59fb3ae70 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161305 Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> Tested-by: Jenkins Reviewed-by: Patrick Luby <plubius@libreoffice.org>
2023-05-28Use getXWeak in vclMike Kaganski
Change-Id: I665c9dc8c4f9cc4a996d9bf990cbfa33822bd07f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150885 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>