diff options
Diffstat (limited to 'svtools/source/uno/wizard')
-rw-r--r-- | svtools/source/uno/wizard/unowizard.cxx | 451 | ||||
-rw-r--r-- | svtools/source/uno/wizard/wizardpagecontroller.cxx | 132 | ||||
-rw-r--r-- | svtools/source/uno/wizard/wizardpagecontroller.hxx | 62 | ||||
-rw-r--r-- | svtools/source/uno/wizard/wizardshell.cxx | 257 | ||||
-rw-r--r-- | svtools/source/uno/wizard/wizardshell.hxx | 130 |
5 files changed, 1032 insertions, 0 deletions
diff --git a/svtools/source/uno/wizard/unowizard.cxx b/svtools/source/uno/wizard/unowizard.cxx new file mode 100644 index 000000000..ddc87539c --- /dev/null +++ b/svtools/source/uno/wizard/unowizard.cxx @@ -0,0 +1,451 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include "wizardshell.hxx" + +#include <com/sun/star/container/NoSuchElementException.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/ucb/AlreadyInitializedException.hpp> +#include <com/sun/star/ui/dialogs/XWizard.hpp> +#include <com/sun/star/ui/dialogs/XWizardController.hpp> +#include <com/sun/star/ui/dialogs/WizardButton.hpp> +#include <com/sun/star/util/InvalidStateException.hpp> + +#include <comphelper/proparrhlp.hxx> +#include <cppuhelper/implbase.hxx> +#include <svtools/genericunodialog.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <tools/diagnose_ex.h> +#include <osl/mutex.hxx> +#include <vcl/svapp.hxx> +#include <tools/urlobj.hxx> + +using namespace ::com::sun::star; +using namespace ::svt::uno; + +namespace { + + using css::uno::Reference; + using css::uno::XInterface; + using css::uno::UNO_QUERY; + using css::uno::Any; + using css::uno::Sequence; + using css::ui::dialogs::XWizard; + using css::beans::XPropertySetInfo; + using css::uno::XComponentContext; + using css::beans::Property; + using css::lang::IllegalArgumentException; + using css::ucb::AlreadyInitializedException; + using css::ui::dialogs::XWizardController; + using css::ui::dialogs::XWizardPage; + using css::container::NoSuchElementException; + using css::util::InvalidStateException; + using css::awt::XWindow; + + namespace WizardButton = css::ui::dialogs::WizardButton; + + WizardButtonFlags lcl_convertWizardButtonToWZB( const sal_Int16 i_nWizardButton ) + { + switch ( i_nWizardButton ) + { + case WizardButton::NONE: return WizardButtonFlags::NONE; + case WizardButton::NEXT: return WizardButtonFlags::NEXT; + case WizardButton::PREVIOUS: return WizardButtonFlags::PREVIOUS; + case WizardButton::FINISH: return WizardButtonFlags::FINISH; + case WizardButton::CANCEL: return WizardButtonFlags::CANCEL; + case WizardButton::HELP: return WizardButtonFlags::HELP; + } + OSL_FAIL( "lcl_convertWizardButtonToWZB: invalid WizardButton constant!" ); + return WizardButtonFlags::NONE; + } + + typedef ::cppu::ImplInheritanceHelper < ::svt::OGenericUnoDialog + , ui::dialogs::XWizard + > Wizard_Base; + class Wizard; + typedef ::comphelper::OPropertyArrayUsageHelper< Wizard > Wizard_PBase; + class Wizard : public Wizard_Base + , public Wizard_PBase + { + public: + explicit Wizard( const css::uno::Reference< css::uno::XComponentContext >& i_rContext ); + + // lang::XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // beans::XPropertySet + virtual css::uno::Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override; + virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + + // OPropertyArrayUsageHelper + virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const override; + + // ui::dialogs::XWizard + virtual OUString SAL_CALL getHelpURL() override; + virtual void SAL_CALL setHelpURL( const OUString& _helpurl ) override; + virtual css::uno::Reference< awt::XWindow > SAL_CALL getDialogWindow() override; + virtual css::uno::Reference< ui::dialogs::XWizardPage > SAL_CALL getCurrentPage( ) override; + virtual void SAL_CALL enableButton( ::sal_Int16 WizardButton, sal_Bool Enable ) override; + virtual void SAL_CALL setDefaultButton( ::sal_Int16 WizardButton ) override; + virtual sal_Bool SAL_CALL travelNext( ) override; + virtual sal_Bool SAL_CALL travelPrevious( ) override; + virtual void SAL_CALL enablePage( ::sal_Int16 PageID, sal_Bool Enable ) override; + virtual void SAL_CALL updateTravelUI( ) override; + virtual sal_Bool SAL_CALL advanceTo( ::sal_Int16 PageId ) override; + virtual sal_Bool SAL_CALL goBackTo( ::sal_Int16 PageId ) override; + virtual void SAL_CALL activatePath( ::sal_Int16 PathIndex, sal_Bool Final ) override; + + // ui::dialogs::XExecutableDialog + virtual void SAL_CALL setTitle( const OUString& aTitle ) override; + virtual ::sal_Int16 SAL_CALL execute( ) override; + + // lang::XInitialization + virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override; + + protected: + virtual ~Wizard() override; + + protected: + virtual std::unique_ptr<weld::DialogController> createDialog(const css::uno::Reference<css::awt::XWindow>& rParent) override; + + private: + css::uno::Sequence< css::uno::Sequence< sal_Int16 > > m_aWizardSteps; + css::uno::Reference< ui::dialogs::XWizardController > m_xController; + OUString m_sHelpURL; + }; + + Wizard::Wizard( const Reference< XComponentContext >& _rxContext ) + :Wizard_Base( _rxContext ) + { + } + + OUString lcl_getHelpURL( const OString& sHelpId ) + { + OUStringBuffer aBuffer; + OUString aTmp( + OStringToOUString( sHelpId, RTL_TEXTENCODING_UTF8 ) ); + INetURLObject aHID( aTmp ); + if ( aHID.GetProtocol() == INetProtocol::NotValid ) + aBuffer.append( INET_HID_SCHEME ); + aBuffer.append( aTmp ); + return aBuffer.makeStringAndClear(); + } + + Wizard::~Wizard() + { + if (m_xDialog) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if (m_xDialog) + { + m_sHelpURL = lcl_getHelpURL(m_xDialog->get_help_id()); + destroyDialog(); + } + } + } + + void lcl_checkPaths( const Sequence< Sequence< sal_Int16 > >& i_rPaths, const Reference< XInterface >& i_rContext ) + { + // need at least one path + if ( !i_rPaths.hasElements() ) + throw IllegalArgumentException( OUString(), i_rContext, 2 ); + + // each path must be of length 1, at least + sal_Int32 i = 0; + for ( const Sequence< sal_Int16 >& rPath : i_rPaths ) + { + if ( !rPath.hasElements() ) + throw IllegalArgumentException( OUString(), i_rContext, 2 ); + + // page IDs must be in ascending order + auto pPageId = std::adjacent_find(rPath.begin(), rPath.end(), std::greater_equal<sal_Int16>()); + if (pPageId != rPath.end()) + { + throw IllegalArgumentException( + "Path " + OUString::number(i) + + ": invalid page ID sequence - each page ID must be greater than the previous one.", + i_rContext, 2 ); + } + ++i; + } + + // if we have one path, that's okay + if ( i_rPaths.getLength() == 1 ) + return; + + // if we have multiple paths, they must start with the same page id + const sal_Int16 nFirstPageId = i_rPaths[0][0]; + if (std::any_of(i_rPaths.begin(), i_rPaths.end(), + [nFirstPageId](const Sequence< sal_Int16 >& rPath) { return rPath[0] != nFirstPageId; })) + throw IllegalArgumentException( + "All paths must start with the same page id.", + i_rContext, 2 ); + } + + void SAL_CALL Wizard::initialize( const Sequence< Any >& i_Arguments ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bInitialized ) + throw AlreadyInitializedException( OUString(), *this ); + + if ( i_Arguments.getLength() != 2 ) + throw IllegalArgumentException( OUString(), *this, -1 ); + + // the second argument must be a XWizardController, for each constructor + m_xController.set( i_Arguments[1], UNO_QUERY ); + if ( !m_xController.is() ) + throw IllegalArgumentException( OUString(), *this, 2 ); + + // the first arg is either a single path (short[]), or multiple paths (short[][]) + Sequence< sal_Int16 > aSinglePath; + i_Arguments[0] >>= aSinglePath; + Sequence< Sequence< sal_Int16 > > aMultiplePaths; + i_Arguments[0] >>= aMultiplePaths; + + if ( !aMultiplePaths.hasElements() ) + { + aMultiplePaths.realloc(1); + aMultiplePaths[0] = aSinglePath; + } + lcl_checkPaths( aMultiplePaths, *this ); + // if we survived this, the paths are valid, and we're done here ... + m_aWizardSteps = aMultiplePaths; + + m_bInitialized = true; + } + + OString lcl_getHelpId( const OUString& _rHelpURL ) + { + INetURLObject aHID( _rHelpURL ); + if ( aHID.GetProtocol() == INetProtocol::Hid ) + return OUStringToOString( aHID.GetURLPath(), RTL_TEXTENCODING_UTF8 ); + else + return OUStringToOString( _rHelpURL, RTL_TEXTENCODING_UTF8 ); + } + + std::unique_ptr<weld::DialogController> Wizard::createDialog(const css::uno::Reference<css::awt::XWindow>& rParent) + { + auto xDialog = std::make_unique<WizardShell>(Application::GetFrameWeld(rParent), m_xController, m_aWizardSteps); + xDialog->set_help_id(lcl_getHelpId(m_sHelpURL)); + xDialog->setTitleBase( m_sTitle ); + return xDialog; + } + + OUString SAL_CALL Wizard::getImplementationName() + { + return "com.sun.star.comp.svtools.uno.Wizard"; + } + + Sequence< OUString > SAL_CALL Wizard::getSupportedServiceNames() + { + return { "com.sun.star.ui.dialogs.Wizard" }; + } + + Reference< XPropertySetInfo > SAL_CALL Wizard::getPropertySetInfo() + { + return createPropertySetInfo( getInfoHelper() ); + } + + ::cppu::IPropertyArrayHelper& SAL_CALL Wizard::getInfoHelper() + { + return *getArrayHelper(); + } + + ::cppu::IPropertyArrayHelper* Wizard::createArrayHelper( ) const + { + Sequence< Property > aProps; + describeProperties( aProps ); + return new ::cppu::OPropertyArrayHelper( aProps ); + } + + OUString SAL_CALL Wizard::getHelpURL() + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + if (!m_xDialog) + return m_sHelpURL; + + return lcl_getHelpURL(m_xDialog->get_help_id()); + } + + void SAL_CALL Wizard::setHelpURL( const OUString& i_HelpURL ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + if (!m_xDialog) + m_sHelpURL = i_HelpURL; + else + m_xDialog->set_help_id(lcl_getHelpId(i_HelpURL)); + } + + Reference< XWindow > SAL_CALL Wizard::getDialogWindow() + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + ENSURE_OR_RETURN( m_xDialog, "Wizard::getDialogWindow: illegal call (execution did not start, yet)!", nullptr ); + return m_xDialog->getDialog()->GetXWindow(); + } + + void SAL_CALL Wizard::enableButton( ::sal_Int16 i_WizardButton, sal_Bool i_Enable ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get()); + ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::enableButtons: invalid dialog implementation!" ); + + pWizardImpl->enableButtons( lcl_convertWizardButtonToWZB( i_WizardButton ), i_Enable ); + } + + void SAL_CALL Wizard::setDefaultButton( ::sal_Int16 i_WizardButton ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get()); + ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::setDefaultButton: invalid dialog implementation!" ); + + pWizardImpl->defaultButton( lcl_convertWizardButtonToWZB( i_WizardButton ) ); + } + + sal_Bool SAL_CALL Wizard::travelNext( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get()); + ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::travelNext: invalid dialog implementation!" ); + + return pWizardImpl->travelNext(); + } + + sal_Bool SAL_CALL Wizard::travelPrevious( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get()); + ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::travelPrevious: invalid dialog implementation!" ); + + return pWizardImpl->travelPrevious(); + } + + void SAL_CALL Wizard::enablePage( ::sal_Int16 i_PageID, sal_Bool i_Enable ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get()); + ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::enablePage: invalid dialog implementation!" ); + + if ( !pWizardImpl->knowsPage( i_PageID ) ) + throw NoSuchElementException( OUString(), *this ); + + if ( i_PageID == pWizardImpl->getCurrentPage() ) + throw InvalidStateException( OUString(), *this ); + + pWizardImpl->enablePage( i_PageID, i_Enable ); + } + + void SAL_CALL Wizard::updateTravelUI( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get()); + ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::updateTravelUI: invalid dialog implementation!" ); + + pWizardImpl->updateTravelUI(); + } + + sal_Bool SAL_CALL Wizard::advanceTo( ::sal_Int16 i_PageId ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get()); + ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::advanceTo: invalid dialog implementation!" ); + + return pWizardImpl->advanceTo( i_PageId ); + } + + sal_Bool SAL_CALL Wizard::goBackTo( ::sal_Int16 i_PageId ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get()); + ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::goBackTo: invalid dialog implementation!" ); + + return pWizardImpl->goBackTo( i_PageId ); + } + + Reference< XWizardPage > SAL_CALL Wizard::getCurrentPage( ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get()); + ENSURE_OR_RETURN( pWizardImpl, "Wizard::getCurrentPage: invalid dialog implementation!", Reference< XWizardPage >() ); + + return pWizardImpl->getCurrentWizardPage(); + } + + void SAL_CALL Wizard::activatePath( ::sal_Int16 i_PathIndex, sal_Bool i_Final ) + { + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( ( i_PathIndex < 0 ) || ( i_PathIndex >= m_aWizardSteps.getLength() ) ) + throw NoSuchElementException( OUString(), *this ); + + WizardShell* pWizardImpl = dynamic_cast<WizardShell*>(m_xDialog.get()); + ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::activatePath: invalid dialog implementation!" ); + + pWizardImpl->activatePath( i_PathIndex, i_Final ); + } + + void SAL_CALL Wizard::setTitle( const OUString& i_Title ) + { + // simply disambiguate + Wizard_Base::OGenericUnoDialog::setTitle( i_Title ); + } + + ::sal_Int16 SAL_CALL Wizard::execute( ) + { + return Wizard_Base::OGenericUnoDialog::execute(); + } +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_svtools_uno_Wizard_get_implementation( + css::uno::XComponentContext *context, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new Wizard(context)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/uno/wizard/wizardpagecontroller.cxx b/svtools/source/uno/wizard/wizardpagecontroller.cxx new file mode 100644 index 000000000..2790a0e57 --- /dev/null +++ b/svtools/source/uno/wizard/wizardpagecontroller.cxx @@ -0,0 +1,132 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include "wizardpagecontroller.hxx" +#include "wizardshell.hxx" + +#include <com/sun/star/awt/XControl.hpp> + +#include <toolkit/helper/vclunohelper.hxx> +#include <tools/diagnose_ex.h> + + +namespace svt::uno +{ + + + using css::uno::Reference; + using css::uno::UNO_SET_THROW; + using css::uno::Exception; + using css::ui::dialogs::XWizardController; + using css::awt::XWindow; + + using namespace ::com::sun::star; + + + //= WizardPageController + + + WizardPageController::WizardPageController(weld::Container* pParent, const Reference< XWizardController >& i_rController, + const sal_Int16 i_nPageId ) + :m_xController( i_rController ) + ,m_xWizardPage() + { + ENSURE_OR_THROW( m_xController.is(), "no controller" ); + try + { + // Plug a toplevel SalFrame into the native page which can host our awt widgetry + m_xWizardPage.set(m_xController->createPage(pParent->CreateChildFrame(), i_nPageId), UNO_SET_THROW); + + Reference< XWindow > xPageWindow(m_xWizardPage->getWindow(), UNO_SET_THROW); + xPageWindow->setVisible( true ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svtools.uno"); + } + } + + WizardPageController::~WizardPageController() + { + try + { + if ( m_xWizardPage.is() ) + m_xWizardPage->dispose(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svtools.uno"); + } + } + + void WizardPageController::initializePage() + { + if ( !m_xWizardPage.is() ) + return; + + try + { + m_xWizardPage->activatePage(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svtools.uno"); + } + } + + bool WizardPageController::commitPage( vcl::WizardTypes::CommitPageReason i_eReason ) + { + if ( !m_xWizardPage.is() ) + return true; + + try + { + return m_xWizardPage->commitPage( WizardShell::convertCommitReasonToTravelType( i_eReason ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svtools.uno"); + } + + return true; + } + + bool WizardPageController::canAdvance() const + { + if ( !m_xWizardPage.is() ) + return true; + + try + { + return m_xWizardPage->canAdvance(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svtools.uno"); + } + + return true; + } + + +} // namespace svt::uno + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/uno/wizard/wizardpagecontroller.hxx b/svtools/source/uno/wizard/wizardpagecontroller.hxx new file mode 100644 index 000000000..68d724591 --- /dev/null +++ b/svtools/source/uno/wizard/wizardpagecontroller.hxx @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <vcl/wizardmachine.hxx> +#include <com/sun/star/ui/dialogs/XWizardController.hpp> + +namespace svt::uno +{ + + + class WizardShell; + + + //= WizardPageController + + class WizardPageController : public vcl::IWizardPageController + { + public: + WizardPageController( + weld::Container* pParent, + const css::uno::Reference< css::ui::dialogs::XWizardController >& i_rController, + const sal_Int16 i_nPageId + ); + virtual ~WizardPageController(); + + // IWizardPageController overridables + virtual void initializePage() override; + virtual bool commitPage( vcl::WizardTypes::CommitPageReason _eReason ) override; + virtual bool canAdvance() const override; + + const css::uno::Reference< css::ui::dialogs::XWizardPage >& + getWizardPage() const { return m_xWizardPage; } + + private: + const css::uno::Reference< css::ui::dialogs::XWizardController > m_xController; + css::uno::Reference< css::ui::dialogs::XWizardPage > m_xWizardPage; + }; + + +} // namespace svt::uno + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/uno/wizard/wizardshell.cxx b/svtools/source/uno/wizard/wizardshell.cxx new file mode 100644 index 000000000..7876e62ac --- /dev/null +++ b/svtools/source/uno/wizard/wizardshell.cxx @@ -0,0 +1,257 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include "wizardshell.hxx" +#include "wizardpagecontroller.hxx" + +#include <tools/diagnose_ex.h> + +#include <com/sun/star/ui/dialogs/WizardTravelType.hpp> + +using vcl::RoadmapWizardTypes::WizardPath; + +namespace svt::uno +{ + + + using css::uno::Reference; + using css::uno::Exception; + using css::uno::Sequence; + using css::ui::dialogs::XWizardController; + using css::ui::dialogs::XWizardPage; + + namespace WizardTravelType = css::ui::dialogs::WizardTravelType; + + + namespace + { + + sal_Int16 lcl_determineFirstPageID( const Sequence< Sequence< sal_Int16 > >& i_rPaths ) + { + ENSURE_OR_THROW( i_rPaths.hasElements() && i_rPaths[0].hasElements(), "illegal paths" ); + return i_rPaths[0][0]; + } + } + + //= WizardShell + WizardShell::WizardShell(weld::Window* i_pParent, const Reference< XWizardController >& i_rController, + const Sequence< Sequence< sal_Int16 > >& i_rPaths) + :WizardShell_Base( i_pParent ) + ,m_xController( i_rController ) + ,m_nFirstPageID( lcl_determineFirstPageID( i_rPaths ) ) + { + ENSURE_OR_THROW( m_xController.is(), "invalid controller" ); + + // declare the paths + for ( sal_Int32 i=0; i<i_rPaths.getLength(); ++i ) + { + const Sequence< sal_Int16 >& rPath( i_rPaths[i] ); + WizardPath aPath( rPath.getLength() ); + std::transform(rPath.begin(), rPath.end(), aPath.begin(), + [this](const sal_Int16 nPageId) -> WizardPath::value_type { return impl_pageIdToState(nPageId); }); + declarePath( i, aPath ); + } + + // create the first page, to know the page size + GetOrCreatePage( impl_pageIdToState( i_rPaths[0][0] ) ); + m_xAssistant->set_current_page(0); + + // some defaults + enableAutomaticNextButtonState(); + } + + short WizardShell::run() + { + ActivatePage(); + return WizardShell_Base::run(); + } + + sal_Int16 WizardShell::convertCommitReasonToTravelType( const CommitPageReason i_eReason ) + { + switch ( i_eReason ) + { + case vcl::WizardTypes::eTravelForward: + return WizardTravelType::FORWARD; + + case vcl::WizardTypes::eTravelBackward: + return WizardTravelType::BACKWARD; + + case vcl::WizardTypes::eFinish: + return WizardTravelType::FINISH; + + default: + break; + } + OSL_FAIL( "WizardShell::convertCommitReasonToTravelType: unsupported CommitPageReason!" ); + return WizardTravelType::FINISH; + } + + + void WizardShell::enterState( WizardState i_nState ) + { + WizardShell_Base::enterState( i_nState ); + + if ( !m_xController.is() ) + return; + + try + { + m_xController->onActivatePage( impl_stateToPageId( i_nState ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svtools.uno"); + } + } + + + bool WizardShell::leaveState( WizardState i_nState ) + { + if ( !WizardShell_Base::leaveState( i_nState ) ) + return false; + + if ( !m_xController.is() ) + return true; + + try + { + m_xController->onDeactivatePage( impl_stateToPageId( i_nState ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svtools.uno"); + } + + return true; + } + + + PWizardPageController WizardShell::impl_getController(BuilderPage* i_pPage) const + { + Page2ControllerMap::const_iterator pos = m_aPageControllers.find( i_pPage ); + ENSURE_OR_RETURN( pos != m_aPageControllers.end(), "WizardShell::impl_getController: no controller for this page!", PWizardPageController() ); + return pos->second; + } + + + Reference< XWizardPage > WizardShell::getCurrentWizardPage() const + { + const WizardState eState = getCurrentState(); + + PWizardPageController pController( impl_getController( GetPage( eState ) ) ); + ENSURE_OR_RETURN( pController, "WizardShell::getCurrentWizardPage: invalid page/controller!", nullptr ); + + return pController->getWizardPage(); + } + + void WizardShell::enablePage( const sal_Int16 i_nPageID, const bool i_bEnable ) + { + enableState( impl_pageIdToState( i_nPageID ), i_bEnable ); + } + + namespace + { + class EmptyPage : public BuilderPage + { + public: + EmptyPage(weld::Widget* pParent, weld::DialogController* pController) + : BuilderPage(pParent, pController, "svt/ui/emptypage.ui", "EmptyPage") + { + m_xContainer->set_size_request(m_xContainer->get_approximate_digit_width() * 70, + m_xContainer->get_text_height() * 45); + } + weld::Container* GetContainer() const { return m_xContainer.get(); } + }; + } + + std::unique_ptr<BuilderPage> WizardShell::createPage( WizardState i_nState ) + { + ENSURE_OR_RETURN( m_xController.is(), "WizardShell::createPage: no WizardController!", nullptr ); + + sal_Int16 nPageId = impl_stateToPageId(i_nState); + + OString sIdent(OString::number(nPageId)); + weld::Container* pPageContainer = m_xAssistant->append_page(sIdent); + + auto xPage = std::make_unique<EmptyPage>(pPageContainer, this); + auto pController = std::make_shared<WizardPageController>(xPage->GetContainer(), m_xController, nPageId); + + m_aPageControllers[xPage.get()] = pController; + + return xPage; + } + + vcl::IWizardPageController* WizardShell::getPageController(BuilderPage* i_pCurrentPage) const + { + return impl_getController( i_pCurrentPage ).get(); + } + + OUString WizardShell::getStateDisplayName( WizardState i_nState ) const + { + try + { + if ( m_xController.is() ) + return m_xController->getPageTitle( impl_stateToPageId( i_nState ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svtools.uno"); + } + // fallback for ill-behaved clients: the numeric state + return OUString::number(i_nState); + } + + + bool WizardShell::canAdvance() const + { + try + { + if ( m_xController.is() && !m_xController->canAdvance() ) + return false; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svtools.uno"); + } + + return WizardShell_Base::canAdvance(); + } + + + bool WizardShell::onFinish() + { + try + { + if ( m_xController.is() && !m_xController->confirmFinish() ) + return false; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svtools.uno"); + } + + return WizardShell_Base::onFinish(); + } + + +} // namespace svt::uno + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/uno/wizard/wizardshell.hxx b/svtools/source/uno/wizard/wizardshell.hxx new file mode 100644 index 000000000..21e3130e4 --- /dev/null +++ b/svtools/source/uno/wizard/wizardshell.hxx @@ -0,0 +1,130 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <com/sun/star/ui/dialogs/XWizardController.hpp> +#include <com/sun/star/ui/dialogs/XWizard.hpp> +#include <vcl/roadmapwizard.hxx> +#include <map> +#include <memory> + +using vcl::WizardTypes::WizardState; +using vcl::WizardTypes::CommitPageReason; + +namespace svt::uno +{ + + + class WizardPageController; + typedef std::shared_ptr< WizardPageController > PWizardPageController; + + + //= WizardShell + + typedef ::vcl::RoadmapWizardMachine WizardShell_Base; + class WizardShell : public WizardShell_Base + { + public: + WizardShell( + weld::Window* pParent, + const css::uno::Reference< css::ui::dialogs::XWizardController >& i_rController, + const css::uno::Sequence< css::uno::Sequence< sal_Int16 > >& i_rPaths + ); + + // Dialog overridables + virtual short run() override; + + // OWizardMachine overridables + virtual std::unique_ptr<BuilderPage> createPage( WizardState i_nState ) override; + virtual void enterState( WizardState i_nState ) override; + virtual bool leaveState( WizardState i_nState ) override; + virtual OUString getStateDisplayName( WizardState i_nState ) const override; + virtual bool canAdvance() const override; + virtual bool onFinish() override; + virtual vcl::IWizardPageController* getPageController(BuilderPage* pCurrentPage) const override; + + static sal_Int16 convertCommitReasonToTravelType( const CommitPageReason i_eReason ); + + // operations + bool advanceTo( const sal_Int16 i_nPageId ) + { + return skipUntil( impl_pageIdToState( i_nPageId ) ); + } + bool goBackTo( const sal_Int16 i_nPageId ) + { + return skipBackwardUntil( impl_pageIdToState( i_nPageId ) ); + } + using WizardShell_Base::travelNext; + using WizardShell_Base::travelPrevious; + + void activatePath( const sal_Int16 i_nPathID, const bool i_bFinal ) + { + WizardShell_Base::activatePath( vcl::RoadmapWizardTypes::PathId( i_nPathID ), i_bFinal ); + } + + css::uno::Reference< css::ui::dialogs::XWizardPage > + getCurrentWizardPage() const; + + sal_Int16 getCurrentPage() const + { + return impl_stateToPageId( getCurrentState() ); + } + + void enablePage( const sal_Int16 i_PageID, const bool i_Enable ); + + bool knowsPage( const sal_Int16 i_nPageID ) const + { + return knowsState( impl_pageIdToState( i_nPageID ) ); + } + + private: + sal_Int16 impl_stateToPageId( const WizardState i_nState ) const + { + return static_cast< sal_Int16 >( i_nState + m_nFirstPageID ); + } + + WizardState impl_pageIdToState( const sal_Int16 i_nPageId ) const + { + return static_cast<WizardState>(i_nPageId - m_nFirstPageID); + } + + PWizardPageController impl_getController(BuilderPage* i_pPage) const; + + // prevent outside access to some base class members + using WizardShell_Base::skip; + using WizardShell_Base::skipUntil; + using WizardShell_Base::skipBackwardUntil; + using WizardShell_Base::getCurrentState; + using WizardShell_Base::activatePath; + + private: + typedef std::map<BuilderPage*, PWizardPageController> Page2ControllerMap; + + const css::uno::Reference< css::ui::dialogs::XWizardController > m_xController; + const sal_Int16 m_nFirstPageID; + Page2ControllerMap m_aPageControllers; + }; + + +} // namespace svt::uno + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |