1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_framework.hxx" 30 #include <uielement/headermenucontroller.hxx> 31 32 //_________________________________________________________________________________________________________________ 33 // my own includes 34 //_________________________________________________________________________________________________________________ 35 #include <threadhelp/resetableguard.hxx> 36 #include "services.h" 37 38 #ifndef __FRAMEWORK_CLASSES_RESOURCE_HRC_ 39 #include <classes/resource.hrc> 40 #endif 41 #include <classes/fwlresid.hxx> 42 43 //_________________________________________________________________________________________________________________ 44 // interface includes 45 //_________________________________________________________________________________________________________________ 46 #include <com/sun/star/awt/XDevice.hpp> 47 #include <com/sun/star/beans/PropertyValue.hpp> 48 #include <com/sun/star/awt/MenuItemStyle.hpp> 49 #include <com/sun/star/frame/XDispatchProvider.hpp> 50 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> 51 #include <com/sun/star/container/XNameContainer.hpp> 52 #include <com/sun/star/beans/XPropertySet.hpp> 53 54 //_________________________________________________________________________________________________________________ 55 // includes of other projects 56 //_________________________________________________________________________________________________________________ 57 58 #ifndef _VCL_MENU_HXX_ 59 #include <vcl/menu.hxx> 60 #endif 61 #include <vcl/svapp.hxx> 62 #include <vcl/i18nhelp.hxx> 63 #include <tools/urlobj.hxx> 64 #include <rtl/ustrbuf.hxx> 65 //#include <tools/solar.hrc> 66 #include <dispatch/uieventloghelper.hxx> 67 #include <vos/mutex.hxx> 68 69 //_________________________________________________________________________________________________________________ 70 // Defines 71 //_________________________________________________________________________________________________________________ 72 // 73 74 using namespace com::sun::star::uno; 75 using namespace com::sun::star::lang; 76 using namespace com::sun::star::frame; 77 using namespace com::sun::star::beans; 78 using namespace com::sun::star::util; 79 using namespace com::sun::star::style; 80 using namespace com::sun::star::container; 81 82 // Copied from Writer module 83 //#define RID_SW_SHELLRES (RID_SW_START + 1250 + 1) 84 //#define STR_ALLPAGE_HEADFOOT 14 85 86 const sal_uInt16 ALL_MENUITEM_ID = 1; 87 88 namespace framework 89 { 90 91 DEFINE_XSERVICEINFO_MULTISERVICE ( HeaderMenuController , 92 OWeakObject , 93 SERVICENAME_POPUPMENUCONTROLLER , 94 IMPLEMENTATIONNAME_HEADERMENUCONTROLLER 95 ) 96 97 DEFINE_INIT_SERVICE ( HeaderMenuController, {} ) 98 99 HeaderMenuController::HeaderMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager,bool _bFooter ) : 100 svt::PopupMenuControllerBase( xServiceManager ) 101 ,m_bFooter(_bFooter) 102 { 103 } 104 105 HeaderMenuController::~HeaderMenuController() 106 { 107 } 108 109 // private function 110 void HeaderMenuController::fillPopupMenu( const Reference< ::com::sun::star::frame::XModel >& rModel, Reference< css::awt::XPopupMenu >& rPopupMenu ) 111 { 112 VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu ); 113 PopupMenu* pVCLPopupMenu = 0; 114 115 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 116 117 resetPopupMenu( rPopupMenu ); 118 if ( pPopupMenu ) 119 pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu(); 120 121 Reference< XStyleFamiliesSupplier > xStyleFamiliesSupplier( rModel, UNO_QUERY ); 122 if ( pVCLPopupMenu && xStyleFamiliesSupplier.is()) 123 { 124 Reference< XNameAccess > xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies(); 125 126 rtl::OUString aCmd( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertPageHeader" )); 127 rtl::OUString aHeaderFooterIsOnStr(RTL_CONSTASCII_USTRINGPARAM( "HeaderIsOn" )); 128 if ( m_bFooter ) 129 { 130 aCmd = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertPageFooter" )); 131 aHeaderFooterIsOnStr = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "FooterIsOn" )); 132 } 133 const rtl::OUString aIsPhysicalStr( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" )); 134 const rtl::OUString aDisplayNameStr( RTL_CONSTASCII_USTRINGPARAM( "DisplayName" )); 135 136 try 137 { 138 Reference< XNameContainer > xNameContainer; 139 if ( xStyleFamilies->getByName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageStyles" ))) >>= xNameContainer ) 140 { 141 Sequence< rtl::OUString > aSeqNames = xNameContainer->getElementNames(); 142 143 sal_uInt16 nId = 2; 144 sal_uInt16 nCount = 0; 145 sal_Bool bAllOneState( sal_True ); 146 sal_Bool bLastCheck( sal_True ); 147 sal_Bool bFirstChecked( sal_False ); 148 sal_Bool bFirstItemInserted( sal_False ); 149 for ( sal_Int32 n = 0; n < aSeqNames.getLength(); n++ ) 150 { 151 rtl::OUString aName = aSeqNames[n]; 152 Reference< XPropertySet > xPropSet( xNameContainer->getByName( aName ), UNO_QUERY ); 153 if ( xPropSet.is() ) 154 { 155 sal_Bool bIsPhysical( sal_False ); 156 if (( xPropSet->getPropertyValue( aIsPhysicalStr ) >>= bIsPhysical ) && bIsPhysical ) 157 { 158 rtl::OUString aDisplayName; 159 sal_Bool bHeaderIsOn( sal_False ); 160 xPropSet->getPropertyValue( aDisplayNameStr ) >>= aDisplayName; 161 xPropSet->getPropertyValue( aHeaderFooterIsOnStr ) >>= bHeaderIsOn; 162 163 rtl::OUStringBuffer aStrBuf( aCmd ); 164 aStrBuf.appendAscii( "?PageStyle:string="); 165 aStrBuf.append( aDisplayName ); 166 aStrBuf.appendAscii( "&On:bool=" ); 167 if ( !bHeaderIsOn ) 168 aStrBuf.appendAscii( "true" ); 169 else 170 aStrBuf.appendAscii( "false" ); 171 rtl::OUString aCommand( aStrBuf.makeStringAndClear() ); 172 pVCLPopupMenu->InsertItem( nId, aDisplayName, MIB_CHECKABLE ); 173 if ( !bFirstItemInserted ) 174 { 175 bFirstItemInserted = sal_True; 176 bFirstChecked = bHeaderIsOn; 177 } 178 179 pVCLPopupMenu->SetItemCommand( nId, aCommand ); 180 181 if ( bHeaderIsOn ) 182 pVCLPopupMenu->CheckItem( nId, sal_True ); 183 ++nId; 184 185 // Check if all entries have the same state 186 if( bAllOneState && n && bHeaderIsOn != bLastCheck ) 187 bAllOneState = sal_False; 188 bLastCheck = bHeaderIsOn; 189 ++nCount; 190 } 191 } 192 } 193 194 if ( bAllOneState && ( nCount > 1 )) 195 { 196 // Insert special item for all command 197 pVCLPopupMenu->InsertItem( ALL_MENUITEM_ID, String( FwlResId( STR_MENU_HEADFOOTALL )), 0, 0 ); 198 199 rtl::OUStringBuffer aStrBuf( aCmd ); 200 aStrBuf.appendAscii( "?On:bool=" ); 201 202 // Command depends on check state of first menu item entry 203 if ( !bFirstChecked ) 204 aStrBuf.appendAscii( "true" ); 205 else 206 aStrBuf.appendAscii( "false" ); 207 208 pVCLPopupMenu->SetItemCommand( 1, aStrBuf.makeStringAndClear() ); 209 pVCLPopupMenu->InsertSeparator( 1 ); 210 } 211 } 212 } 213 catch ( com::sun::star::container::NoSuchElementException& ) 214 { 215 } 216 } 217 } 218 219 // XEventListener 220 void SAL_CALL HeaderMenuController::disposing( const EventObject& ) throw ( RuntimeException ) 221 { 222 Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY ); 223 224 osl::MutexGuard aLock( m_aMutex ); 225 m_xFrame.clear(); 226 m_xDispatch.clear(); 227 m_xServiceManager.clear(); 228 229 if ( m_xPopupMenu.is() ) 230 m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY )); 231 m_xPopupMenu.clear(); 232 } 233 234 // XStatusListener 235 void SAL_CALL HeaderMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException ) 236 { 237 Reference< com::sun::star::frame::XModel > xModel; 238 239 if ( Event.State >>= xModel ) 240 { 241 osl::MutexGuard aLock( m_aMutex ); 242 m_xModel = xModel; 243 if ( m_xPopupMenu.is() ) 244 fillPopupMenu( xModel, m_xPopupMenu ); 245 } 246 } 247 248 // XMenuListener 249 void HeaderMenuController::impl_select(const Reference< XDispatch >& _xDispatch,const ::com::sun::star::util::URL& aTargetURL) 250 { 251 Sequence<PropertyValue> aArgs; 252 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# 253 UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(m_bFooter ? "FooterMenuController" : "HeaderMenuController"))).log(m_xServiceManager, m_xFrame, aTargetURL, aArgs); 254 OSL_ENSURE(_xDispatch.is(),"HeaderMenuController::impl_select: No dispatch"); 255 if ( _xDispatch.is() ) 256 _xDispatch->dispatch( aTargetURL, aArgs ); 257 } 258 259 void SAL_CALL HeaderMenuController::updatePopupMenu() throw (::com::sun::star::uno::RuntimeException) 260 { 261 osl::ResettableMutexGuard aLock( m_aMutex ); 262 263 throwIfDisposed(); 264 265 Reference< com::sun::star::frame::XModel > xModel( m_xModel ); 266 aLock.clear(); 267 268 if ( !xModel.is() ) 269 svt::PopupMenuControllerBase::updatePopupMenu(); 270 271 aLock.reset(); 272 if ( m_xPopupMenu.is() && m_xModel.is() ) 273 fillPopupMenu( m_xModel, m_xPopupMenu ); 274 } 275 276 } 277