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