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_extensions.hxx" 30 #include "pushbuttonnavigation.hxx" 31 #include <com/sun/star/form/FormButtonType.hpp> 32 #include <com/sun/star/beans/XPropertyState.hpp> 33 #include "formstrings.hxx" 34 #include <comphelper/extract.hxx> 35 #include <comphelper/property.hxx> 36 #include <osl/diagnose.h> 37 #include <tools/diagnose_ex.h> 38 39 //............................................................................ 40 namespace pcr 41 { 42 //............................................................................ 43 44 using namespace ::com::sun::star::uno; 45 using namespace ::com::sun::star::beans; 46 using namespace ::com::sun::star::form; 47 48 //------------------------------------------------------------------------ 49 namespace 50 { 51 static const sal_Int32 s_nFirstVirtualButtonType = 1 + (sal_Int32)FormButtonType_URL; 52 53 static const sal_Char* pNavigationURLs[] = 54 { 55 ".uno:FormController/moveToFirst", 56 ".uno:FormController/moveToPrev", 57 ".uno:FormController/moveToNext", 58 ".uno:FormController/moveToLast", 59 ".uno:FormController/saveRecord", 60 ".uno:FormController/undoRecord", 61 ".uno:FormController/moveToNew", 62 ".uno:FormController/deleteRecord", 63 ".uno:FormController/refreshForm", 64 NULL 65 }; 66 67 static sal_Int32 lcl_getNavigationURLIndex( const ::rtl::OUString& _rNavURL ) 68 { 69 const sal_Char** pLookup = pNavigationURLs; 70 while ( *pLookup ) 71 { 72 if ( _rNavURL.equalsAscii( *pLookup ) ) 73 return pLookup - pNavigationURLs; 74 ++pLookup; 75 } 76 return -1; 77 } 78 79 static const sal_Char* lcl_getNavigationURL( sal_Int32 _nButtonTypeIndex ) 80 { 81 const sal_Char** pLookup = pNavigationURLs; 82 while ( _nButtonTypeIndex-- && *pLookup++ ) 83 ; 84 OSL_ENSURE( *pLookup, "lcl_getNavigationURL: invalid index!" ); 85 return *pLookup; 86 } 87 } 88 89 //======================================================================== 90 //= PushButtonNavigation 91 //======================================================================== 92 //------------------------------------------------------------------------ 93 PushButtonNavigation::PushButtonNavigation( const Reference< XPropertySet >& _rxControlModel ) 94 :m_xControlModel( _rxControlModel ) 95 ,m_bIsPushButton( sal_False ) 96 { 97 OSL_ENSURE( m_xControlModel.is(), "PushButtonNavigation::PushButtonNavigation: invalid control model!" ); 98 99 try 100 { 101 m_bIsPushButton = ::comphelper::hasProperty( PROPERTY_BUTTONTYPE, m_xControlModel ); 102 } 103 catch( const Exception& ) 104 { 105 OSL_ENSURE( sal_False, "PushButtonNavigation::PushButtonNavigation: caught an exception!" ); 106 } 107 } 108 109 //------------------------------------------------------------------------ 110 sal_Int32 PushButtonNavigation::implGetCurrentButtonType() const SAL_THROW((Exception)) 111 { 112 sal_Int32 nButtonType = FormButtonType_PUSH; 113 if ( !m_xControlModel.is() ) 114 return nButtonType; 115 OSL_VERIFY( ::cppu::enum2int( nButtonType, m_xControlModel->getPropertyValue( PROPERTY_BUTTONTYPE ) ) ); 116 117 if ( nButtonType == FormButtonType_URL ) 118 { 119 // there's a chance that this is a "virtual" button type 120 // (which are realized by special URLs) 121 ::rtl::OUString sTargetURL; 122 m_xControlModel->getPropertyValue( PROPERTY_TARGET_URL ) >>= sTargetURL; 123 124 sal_Int32 nNavigationURLIndex = lcl_getNavigationURLIndex( sTargetURL ); 125 if ( nNavigationURLIndex >= 0) 126 // it actually *is* a virtual button type 127 nButtonType = s_nFirstVirtualButtonType + nNavigationURLIndex; 128 } 129 return nButtonType; 130 } 131 132 //------------------------------------------------------------------------ 133 Any PushButtonNavigation::getCurrentButtonType() const SAL_THROW(()) 134 { 135 OSL_ENSURE( m_bIsPushButton, "PushButtonNavigation::getCurrentButtonType: not expected to be called for forms!" ); 136 Any aReturn; 137 138 try 139 { 140 aReturn <<= implGetCurrentButtonType(); 141 } 142 catch( const Exception& ) 143 { 144 OSL_ENSURE( sal_False, "PushButtonNavigation::getCurrentButtonType: caught an exception!" ); 145 } 146 return aReturn; 147 } 148 149 //------------------------------------------------------------------------ 150 void PushButtonNavigation::setCurrentButtonType( const Any& _rValue ) const SAL_THROW(()) 151 { 152 OSL_ENSURE( m_bIsPushButton, "PushButtonNavigation::setCurrentButtonType: not expected to be called for forms!" ); 153 if ( !m_xControlModel.is() ) 154 return; 155 156 try 157 { 158 sal_Int32 nButtonType = FormButtonType_PUSH; 159 OSL_VERIFY( ::cppu::enum2int( nButtonType, _rValue ) ); 160 ::rtl::OUString sTargetURL; 161 162 bool bIsVirtualButtonType = nButtonType >= s_nFirstVirtualButtonType; 163 if ( bIsVirtualButtonType ) 164 { 165 const sal_Char* pURL = lcl_getNavigationURL( nButtonType - s_nFirstVirtualButtonType ); 166 sTargetURL = ::rtl::OUString::createFromAscii( pURL ); 167 168 nButtonType = FormButtonType_URL; 169 } 170 171 m_xControlModel->setPropertyValue( PROPERTY_BUTTONTYPE, makeAny( static_cast< FormButtonType >( nButtonType ) ) ); 172 m_xControlModel->setPropertyValue( PROPERTY_TARGET_URL, makeAny( sTargetURL ) ); 173 } 174 catch( const Exception& ) 175 { 176 OSL_ENSURE( sal_False, "PushButtonNavigation::setCurrentButtonType: caught an exception!" ); 177 } 178 } 179 180 //------------------------------------------------------------------------ 181 PropertyState PushButtonNavigation::getCurrentButtonTypeState( ) const SAL_THROW(()) 182 { 183 OSL_ENSURE( m_bIsPushButton, "PushButtonNavigation::getCurrentButtonTypeState: not expected to be called for forms!" ); 184 PropertyState eState = PropertyState_DIRECT_VALUE; 185 186 try 187 { 188 Reference< XPropertyState > xStateAccess( m_xControlModel, UNO_QUERY ); 189 if ( xStateAccess.is() ) 190 { 191 // let's see what the model says about the ButtonType property 192 eState = xStateAccess->getPropertyState( PROPERTY_BUTTONTYPE ); 193 if ( eState == PropertyState_DIRECT_VALUE ) 194 { 195 sal_Int32 nRealButtonType = FormButtonType_PUSH; 196 OSL_VERIFY( ::cppu::enum2int( nRealButtonType, m_xControlModel->getPropertyValue( PROPERTY_BUTTONTYPE ) ) ); 197 // perhaps it's one of the virtual button types? 198 if ( FormButtonType_URL == nRealButtonType ) 199 { 200 // yes, it is -> rely on the state of the URL property 201 eState = xStateAccess->getPropertyState( PROPERTY_TARGET_URL ); 202 } 203 } 204 } 205 } 206 catch( const Exception& ) 207 { 208 OSL_ENSURE( sal_False, "PushButtonNavigation::getCurrentButtonTypeState: caught an exception!" ); 209 } 210 211 return eState; 212 } 213 214 //------------------------------------------------------------------------ 215 Any PushButtonNavigation::getCurrentTargetURL() const SAL_THROW(()) 216 { 217 Any aReturn; 218 if ( !m_xControlModel.is() ) 219 return aReturn; 220 221 try 222 { 223 aReturn = m_xControlModel->getPropertyValue( PROPERTY_TARGET_URL ); 224 if ( m_bIsPushButton ) 225 { 226 sal_Int32 nCurrentButtonType = implGetCurrentButtonType(); 227 bool bIsVirtualButtonType = nCurrentButtonType >= s_nFirstVirtualButtonType; 228 if ( bIsVirtualButtonType ) 229 { 230 // pretend (to the user) that there's no URL set - since 231 // virtual button types imply a special (technical) URL which 232 // the user should not see 233 aReturn <<= ::rtl::OUString(); 234 } 235 } 236 } 237 catch( const Exception& ) 238 { 239 OSL_ENSURE( sal_False, "PushButtonNavigation::getCurrentTargetURL: caught an exception!" ); 240 } 241 return aReturn; 242 } 243 244 //------------------------------------------------------------------------ 245 void PushButtonNavigation::setCurrentTargetURL( const Any& _rValue ) const SAL_THROW(()) 246 { 247 if ( !m_xControlModel.is() ) 248 return; 249 250 try 251 { 252 m_xControlModel->setPropertyValue( PROPERTY_TARGET_URL, _rValue ); 253 } 254 catch( const Exception& ) 255 { 256 OSL_ENSURE( sal_False, "PushButtonNavigation::setCurrentTargetURL: caught an exception!" ); 257 } 258 } 259 260 //------------------------------------------------------------------------ 261 PropertyState PushButtonNavigation::getCurrentTargetURLState( ) const SAL_THROW(()) 262 { 263 PropertyState eState = PropertyState_DIRECT_VALUE; 264 265 try 266 { 267 Reference< XPropertyState > xStateAccess( m_xControlModel, UNO_QUERY ); 268 if ( xStateAccess.is() ) 269 { 270 eState = xStateAccess->getPropertyState( PROPERTY_TARGET_URL ); 271 } 272 } 273 catch( const Exception& ) 274 { 275 OSL_ENSURE( sal_False, "PushButtonNavigation::setCurrentTargetURL: caught an exception!" ); 276 } 277 278 return eState; 279 } 280 281 //------------------------------------------------------------------------ 282 bool PushButtonNavigation::currentButtonTypeIsOpenURL() const 283 { 284 sal_Int32 nButtonType( FormButtonType_PUSH ); 285 try 286 { 287 nButtonType = implGetCurrentButtonType(); 288 } 289 catch( const Exception& ) 290 { 291 DBG_UNHANDLED_EXCEPTION(); 292 } 293 return nButtonType == FormButtonType_URL; 294 } 295 296 //------------------------------------------------------------------------ 297 bool PushButtonNavigation::hasNonEmptyCurrentTargetURL() const 298 { 299 ::rtl::OUString sTargetURL; 300 OSL_VERIFY( getCurrentTargetURL() >>= sTargetURL ); 301 return sTargetURL.getLength() != 0; 302 } 303 304 //............................................................................ 305 } // namespace pcr 306 //............................................................................ 307