diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /forms/source/solar | |
parent | Initial commit. (diff) | |
download | libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'forms/source/solar')
-rw-r--r-- | forms/source/solar/component/navbarcontrol.cxx | 495 | ||||
-rw-r--r-- | forms/source/solar/component/navbarcontrol.hxx | 131 | ||||
-rw-r--r-- | forms/source/solar/control/navtoolbar.cxx | 704 | ||||
-rw-r--r-- | forms/source/solar/inc/navtoolbar.hxx | 178 |
4 files changed, 1508 insertions, 0 deletions
diff --git a/forms/source/solar/component/navbarcontrol.cxx b/forms/source/solar/component/navbarcontrol.cxx new file mode 100644 index 000000000..f39464fc8 --- /dev/null +++ b/forms/source/solar/component/navbarcontrol.cxx @@ -0,0 +1,495 @@ +/* -*- 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 "navbarcontrol.hxx" +#include <frm_strings.hxx> +#include <componenttools.hxx> +#include <navtoolbar.hxx> +#include <commandimageprovider.hxx> + +#include <com/sun/star/awt/XView.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/form/runtime/FormFeature.hpp> +#include <com/sun/star/awt/XControlModel.hpp> +#include <com/sun/star/frame/ModuleManager.hpp> + +#include <tools/debug.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> + + +namespace frm +{ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::frame; + using namespace ::com::sun::star::graphic; + namespace FormFeature = ::com::sun::star::form::runtime::FormFeature; + +#define FORWARD_TO_PEER_1( unoInterface, method, param1 ) \ + Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \ + if ( xTypedPeer.is() ) \ + { \ + xTypedPeer->method( param1 ); \ + } + + ONavigationBarControl::ONavigationBarControl( const Reference< XComponentContext >& _rxORB) + :UnoControl(), m_xContext(_rxORB) + { + } + + + ONavigationBarControl::~ONavigationBarControl() + { + } + + + IMPLEMENT_FORWARD_XTYPEPROVIDER2( ONavigationBarControl, UnoControl, ONavigationBarControl_Base ) + + + Any SAL_CALL ONavigationBarControl::queryAggregation( const Type& _rType ) + { + Any aReturn = UnoControl::queryAggregation( _rType ); + + if ( !aReturn.hasValue() ) + aReturn = ONavigationBarControl_Base::queryInterface( _rType ); + + return aReturn; + } + + + namespace + { + + WinBits lcl_getWinBits_nothrow( const Reference< XControlModel >& _rxModel ) + { + WinBits nBits = 0; + try + { + Reference< XPropertySet > xProps( _rxModel, UNO_QUERY ); + if ( xProps.is() ) + { + sal_Int16 nBorder = 0; + xProps->getPropertyValue( PROPERTY_BORDER ) >>= nBorder; + if ( nBorder ) + nBits |= WB_BORDER; + + bool bTabStop = false; + if ( xProps->getPropertyValue( PROPERTY_TABSTOP ) >>= bTabStop ) + nBits |= ( bTabStop ? WB_TABSTOP : WB_NOTABSTOP ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("forms.component"); + } + return nBits; + } + } + + + void SAL_CALL ONavigationBarControl::createPeer( const Reference< XToolkit >& /*_rToolkit*/, const Reference< XWindowPeer >& _rParentPeer ) + { + SolarMutexGuard aGuard; + + if (getPeer().is()) + return; + + mbCreatingPeer = true; + + // determine the VLC window for the parent + vcl::Window* pParentWin = nullptr; + if ( _rParentPeer.is() ) + { + VCLXWindow* pParentXWin = comphelper::getUnoTunnelImplementation<VCLXWindow>( _rParentPeer ); + if ( pParentXWin ) + pParentWin = pParentXWin->GetWindow().get(); + DBG_ASSERT( pParentWin, "ONavigationBarControl::createPeer: could not obtain the VCL-level parent window!" ); + } + + // create the peer + rtl::Reference<ONavigationBarPeer> pPeer = ONavigationBarPeer::Create( m_xContext, pParentWin, getModel() ); + assert(pPeer && "ONavigationBarControl::createPeer: invalid peer returned!"); + + // announce the peer to the base class + setPeer( pPeer.get() ); + + // initialize ourself (and thus the peer) with the model properties + updateFromModel(); + + Reference< XView > xPeerView( getPeer(), UNO_QUERY ); + if ( xPeerView.is() ) + { + xPeerView->setZoom( maComponentInfos.nZoomX, maComponentInfos.nZoomY ); + xPeerView->setGraphics( mxGraphics ); + } + + // a lot of initial settings from our component infos + setPosSize( maComponentInfos.nX, maComponentInfos.nY, maComponentInfos.nWidth, maComponentInfos.nHeight, PosSize::POSSIZE ); + + pPeer->setVisible ( maComponentInfos.bVisible && !mbDesignMode ); + pPeer->setEnable ( maComponentInfos.bEnable ); + pPeer->setDesignMode( mbDesignMode ); + + peerCreated(); + + mbCreatingPeer = false; + } + + + OUString SAL_CALL ONavigationBarControl::getImplementationName() + { + return "com.sun.star.comp.form.ONavigationBarControl"; + } + + + Sequence< OUString > SAL_CALL ONavigationBarControl::getSupportedServiceNames() + { + return { "com.sun.star.awt.UnoControl", + "com.sun.star.form.control.NavigationToolBar" }; + } + + + void SAL_CALL ONavigationBarControl::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) + { + FORWARD_TO_PEER_1( XDispatchProviderInterception, registerDispatchProviderInterceptor, _rxInterceptor ); + } + + + void SAL_CALL ONavigationBarControl::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) + { + FORWARD_TO_PEER_1( XDispatchProviderInterception, releaseDispatchProviderInterceptor, _rxInterceptor ); + } + + + void SAL_CALL ONavigationBarControl::setDesignMode( sal_Bool _bOn ) + { + UnoControl::setDesignMode( _bOn ); + FORWARD_TO_PEER_1( XVclWindowPeer, setDesignMode, _bOn ); + } + + + // ONavigationBarPeer + + + rtl::Reference<ONavigationBarPeer> ONavigationBarPeer::Create( const Reference< XComponentContext >& _rxORB, + vcl::Window* _pParentWindow, const Reference< XControlModel >& _rxModel ) + { + DBG_TESTSOLARMUTEX(); + + // the peer itself + rtl::Reference<ONavigationBarPeer> pPeer(new ONavigationBarPeer( _rxORB )); + + // the VCL control for the peer + Reference< XModel > xContextDocument( getXModel( _rxModel ) ); + Reference< XModuleManager2 > xModuleManager( ModuleManager::create(_rxORB) ); + OUString sModuleID = xModuleManager->identify( xContextDocument ); + + VclPtrInstance<NavigationToolBar> pNavBar( + _pParentWindow, + lcl_getWinBits_nothrow( _rxModel ), + std::make_shared<DocumentCommandImageProvider>( _rxORB, xContextDocument ), + sModuleID + ); + + // some knittings + pNavBar->setDispatcher( pPeer.get() ); + pNavBar->SetComponentInterface( pPeer.get() ); + + // we want a faster repeating rate for the slots in this + // toolbox + AllSettings aSettings = pNavBar->GetSettings(); + MouseSettings aMouseSettings = aSettings.GetMouseSettings(); + aMouseSettings.SetButtonRepeat( 10 ); + aSettings.SetMouseSettings( aMouseSettings ); + pNavBar->SetSettings( aSettings, true ); + + // outta here + return pPeer; + } + + + ONavigationBarPeer::ONavigationBarPeer( const Reference< XComponentContext >& _rxORB ) + :OFormNavigationHelper( _rxORB ) + { + } + + + ONavigationBarPeer::~ONavigationBarPeer() + { + } + + + IMPLEMENT_FORWARD_XINTERFACE2( ONavigationBarPeer, VCLXWindow, OFormNavigationHelper ) + + + IMPLEMENT_FORWARD_XTYPEPROVIDER2( ONavigationBarPeer, VCLXWindow, OFormNavigationHelper ) + + + void SAL_CALL ONavigationBarPeer::dispose( ) + { + VCLXWindow::dispose(); + OFormNavigationHelper::dispose(); + } + + + void SAL_CALL ONavigationBarPeer::setProperty( const OUString& _rPropertyName, const Any& _rValue ) + { + SolarMutexGuard aGuard; + + VclPtr< NavigationToolBar > pNavBar = GetAs< NavigationToolBar >(); + if ( !pNavBar ) + { + VCLXWindow::setProperty( _rPropertyName, _rValue ); + return; + } + + bool bVoid = !_rValue.hasValue(); + + bool bBoolValue = false; + Color nColor = COL_TRANSPARENT; + + // TODO: more generic mechanisms for this (the grid control implementation, + // when used herein, will do the same stuff for lot of these) + + if ( _rPropertyName == PROPERTY_BACKGROUNDCOLOR ) + { + if ( bVoid ) + { + pNavBar->SetBackground( pNavBar->GetSettings().GetStyleSettings().GetFaceColor() ); + pNavBar->SetControlBackground(); + } + else + { + OSL_VERIFY( _rValue >>= nColor ); + Color aColor( nColor ); + pNavBar->SetBackground( aColor ); + pNavBar->SetControlBackground( aColor ); + } + } + else if ( _rPropertyName == PROPERTY_TEXTLINECOLOR ) + { + if ( bVoid ) + { + pNavBar->SetTextLineColor(); + } + else + { + OSL_VERIFY( _rValue >>= nColor ); + pNavBar->SetTextLineColor( nColor ); + } + } + else if ( _rPropertyName == PROPERTY_ICONSIZE ) + { + sal_Int16 nInt16Value = 0; + OSL_VERIFY( _rValue >>= nInt16Value ); + pNavBar->SetImageSize( nInt16Value ? NavigationToolBar::eLarge : NavigationToolBar::eSmall ); + } + else if ( _rPropertyName == PROPERTY_SHOW_POSITION ) + { + OSL_VERIFY( _rValue >>= bBoolValue ); + pNavBar->ShowFunctionGroup( NavigationToolBar::ePosition, bBoolValue ); + } + else if ( _rPropertyName == PROPERTY_SHOW_NAVIGATION ) + { + OSL_VERIFY( _rValue >>= bBoolValue ); + pNavBar->ShowFunctionGroup( NavigationToolBar::eNavigation, bBoolValue ); + } + else if ( _rPropertyName == PROPERTY_SHOW_RECORDACTIONS ) + { + OSL_VERIFY( _rValue >>= bBoolValue ); + pNavBar->ShowFunctionGroup( NavigationToolBar::eRecordActions, bBoolValue ); + } + else if ( _rPropertyName == PROPERTY_SHOW_FILTERSORT ) + { + OSL_VERIFY( _rValue >>= bBoolValue ); + pNavBar->ShowFunctionGroup( NavigationToolBar::eFilterSort, bBoolValue ); + } + else + { + VCLXWindow::setProperty( _rPropertyName, _rValue ); + } + } + + + Any SAL_CALL ONavigationBarPeer::getProperty( const OUString& _rPropertyName ) + { + SolarMutexGuard aGuard; + + Any aReturn; + VclPtr< NavigationToolBar > pNavBar = GetAs< NavigationToolBar >(); + + if ( _rPropertyName == PROPERTY_BACKGROUNDCOLOR ) + { + aReturn <<= pNavBar->GetControlBackground(); + } + else if ( _rPropertyName == PROPERTY_TEXTLINECOLOR ) + { + aReturn <<= pNavBar->GetTextLineColor(); + } + else if ( _rPropertyName == PROPERTY_ICONSIZE ) + { + sal_Int16 nIconType = ( NavigationToolBar::eLarge == pNavBar->GetImageSize() ) + ? 1 : 0; + aReturn <<= nIconType; + } + else if ( _rPropertyName == PROPERTY_SHOW_POSITION ) + { + aReturn <<= pNavBar->IsFunctionGroupVisible( NavigationToolBar::ePosition ); + } + else if ( _rPropertyName == PROPERTY_SHOW_NAVIGATION ) + { + aReturn <<= pNavBar->IsFunctionGroupVisible( NavigationToolBar::eNavigation ); + } + else if ( _rPropertyName == PROPERTY_SHOW_RECORDACTIONS ) + { + aReturn <<= pNavBar->IsFunctionGroupVisible( NavigationToolBar::eRecordActions ); + } + else if ( _rPropertyName == PROPERTY_SHOW_FILTERSORT ) + { + aReturn <<= pNavBar->IsFunctionGroupVisible( NavigationToolBar::eFilterSort ); + } + else + aReturn = VCLXWindow::getProperty( _rPropertyName ); + + return aReturn; + } + + + void ONavigationBarPeer::interceptorsChanged( ) + { + if ( isDesignMode() ) + // not interested in if we're in design mode + return; + + OFormNavigationHelper::interceptorsChanged(); + } + + + void ONavigationBarPeer::featureStateChanged( sal_Int16 _nFeatureId, bool _bEnabled ) + { + // enable this button on the toolbox + VclPtr< NavigationToolBar > pNavBar = GetAs< NavigationToolBar >(); + if ( pNavBar ) + { + pNavBar->enableFeature( _nFeatureId, _bEnabled ); + + // is it a feature with additional state information? + if ( _nFeatureId == FormFeature::ToggleApplyFilter ) + { // additional boolean state + pNavBar->checkFeature( _nFeatureId, getBooleanState( _nFeatureId ) ); + } + else if ( _nFeatureId == FormFeature::TotalRecords ) + { + pNavBar->setFeatureText( _nFeatureId, getStringState( _nFeatureId ) ); + } + else if ( _nFeatureId == FormFeature::MoveAbsolute ) + { + pNavBar->setFeatureText( _nFeatureId, OUString::number(getIntegerState(_nFeatureId)) ); + } + } + + // base class + OFormNavigationHelper::featureStateChanged( _nFeatureId, _bEnabled ); + } + + + void ONavigationBarPeer::allFeatureStatesChanged( ) + { + { + // force the control to update it's states + SolarMutexGuard g; + VclPtr< NavigationToolBar > pNavBar = GetAs< NavigationToolBar >(); + if ( pNavBar ) + pNavBar->setDispatcher( this ); + } + + // base class + OFormNavigationHelper::allFeatureStatesChanged( ); + } + + + bool ONavigationBarPeer::isEnabled( sal_Int16 _nFeatureId ) const + { + if ( const_cast< ONavigationBarPeer* >( this )->isDesignMode() ) + return false; + + return OFormNavigationHelper::isEnabled( _nFeatureId ); + } + + + void SAL_CALL ONavigationBarPeer::setDesignMode( sal_Bool _bOn ) + { + VCLXWindow::setDesignMode( _bOn ); + + if ( _bOn ) + disconnectDispatchers(); + else + connectDispatchers(); + // this will connect if not already connected and just update else + } + + + void SAL_CALL ONavigationBarPeer::disposing( const EventObject& _rSource ) + { + VCLXWindow::disposing( _rSource ); + OFormNavigationHelper::disposing( _rSource ); + } + + + void ONavigationBarPeer::getSupportedFeatures( ::std::vector< sal_Int16 >& _rFeatureIds ) + { + _rFeatureIds.push_back( FormFeature::MoveAbsolute ); + _rFeatureIds.push_back( FormFeature::TotalRecords ); + _rFeatureIds.push_back( FormFeature::MoveToFirst ); + _rFeatureIds.push_back( FormFeature::MoveToPrevious ); + _rFeatureIds.push_back( FormFeature::MoveToNext ); + _rFeatureIds.push_back( FormFeature::MoveToLast ); + _rFeatureIds.push_back( FormFeature::SaveRecordChanges ); + _rFeatureIds.push_back( FormFeature::UndoRecordChanges ); + _rFeatureIds.push_back( FormFeature::MoveToInsertRow ); + _rFeatureIds.push_back( FormFeature::DeleteRecord ); + _rFeatureIds.push_back( FormFeature::ReloadForm ); + _rFeatureIds.push_back( FormFeature::RefreshCurrentControl ); + _rFeatureIds.push_back( FormFeature::SortAscending ); + _rFeatureIds.push_back( FormFeature::SortDescending ); + _rFeatureIds.push_back( FormFeature::InteractiveSort ); + _rFeatureIds.push_back( FormFeature::AutoFilter ); + _rFeatureIds.push_back( FormFeature::InteractiveFilter ); + _rFeatureIds.push_back( FormFeature::ToggleApplyFilter ); + _rFeatureIds.push_back( FormFeature::RemoveFilterAndSort ); + } + +} // namespace frm + + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +com_sun_star_comp_form_ONavigationBarControl_get_implementation (css::uno::XComponentContext* context, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new frm::ONavigationBarControl(context)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/forms/source/solar/component/navbarcontrol.hxx b/forms/source/solar/component/navbarcontrol.hxx new file mode 100644 index 000000000..f7acd35ed --- /dev/null +++ b/forms/source/solar/component/navbarcontrol.hxx @@ -0,0 +1,131 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_FORMS_SOURCE_SOLAR_COMPONENT_NAVBARCONTROL_HXX +#define INCLUDED_FORMS_SOURCE_SOLAR_COMPONENT_NAVBARCONTROL_HXX + +#include <formnavigation.hxx> + +#include <com/sun/star/frame/XDispatchProviderInterception.hpp> + +#include <toolkit/controls/unocontrol.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <comphelper/uno3.hxx> +#include <cppuhelper/implbase1.hxx> + + +namespace frm +{ + + typedef ::cppu::ImplHelper1 < css::frame::XDispatchProviderInterception + > ONavigationBarControl_Base; + + class ONavigationBarControl + :public UnoControl + ,public ONavigationBarControl_Base + { + css::uno::Reference< css::uno::XComponentContext > m_xContext; + public: + explicit ONavigationBarControl( + const css::uno::Reference< css::uno::XComponentContext >& _rxORB + ); + + protected: + virtual ~ONavigationBarControl() override; + + // UNO + DECLARE_UNO3_AGG_DEFAULTS( ONavigationBarControl, UnoControl ) + virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override; + + // XControl + virtual void SAL_CALL createPeer( const css::uno::Reference< css::awt::XToolkit >& _rToolkit, const css::uno::Reference< css::awt::XWindowPeer >& _rParent ) override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XTypeProvider + DECLARE_XTYPEPROVIDER() + + // XVclWindowPeer + virtual void SAL_CALL setDesignMode( sal_Bool _bOn ) override; + + // XDispatchProviderInterception + virtual void SAL_CALL registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& Interceptor ) override; + virtual void SAL_CALL releaseDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& Interceptor ) override; + }; + + class ONavigationBarPeer final + :public VCLXWindow + ,public OFormNavigationHelper + { + public: + /** factory method + */ + static rtl::Reference<ONavigationBarPeer> Create( + const css::uno::Reference< css::uno::XComponentContext >& _rxORB, + vcl::Window* _pParentWindow, + const css::uno::Reference< css::awt::XControlModel >& _rxModel + ); + + // XInterface + DECLARE_XINTERFACE( ) + + // XVclWindowPeer + virtual void SAL_CALL setDesignMode( sal_Bool _bOn ) override; + + // XWindow2 + using VCLXWindow::isEnabled; + + private: + explicit ONavigationBarPeer( + const css::uno::Reference< css::uno::XComponentContext >& _rxORB + ); + virtual ~ONavigationBarPeer() override; + + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XComponent + void SAL_CALL dispose( ) override; + + // XVclWindowPeer + void SAL_CALL setProperty( const OUString& _rPropertyName, const css::uno::Any& _rValue ) override; + css::uno::Any SAL_CALL getProperty( const OUString& _rPropertyName ) override; + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + // OFormNavigationHelper overriables + virtual void interceptorsChanged( ) override; + virtual void featureStateChanged( sal_Int16 _nFeatureId, bool _bEnabled ) override; + virtual void allFeatureStatesChanged( ) override; + virtual void getSupportedFeatures( ::std::vector< sal_Int16 >& /* [out] */ _rFeatureIds ) override; + + // IFeatureDispatcher overriables + virtual bool isEnabled( sal_Int16 _nFeatureId ) const override; + }; + + +} // namespace frm + + +#endif // INCLUDED_FORMS_SOURCE_SOLAR_COMPONENT_NAVBARCONTROL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/forms/source/solar/control/navtoolbar.cxx b/forms/source/solar/control/navtoolbar.cxx new file mode 100644 index 000000000..d361aa0a9 --- /dev/null +++ b/forms/source/solar/control/navtoolbar.cxx @@ -0,0 +1,704 @@ +/* -*- 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 <navtoolbar.hxx> +#include <frm_resource.hxx> +#include <featuredispatcher.hxx> +#include <strings.hrc> +#include <commandimageprovider.hxx> + +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/form/runtime/FormFeature.hpp> + +#include <vcl/event.hxx> +#include <vcl/fixed.hxx> +#include <vcl/commandinfoprovider.hxx> +#include <vcl/toolbox.hxx> + +#include <sal/macros.h> +#include <osl/diagnose.h> +#include <tools/debug.hxx> + +#define LID_RECORD_LABEL 1000 +#define LID_RECORD_FILLER 1001 + + +namespace frm +{ + + + using ::com::sun::star::uno::makeAny; + namespace FormFeature = ::com::sun::star::form::runtime::FormFeature; + + + namespace + { + bool isArtificialItem( sal_Int16 _nFeatureId ) + { + return ( _nFeatureId == LID_RECORD_LABEL ) + || ( _nFeatureId == LID_RECORD_FILLER ); + } + + OUString getLabelString(const char* pResId) + { + OUString sLabel( " " + FRM_RES_STRING(pResId) + " " ); + return sLabel; + } + + OUString lcl_getCommandURL( const sal_Int16 _nFormFeature ) + { + const char* pAsciiCommandName = nullptr; + switch ( _nFormFeature ) + { + case FormFeature::MoveAbsolute : pAsciiCommandName = "AbsoluteRecord"; break; + case FormFeature::TotalRecords : pAsciiCommandName = "RecTotal"; break; + case FormFeature::MoveToFirst : pAsciiCommandName = "FirstRecord"; break; + case FormFeature::MoveToPrevious : pAsciiCommandName = "PrevRecord"; break; + case FormFeature::MoveToNext : pAsciiCommandName = "NextRecord"; break; + case FormFeature::MoveToLast : pAsciiCommandName = "LastRecord"; break; + case FormFeature::SaveRecordChanges : pAsciiCommandName = "RecSave"; break; + case FormFeature::UndoRecordChanges : pAsciiCommandName = "RecUndo"; break; + case FormFeature::MoveToInsertRow : pAsciiCommandName = "NewRecord"; break; + case FormFeature::DeleteRecord : pAsciiCommandName = "DeleteRecord"; break; + case FormFeature::ReloadForm : pAsciiCommandName = "Refresh"; break; + case FormFeature::RefreshCurrentControl : pAsciiCommandName = "RefreshFormControl"; break; + case FormFeature::SortAscending : pAsciiCommandName = "Sortup"; break; + case FormFeature::SortDescending : pAsciiCommandName = "SortDown"; break; + case FormFeature::InteractiveSort : pAsciiCommandName = "OrderCrit"; break; + case FormFeature::AutoFilter : pAsciiCommandName = "AutoFilter"; break; + case FormFeature::InteractiveFilter : pAsciiCommandName = "FilterCrit"; break; + case FormFeature::ToggleApplyFilter : pAsciiCommandName = "FormFiltered"; break; + case FormFeature::RemoveFilterAndSort : pAsciiCommandName = "RemoveFilterSort"; break; + } + if ( pAsciiCommandName != nullptr ) + return ".uno:" + OUString::createFromAscii( pAsciiCommandName ); + + OSL_FAIL( "lcl_getCommandURL: unknown FormFeature!" ); + return OUString(); + } + } + + class ImplNavToolBar : public ToolBox + { + protected: + const IFeatureDispatcher* m_pDispatcher; + + public: + explicit ImplNavToolBar( vcl::Window* _pParent ) + :ToolBox( _pParent, WB_3DLOOK ) + ,m_pDispatcher( nullptr ) + { + } + + void setDispatcher( const IFeatureDispatcher* _pDispatcher ) + { + m_pDispatcher = _pDispatcher; + } + + protected: + // ToolBox overridables + virtual void Select() override; + + }; + + + void ImplNavToolBar::Select() + { + if ( m_pDispatcher ) + { + if ( !m_pDispatcher->isEnabled( GetCurItemId() ) ) + // the toolbox is a little bit buggy: With ToolBoxItemBits::REPEAT, it sometimes + // happens that a select is reported, even though the respective + // item has just been disabled. + return; + m_pDispatcher->dispatch( GetCurItemId() ); + } + } + + NavigationToolBar::NavigationToolBar( vcl::Window* _pParent, WinBits _nStyle, + const PCommandImageProvider& _pImageProvider, + const OUString & sModuleId ) + :Window( _pParent, _nStyle ) + ,m_pDispatcher( nullptr ) + ,m_pImageProvider( _pImageProvider ) + ,m_eImageSize( eSmall ) + ,m_pToolbar( nullptr ) + ,m_sModuleId( sModuleId ) + { + implInit( ); + } + + + NavigationToolBar::~NavigationToolBar( ) + { + disposeOnce(); + } + + void NavigationToolBar::dispose() + { + for (auto & childWin : m_aChildWins) + childWin.disposeAndClear(); + m_aChildWins.clear(); + m_pToolbar.disposeAndClear(); + vcl::Window::dispose(); + } + + + void NavigationToolBar::setDispatcher( const IFeatureDispatcher* _pDispatcher ) + { + m_pDispatcher = _pDispatcher; + + m_pToolbar->setDispatcher( _pDispatcher ); + + RecordPositionInput* pPositionWindow = static_cast< RecordPositionInput* >( m_pToolbar->GetItemWindow( FormFeature::MoveAbsolute ) ); + OSL_ENSURE( pPositionWindow, "NavigationToolBar::setDispatcher: can't forward the dispatcher to the position window!" ); + if ( pPositionWindow ) + pPositionWindow->setDispatcher( _pDispatcher ); + + // update feature states + for ( ToolBox::ImplToolItems::size_type nPos = 0; nPos < m_pToolbar->GetItemCount(); ++nPos ) + { + sal_uInt16 nItemId = m_pToolbar->GetItemId( nPos ); + + if ( ( nItemId == LID_RECORD_LABEL ) || ( nItemId == LID_RECORD_FILLER ) ) + continue; + + // is this item enabled? + bool bEnabled = m_pDispatcher && m_pDispatcher->isEnabled( nItemId ); + implEnableItem( nItemId, bEnabled ); + } + } + + + void NavigationToolBar::implEnableItem( sal_uInt16 _nItemId, bool _bEnabled ) + { + m_pToolbar->EnableItem( _nItemId, _bEnabled ); + + if ( _nItemId == FormFeature::MoveAbsolute ) + m_pToolbar->EnableItem( LID_RECORD_LABEL, _bEnabled ); + + if ( _nItemId == FormFeature::TotalRecords ) + m_pToolbar->EnableItem( LID_RECORD_FILLER, _bEnabled ); + } + + + void NavigationToolBar::enableFeature( sal_Int16 _nFeatureId, bool _bEnabled ) + { + DBG_ASSERT( m_pToolbar->GetItemPos( static_cast<sal_uInt16>(_nFeatureId) ) != ToolBox::ITEM_NOTFOUND, + "NavigationToolBar::enableFeature: invalid id!" ); + + implEnableItem( static_cast<sal_uInt16>(_nFeatureId), _bEnabled ); + } + + + void NavigationToolBar::checkFeature( sal_Int16 _nFeatureId, bool _bEnabled ) + { + DBG_ASSERT( m_pToolbar->GetItemPos( static_cast<sal_uInt16>(_nFeatureId) ) != ToolBox::ITEM_NOTFOUND, + "NavigationToolBar::checkFeature: invalid id!" ); + + m_pToolbar->CheckItem( static_cast<sal_uInt16>(_nFeatureId), _bEnabled ); + } + + + void NavigationToolBar::setFeatureText( sal_Int16 _nFeatureId, const OUString& _rText ) + { + DBG_ASSERT( m_pToolbar->GetItemPos( static_cast<sal_uInt16>(_nFeatureId) ) != ToolBox::ITEM_NOTFOUND, + "NavigationToolBar::checkFeature: invalid id!" ); + + vcl::Window* pItemWindow = m_pToolbar->GetItemWindow( static_cast<sal_uInt16>(_nFeatureId) ); + if ( pItemWindow ) + pItemWindow->SetText( _rText ); + else + m_pToolbar->SetItemText( static_cast<sal_uInt16>(_nFeatureId), _rText ); + } + + + void NavigationToolBar::implInit( ) + { + m_pToolbar = VclPtr<ImplNavToolBar>::Create( this ); + m_pToolbar->SetOutStyle( TOOLBOX_STYLE_FLAT ); + m_pToolbar->Show(); + + // need the SfxApplication for retrieving information about our + // items. We could duplicate all the information here in our lib + // (such as the item text and the image), but why should we? + + static struct FeatureDescription + { + sal_uInt16 nId; + bool bRepeat; + bool bItemWindow; + } const aSupportedFeatures[] = + { + { LID_RECORD_LABEL, false, true }, + { FormFeature::MoveAbsolute, false, true }, + { LID_RECORD_FILLER, false, true }, + { FormFeature::TotalRecords, false, true }, + { FormFeature::MoveToFirst, true, false }, + { FormFeature::MoveToPrevious, true, false }, + { FormFeature::MoveToNext, true, false }, + { FormFeature::MoveToLast, true, false }, + { FormFeature::MoveToInsertRow, false, false }, + { 0, false, false }, + { FormFeature::SaveRecordChanges, false, false }, + { FormFeature::UndoRecordChanges, false, false }, + { FormFeature::DeleteRecord, false, false }, + { FormFeature::ReloadForm, false, false }, + { FormFeature::RefreshCurrentControl, false, false }, + { 0, false, false }, + { FormFeature::SortAscending, false, false }, + { FormFeature::SortDescending, false, false }, + { FormFeature::InteractiveSort, false, false }, + { FormFeature::AutoFilter, false, false }, + { FormFeature::InteractiveFilter, false, false }, + { FormFeature::ToggleApplyFilter, false, false }, + { FormFeature::RemoveFilterAndSort, false, false }, + }; + + FeatureDescription const * pSupportedFeatures = aSupportedFeatures; + FeatureDescription const * pSupportedFeaturesEnd = aSupportedFeatures + SAL_N_ELEMENTS( aSupportedFeatures ); + for ( ; pSupportedFeatures < pSupportedFeaturesEnd; ++pSupportedFeatures ) + { + if ( pSupportedFeatures->nId ) + { // it's _not_ a separator + + // insert the entry + m_pToolbar->InsertItem( pSupportedFeatures->nId, OUString(), pSupportedFeatures->bRepeat ? ToolBoxItemBits::REPEAT : ToolBoxItemBits::NONE ); + m_pToolbar->SetQuickHelpText( pSupportedFeatures->nId, OUString() ); // TODO + + if ( !isArtificialItem( pSupportedFeatures->nId ) ) + { + OUString sCommandURL( lcl_getCommandURL( pSupportedFeatures->nId ) ); + m_pToolbar->SetItemCommand( pSupportedFeatures->nId, sCommandURL ); + auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(sCommandURL, m_sModuleId); + m_pToolbar->SetQuickHelpText(pSupportedFeatures->nId, + vcl::CommandInfoProvider::GetLabelForCommand(aProperties)); + } + + if ( pSupportedFeatures->bItemWindow ) + { + vcl::Window* pItemWindow = nullptr; + if ( FormFeature::MoveAbsolute == pSupportedFeatures->nId ) + { + pItemWindow = VclPtr<RecordPositionInput>::Create( m_pToolbar ); + static_cast< RecordPositionInput* >( pItemWindow )->setDispatcher( m_pDispatcher ); + } + else if ( LID_RECORD_FILLER == pSupportedFeatures->nId ) + { + pItemWindow = VclPtr<FixedText>::Create( m_pToolbar, WB_CENTER | WB_VCENTER ); + pItemWindow->SetBackground(Wallpaper(COL_TRANSPARENT)); + } + else + { + pItemWindow = VclPtr<FixedText>::Create( m_pToolbar, WB_VCENTER ); + pItemWindow->SetBackground(); + pItemWindow->SetPaintTransparent(true); + } + m_aChildWins.emplace_back(pItemWindow ); + + switch ( pSupportedFeatures->nId ) + { + case LID_RECORD_LABEL: + pItemWindow->SetText( getLabelString( RID_STR_LABEL_RECORD ) ); + break; + + case LID_RECORD_FILLER: + pItemWindow->SetText( getLabelString( RID_STR_LABEL_OF ) ); + break; + } + + m_pToolbar->SetItemWindow( pSupportedFeatures->nId, pItemWindow ); + } + } + else + { // a separator + m_pToolbar->InsertSeparator( ); + } + } + + forEachItemWindow( &NavigationToolBar::adjustItemWindowWidth ); + + implUpdateImages(); + } + + + void NavigationToolBar::implUpdateImages() + { + OSL_ENSURE( m_pImageProvider, "NavigationToolBar::implUpdateImages: no image provider => no images!" ); + if ( !m_pImageProvider ) + return; + + const ToolBox::ImplToolItems::size_type nItemCount = m_pToolbar->GetItemCount(); + + // collect the FormFeatures in the toolbar + std::vector<sal_Int16> aFormFeatures; + aFormFeatures.reserve( nItemCount ); + + for ( ToolBox::ImplToolItems::size_type i=0; i<nItemCount; ++i ) + { + sal_uInt16 nId = m_pToolbar->GetItemId( i ); + if ( ( ToolBoxItemType::BUTTON == m_pToolbar->GetItemType( i ) ) && !isArtificialItem( nId ) ) + aFormFeatures.push_back( nId ); + } + + // translate them into command URLs + css::uno::Sequence< OUString > aCommandURLs( aFormFeatures.size() ); + size_t i = 0; + for (auto const& formFeature : aFormFeatures) + { + aCommandURLs[i++] = lcl_getCommandURL(formFeature); + } + + // retrieve the images for the command URLs + std::vector<Image> aCommandImages = m_pImageProvider->getCommandImages( aCommandURLs, m_eImageSize == eLarge ); + + // and set them at the toolbar + auto commandImage = aCommandImages.begin(); + for (auto const& formFeature : aFormFeatures) + { + m_pToolbar->SetItemImage( formFeature, *commandImage ); + ++commandImage; + } + + // parts of our layout is dependent on the size of our icons + Resize(); + } + + + void NavigationToolBar::implSetImageSize( ImageSize _eSize ) + { + if ( _eSize != m_eImageSize ) + { + m_eImageSize = _eSize; + implUpdateImages(); + } + } + + + void NavigationToolBar::SetImageSize( ImageSize _eSize ) + { + implSetImageSize( _eSize ); + } + + + void NavigationToolBar::ShowFunctionGroup( FunctionGroup _eGroup, bool _bShow ) + { + const sal_uInt16* pGroupIds = nullptr; + + switch ( _eGroup ) + { + case ePosition: + { + static const sal_uInt16 aPositionIds[] = { + LID_RECORD_LABEL, FormFeature::MoveAbsolute, LID_RECORD_FILLER, FormFeature::TotalRecords, 0 + }; + pGroupIds = aPositionIds; + } + break; + case eNavigation: + { + static const sal_uInt16 aNavigationIds[] = { + FormFeature::MoveToFirst, FormFeature::MoveToPrevious, FormFeature::MoveToNext, FormFeature::MoveToLast, FormFeature::MoveToInsertRow, 0 + }; + pGroupIds = aNavigationIds; + } + break; + case eRecordActions: + { + static const sal_uInt16 aActionIds[] = { + FormFeature::SaveRecordChanges, FormFeature::UndoRecordChanges, FormFeature::DeleteRecord, FormFeature::ReloadForm, FormFeature::RefreshCurrentControl, 0 + }; + pGroupIds = aActionIds; + } + break; + case eFilterSort: + { + static const sal_uInt16 aFilterSortIds[] = { + FormFeature::SortAscending, FormFeature::SortDescending, FormFeature::InteractiveSort, FormFeature::AutoFilter, FormFeature::InteractiveFilter, FormFeature::ToggleApplyFilter, FormFeature::RemoveFilterAndSort, 0 + }; + pGroupIds = aFilterSortIds; + } + break; + default: + OSL_FAIL( "NavigationToolBar::ShowFunctionGroup: invalid group id!" ); + } + + if ( pGroupIds ) + while ( *pGroupIds ) + m_pToolbar->ShowItem( *pGroupIds++, _bShow ); + } + + + bool NavigationToolBar::IsFunctionGroupVisible( FunctionGroup _eGroup ) + { + sal_uInt16 nIndicatorItem = 0; + switch ( _eGroup ) + { + case ePosition : nIndicatorItem = LID_RECORD_LABEL; break; + case eNavigation : nIndicatorItem = FormFeature::MoveToFirst; break; + case eRecordActions : nIndicatorItem = FormFeature::SaveRecordChanges; break; + case eFilterSort : nIndicatorItem = FormFeature::SortAscending; break; + default: + OSL_FAIL( "NavigationToolBar::IsFunctionGroupVisible: invalid group id!" ); + } + + return m_pToolbar->IsItemVisible( nIndicatorItem ); + } + + + void NavigationToolBar::StateChanged( StateChangedType nType ) + { + Window::StateChanged( nType ); + + switch ( nType ) + { + case StateChangedType::Zoom: +// m_pToolbar->SetZoom( GetZoom() ); +// forEachItemWindow( setItemWindowZoom, NULL ); + // the ToolBox class is not zoomable at the moment, so + // we better have no zoom at all instead of only half a zoom ... + break; + + case StateChangedType::ControlFont: + forEachItemWindow( &NavigationToolBar::setItemControlFont ); + forEachItemWindow( &NavigationToolBar::adjustItemWindowWidth ); + break; + + case StateChangedType::ControlForeground: + forEachItemWindow( &NavigationToolBar::setItemControlForeground ); + break; + + case StateChangedType::Mirroring: + { + sal_Bool bIsRTLEnabled( IsRTLEnabled() ); + m_pToolbar->EnableRTL( bIsRTLEnabled ); + forEachItemWindow( &NavigationToolBar::enableItemRTL, &bIsRTLEnabled ); + Resize(); + } + break; + default:; + } + } + + + void NavigationToolBar::Resize() + { + // resize/position the toolbox as a whole + sal_Int32 nToolbarHeight = m_pToolbar->CalcWindowSizePixel().Height(); + + sal_Int32 nMyHeight = GetOutputSizePixel().Height(); + m_pToolbar->SetPosSizePixel( Point( 0, ( nMyHeight - nToolbarHeight ) / 2 ), + Size( GetSizePixel().Width(), nToolbarHeight ) ); + + Window::Resize(); + } + + + void NavigationToolBar::SetControlBackground() + { + Window::SetControlBackground(); + m_pToolbar->SetControlBackground(); + forEachItemWindow( &NavigationToolBar::setItemBackground, nullptr ); + + implUpdateImages(); + } + + + void NavigationToolBar::SetControlBackground( const Color& _rColor ) + { + Window::SetControlBackground( _rColor ); + m_pToolbar->SetControlBackground( _rColor ); + forEachItemWindow( &NavigationToolBar::setItemBackground, &_rColor ); + + implUpdateImages(); + } + + + void NavigationToolBar::SetTextLineColor( ) + { + Window::SetTextLineColor( ); + m_pToolbar->SetTextLineColor( ); + forEachItemWindow( &NavigationToolBar::setTextLineColor, nullptr ); + } + + + void NavigationToolBar::SetTextLineColor( const Color& _rColor ) + { + Window::SetTextLineColor( _rColor ); + m_pToolbar->SetTextLineColor( _rColor ); + forEachItemWindow( &NavigationToolBar::setTextLineColor, &_rColor ); + } + + + void NavigationToolBar::forEachItemWindow( ItemWindowHandler _handler ) + { + for ( ToolBox::ImplToolItems::size_type item = 0; item < m_pToolbar->GetItemCount(); ++item ) + { + sal_uInt16 nItemId = m_pToolbar->GetItemId( item ); + vcl::Window* pItemWindow = m_pToolbar->GetItemWindow( nItemId ); + if ( pItemWindow ) + (this->*_handler)( nItemId, pItemWindow ); + } + } + + void NavigationToolBar::forEachItemWindow( ItemWindowHandler2 _handler, const void* _pParam ) + { + for ( ToolBox::ImplToolItems::size_type item = 0; item < m_pToolbar->GetItemCount(); ++item ) + { + sal_uInt16 nItemId = m_pToolbar->GetItemId( item ); + vcl::Window* pItemWindow = m_pToolbar->GetItemWindow( nItemId ); + if ( pItemWindow ) + (*_handler)( nItemId, pItemWindow, _pParam ); + } + } + + void NavigationToolBar::setItemBackground( sal_uInt16 /* _nItemId */, vcl::Window* _pItemWindow, const void* _pColor ) + { + if ( _pColor ) + _pItemWindow->SetControlBackground( *static_cast< const Color* >( _pColor ) ); + else + _pItemWindow->SetControlBackground(); + } + + + void NavigationToolBar::setTextLineColor( sal_uInt16 /* _nItemId */, vcl::Window* _pItemWindow, const void* _pColor ) + { + if ( _pColor ) + _pItemWindow->SetTextLineColor( *static_cast< const Color* >( _pColor ) ); + else + _pItemWindow->SetTextLineColor(); + } +#if 0 + + void NavigationToolBar::setItemWindowZoom( sal_uInt16 /* _nItemId */, vcl::Window* _pItemWindow, const void* /* _pParam */ ) const + { + _pItemWindow->SetZoom( GetZoom() ); + _pItemWindow->SetZoomedPointFont( IsControlFont() ? GetControlFont() : GetPointFont() ); + } +#endif + + void NavigationToolBar::setItemControlFont( sal_uInt16 /* _nItemId */, vcl::Window* _pItemWindow ) const + { + if ( IsControlFont() ) + _pItemWindow->SetControlFont( GetControlFont() ); + else + _pItemWindow->SetControlFont( ); + } + + + void NavigationToolBar::setItemControlForeground( sal_uInt16 /* _nItemId */, vcl::Window* _pItemWindow ) const + { + if ( IsControlForeground() ) + _pItemWindow->SetControlForeground( GetControlForeground() ); + else + _pItemWindow->SetControlForeground( ); + _pItemWindow->SetTextColor( GetTextColor() ); + } + + + void NavigationToolBar::adjustItemWindowWidth( sal_uInt16 _nItemId, vcl::Window* _pItemWindow ) const + { + OUString sItemText; + switch ( _nItemId ) + { + case LID_RECORD_LABEL: + sItemText = getLabelString( RID_STR_LABEL_RECORD ); + break; + + case LID_RECORD_FILLER: + sItemText = getLabelString( RID_STR_LABEL_OF ); + break; + + case FormFeature::MoveAbsolute: + sItemText = "12345678"; + break; + + case FormFeature::TotalRecords: + sItemText = "123456"; + break; + } + + Size aSize( _pItemWindow->GetTextWidth( sItemText ), /* _pItemWindow->GetSizePixel( ).Height() */ _pItemWindow->GetTextHeight() + 4 ); + aSize.AdjustWidth(6 ); + _pItemWindow->SetSizePixel( aSize ); + + m_pToolbar->SetItemWindow( _nItemId, _pItemWindow ); + } + + + void NavigationToolBar::enableItemRTL( sal_uInt16 /*_nItemId*/, vcl::Window* _pItemWindow, const void* _pIsRTLEnabled ) + { + _pItemWindow->EnableRTL( *static_cast< const sal_Bool* >( _pIsRTLEnabled ) ); + } + + RecordPositionInput::RecordPositionInput( vcl::Window* _pParent ) + :NumericField( _pParent, WB_BORDER | WB_VCENTER ) + ,m_pDispatcher( nullptr ) + { + SetMin( 1 ); + SetFirst( 1 ); + SetSpinSize( 1 ); + SetDecimalDigits( 0 ); + SetStrictFormat( true ); + SetBorderStyle( WindowBorderStyle::MONO ); + } + + + void RecordPositionInput::setDispatcher( const IFeatureDispatcher* _pDispatcher ) + { + m_pDispatcher = _pDispatcher; + } + + + void RecordPositionInput::FirePosition( bool _bForce ) + { + if ( _bForce || IsValueChangedFromSaved() ) + { + sal_Int64 nRecord = GetValue(); + if ( nRecord < GetMin() || nRecord > GetMax() ) + return; + + if ( m_pDispatcher ) + m_pDispatcher->dispatchWithArgument( FormFeature::MoveAbsolute, "Position", makeAny( static_cast<sal_Int32>(nRecord) ) ); + + SaveValue(); + } + } + + + void RecordPositionInput::LoseFocus() + { + FirePosition( false ); + } + + + void RecordPositionInput::KeyInput( const KeyEvent& rKeyEvent ) + { + if( rKeyEvent.GetKeyCode() == KEY_RETURN && !GetText().isEmpty() ) + FirePosition( true ); + else + NumericField::KeyInput( rKeyEvent ); + } + + +} // namespace frm + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/forms/source/solar/inc/navtoolbar.hxx b/forms/source/solar/inc/navtoolbar.hxx new file mode 100644 index 000000000..5b643b367 --- /dev/null +++ b/forms/source/solar/inc/navtoolbar.hxx @@ -0,0 +1,178 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_FORMS_SOURCE_SOLAR_INC_NAVTOOLBAR_HXX +#define INCLUDED_FORMS_SOURCE_SOLAR_INC_NAVTOOLBAR_HXX + +#include <vcl/field.hxx> + +#include <memory> + + +namespace frm +{ + + + class IFeatureDispatcher; + class DocumentCommandImageProvider; + class ICommandDescriptionProvider; + class ImplNavToolBar; + typedef std::shared_ptr< const DocumentCommandImageProvider > PCommandImageProvider; + + class NavigationToolBar final : public vcl::Window + { + public: + enum ImageSize + { + eSmall, + eLarge + }; + + enum FunctionGroup + { + ePosition, + eNavigation, + eRecordActions, + eFilterSort + }; + + private: + const IFeatureDispatcher* m_pDispatcher; + const std::shared_ptr< const DocumentCommandImageProvider > + m_pImageProvider; + ImageSize m_eImageSize; + VclPtr<ImplNavToolBar> m_pToolbar; + ::std::vector< VclPtr<vcl::Window> > m_aChildWins; + const OUString m_sModuleId; + + public: + NavigationToolBar( + vcl::Window* _pParent, + WinBits _nStyle, + const PCommandImageProvider& _pImageProvider, + const OUString & sModuleId + ); + virtual ~NavigationToolBar( ) override; + virtual void dispose() override; + + /** sets the dispatcher which is to be used for the features + + If the dispatcher is the same as the one which is currently set, + then the states of the features are updated + + @param _pDispatcher + the new (or old) dispatcher. The caller is responsible for + ensuring the life time of the object does exceed the life time + of the tool bar instance. + */ + void setDispatcher( const IFeatureDispatcher* _pDispatcher ); + + /// enables or disables a given feature + void enableFeature( sal_Int16 _nFeatureId, bool _bEnabled ); + + /// checks or unchecks a given feature + void checkFeature( sal_Int16 _nFeatureId, bool _bEnabled ); + + /// sets the text of a given feature + void setFeatureText( sal_Int16 _nFeatureId, const OUString& _rText ); + + /** retrieves the current image size + */ + ImageSize GetImageSize( ) const { return m_eImageSize; } + + /** sets the size of the images + */ + void SetImageSize( ImageSize _eSize ); + + /** shows or hides a function group + */ + void ShowFunctionGroup( FunctionGroup _eGroup, bool _bShow ); + + /** determines whether or not a given function group is currently visible + */ + bool IsFunctionGroupVisible( FunctionGroup _eGroup ); + + // Window "overridables" (hiding the respective Window methods) + void SetControlBackground(); + void SetControlBackground( const Color& rColor ); + void SetTextLineColor( ); + void SetTextLineColor( const Color& rColor ); + + private: + // Window overridables + virtual void Resize() override; + virtual void StateChanged( StateChangedType nType ) override; + + /// ctor implementation + void implInit( ); + + /// impl version of SetImageSize + void implSetImageSize( ImageSize _eSize ); + + /// updates the images of our items + void implUpdateImages(); + + /// enables or disables an item, plus possible dependent items + void implEnableItem( sal_uInt16 _nItemId, bool _bEnabled ); + + // iterating through item windows + typedef void (NavigationToolBar::*ItemWindowHandler) (sal_uInt16, vcl::Window*) const; + void forEachItemWindow( ItemWindowHandler _handler ); + typedef void (*ItemWindowHandler2) (sal_uInt16, vcl::Window*, const void*); + void forEachItemWindow( ItemWindowHandler2 _handler, const void* _pParam ); + + static void setItemBackground( sal_uInt16 /* _nItemId */, vcl::Window* _pItemWindow, const void* _pColor ); + static void setTextLineColor( sal_uInt16 /* _nItemId */, vcl::Window* _pItemWindow, const void* _pColor ); +#if 0 + void setItemWindowZoom( sal_uInt16 /* _nItemId */, vcl::Window* _pItemWindow, const void* /* _pParam */ ) const; +#endif + void setItemControlFont( sal_uInt16 /* _nItemId */, vcl::Window* _pItemWindow ) const; + void setItemControlForeground( sal_uInt16 /* _nItemId */, vcl::Window* _pItemWindow ) const; + void adjustItemWindowWidth( sal_uInt16 _nItemId, vcl::Window* _pItemWindow ) const; + static void enableItemRTL( sal_uInt16 /*_nItemId*/, vcl::Window* _pItemWindow, const void* _pIsRTLEnabled ); + }; + + class RecordPositionInput : public NumericField + { + private: + const IFeatureDispatcher* m_pDispatcher; + + public: + RecordPositionInput( vcl::Window* _pParent ); + + /** sets the dispatcher which is to be used for the features + */ + void setDispatcher( const IFeatureDispatcher* _pDispatcher ); + + protected: + // Window overridables + virtual void LoseFocus() override; + virtual void KeyInput( const KeyEvent& rKeyEvent ) override; + + private: + void FirePosition( bool _bForce ); + }; + + +} // namespace frm + + +#endif // INCLUDED_FORMS_SOURCE_SOLAR_INC_NAVTOOLBAR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |