1
0
Fork 0
libreoffice/dbaccess/source/ui/querydesign/limitboxcontroller.cxx
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

301 lines
7.9 KiB
C++

/* -*- 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/.
*/
#include "limitboxcontroller.hxx"
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
#include <comphelper/propertyvalue.hxx>
#include <vcl/InterimItemWindow.hxx>
#include <vcl/event.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <core_resource.hxx>
#include <strings.hrc>
using namespace ::com::sun::star;
namespace
{
/// Default values
sal_Int64 const aDefLimitAry[] =
{
5,
10,
20,
50
};
}
namespace dbaui
{
/**
* Input box to add limit to an SQL query (maximum number of result's rows)
* This box is reachable on the Query Design Toolbar
*/
class LimitBox final : public InterimItemWindow
{
public:
LimitBox(vcl::Window* pParent, LimitBoxController* pCtrl)
: InterimItemWindow(pParent, u"dbaccess/ui/limitbox.ui"_ustr, u"LimitBox"_ustr)
, m_pControl( pCtrl )
, m_xWidget(m_xBuilder->weld_combo_box(u"limit"_ustr))
{
InitControlBase(m_xWidget.get());
LoadDefaultLimits();
m_xWidget->connect_key_press(LINK(this, LimitBox, KeyInputHdl));
m_xWidget->connect_entry_activate(LINK(this, LimitBox, ActivateHdl));
m_xWidget->connect_changed(LINK(this, LimitBox, ChangeHdl));
m_xWidget->connect_focus_out(LINK(this, LimitBox, FocusOutHdl));
m_xWidget->set_entry_width_chars(6);
SetSizePixel(m_xContainer->get_preferred_size());
}
virtual void dispose() override
{
m_xWidget.reset();
InterimItemWindow::dispose();
}
virtual ~LimitBox() override
{
disposeOnce();
}
void set_sensitive(bool bSensitive)
{
m_xWidget->set_sensitive(bSensitive);
}
void set_value(int nLimit)
{
if (nLimit < 0)
m_xWidget->set_active(0);
else
m_xWidget->set_entry_text(OUString::number(nLimit));
m_xWidget->save_value();
}
private:
LimitBoxController* m_pControl;
std::unique_ptr<weld::ComboBox> m_xWidget;
DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
DECL_LINK(ActivateHdl, weld::ComboBox&, bool);
DECL_LINK(ChangeHdl, weld::ComboBox&, void);
DECL_LINK(FocusOutHdl, weld::Widget&, void);
void Apply()
{
if (!m_xWidget->get_value_changed_from_saved())
return;
sal_Int64 nLimit;
OUString sActiveText = m_xWidget->get_active_text();
if (sActiveText == DBA_RES(STR_QUERY_LIMIT_ALL))
nLimit = -1;
else
{
nLimit = m_xWidget->get_active_text().toInt64();
if (nLimit < 0)
nLimit = -1;
}
set_value(nLimit);
m_pControl->dispatchCommand({ comphelper::makePropertyValue(u"DBLimit.Value"_ustr, nLimit) });
}
///Initialize entries
void LoadDefaultLimits()
{
m_xWidget->freeze();
m_xWidget->append_text(DBA_RES(STR_QUERY_LIMIT_ALL));
for (auto nIndex : aDefLimitAry)
{
m_xWidget->append_text(OUString::number(nIndex));
}
m_xWidget->thaw();
}
};
IMPL_LINK(LimitBox, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
bool bHandled = false;
const sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
switch (nCode)
{
case KEY_ESCAPE:
m_xWidget->set_entry_text(m_xWidget->get_saved_value());
bHandled = true;
break;
case KEY_RETURN:
{
bHandled = ActivateHdl(*m_xWidget);
break;
}
}
return bHandled || ChildKeyInput(rKEvt);
}
IMPL_LINK_NOARG(LimitBox, FocusOutHdl, weld::Widget&, void)
{
if (!m_xWidget || m_xWidget->has_focus()) // comboboxes can be comprised of multiple widgets, ensure all have lost focus
return;
Apply();
}
IMPL_LINK(LimitBox, ChangeHdl, weld::ComboBox&, rComboBox, void)
{
if (rComboBox.changed_by_direct_pick())
ActivateHdl(rComboBox);
}
IMPL_LINK_NOARG(LimitBox, ActivateHdl, weld::ComboBox&, bool)
{
GrabFocusToDocument();
Apply();
return true;
}
LimitBoxController::LimitBoxController(
const uno::Reference< uno::XComponentContext >& rxContext ) :
LimitBoxController_Base( rxContext,
uno::Reference< frame::XFrame >(),
".uno:DBLimit" ),
m_xLimitBox( nullptr )
{
}
LimitBoxController::~LimitBoxController()
{
}
/// XServiceInfo
OUString SAL_CALL LimitBoxController::getImplementationName()
{
return u"org.libreoffice.comp.dbu.LimitBoxController"_ustr;
}
sal_Bool SAL_CALL LimitBoxController::supportsService(const OUString& _rServiceName)
{
const css::uno::Sequence< OUString > aSupported(getSupportedServiceNames());
for (const OUString& s : aSupported)
if (s == _rServiceName)
return true;
return false;
}
css::uno::Sequence< OUString > SAL_CALL LimitBoxController::getSupportedServiceNames()
{
return { u"com.sun.star.frame.ToolbarController"_ustr };
}
/// XComponent
void SAL_CALL LimitBoxController::dispose()
{
svt::ToolboxController::dispose();
SolarMutexGuard aSolarMutexGuard;
m_xLimitBox.disposeAndClear();
}
/// XStatusListener
void SAL_CALL LimitBoxController::statusChanged(
const frame::FeatureStateEvent& rEvent )
{
if ( !m_xLimitBox )
return;
SolarMutexGuard aSolarMutexGuard;
if ( rEvent.FeatureURL.Path == "DBLimit" )
{
if ( rEvent.IsEnabled )
{
m_xLimitBox->set_sensitive(true);
sal_Int64 nLimit = 0;
if (rEvent.State >>= nLimit)
m_xLimitBox->set_value(nLimit);
}
else
m_xLimitBox->set_sensitive(false);
}
}
/// XToolbarController
void SAL_CALL LimitBoxController::execute( sal_Int16 /*KeyModifier*/ )
{
}
void SAL_CALL LimitBoxController::click()
{
}
void SAL_CALL LimitBoxController::doubleClick()
{
}
uno::Reference< awt::XWindow > SAL_CALL LimitBoxController::createPopupWindow()
{
return uno::Reference< awt::XWindow >();
}
uno::Reference< awt::XWindow > SAL_CALL LimitBoxController::createItemWindow(
const uno::Reference< awt::XWindow >& xParent )
{
uno::Reference< awt::XWindow > xItemWindow;
VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow( xParent );
if ( pParent )
{
SolarMutexGuard aSolarMutexGuard;
m_xLimitBox = VclPtr<LimitBox>::Create(pParent, this);
xItemWindow = VCLUnoHelper::GetInterface(m_xLimitBox);
}
return xItemWindow;
}
void LimitBoxController::dispatchCommand(
const uno::Sequence< beans::PropertyValue >& rArgs )
{
uno::Reference< frame::XDispatchProvider > xDispatchProvider( m_xFrame, uno::UNO_QUERY );
if ( xDispatchProvider.is() )
{
util::URL aURL;
uno::Reference< frame::XDispatch > xDispatch;
uno::Reference< util::XURLTransformer > xURLTransformer = getURLTransformer();
aURL.Complete = ".uno:DBLimit";
xURLTransformer->parseStrict( aURL );
xDispatch = xDispatchProvider->queryDispatch( aURL, OUString(), 0 );
if ( xDispatch.is() )
xDispatch->dispatch( aURL, rArgs );
}
}
} // dbaui namespace
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
org_libreoffice_comp_dbu_LimitBoxController_get_implementation(
css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
{
return cppu::acquire(new ::dbaui::LimitBoxController(context));
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */