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