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