nss: upgrade to release 3.73
[LibreOffice.git] / svtools / source / uno / wizard / unowizard.cxx
blobddc87539c66a9d0d8e468adde5175193fbf9216b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "wizardshell.hxx"
23 #include <com/sun/star/container/NoSuchElementException.hpp>
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/XWizard.hpp>
29 #include <com/sun/star/ui/dialogs/XWizardController.hpp>
30 #include <com/sun/star/ui/dialogs/WizardButton.hpp>
31 #include <com/sun/star/util/InvalidStateException.hpp>
33 #include <comphelper/proparrhlp.hxx>
34 #include <cppuhelper/implbase.hxx>
35 #include <svtools/genericunodialog.hxx>
36 #include <toolkit/helper/vclunohelper.hxx>
37 #include <tools/diagnose_ex.h>
38 #include <osl/mutex.hxx>
39 #include <vcl/svapp.hxx>
40 #include <tools/urlobj.hxx>
42 using namespace ::com::sun::star;
43 using namespace ::svt::uno;
45 namespace {
47 using css::uno::Reference;
48 using css::uno::XInterface;
49 using css::uno::UNO_QUERY;
50 using css::uno::Any;
51 using css::uno::Sequence;
52 using css::ui::dialogs::XWizard;
53 using css::beans::XPropertySetInfo;
54 using css::uno::XComponentContext;
55 using css::beans::Property;
56 using css::lang::IllegalArgumentException;
57 using css::ucb::AlreadyInitializedException;
58 using css::ui::dialogs::XWizardController;
59 using css::ui::dialogs::XWizardPage;
60 using css::container::NoSuchElementException;
61 using css::util::InvalidStateException;
62 using css::awt::XWindow;
64 namespace WizardButton = css::ui::dialogs::WizardButton;
66 WizardButtonFlags lcl_convertWizardButtonToWZB( const sal_Int16 i_nWizardButton )
68 switch ( i_nWizardButton )
70 case WizardButton::NONE: return WizardButtonFlags::NONE;
71 case WizardButton::NEXT: return WizardButtonFlags::NEXT;
72 case WizardButton::PREVIOUS: return WizardButtonFlags::PREVIOUS;
73 case WizardButton::FINISH: return WizardButtonFlags::FINISH;
74 case WizardButton::CANCEL: return WizardButtonFlags::CANCEL;
75 case WizardButton::HELP: return WizardButtonFlags::HELP;
77 OSL_FAIL( "lcl_convertWizardButtonToWZB: invalid WizardButton constant!" );
78 return WizardButtonFlags::NONE;
81 typedef ::cppu::ImplInheritanceHelper < ::svt::OGenericUnoDialog
82 , ui::dialogs::XWizard
83 > Wizard_Base;
84 class Wizard;
85 typedef ::comphelper::OPropertyArrayUsageHelper< Wizard > Wizard_PBase;
86 class Wizard : public Wizard_Base
87 , public Wizard_PBase
89 public:
90 explicit Wizard( const css::uno::Reference< css::uno::XComponentContext >& i_rContext );
92 // lang::XServiceInfo
93 virtual OUString SAL_CALL getImplementationName() override;
94 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
96 // beans::XPropertySet
97 virtual css::uno::Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
98 virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
100 // OPropertyArrayUsageHelper
101 virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const override;
103 // ui::dialogs::XWizard
104 virtual OUString SAL_CALL getHelpURL() override;
105 virtual void SAL_CALL setHelpURL( const OUString& _helpurl ) override;
106 virtual css::uno::Reference< awt::XWindow > SAL_CALL getDialogWindow() override;
107 virtual css::uno::Reference< ui::dialogs::XWizardPage > SAL_CALL getCurrentPage( ) override;
108 virtual void SAL_CALL enableButton( ::sal_Int16 WizardButton, sal_Bool Enable ) override;
109 virtual void SAL_CALL setDefaultButton( ::sal_Int16 WizardButton ) override;
110 virtual sal_Bool SAL_CALL travelNext( ) override;
111 virtual sal_Bool SAL_CALL travelPrevious( ) override;
112 virtual void SAL_CALL enablePage( ::sal_Int16 PageID, sal_Bool Enable ) override;
113 virtual void SAL_CALL updateTravelUI( ) override;
114 virtual sal_Bool SAL_CALL advanceTo( ::sal_Int16 PageId ) override;
115 virtual sal_Bool SAL_CALL goBackTo( ::sal_Int16 PageId ) override;
116 virtual void SAL_CALL activatePath( ::sal_Int16 PathIndex, sal_Bool Final ) override;
118 // ui::dialogs::XExecutableDialog
119 virtual void SAL_CALL setTitle( const OUString& aTitle ) override;
120 virtual ::sal_Int16 SAL_CALL execute( ) override;
122 // lang::XInitialization
123 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
125 protected:
126 virtual ~Wizard() override;
128 protected:
129 virtual std::unique_ptr<weld::DialogController> createDialog(const css::uno::Reference<css::awt::XWindow>& rParent) override;
131 private:
132 css::uno::Sequence< css::uno::Sequence< sal_Int16 > > m_aWizardSteps;
133 css::uno::Reference< ui::dialogs::XWizardController > m_xController;
134 OUString m_sHelpURL;
137 Wizard::Wizard( const Reference< XComponentContext >& _rxContext )
138 :Wizard_Base( _rxContext )
142 OUString lcl_getHelpURL( const OString& sHelpId )
144 OUStringBuffer aBuffer;
145 OUString aTmp(
146 OStringToOUString( sHelpId, RTL_TEXTENCODING_UTF8 ) );
147 INetURLObject aHID( aTmp );
148 if ( aHID.GetProtocol() == INetProtocol::NotValid )
149 aBuffer.append( INET_HID_SCHEME );
150 aBuffer.append( aTmp );
151 return aBuffer.makeStringAndClear();
154 Wizard::~Wizard()
156 if (m_xDialog)
158 ::osl::MutexGuard aGuard( m_aMutex );
159 if (m_xDialog)
161 m_sHelpURL = lcl_getHelpURL(m_xDialog->get_help_id());
162 destroyDialog();
167 void lcl_checkPaths( const Sequence< Sequence< sal_Int16 > >& i_rPaths, const Reference< XInterface >& i_rContext )
169 // need at least one path
170 if ( !i_rPaths.hasElements() )
171 throw IllegalArgumentException( OUString(), i_rContext, 2 );
173 // each path must be of length 1, at least
174 sal_Int32 i = 0;
175 for ( const Sequence< sal_Int16 >& rPath : i_rPaths )
177 if ( !rPath.hasElements() )
178 throw IllegalArgumentException( OUString(), i_rContext, 2 );
180 // page IDs must be in ascending order
181 auto pPageId = std::adjacent_find(rPath.begin(), rPath.end(), std::greater_equal<sal_Int16>());
182 if (pPageId != rPath.end())
184 throw IllegalArgumentException(
185 "Path " + OUString::number(i)
186 + ": invalid page ID sequence - each page ID must be greater than the previous one.",
187 i_rContext, 2 );
189 ++i;
192 // if we have one path, that's okay
193 if ( i_rPaths.getLength() == 1 )
194 return;
196 // if we have multiple paths, they must start with the same page id
197 const sal_Int16 nFirstPageId = i_rPaths[0][0];
198 if (std::any_of(i_rPaths.begin(), i_rPaths.end(),
199 [nFirstPageId](const Sequence< sal_Int16 >& rPath) { return rPath[0] != nFirstPageId; }))
200 throw IllegalArgumentException(
201 "All paths must start with the same page id.",
202 i_rContext, 2 );
205 void SAL_CALL Wizard::initialize( const Sequence< Any >& i_Arguments )
207 ::osl::MutexGuard aGuard( m_aMutex );
208 if ( m_bInitialized )
209 throw AlreadyInitializedException( OUString(), *this );
211 if ( i_Arguments.getLength() != 2 )
212 throw IllegalArgumentException( OUString(), *this, -1 );
214 // the second argument must be a XWizardController, for each constructor
215 m_xController.set( i_Arguments[1], UNO_QUERY );
216 if ( !m_xController.is() )
217 throw IllegalArgumentException( OUString(), *this, 2 );
219 // the first arg is either a single path (short[]), or multiple paths (short[][])
220 Sequence< sal_Int16 > aSinglePath;
221 i_Arguments[0] >>= aSinglePath;
222 Sequence< Sequence< sal_Int16 > > aMultiplePaths;
223 i_Arguments[0] >>= aMultiplePaths;
225 if ( !aMultiplePaths.hasElements() )
227 aMultiplePaths.realloc(1);
228 aMultiplePaths[0] = aSinglePath;
230 lcl_checkPaths( aMultiplePaths, *this );
231 // if we survived this, the paths are valid, and we're done here ...
232 m_aWizardSteps = aMultiplePaths;
234 m_bInitialized = true;
237 OString lcl_getHelpId( const OUString& _rHelpURL )
239 INetURLObject aHID( _rHelpURL );
240 if ( aHID.GetProtocol() == INetProtocol::Hid )
241 return OUStringToOString( aHID.GetURLPath(), RTL_TEXTENCODING_UTF8 );
242 else
243 return OUStringToOString( _rHelpURL, RTL_TEXTENCODING_UTF8 );
246 std::unique_ptr<weld::DialogController> Wizard::createDialog(const css::uno::Reference<css::awt::XWindow>& rParent)
248 auto xDialog = std::make_unique<WizardShell>(Application::GetFrameWeld(rParent), m_xController, m_aWizardSteps);
249 xDialog->set_help_id(lcl_getHelpId(m_sHelpURL));
250 xDialog->setTitleBase( m_sTitle );
251 return xDialog;
254 OUString SAL_CALL Wizard::getImplementationName()
256 return "com.sun.star.comp.svtools.uno.Wizard";
259 Sequence< OUString > SAL_CALL Wizard::getSupportedServiceNames()
261 return { "com.sun.star.ui.dialogs.Wizard" };
264 Reference< XPropertySetInfo > SAL_CALL Wizard::getPropertySetInfo()
266 return createPropertySetInfo( getInfoHelper() );
269 ::cppu::IPropertyArrayHelper& SAL_CALL Wizard::getInfoHelper()
271 return *getArrayHelper();
274 ::cppu::IPropertyArrayHelper* Wizard::createArrayHelper( ) const
276 Sequence< Property > aProps;
277 describeProperties( aProps );
278 return new ::cppu::OPropertyArrayHelper( aProps );
281 OUString SAL_CALL Wizard::getHelpURL()
283 SolarMutexGuard aSolarGuard;
284 ::osl::MutexGuard aGuard( m_aMutex );
286 if (!m_xDialog)
287 return m_sHelpURL;
289 return lcl_getHelpURL(m_xDialog->get_help_id());
292 void SAL_CALL Wizard::setHelpURL( const OUString& i_HelpURL )
294 SolarMutexGuard aSolarGuard;
295 ::osl::MutexGuard aGuard( m_aMutex );
297 if (!m_xDialog)
298 m_sHelpURL = i_HelpURL;
299 else
300 m_xDialog->set_help_id(lcl_getHelpId(i_HelpURL));
303 Reference< XWindow > SAL_CALL Wizard::getDialogWindow()
305 SolarMutexGuard aSolarGuard;
306 ::osl::MutexGuard aGuard( m_aMutex );
308 ENSURE_OR_RETURN( m_xDialog, "Wizard::getDialogWindow: illegal call (execution did not start, yet)!", nullptr );
309 return m_xDialog->getDialog()->GetXWindow();
312 void SAL_CALL Wizard::enableButton( ::sal_Int16 i_WizardButton, sal_Bool i_Enable )
314 SolarMutexGuard aSolarGuard;
315 ::osl::MutexGuard aGuard( m_aMutex );
317 WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get());
318 ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::enableButtons: invalid dialog implementation!" );
320 pWizardImpl->enableButtons( lcl_convertWizardButtonToWZB( i_WizardButton ), i_Enable );
323 void SAL_CALL Wizard::setDefaultButton( ::sal_Int16 i_WizardButton )
325 SolarMutexGuard aSolarGuard;
326 ::osl::MutexGuard aGuard( m_aMutex );
328 WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get());
329 ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::setDefaultButton: invalid dialog implementation!" );
331 pWizardImpl->defaultButton( lcl_convertWizardButtonToWZB( i_WizardButton ) );
334 sal_Bool SAL_CALL Wizard::travelNext( )
336 SolarMutexGuard aSolarGuard;
337 ::osl::MutexGuard aGuard( m_aMutex );
339 WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get());
340 ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::travelNext: invalid dialog implementation!" );
342 return pWizardImpl->travelNext();
345 sal_Bool SAL_CALL Wizard::travelPrevious( )
347 SolarMutexGuard aSolarGuard;
348 ::osl::MutexGuard aGuard( m_aMutex );
350 WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get());
351 ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::travelPrevious: invalid dialog implementation!" );
353 return pWizardImpl->travelPrevious();
356 void SAL_CALL Wizard::enablePage( ::sal_Int16 i_PageID, sal_Bool i_Enable )
358 SolarMutexGuard aSolarGuard;
359 ::osl::MutexGuard aGuard( m_aMutex );
361 WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get());
362 ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::enablePage: invalid dialog implementation!" );
364 if ( !pWizardImpl->knowsPage( i_PageID ) )
365 throw NoSuchElementException( OUString(), *this );
367 if ( i_PageID == pWizardImpl->getCurrentPage() )
368 throw InvalidStateException( OUString(), *this );
370 pWizardImpl->enablePage( i_PageID, i_Enable );
373 void SAL_CALL Wizard::updateTravelUI( )
375 SolarMutexGuard aSolarGuard;
376 ::osl::MutexGuard aGuard( m_aMutex );
378 WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get());
379 ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::updateTravelUI: invalid dialog implementation!" );
381 pWizardImpl->updateTravelUI();
384 sal_Bool SAL_CALL Wizard::advanceTo( ::sal_Int16 i_PageId )
386 SolarMutexGuard aSolarGuard;
387 ::osl::MutexGuard aGuard( m_aMutex );
389 WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get());
390 ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::advanceTo: invalid dialog implementation!" );
392 return pWizardImpl->advanceTo( i_PageId );
395 sal_Bool SAL_CALL Wizard::goBackTo( ::sal_Int16 i_PageId )
397 SolarMutexGuard aSolarGuard;
398 ::osl::MutexGuard aGuard( m_aMutex );
400 WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get());
401 ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::goBackTo: invalid dialog implementation!" );
403 return pWizardImpl->goBackTo( i_PageId );
406 Reference< XWizardPage > SAL_CALL Wizard::getCurrentPage( )
408 SolarMutexGuard aSolarGuard;
409 ::osl::MutexGuard aGuard( m_aMutex );
411 WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get());
412 ENSURE_OR_RETURN( pWizardImpl, "Wizard::getCurrentPage: invalid dialog implementation!", Reference< XWizardPage >() );
414 return pWizardImpl->getCurrentWizardPage();
417 void SAL_CALL Wizard::activatePath( ::sal_Int16 i_PathIndex, sal_Bool i_Final )
419 SolarMutexGuard aSolarGuard;
420 ::osl::MutexGuard aGuard( m_aMutex );
422 if ( ( i_PathIndex < 0 ) || ( i_PathIndex >= m_aWizardSteps.getLength() ) )
423 throw NoSuchElementException( OUString(), *this );
425 WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get());
426 ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::activatePath: invalid dialog implementation!" );
428 pWizardImpl->activatePath( i_PathIndex, i_Final );
431 void SAL_CALL Wizard::setTitle( const OUString& i_Title )
433 // simply disambiguate
434 Wizard_Base::OGenericUnoDialog::setTitle( i_Title );
437 ::sal_Int16 SAL_CALL Wizard::execute( )
439 return Wizard_Base::OGenericUnoDialog::execute();
443 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
444 com_sun_star_comp_svtools_uno_Wizard_get_implementation(
445 css::uno::XComponentContext *context,
446 css::uno::Sequence<css::uno::Any> const &)
448 return cppu::acquire(new Wizard(context));
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */