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
)
97 //--------------------------------------------------------------------
100 // we do this here cause the base class' call to destroyDialog won't reach us anymore : we're within an dtor,
101 // so this virtual-method-call the base class does does not work, we're already dead then ...
104 ::osl::MutexGuard
aGuard( m_aMutex
);
110 //--------------------------------------------------------------------
111 Reference
< XInterface
> SAL_CALL
Wizard::Create( const Reference
< XComponentContext
>& _rxContext
)
113 return *(new Wizard( _rxContext
) );
116 //--------------------------------------------------------------------
119 static void lcl_checkPaths( const Sequence
< Sequence
< sal_Int16
> >& i_rPaths
, const Reference
< XInterface
>& i_rContext
)
121 // need at least one path
122 if ( i_rPaths
.getLength() == 0 )
123 throw IllegalArgumentException( OUString(), i_rContext
, 2 );
125 // each path must be of length 1, at least
126 for ( sal_Int32 i
= 0; i
< i_rPaths
.getLength(); ++i
)
128 if ( i_rPaths
[i
].getLength() == 0 )
129 throw IllegalArgumentException( OUString(), i_rContext
, 2 );
131 // page IDs must be in ascending order
132 sal_Int16 nPreviousPageID
= i_rPaths
[i
][0];
133 for ( sal_Int32 j
=1; j
<i_rPaths
[i
].getLength(); ++j
)
135 if ( i_rPaths
[i
][j
] <= nPreviousPageID
)
137 OStringBuffer message
;
138 message
.append( "Path " );
140 message
.append( ": invalid page ID sequence - each page ID must be greater than the previous one." );
141 throw IllegalArgumentException(
142 OStringToOUString( message
.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US
),
145 nPreviousPageID
= i_rPaths
[i
][j
];
149 // if we have one path, that's okay
150 if ( i_rPaths
.getLength() == 1 )
153 // if we have multiple paths, they must start with the same page id
154 const sal_Int16 nFirstPageId
= i_rPaths
[0][0];
155 for ( sal_Int32 i
= 0; i
< i_rPaths
.getLength(); ++i
)
157 if ( i_rPaths
[i
][0] != nFirstPageId
)
158 throw IllegalArgumentException(
159 OUString( "All paths must start with the same page id." ),
165 //--------------------------------------------------------------------
166 void SAL_CALL
Wizard::initialize( const Sequence
< Any
>& i_Arguments
) throw (Exception
, RuntimeException
)
168 ::osl::MutexGuard
aGuard( m_aMutex
);
169 if ( m_bInitialized
)
170 throw AlreadyInitializedException( OUString(), *this );
172 if ( i_Arguments
.getLength() != 2 )
173 throw IllegalArgumentException( OUString(), *this, -1 );
175 // the second argument must be a XWizardController, for each constructor
176 m_xController
.set( i_Arguments
[1], UNO_QUERY
);
177 if ( !m_xController
.is() )
178 throw IllegalArgumentException( OUString(), *this, 2 );
180 // the first arg is either a single path (short[]), or multiple paths (short[][])
181 Sequence
< sal_Int16
> aSinglePath
;
182 i_Arguments
[0] >>= aSinglePath
;
183 Sequence
< Sequence
< sal_Int16
> > aMultiplePaths
;
184 i_Arguments
[0] >>= aMultiplePaths
;
186 if ( !aMultiplePaths
.getLength() )
188 aMultiplePaths
.realloc(1);
189 aMultiplePaths
[0] = aSinglePath
;
191 lcl_checkPaths( aMultiplePaths
, *this );
192 // if we survived this, the paths are valid, and we're done here ...
193 m_aWizardSteps
= aMultiplePaths
;
195 m_bInitialized
= true;
198 static OString
lcl_getHelpId( const OUString
& _rHelpURL
)
200 INetURLObject
aHID( _rHelpURL
);
201 if ( aHID
.GetProtocol() == INET_PROT_HID
)
202 return OUStringToOString( aHID
.GetURLPath(), RTL_TEXTENCODING_UTF8
);
204 return OUStringToOString( _rHelpURL
, RTL_TEXTENCODING_UTF8
);
207 //------------------------------------------------------------------------
208 static OUString
lcl_getHelpURL( const OString
& sHelpId
)
210 OUStringBuffer aBuffer
;
212 OStringToOUString( sHelpId
, RTL_TEXTENCODING_UTF8
) );
213 INetURLObject
aHID( aTmp
);
214 if ( aHID
.GetProtocol() == INET_PROT_NOT_VALID
)
215 aBuffer
.appendAscii( INET_HID_SCHEME
);
216 aBuffer
.append( aTmp
.getStr() );
217 return aBuffer
.makeStringAndClear();
220 //--------------------------------------------------------------------
221 Dialog
* Wizard::createDialog( Window
* i_pParent
)
223 WizardShell
* pDialog( new WizardShell( i_pParent
, this, m_xController
, m_aWizardSteps
) );
224 pDialog
->SetHelpId( lcl_getHelpId( m_sHelpURL
) );
225 pDialog
->setTitleBase( m_sTitle
);
229 //--------------------------------------------------------------------
230 void Wizard::destroyDialog()
233 m_sHelpURL
= lcl_getHelpURL( m_pDialog
->GetHelpId() );
235 Wizard_Base::destroyDialog();
238 //--------------------------------------------------------------------
239 OUString SAL_CALL
Wizard::getImplementationName_static() throw(RuntimeException
)
241 return OUString( "com.sun.star.comp.svtools.uno.Wizard" );
244 //--------------------------------------------------------------------
245 Sequence
< OUString
> SAL_CALL
Wizard::getSupportedServiceNames_static() throw(RuntimeException
)
247 Sequence
< OUString
> aServices(1);
248 aServices
[0] = "com.sun.star.ui.dialogs.Wizard";
252 //--------------------------------------------------------------------
253 OUString SAL_CALL
Wizard::getImplementationName() throw(RuntimeException
)
255 return getImplementationName_static();
258 //--------------------------------------------------------------------
259 Sequence
< OUString
> SAL_CALL
Wizard::getSupportedServiceNames() throw(RuntimeException
)
261 return getSupportedServiceNames_static();
264 //--------------------------------------------------------------------
265 Reference
< XPropertySetInfo
> SAL_CALL
Wizard::getPropertySetInfo() throw(RuntimeException
)
267 return createPropertySetInfo( getInfoHelper() );
270 //--------------------------------------------------------------------
271 ::cppu::IPropertyArrayHelper
& SAL_CALL
Wizard::getInfoHelper()
273 return *const_cast< Wizard
* >( this )->getArrayHelper();
276 //--------------------------------------------------------------------
277 ::cppu::IPropertyArrayHelper
* Wizard::createArrayHelper( ) const
279 Sequence
< Property
> aProps
;
280 describeProperties( aProps
);
281 return new ::cppu::OPropertyArrayHelper( aProps
);
284 //------------------------------------------------------------------------------------------------------------------
285 OUString SAL_CALL
Wizard::getHelpURL() throw (RuntimeException
)
287 SolarMutexGuard aSolarGuard
;
288 ::osl::MutexGuard
aGuard( m_aMutex
);
293 return lcl_getHelpURL( m_pDialog
->GetHelpId() );
296 //------------------------------------------------------------------------------------------------------------------
297 void SAL_CALL
Wizard::setHelpURL( const OUString
& i_HelpURL
) throw (RuntimeException
)
299 SolarMutexGuard aSolarGuard
;
300 ::osl::MutexGuard
aGuard( m_aMutex
);
303 m_sHelpURL
= i_HelpURL
;
305 m_pDialog
->SetHelpId( lcl_getHelpId( i_HelpURL
) );
308 //------------------------------------------------------------------------------------------------------------------
309 Reference
< XWindow
> SAL_CALL
Wizard::getDialogWindow() throw (RuntimeException
)
311 SolarMutexGuard aSolarGuard
;
312 ::osl::MutexGuard
aGuard( m_aMutex
);
314 ENSURE_OR_RETURN( m_pDialog
, "Wizard::getDialogWindow: illegal call (execution did not start, yet)!", NULL
);
315 return Reference
< XWindow
>( m_pDialog
->GetComponentInterface(), UNO_QUERY
);
318 //------------------------------------------------------------------------------------------------------------------
319 void SAL_CALL
Wizard::enableButton( ::sal_Int16 i_WizardButton
, ::sal_Bool i_Enable
) throw (RuntimeException
)
321 SolarMutexGuard aSolarGuard
;
322 ::osl::MutexGuard
aGuard( m_aMutex
);
324 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
325 ENSURE_OR_RETURN_VOID( pWizardImpl
, "Wizard::enableButtons: invalid dialog implementation!" );
327 pWizardImpl
->enableButtons( lcl_convertWizardButtonToWZB( i_WizardButton
), i_Enable
);
330 //------------------------------------------------------------------------------------------------------------------
331 void SAL_CALL
Wizard::setDefaultButton( ::sal_Int16 i_WizardButton
) throw (RuntimeException
)
333 SolarMutexGuard aSolarGuard
;
334 ::osl::MutexGuard
aGuard( m_aMutex
);
336 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
337 ENSURE_OR_RETURN_VOID( pWizardImpl
, "Wizard::setDefaultButton: invalid dialog implementation!" );
339 pWizardImpl
->defaultButton( lcl_convertWizardButtonToWZB( i_WizardButton
) );
342 //------------------------------------------------------------------------------------------------------------------
343 sal_Bool SAL_CALL
Wizard::travelNext( ) throw (RuntimeException
)
345 SolarMutexGuard aSolarGuard
;
346 ::osl::MutexGuard
aGuard( m_aMutex
);
348 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
349 ENSURE_OR_RETURN_FALSE( pWizardImpl
, "Wizard::travelNext: invalid dialog implementation!" );
351 return pWizardImpl
->travelNext();
354 //------------------------------------------------------------------------------------------------------------------
355 sal_Bool SAL_CALL
Wizard::travelPrevious( ) throw (RuntimeException
)
357 SolarMutexGuard aSolarGuard
;
358 ::osl::MutexGuard
aGuard( m_aMutex
);
360 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
361 ENSURE_OR_RETURN_FALSE( pWizardImpl
, "Wizard::travelPrevious: invalid dialog implementation!" );
363 return pWizardImpl
->travelPrevious();
366 //------------------------------------------------------------------------------------------------------------------
367 void SAL_CALL
Wizard::enablePage( ::sal_Int16 i_PageID
, ::sal_Bool i_Enable
) throw (NoSuchElementException
, InvalidStateException
, RuntimeException
)
369 SolarMutexGuard aSolarGuard
;
370 ::osl::MutexGuard
aGuard( m_aMutex
);
372 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
373 ENSURE_OR_RETURN_VOID( pWizardImpl
, "Wizard::enablePage: invalid dialog implementation!" );
375 if ( !pWizardImpl
->knowsPage( i_PageID
) )
376 throw NoSuchElementException( OUString(), *this );
378 if ( i_PageID
== pWizardImpl
->getCurrentPage() )
379 throw InvalidStateException( OUString(), *this );
381 pWizardImpl
->enablePage( i_PageID
, i_Enable
);
384 //------------------------------------------------------------------------------------------------------------------
385 void SAL_CALL
Wizard::updateTravelUI( ) throw (RuntimeException
)
387 SolarMutexGuard aSolarGuard
;
388 ::osl::MutexGuard
aGuard( m_aMutex
);
390 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
391 ENSURE_OR_RETURN_VOID( pWizardImpl
, "Wizard::updateTravelUI: invalid dialog implementation!" );
393 pWizardImpl
->updateTravelUI();
396 //------------------------------------------------------------------------------------------------------------------
397 ::sal_Bool SAL_CALL
Wizard::advanceTo( ::sal_Int16 i_PageId
) throw (RuntimeException
)
399 SolarMutexGuard aSolarGuard
;
400 ::osl::MutexGuard
aGuard( m_aMutex
);
402 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
403 ENSURE_OR_RETURN_FALSE( pWizardImpl
, "Wizard::advanceTo: invalid dialog implementation!" );
405 return pWizardImpl
->advanceTo( i_PageId
);
408 //------------------------------------------------------------------------------------------------------------------
409 ::sal_Bool SAL_CALL
Wizard::goBackTo( ::sal_Int16 i_PageId
) throw (RuntimeException
)
411 SolarMutexGuard aSolarGuard
;
412 ::osl::MutexGuard
aGuard( m_aMutex
);
414 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
415 ENSURE_OR_RETURN_FALSE( pWizardImpl
, "Wizard::goBackTo: invalid dialog implementation!" );
417 return pWizardImpl
->goBackTo( i_PageId
);
420 //------------------------------------------------------------------------------------------------------------------
421 Reference
< XWizardPage
> SAL_CALL
Wizard::getCurrentPage( ) throw (RuntimeException
)
423 SolarMutexGuard aSolarGuard
;
424 ::osl::MutexGuard
aGuard( m_aMutex
);
426 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
427 ENSURE_OR_RETURN( pWizardImpl
, "Wizard::getCurrentPage: invalid dialog implementation!", Reference
< XWizardPage
>() );
429 return pWizardImpl
->getCurrentWizardPage();
432 //------------------------------------------------------------------------------------------------------------------
433 void SAL_CALL
Wizard::activatePath( ::sal_Int16 i_PathIndex
, ::sal_Bool i_Final
) throw (NoSuchElementException
, InvalidStateException
, RuntimeException
)
435 SolarMutexGuard aSolarGuard
;
436 ::osl::MutexGuard
aGuard( m_aMutex
);
438 if ( ( i_PathIndex
< 0 ) || ( i_PathIndex
>= m_aWizardSteps
.getLength() ) )
439 throw NoSuchElementException( OUString(), *this );
441 WizardShell
* pWizardImpl
= dynamic_cast< WizardShell
* >( m_pDialog
);
442 ENSURE_OR_RETURN_VOID( pWizardImpl
, "Wizard::activatePath: invalid dialog implementation!" );
444 pWizardImpl
->activatePath( i_PathIndex
, i_Final
);
447 //------------------------------------------------------------------------------------------------------------------
448 void SAL_CALL
Wizard::setTitle( const OUString
& i_Title
) throw (RuntimeException
)
450 // simply disambiguate
451 Wizard_Base::OGenericUnoDialog::setTitle( i_Title
);
454 //------------------------------------------------------------------------------------------------------------------
455 ::sal_Int16 SAL_CALL
Wizard::execute( ) throw (RuntimeException
)
457 return Wizard_Base::OGenericUnoDialog::execute();
460 //......................................................................................................................
461 } } // namespace svt::uno
462 //......................................................................................................................
464 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */