1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "../unowizard.hxx"
22 #include "wizardshell.hxx"
24 #include <com/sun/star/lang/XInitialization.hpp>
25 #include <com/sun/star/beans/XPropertySetInfo.hpp>
26 #include <com/sun/star/uno/XComponentContext.hpp>
27 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
28 #include <com/sun/star/ui/dialogs/XWizardController.hpp>
29 #include <com/sun/star/ui/dialogs/WizardButton.hpp>
31 #include <tools/diagnose_ex.h>
32 #include <rtl/strbuf.hxx>
33 #include <osl/mutex.hxx>
34 #include <vcl/svapp.hxx>
35 #include <tools/urlobj.hxx>
37 //......................................................................................................................
38 namespace svt
{ namespace uno
40 //......................................................................................................................
42 using ::com::sun::star::uno::Reference
;
43 using ::com::sun::star::uno::XInterface
;
44 using ::com::sun::star::uno::UNO_QUERY
;
45 using ::com::sun::star::uno::UNO_QUERY_THROW
;
46 using ::com::sun::star::uno::UNO_SET_THROW
;
47 using ::com::sun::star::uno::Exception
;
48 using ::com::sun::star::uno::RuntimeException
;
49 using ::com::sun::star::uno::Any
;
50 using ::com::sun::star::uno::makeAny
;
51 using ::com::sun::star::uno::Sequence
;
52 using ::com::sun::star::uno::Type
;
53 using ::com::sun::star::lang::XServiceInfo
;
54 using ::com::sun::star::ui::dialogs::XWizard
;
55 using ::com::sun::star::lang::XInitialization
;
56 using ::com::sun::star::beans::XPropertySetInfo
;
57 using ::com::sun::star::uno::XComponentContext
;
58 using ::com::sun::star::beans::Property
;
59 using ::com::sun::star::lang::IllegalArgumentException
;
60 using ::com::sun::star::ucb::AlreadyInitializedException
;
61 using ::com::sun::star::ui::dialogs::XWizardController
;
62 using ::com::sun::star::ui::dialogs::XWizardPage
;
63 using ::com::sun::star::container::NoSuchElementException
;
64 using ::com::sun::star::util::InvalidStateException
;
65 using ::com::sun::star::awt::XWindow
;
67 namespace WizardButton
= ::com::sun::star::ui::dialogs::WizardButton
;
69 //------------------------------------------------------------------------------------------------------------------
72 sal_uInt32
lcl_convertWizardButtonToWZB( const sal_Int16 i_nWizardButton
)
74 switch ( i_nWizardButton
)
76 case WizardButton::NONE
: return WZB_NONE
;
77 case WizardButton::NEXT
: return WZB_NEXT
;
78 case WizardButton::PREVIOUS
: return WZB_PREVIOUS
;
79 case WizardButton::FINISH
: return WZB_FINISH
;
80 case WizardButton::CANCEL
: return WZB_CANCEL
;
81 case WizardButton::HELP
: return WZB_HELP
;
83 OSL_FAIL( "lcl_convertWizardButtonToWZB: invalid WizardButton constant!" );
88 //==================================================================================================================
89 //= Wizard - implementation
90 //==================================================================================================================
91 //------------------------------------------------------------------------------------------------------------------
92 Wizard::Wizard( const Reference
< XComponentContext
>& _rxContext
)
93 :Wizard_Base( _rxContext
)
94 ,m_aContext( _rxContext
)
98 //--------------------------------------------------------------------
101 // we do this here cause the base class' call to destroyDialog won't reach us anymore : we're within an dtor,
102 // so this virtual-method-call the base class does does not work, we're already dead then ...
105 ::osl::MutexGuard
aGuard( m_aMutex
);
111 //--------------------------------------------------------------------
112 Reference
< XInterface
> SAL_CALL
Wizard::Create( const Reference
< XComponentContext
>& _rxContext
)
114 return *(new Wizard( _rxContext
) );
117 //--------------------------------------------------------------------
120 static void lcl_checkPaths( const Sequence
< Sequence
< sal_Int16
> >& i_rPaths
, const Reference
< XInterface
>& i_rContext
)
122 // need at least one path
123 if ( i_rPaths
.getLength() == 0 )
124 throw IllegalArgumentException( OUString(), i_rContext
, 2 );
126 // each path must be of length 1, at least
127 for ( sal_Int32 i
= 0; i
< i_rPaths
.getLength(); ++i
)
129 if ( i_rPaths
[i
].getLength() == 0 )
130 throw IllegalArgumentException( OUString(), i_rContext
, 2 );
132 // page IDs must be in ascending order
133 sal_Int16 nPreviousPageID
= i_rPaths
[i
][0];
134 for ( sal_Int32 j
=1; j
<i_rPaths
[i
].getLength(); ++j
)
136 if ( i_rPaths
[i
][j
] <= nPreviousPageID
)
138 OStringBuffer message
;
139 message
.append( "Path " );
141 message
.append( ": invalid page ID sequence - each page ID must be greater than the previous one." );
142 throw IllegalArgumentException(
143 OStringToOUString( message
.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US
),
146 nPreviousPageID
= i_rPaths
[i
][j
];
150 // if we have one path, that's okay
151 if ( i_rPaths
.getLength() == 1 )
154 // if we have multiple paths, they must start with the same page id
155 const sal_Int16 nFirstPageId
= i_rPaths
[0][0];
156 for ( sal_Int32 i
= 0; i
< i_rPaths
.getLength(); ++i
)
158 if ( i_rPaths
[i
][0] != nFirstPageId
)
159 throw IllegalArgumentException(
160 OUString( "All paths must start with the same page id." ),
166 //--------------------------------------------------------------------
167 void SAL_CALL
Wizard::initialize( const Sequence
< Any
>& i_Arguments
) throw (Exception
, RuntimeException
)
169 ::osl::MutexGuard
aGuard( m_aMutex
);
170 if ( m_bInitialized
)
171 throw AlreadyInitializedException( OUString(), *this );
173 if ( i_Arguments
.getLength() != 2 )
174 throw IllegalArgumentException( OUString(), *this, -1 );
176 // the second argument must be a XWizardController, for each constructor
177 m_xController
.set( i_Arguments
[1], UNO_QUERY
);
178 if ( !m_xController
.is() )
179 throw IllegalArgumentException( OUString(), *this, 2 );
181 // the first arg is either a single path (short[]), or multiple paths (short[][])
182 Sequence
< sal_Int16
> aSinglePath
;
183 i_Arguments
[0] >>= aSinglePath
;
184 Sequence
< Sequence
< sal_Int16
> > aMultiplePaths
;
185 i_Arguments
[0] >>= aMultiplePaths
;
187 if ( !aMultiplePaths
.getLength() )
189 aMultiplePaths
.realloc(1);
190 aMultiplePaths
[0] = aSinglePath
;
192 lcl_checkPaths( aMultiplePaths
, *this );
193 // if we survived this, the paths are valid, and we're done here ...
194 m_aWizardSteps
= aMultiplePaths
;
196 m_bInitialized
= true;
199 static OString
lcl_getHelpId( const OUString
& _rHelpURL
)
201 INetURLObject
aHID( _rHelpURL
);
202 if ( aHID
.GetProtocol() == INET_PROT_HID
)
203 return OUStringToOString( aHID
.GetURLPath(), RTL_TEXTENCODING_UTF8
);
205 return OUStringToOString( _rHelpURL
, RTL_TEXTENCODING_UTF8
);
208 //------------------------------------------------------------------------
209 static OUString
lcl_getHelpURL( const OString
& sHelpId
)
211 OUStringBuffer aBuffer
;
213 OStringToOUString( sHelpId
, RTL_TEXTENCODING_UTF8
) );
214 INetURLObject
aHID( aTmp
);
215 if ( aHID
.GetProtocol() == INET_PROT_NOT_VALID
)
216 aBuffer
.appendAscii( INET_HID_SCHEME
);
217 aBuffer
.append( aTmp
.getStr() );
218 return aBuffer
.makeStringAndClear();
221 //--------------------------------------------------------------------
222 Dialog
* Wizard::createDialog( Window
* i_pParent
)
224 WizardShell
* pDialog( new WizardShell( i_pParent
, this, m_xController
, m_aWizardSteps
) );
225 pDialog
->SetHelpId( lcl_getHelpId( m_sHelpURL
) );
226 pDialog
->setTitleBase( m_sTitle
);
230 //--------------------------------------------------------------------
231 void Wizard::destroyDialog()
234 m_sHelpURL
= lcl_getHelpURL( m_pDialog
->GetHelpId() );
236 Wizard_Base::destroyDialog();
239 //--------------------------------------------------------------------
240 OUString SAL_CALL
Wizard::getImplementationName_static() throw(RuntimeException
)
242 return OUString( "com.sun.star.comp.svtools.uno.Wizard" );
245 //--------------------------------------------------------------------
246 Sequence
< OUString
> SAL_CALL
Wizard::getSupportedServiceNames_static() throw(RuntimeException
)
248 Sequence
< OUString
> aServices(1);
249 aServices
[0] = OUString( "com.sun.star.ui.dialogs.Wizard" );
253 //--------------------------------------------------------------------
254 OUString SAL_CALL
Wizard::getImplementationName() throw(RuntimeException
)
256 return getImplementationName_static();
259 //--------------------------------------------------------------------
260 Sequence
< OUString
> SAL_CALL
Wizard::getSupportedServiceNames() throw(RuntimeException
)
262 return getSupportedServiceNames_static();
265 //--------------------------------------------------------------------
266 Reference
< XPropertySetInfo
> SAL_CALL
Wizard::getPropertySetInfo() throw(RuntimeException
)
268 return createPropertySetInfo( getInfoHelper() );
271 //--------------------------------------------------------------------
272 ::cppu::IPropertyArrayHelper
& SAL_CALL
Wizard::getInfoHelper()
274 return *const_cast< Wizard
* >( this )->getArrayHelper();
277 //--------------------------------------------------------------------
278 ::cppu::IPropertyArrayHelper
* Wizard::createArrayHelper( ) const
280 Sequence
< Property
> aProps
;
281 describeProperties( aProps
);
282 return new ::cppu::OPropertyArrayHelper( aProps
);
285 //------------------------------------------------------------------------------------------------------------------
286 OUString SAL_CALL
Wizard::getHelpURL() throw (RuntimeException
)
288 SolarMutexGuard aSolarGuard
;
289 ::osl::MutexGuard
aGuard( m_aMutex
);
294 return lcl_getHelpURL( m_pDialog
->GetHelpId() );
297 //------------------------------------------------------------------------------------------------------------------
298 void SAL_CALL
Wizard::setHelpURL( const OUString
& i_HelpURL
) throw (RuntimeException
)
300 SolarMutexGuard aSolarGuard
;
301 ::osl::MutexGuard
aGuard( m_aMutex
);
304 m_sHelpURL
= i_HelpURL
;
306 m_pDialog
->SetHelpId( lcl_getHelpId( i_HelpURL
) );
309 //------------------------------------------------------------------------------------------------------------------
310 Reference
< XWindow
> SAL_CALL
Wizard::getDialogWindow() throw (RuntimeException
)
312 SolarMutexGuard aSolarGuard
;
313 ::osl::MutexGuard
aGuard( m_aMutex
);
315 ENSURE_OR_RETURN( m_pDialog
, "Wizard::getDialogWindow: illegal call (execution did not start, yet)!", NULL
);
316 return Reference
< XWindow
>( m_pDialog
->GetComponentInterface(), UNO_QUERY
);
319 //------------------------------------------------------------------------------------------------------------------
320 void SAL_CALL
Wizard::enableButton( ::sal_Int16 i_WizardButton
, ::sal_Bool i_Enable
) throw (RuntimeException
)
322 SolarMutexGuard aSolarGuard
;
323 ::osl::MutexGuard
aGuard( m_aMutex
);
325 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
326 ENSURE_OR_RETURN_VOID( pWizardImpl
, "Wizard::enableButtons: invalid dialog implementation!" );
328 pWizardImpl
->enableButtons( lcl_convertWizardButtonToWZB( i_WizardButton
), i_Enable
);
331 //------------------------------------------------------------------------------------------------------------------
332 void SAL_CALL
Wizard::setDefaultButton( ::sal_Int16 i_WizardButton
) throw (RuntimeException
)
334 SolarMutexGuard aSolarGuard
;
335 ::osl::MutexGuard
aGuard( m_aMutex
);
337 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
338 ENSURE_OR_RETURN_VOID( pWizardImpl
, "Wizard::setDefaultButton: invalid dialog implementation!" );
340 pWizardImpl
->defaultButton( lcl_convertWizardButtonToWZB( i_WizardButton
) );
343 //------------------------------------------------------------------------------------------------------------------
344 sal_Bool SAL_CALL
Wizard::travelNext( ) throw (RuntimeException
)
346 SolarMutexGuard aSolarGuard
;
347 ::osl::MutexGuard
aGuard( m_aMutex
);
349 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
350 ENSURE_OR_RETURN_FALSE( pWizardImpl
, "Wizard::travelNext: invalid dialog implementation!" );
352 return pWizardImpl
->travelNext();
355 //------------------------------------------------------------------------------------------------------------------
356 sal_Bool SAL_CALL
Wizard::travelPrevious( ) throw (RuntimeException
)
358 SolarMutexGuard aSolarGuard
;
359 ::osl::MutexGuard
aGuard( m_aMutex
);
361 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
362 ENSURE_OR_RETURN_FALSE( pWizardImpl
, "Wizard::travelPrevious: invalid dialog implementation!" );
364 return pWizardImpl
->travelPrevious();
367 //------------------------------------------------------------------------------------------------------------------
368 void SAL_CALL
Wizard::enablePage( ::sal_Int16 i_PageID
, ::sal_Bool i_Enable
) throw (NoSuchElementException
, InvalidStateException
, RuntimeException
)
370 SolarMutexGuard aSolarGuard
;
371 ::osl::MutexGuard
aGuard( m_aMutex
);
373 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
374 ENSURE_OR_RETURN_VOID( pWizardImpl
, "Wizard::enablePage: invalid dialog implementation!" );
376 if ( !pWizardImpl
->knowsPage( i_PageID
) )
377 throw NoSuchElementException( OUString(), *this );
379 if ( i_PageID
== pWizardImpl
->getCurrentPage() )
380 throw InvalidStateException( OUString(), *this );
382 pWizardImpl
->enablePage( i_PageID
, i_Enable
);
385 //------------------------------------------------------------------------------------------------------------------
386 void SAL_CALL
Wizard::updateTravelUI( ) throw (RuntimeException
)
388 SolarMutexGuard aSolarGuard
;
389 ::osl::MutexGuard
aGuard( m_aMutex
);
391 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
392 ENSURE_OR_RETURN_VOID( pWizardImpl
, "Wizard::updateTravelUI: invalid dialog implementation!" );
394 pWizardImpl
->updateTravelUI();
397 //------------------------------------------------------------------------------------------------------------------
398 ::sal_Bool SAL_CALL
Wizard::advanceTo( ::sal_Int16 i_PageId
) throw (RuntimeException
)
400 SolarMutexGuard aSolarGuard
;
401 ::osl::MutexGuard
aGuard( m_aMutex
);
403 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
404 ENSURE_OR_RETURN_FALSE( pWizardImpl
, "Wizard::advanceTo: invalid dialog implementation!" );
406 return pWizardImpl
->advanceTo( i_PageId
);
409 //------------------------------------------------------------------------------------------------------------------
410 ::sal_Bool SAL_CALL
Wizard::goBackTo( ::sal_Int16 i_PageId
) throw (RuntimeException
)
412 SolarMutexGuard aSolarGuard
;
413 ::osl::MutexGuard
aGuard( m_aMutex
);
415 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
416 ENSURE_OR_RETURN_FALSE( pWizardImpl
, "Wizard::goBackTo: invalid dialog implementation!" );
418 return pWizardImpl
->goBackTo( i_PageId
);
421 //------------------------------------------------------------------------------------------------------------------
422 Reference
< XWizardPage
> SAL_CALL
Wizard::getCurrentPage( ) throw (RuntimeException
)
424 SolarMutexGuard aSolarGuard
;
425 ::osl::MutexGuard
aGuard( m_aMutex
);
427 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
428 ENSURE_OR_RETURN( pWizardImpl
, "Wizard::getCurrentPage: invalid dialog implementation!", Reference
< XWizardPage
>() );
430 return pWizardImpl
->getCurrentWizardPage();
433 //------------------------------------------------------------------------------------------------------------------
434 void SAL_CALL
Wizard::activatePath( ::sal_Int16 i_PathIndex
, ::sal_Bool i_Final
) throw (NoSuchElementException
, InvalidStateException
, RuntimeException
)
436 SolarMutexGuard aSolarGuard
;
437 ::osl::MutexGuard
aGuard( m_aMutex
);
439 if ( ( i_PathIndex
< 0 ) || ( i_PathIndex
>= m_aWizardSteps
.getLength() ) )
440 throw NoSuchElementException( OUString(), *this );
442 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
443 ENSURE_OR_RETURN_VOID( pWizardImpl
, "Wizard::activatePath: invalid dialog implementation!" );
445 pWizardImpl
->activatePath( i_PathIndex
, i_Final
);
448 //------------------------------------------------------------------------------------------------------------------
449 void SAL_CALL
Wizard::setTitle( const OUString
& i_Title
) throw (RuntimeException
)
451 // simply disambiguate
452 Wizard_Base::OGenericUnoDialog::setTitle( i_Title
);
455 //------------------------------------------------------------------------------------------------------------------
456 ::sal_Int16 SAL_CALL
Wizard::execute( ) throw (RuntimeException
)
458 return Wizard_Base::OGenericUnoDialog::execute();
461 //......................................................................................................................
462 } } // namespace svt::uno
463 //......................................................................................................................
465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */