summaryrefslogtreecommitdiffstats
path: root/reportdesign/source/ui/dlg/Condition.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'reportdesign/source/ui/dlg/Condition.cxx')
-rw-r--r--reportdesign/source/ui/dlg/Condition.cxx379
1 files changed, 379 insertions, 0 deletions
diff --git a/reportdesign/source/ui/dlg/Condition.cxx b/reportdesign/source/ui/dlg/Condition.cxx
new file mode 100644
index 0000000000..c442e4ccfc
--- /dev/null
+++ b/reportdesign/source/ui/dlg/Condition.cxx
@@ -0,0 +1,379 @@
+/* -*- 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 "Condition.hxx"
+#include <UITools.hxx>
+#include <CondFormat.hxx>
+#include <core_resource.hxx>
+#include <strings.hrc>
+#include <ReportController.hxx>
+#include <reportformula.hxx>
+
+#include <svx/PaletteManager.hxx>
+#include <svx/svxids.hrc>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+
+#include <comphelper/diagnose_ex.hxx>
+
+namespace rptui
+{
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+ConditionField::ConditionField(Condition* pParent, std::unique_ptr<weld::Entry> xSubEdit,
+ std::unique_ptr<weld::Button> xFormula)
+ : m_pParent(pParent)
+ , m_xSubEdit(std::move(xSubEdit))
+ , m_xFormula(std::move(xFormula))
+{
+ m_xFormula->set_label("...");
+ m_xFormula->connect_clicked( LINK( this, ConditionField, OnFormula ) );
+}
+
+IMPL_LINK_NOARG(ConditionField, OnFormula, weld::Button&, void)
+{
+ OUString sFormula(m_xSubEdit->get_text());
+ const sal_Int32 nLen = sFormula.getLength();
+ if ( nLen )
+ {
+ ReportFormula aFormula( sFormula );
+ sFormula = aFormula.getCompleteFormula();
+ }
+ uno::Reference< awt::XWindow> xInspectorWindow = m_pParent->GetXWindow();
+ uno::Reference< beans::XPropertySet> xProp(m_pParent->getController().getRowSet(),uno::UNO_QUERY);
+ if ( rptui::openDialogFormula_nothrow( sFormula, m_pParent->getController().getContext(),xInspectorWindow,xProp ) )
+ {
+ ReportFormula aFormula( sFormula );
+ m_xSubEdit->set_text(aFormula.getUndecoratedContent());
+ }
+}
+
+ConditionColorWrapper::ConditionColorWrapper(Condition* pControl, sal_uInt16 nSlotId)
+ : mpControl(pControl)
+ , mnSlotId(nSlotId)
+{
+}
+
+void ConditionColorWrapper::operator()(
+ [[maybe_unused]] const OUString& /*rCommand*/, const NamedColor& rNamedColor)
+{
+ mpControl->ApplyCommand(mnSlotId, rNamedColor);
+}
+
+// = Condition
+Condition::Condition(weld::Container* pParent, weld::Window* pDialog, IConditionalFormatAction& _rAction, ::rptui::OReportController& _rController)
+ : m_xPaletteManager(std::make_shared<PaletteManager>())
+ , m_aBackColorWrapper(this, SID_BACKGROUND_COLOR)
+ , m_aForeColorWrapper(this, SID_ATTR_CHAR_COLOR2)
+ , m_rController(_rController)
+ , m_rAction(_rAction)
+ , m_nCondIndex(0)
+ , m_pDialog(pDialog)
+ , m_xBuilder(Application::CreateBuilder(pParent, "modules/dbreport/ui/conditionwin.ui"))
+ , m_xContainer(m_xBuilder->weld_container("ConditionWin"))
+ , m_xHeader(m_xBuilder->weld_label("headerLabel"))
+ , m_xConditionType(m_xBuilder->weld_combo_box("typeCombobox"))
+ , m_xOperationList(m_xBuilder->weld_combo_box("opCombobox"))
+ , m_xOperandGlue(m_xBuilder->weld_label("andLabel"))
+ , m_xActions(m_xBuilder->weld_toolbar("formatToolbox"))
+ , m_xPreview(new weld::CustomWeld(*m_xBuilder, "previewDrawingarea", m_aPreview))
+ , m_xMoveUp(m_xBuilder->weld_button("upButton"))
+ , m_xMoveDown(m_xBuilder->weld_button("downButton"))
+ , m_xAddCondition(m_xBuilder->weld_button("addButton"))
+ , m_xRemoveCondition(m_xBuilder->weld_button("removeButton"))
+{
+ m_xCondLHS.reset(new ConditionField(this, m_xBuilder->weld_entry("lhsEntry"), m_xBuilder->weld_button("lhsButton")));
+ m_xCondRHS.reset(new ConditionField(this, m_xBuilder->weld_entry("rhsEntry"), m_xBuilder->weld_button("rhsButton")));
+
+ m_xCondLHS->grab_focus();
+
+ m_xConditionType->connect_changed( LINK( this, Condition, OnTypeSelected ) );
+
+ m_xOperationList->connect_changed( LINK( this, Condition, OnOperationSelected ) );
+
+ m_xActions->connect_clicked(LINK(this, Condition, OnFormatAction));
+
+ m_xMoveUp->connect_clicked( LINK( this, Condition, OnConditionAction ) );
+ m_xMoveDown->connect_clicked( LINK( this, Condition, OnConditionAction ) );
+ m_xAddCondition->connect_clicked( LINK( this, Condition, OnConditionAction ) );
+ m_xRemoveCondition->connect_clicked( LINK( this, Condition, OnConditionAction ) );
+
+ m_xConditionType->set_active(0);
+ m_xOperationList->set_active(0);
+
+ SetBackgroundDropdownClick();
+ SetForegroundDropdownClick();
+
+ m_xContainer->show();
+
+ ConditionalExpressionFactory::getKnownConditionalExpressions( m_aConditionalExpressions );
+}
+
+sal_uInt16 Condition::mapToolbarItemToSlotId(std::u16string_view rItemId)
+{
+ if (rItemId == u"bold")
+ return SID_ATTR_CHAR_WEIGHT;
+ if (rItemId == u"italic")
+ return SID_ATTR_CHAR_POSTURE;
+ if (rItemId == u"underline")
+ return SID_ATTR_CHAR_UNDERLINE;
+ if (rItemId == u"background")
+ return SID_BACKGROUND_COLOR;
+ if (rItemId == u"foreground")
+ return SID_ATTR_CHAR_COLOR2;
+ if (rItemId == u"fontdialog")
+ return SID_CHAR_DLG;
+ return 0;
+}
+
+Condition::~Condition()
+{
+}
+
+void Condition::SetBackgroundDropdownClick()
+{
+ m_xBackColorFloat.reset(new ColorWindow(
+ OUString() /*m_aCommandURL*/,
+ m_xPaletteManager,
+ m_aColorStatus,
+ SID_BACKGROUND_COLOR,
+ nullptr,
+ MenuOrToolMenuButton(m_xActions.get(), "background"),
+ [this]{ return m_pDialog; },
+ m_aBackColorWrapper));
+
+ m_xActions->set_item_popover("background", m_xBackColorFloat->getTopLevel());
+}
+
+void Condition::SetForegroundDropdownClick()
+{
+ m_xForeColorFloat.reset(new ColorWindow(
+ OUString() /*m_aCommandURL*/,
+ m_xPaletteManager,
+ m_aColorStatus,
+ SID_ATTR_CHAR_COLOR2,
+ nullptr,
+ MenuOrToolMenuButton(m_xActions.get(), "foreground"),
+ [this]{ return m_pDialog; },
+ m_aForeColorWrapper));
+
+ m_xActions->set_item_popover("foreground", m_xForeColorFloat->getTopLevel());
+}
+
+
+IMPL_LINK(Condition, OnFormatAction, const OUString&, rIdent, void)
+{
+ ApplyCommand(mapToolbarItemToSlotId(rIdent),
+ NamedColor(COL_AUTO, "#" + COL_AUTO.AsRGBHexString()));
+}
+
+IMPL_LINK(Condition, OnConditionAction, weld::Button&, rClickedButton, void)
+{
+ if ( &rClickedButton == m_xMoveUp.get() )
+ m_rAction.moveConditionUp( getConditionIndex() );
+ else if ( &rClickedButton == m_xMoveDown.get() )
+ m_rAction.moveConditionDown( getConditionIndex() );
+ else if ( &rClickedButton == m_xAddCondition.get() )
+ m_rAction.addCondition( getConditionIndex() );
+ else if ( &rClickedButton == m_xRemoveCondition.get() )
+ m_rAction.deleteCondition( getConditionIndex() );
+}
+
+void Condition::ApplyCommand( sal_uInt16 _nCommandId, const NamedColor& rNamedColor )
+{
+ m_rAction.applyCommand(m_nCondIndex, _nCommandId, rNamedColor.m_aColor);
+}
+
+IMPL_LINK_NOARG( Condition, OnTypeSelected, weld::ComboBox&, void )
+{
+ impl_layoutOperands();
+}
+
+IMPL_LINK_NOARG( Condition, OnOperationSelected, weld::ComboBox&, void )
+{
+ impl_layoutOperands();
+}
+
+void Condition::impl_layoutOperands()
+{
+ const ConditionType eType( impl_getCurrentConditionType() );
+ const ComparisonOperation eOperation( impl_getCurrentComparisonOperation() );
+
+ const bool bIsExpression = ( eType == eExpression );
+ const bool bHaveRHS =
+ ( ( eType == eFieldValueComparison )
+ && ( ( eOperation == eBetween )
+ || ( eOperation == eNotBetween )
+ )
+ );
+
+ // the "condition type" list box
+ m_xOperationList->set_visible( !bIsExpression );
+ m_xOperandGlue->set_visible( bHaveRHS );
+ m_xCondRHS->set_visible( bHaveRHS );
+}
+
+void Condition::impl_setCondition( const OUString& _rConditionFormula )
+{
+ // determine the condition's type and comparison operation
+ ConditionType eType( eFieldValueComparison );
+ ComparisonOperation eOperation( eBetween );
+
+ // LHS and RHS, matched below
+ OUString sLHS, sRHS;
+
+ if ( !_rConditionFormula.isEmpty() )
+ {
+ // the unprefixed expression which forms the condition
+ ReportFormula aFormula( _rConditionFormula );
+ OSL_ENSURE( aFormula.getType() == ReportFormula::Expression, "Condition::setCondition: illegal formula!" );
+ OUString sExpression;
+ if ( aFormula.getType() == ReportFormula::Expression )
+ sExpression = aFormula.getExpression();
+ // as fallback, if the below matching does not succeed, assume
+ // the whole expression is the LHS
+ eType = eExpression;
+ sLHS = sExpression;
+
+ // the data field (or expression) to which our control is bound
+ const ReportFormula aFieldContentFormula( m_rAction.getDataField() );
+ const OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() );
+
+ // check whether one of the Field Value Expression Factories recognizes the expression
+ for (const auto& [rOperation, rxConditionalExpression] : m_aConditionalExpressions)
+ {
+ if ( rxConditionalExpression->matchExpression( sExpression, sUnprefixedFieldContent, sLHS, sRHS ) )
+ {
+ eType = eFieldValueComparison;
+ eOperation = rOperation;
+ break;
+ }
+ }
+ }
+
+ // update UI
+ m_xConditionType->set_active(static_cast<sal_uInt16>(eType));
+ m_xOperationList->set_active(static_cast<sal_uInt16>(eOperation));
+ m_xCondLHS->set_text( sLHS );
+ m_xCondRHS->set_text( sRHS );
+
+ // re-layout
+ impl_layoutOperands();
+}
+
+
+void Condition::setCondition( const uno::Reference< report::XFormatCondition >& _rxCondition )
+{
+ OSL_PRECOND( _rxCondition.is(), "Condition::setCondition: empty condition object!" );
+ if ( !_rxCondition.is() )
+ return;
+
+ OUString sConditionFormula;
+ try
+ {
+ if ( _rxCondition.is() )
+ sConditionFormula = _rxCondition->getFormula();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ impl_setCondition( sConditionFormula );
+ updateToolbar( _rxCondition );
+}
+
+
+void Condition::updateToolbar(const uno::Reference< report::XReportControlFormat >& _xReportControlFormat)
+{
+ OUString aItems[] = { "bold", "italic", "underline", "fontdialog" };
+
+ OSL_ENSURE(_xReportControlFormat.is(),"XReportControlFormat is NULL!");
+ if ( !_xReportControlFormat.is() )
+ return;
+
+ for (size_t j = 0; j < SAL_N_ELEMENTS(aItems); ++j)
+ {
+ m_xActions->set_item_active(aItems[j], OReportController::isFormatCommandEnabled(mapToolbarItemToSlotId(aItems[j]),
+ _xReportControlFormat));
+ }
+
+ try
+ {
+ vcl::Font aBaseFont( Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetAppFont() );
+ SvxFont aFont( VCLUnoHelper::CreateFont( _xReportControlFormat->getFontDescriptor(), aBaseFont ) );
+ aFont.SetFontHeight(o3tl::convert(aFont.GetFontHeight(), o3tl::Length::pt, o3tl::Length::twip));
+ aFont.SetEmphasisMark( static_cast< FontEmphasisMark >( _xReportControlFormat->getControlTextEmphasis() ) );
+ aFont.SetRelief( static_cast< FontRelief >( _xReportControlFormat->getCharRelief() ) );
+ aFont.SetColor( Color(ColorTransparency, _xReportControlFormat->getCharColor()) );
+ m_aPreview.SetFont( aFont, aFont, aFont );
+ m_aPreview.SetTextLineColor( Color( ColorTransparency, _xReportControlFormat->getCharUnderlineColor() ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+void Condition::fillFormatCondition(const uno::Reference< report::XFormatCondition >& _xCondition)
+{
+ const ConditionType eType( impl_getCurrentConditionType() );
+ const ComparisonOperation eOperation( impl_getCurrentComparisonOperation() );
+
+ const OUString sLHS( m_xCondLHS->get_text() );
+ const OUString sRHS( m_xCondRHS->get_text() );
+
+ OUString sUndecoratedFormula( sLHS );
+
+ if ( eType == eFieldValueComparison )
+ {
+ ReportFormula aFieldContentFormula( m_rAction.getDataField() );
+ OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() );
+
+ PConditionalExpression pFactory( m_aConditionalExpressions[ eOperation ] );
+ sUndecoratedFormula = pFactory->assembleExpression( sUnprefixedFieldContent, sLHS, sRHS );
+ }
+
+ ReportFormula aFormula( ReportFormula::Expression, sUndecoratedFormula );
+ _xCondition->setFormula( aFormula.getCompleteFormula() );
+}
+
+void Condition::setConditionIndex( size_t _nCondIndex, size_t _nCondCount )
+{
+ m_nCondIndex = _nCondIndex;
+ OUString sHeader( RptResId( STR_NUMBERED_CONDITION ) );
+ sHeader = sHeader.replaceFirst( "$number$", OUString::number( _nCondIndex + 1) );
+ m_xHeader->set_label( sHeader );
+
+ m_xMoveUp->set_sensitive(_nCondIndex > 0);
+ OSL_PRECOND( _nCondCount > 0, "Condition::setConditionIndex: having no conditions at all is nonsense!" );
+ m_xMoveDown->set_sensitive(_nCondIndex < _nCondCount - 1);
+}
+
+bool Condition::isEmpty() const
+{
+ return m_xCondLHS->get_text().isEmpty();
+}
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */