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 #include "precompiled_svtools.hxx" 25 26 #include "../unowizard.hxx" 27 #include "wizardshell.hxx" 28 29 /** === begin UNO includes === **/ 30 #include <com/sun/star/lang/XInitialization.hpp> 31 #include <com/sun/star/beans/XPropertySetInfo.hpp> 32 #include <com/sun/star/uno/XComponentContext.hpp> 33 #include <com/sun/star/ucb/AlreadyInitializedException.hpp> 34 #include <com/sun/star/ui/dialogs/XWizardController.hpp> 35 #include <com/sun/star/ui/dialogs/WizardButton.hpp> 36 /** === end UNO includes === **/ 37 38 #include <tools/diagnose_ex.h> 39 #include <rtl/strbuf.hxx> 40 #include <vos/mutex.hxx> 41 #include <vcl/svapp.hxx> 42 #include <tools/urlobj.hxx> 43 44 //...................................................................................................................... 45 namespace svt { namespace uno 46 { 47 //...................................................................................................................... 48 49 /** === begin UNO using === **/ 50 using ::com::sun::star::uno::Reference; 51 using ::com::sun::star::uno::XInterface; 52 using ::com::sun::star::uno::UNO_QUERY; 53 using ::com::sun::star::uno::UNO_QUERY_THROW; 54 using ::com::sun::star::uno::UNO_SET_THROW; 55 using ::com::sun::star::uno::Exception; 56 using ::com::sun::star::uno::RuntimeException; 57 using ::com::sun::star::uno::Any; 58 using ::com::sun::star::uno::makeAny; 59 using ::com::sun::star::uno::Sequence; 60 using ::com::sun::star::uno::Type; 61 using ::com::sun::star::lang::XServiceInfo; 62 using ::com::sun::star::ui::dialogs::XWizard; 63 using ::com::sun::star::lang::XInitialization; 64 using ::com::sun::star::beans::XPropertySetInfo; 65 using ::com::sun::star::uno::XComponentContext; 66 using ::com::sun::star::beans::Property; 67 using ::com::sun::star::lang::IllegalArgumentException; 68 using ::com::sun::star::ucb::AlreadyInitializedException; 69 using ::com::sun::star::ui::dialogs::XWizardController; 70 using ::com::sun::star::ui::dialogs::XWizardPage; 71 using ::com::sun::star::container::NoSuchElementException; 72 using ::com::sun::star::util::InvalidStateException; 73 using ::com::sun::star::awt::XWindow; 74 /** === end UNO using === **/ 75 namespace WizardButton = ::com::sun::star::ui::dialogs::WizardButton; 76 77 //------------------------------------------------------------------------------------------------------------------ 78 namespace 79 { 80 sal_uInt32 lcl_convertWizardButtonToWZB( const sal_Int16 i_nWizardButton ) 81 { 82 switch ( i_nWizardButton ) 83 { 84 case WizardButton::NONE: return WZB_NONE; 85 case WizardButton::NEXT: return WZB_NEXT; 86 case WizardButton::PREVIOUS: return WZB_PREVIOUS; 87 case WizardButton::FINISH: return WZB_FINISH; 88 case WizardButton::CANCEL: return WZB_CANCEL; 89 case WizardButton::HELP: return WZB_HELP; 90 } 91 OSL_ENSURE( false, "lcl_convertWizardButtonToWZB: invalid WizardButton constant!" ); 92 return WZB_NONE; 93 } 94 } 95 96 //================================================================================================================== 97 //= Wizard - implementation 98 //================================================================================================================== 99 //------------------------------------------------------------------------------------------------------------------ 100 Wizard::Wizard( const Reference< XComponentContext >& _rxContext ) 101 :Wizard_Base( _rxContext ) 102 ,m_aContext( _rxContext ) 103 { 104 } 105 106 //-------------------------------------------------------------------- 107 Wizard::~Wizard() 108 { 109 // we do this here cause the base class' call to destroyDialog won't reach us anymore : we're within an dtor, 110 // so this virtual-method-call the base class does does not work, we're already dead then ... 111 if ( m_pDialog ) 112 { 113 ::osl::MutexGuard aGuard( m_aMutex ); 114 if ( m_pDialog ) 115 destroyDialog(); 116 } 117 } 118 119 //-------------------------------------------------------------------- 120 Reference< XInterface > SAL_CALL Wizard::Create( const Reference< XComponentContext >& _rxContext ) 121 { 122 return *(new Wizard( _rxContext ) ); 123 } 124 125 //-------------------------------------------------------------------- 126 namespace 127 { 128 static void lcl_checkPaths( const Sequence< Sequence< sal_Int16 > >& i_rPaths, const Reference< XInterface >& i_rContext ) 129 { 130 // need at least one path 131 if ( i_rPaths.getLength() == 0 ) 132 throw IllegalArgumentException( ::rtl::OUString(), i_rContext, 2 ); 133 134 // each path must be of length 1, at least 135 for ( sal_Int32 i = 0; i < i_rPaths.getLength(); ++i ) 136 { 137 if ( i_rPaths[i].getLength() == 0 ) 138 throw IllegalArgumentException( ::rtl::OUString(), i_rContext, 2 ); 139 140 // page IDs must be in ascending order 141 sal_Int16 nPreviousPageID = i_rPaths[i][0]; 142 for ( sal_Int32 j=1; j<i_rPaths[i].getLength(); ++j ) 143 { 144 if ( i_rPaths[i][j] <= nPreviousPageID ) 145 { 146 ::rtl::OStringBuffer message; 147 message.append( "Path " ); 148 message.append( i ); 149 message.append( ": invalid page ID sequence - each page ID must be greater than the previous one." ); 150 throw IllegalArgumentException( 151 ::rtl::OStringToOUString( message.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ), 152 i_rContext, 2 ); 153 } 154 nPreviousPageID = i_rPaths[i][j]; 155 } 156 } 157 158 // if we have one path, that's okay 159 if ( i_rPaths.getLength() == 1 ) 160 return; 161 162 // if we have multiple paths, they must start with the same page id 163 const sal_Int16 nFirstPageId = i_rPaths[0][0]; 164 for ( sal_Int32 i = 0; i < i_rPaths.getLength(); ++i ) 165 { 166 if ( i_rPaths[i][0] != nFirstPageId ) 167 throw IllegalArgumentException( 168 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "All paths must start with the same page id." ) ), 169 i_rContext, 2 ); 170 } 171 } 172 } 173 174 //-------------------------------------------------------------------- 175 void SAL_CALL Wizard::initialize( const Sequence< Any >& i_Arguments ) throw (Exception, RuntimeException) 176 { 177 ::osl::MutexGuard aGuard( m_aMutex ); 178 if ( m_bInitialized ) 179 throw AlreadyInitializedException( ::rtl::OUString(), *this ); 180 181 if ( i_Arguments.getLength() != 2 ) 182 throw IllegalArgumentException( ::rtl::OUString(), *this, -1 ); 183 184 // the second argument must be a XWizardController, for each constructor 185 m_xController.set( i_Arguments[1], UNO_QUERY ); 186 if ( !m_xController.is() ) 187 throw IllegalArgumentException( ::rtl::OUString(), *this, 2 ); 188 189 // the first arg is either a single path (short[]), or multiple paths (short[][]) 190 Sequence< sal_Int16 > aSinglePath; 191 i_Arguments[0] >>= aSinglePath; 192 Sequence< Sequence< sal_Int16 > > aMultiplePaths; 193 i_Arguments[0] >>= aMultiplePaths; 194 195 if ( !aMultiplePaths.getLength() ) 196 { 197 aMultiplePaths.realloc(1); 198 aMultiplePaths[0] = aSinglePath; 199 } 200 lcl_checkPaths( aMultiplePaths, *this ); 201 // if we survived this, the paths are valid, and we're done here ... 202 m_aWizardSteps = aMultiplePaths; 203 204 m_bInitialized = true; 205 } 206 207 static rtl::OString lcl_getHelpId( const ::rtl::OUString& _rHelpURL ) 208 { 209 INetURLObject aHID( _rHelpURL ); 210 if ( aHID.GetProtocol() == INET_PROT_HID ) 211 return rtl::OUStringToOString( aHID.GetURLPath(), RTL_TEXTENCODING_UTF8 ); 212 else 213 return rtl::OUStringToOString( _rHelpURL, RTL_TEXTENCODING_UTF8 ); 214 } 215 216 //------------------------------------------------------------------------ 217 static ::rtl::OUString lcl_getHelpURL( const rtl::OString& sHelpId ) 218 { 219 ::rtl::OUStringBuffer aBuffer; 220 ::rtl::OUString aTmp( OStringToOUString( sHelpId, RTL_TEXTENCODING_UTF8 )); 221 INetURLObject aHID( aTmp ); 222 if ( aHID.GetProtocol() == INET_PROT_NOT_VALID ) 223 aBuffer.appendAscii( INET_HID_SCHEME ); 224 aBuffer.append( aTmp.getStr() ); 225 return aBuffer.makeStringAndClear(); 226 } 227 228 //-------------------------------------------------------------------- 229 Dialog* Wizard::createDialog( Window* i_pParent ) 230 { 231 WizardShell* pDialog( new WizardShell( i_pParent, this, m_xController, m_aWizardSteps ) ); 232 pDialog->SetHelpId( lcl_getHelpId( m_sHelpURL ) ); 233 pDialog->setTitleBase( m_sTitle ); 234 return pDialog; 235 } 236 237 //-------------------------------------------------------------------- 238 void Wizard::destroyDialog() 239 { 240 if ( m_pDialog ) 241 m_sHelpURL = lcl_getHelpURL( m_pDialog->GetHelpId() ); 242 243 Wizard_Base::destroyDialog(); 244 } 245 246 //-------------------------------------------------------------------- 247 ::rtl::OUString SAL_CALL Wizard::getImplementationName_static() throw(RuntimeException) 248 { 249 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.uno.Wizard" ) ); 250 } 251 252 //-------------------------------------------------------------------- 253 Sequence< ::rtl::OUString > SAL_CALL Wizard::getSupportedServiceNames_static() throw(RuntimeException) 254 { 255 Sequence< ::rtl::OUString > aServices(1); 256 aServices[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.Wizard" ) ); 257 return aServices; 258 } 259 260 //-------------------------------------------------------------------- 261 ::rtl::OUString SAL_CALL Wizard::getImplementationName() throw(RuntimeException) 262 { 263 return getImplementationName_static(); 264 } 265 266 //-------------------------------------------------------------------- 267 Sequence< ::rtl::OUString > SAL_CALL Wizard::getSupportedServiceNames() throw(RuntimeException) 268 { 269 return getSupportedServiceNames_static(); 270 } 271 272 //-------------------------------------------------------------------- 273 Reference< XPropertySetInfo > SAL_CALL Wizard::getPropertySetInfo() throw(RuntimeException) 274 { 275 return createPropertySetInfo( getInfoHelper() ); 276 } 277 278 //-------------------------------------------------------------------- 279 ::cppu::IPropertyArrayHelper& SAL_CALL Wizard::getInfoHelper() 280 { 281 return *const_cast< Wizard* >( this )->getArrayHelper(); 282 } 283 284 //-------------------------------------------------------------------- 285 ::cppu::IPropertyArrayHelper* Wizard::createArrayHelper( ) const 286 { 287 Sequence< Property > aProps; 288 describeProperties( aProps ); 289 return new ::cppu::OPropertyArrayHelper( aProps ); 290 } 291 292 //------------------------------------------------------------------------------------------------------------------ 293 ::rtl::OUString SAL_CALL Wizard::getHelpURL() throw (RuntimeException) 294 { 295 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 296 ::osl::MutexGuard aGuard( m_aMutex ); 297 298 if ( !m_pDialog ) 299 return m_sHelpURL; 300 301 return lcl_getHelpURL( m_pDialog->GetHelpId() ); 302 } 303 304 //------------------------------------------------------------------------------------------------------------------ 305 void SAL_CALL Wizard::setHelpURL( const ::rtl::OUString& i_HelpURL ) throw (RuntimeException) 306 { 307 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 308 ::osl::MutexGuard aGuard( m_aMutex ); 309 310 if ( !m_pDialog ) 311 m_sHelpURL = i_HelpURL; 312 else 313 m_pDialog->SetHelpId( lcl_getHelpId( i_HelpURL ) ); 314 } 315 316 //------------------------------------------------------------------------------------------------------------------ 317 Reference< XWindow > SAL_CALL Wizard::getDialogWindow() throw (RuntimeException) 318 { 319 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 320 ::osl::MutexGuard aGuard( m_aMutex ); 321 322 ENSURE_OR_RETURN( m_pDialog, "Wizard::getDialogWindow: illegal call (execution did not start, yet)!", NULL ); 323 return Reference< XWindow >( m_pDialog->GetComponentInterface(), UNO_QUERY ); 324 } 325 326 //------------------------------------------------------------------------------------------------------------------ 327 void SAL_CALL Wizard::enableButton( ::sal_Int16 i_WizardButton, ::sal_Bool i_Enable ) throw (RuntimeException) 328 { 329 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 330 ::osl::MutexGuard aGuard( m_aMutex ); 331 332 WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); 333 ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::enableButtons: invalid dialog implementation!" ); 334 335 pWizardImpl->enableButtons( lcl_convertWizardButtonToWZB( i_WizardButton ), i_Enable ); 336 } 337 338 //------------------------------------------------------------------------------------------------------------------ 339 void SAL_CALL Wizard::setDefaultButton( ::sal_Int16 i_WizardButton ) throw (RuntimeException) 340 { 341 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 342 ::osl::MutexGuard aGuard( m_aMutex ); 343 344 WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); 345 ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::setDefaultButton: invalid dialog implementation!" ); 346 347 pWizardImpl->defaultButton( lcl_convertWizardButtonToWZB( i_WizardButton ) ); 348 } 349 350 //------------------------------------------------------------------------------------------------------------------ 351 sal_Bool SAL_CALL Wizard::travelNext( ) throw (RuntimeException) 352 { 353 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 354 ::osl::MutexGuard aGuard( m_aMutex ); 355 356 WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); 357 ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::travelNext: invalid dialog implementation!" ); 358 359 return pWizardImpl->travelNext(); 360 } 361 362 //------------------------------------------------------------------------------------------------------------------ 363 sal_Bool SAL_CALL Wizard::travelPrevious( ) throw (RuntimeException) 364 { 365 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 366 ::osl::MutexGuard aGuard( m_aMutex ); 367 368 WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); 369 ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::travelPrevious: invalid dialog implementation!" ); 370 371 return pWizardImpl->travelPrevious(); 372 } 373 374 //------------------------------------------------------------------------------------------------------------------ 375 void SAL_CALL Wizard::enablePage( ::sal_Int16 i_PageID, ::sal_Bool i_Enable ) throw (NoSuchElementException, InvalidStateException, RuntimeException) 376 { 377 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 378 ::osl::MutexGuard aGuard( m_aMutex ); 379 380 WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); 381 ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::enablePage: invalid dialog implementation!" ); 382 383 if ( !pWizardImpl->knowsPage( i_PageID ) ) 384 throw NoSuchElementException( ::rtl::OUString(), *this ); 385 386 if ( i_PageID == pWizardImpl->getCurrentPage() ) 387 throw InvalidStateException( ::rtl::OUString(), *this ); 388 389 pWizardImpl->enablePage( i_PageID, i_Enable ); 390 } 391 392 //------------------------------------------------------------------------------------------------------------------ 393 void SAL_CALL Wizard::updateTravelUI( ) throw (RuntimeException) 394 { 395 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 396 ::osl::MutexGuard aGuard( m_aMutex ); 397 398 WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); 399 ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::updateTravelUI: invalid dialog implementation!" ); 400 401 pWizardImpl->updateTravelUI(); 402 } 403 404 //------------------------------------------------------------------------------------------------------------------ 405 ::sal_Bool SAL_CALL Wizard::advanceTo( ::sal_Int16 i_PageId ) throw (RuntimeException) 406 { 407 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 408 ::osl::MutexGuard aGuard( m_aMutex ); 409 410 WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); 411 ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::advanceTo: invalid dialog implementation!" ); 412 413 return pWizardImpl->advanceTo( i_PageId ); 414 } 415 416 //------------------------------------------------------------------------------------------------------------------ 417 ::sal_Bool SAL_CALL Wizard::goBackTo( ::sal_Int16 i_PageId ) throw (RuntimeException) 418 { 419 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 420 ::osl::MutexGuard aGuard( m_aMutex ); 421 422 WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); 423 ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::goBackTo: invalid dialog implementation!" ); 424 425 return pWizardImpl->goBackTo( i_PageId ); 426 } 427 428 //------------------------------------------------------------------------------------------------------------------ 429 Reference< XWizardPage > SAL_CALL Wizard::getCurrentPage( ) throw (RuntimeException) 430 { 431 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 432 ::osl::MutexGuard aGuard( m_aMutex ); 433 434 WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); 435 ENSURE_OR_RETURN( pWizardImpl, "Wizard::getCurrentPage: invalid dialog implementation!", Reference< XWizardPage >() ); 436 437 return pWizardImpl->getCurrentWizardPage(); 438 } 439 440 //------------------------------------------------------------------------------------------------------------------ 441 void SAL_CALL Wizard::activatePath( ::sal_Int16 i_PathIndex, ::sal_Bool i_Final ) throw (NoSuchElementException, InvalidStateException, RuntimeException) 442 { 443 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 444 ::osl::MutexGuard aGuard( m_aMutex ); 445 446 if ( ( i_PathIndex < 0 ) || ( i_PathIndex >= m_aWizardSteps.getLength() ) ) 447 throw NoSuchElementException( ::rtl::OUString(), *this ); 448 449 WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); 450 ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::activatePath: invalid dialog implementation!" ); 451 452 pWizardImpl->activatePath( i_PathIndex, i_Final ); 453 } 454 455 //------------------------------------------------------------------------------------------------------------------ 456 void SAL_CALL Wizard::setTitle( const ::rtl::OUString& i_Title ) throw (RuntimeException) 457 { 458 // simply disambiguate 459 Wizard_Base::OGenericUnoDialog::setTitle( i_Title ); 460 } 461 462 //------------------------------------------------------------------------------------------------------------------ 463 ::sal_Int16 SAL_CALL Wizard::execute( ) throw (RuntimeException) 464 { 465 return Wizard_Base::OGenericUnoDialog::execute(); 466 } 467 468 //...................................................................................................................... 469 } } // namespace svt::uno 470 //...................................................................................................................... 471