LibreOffice Module reportdesign (master) 1
Condition.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include "Condition.hxx"
21#include <UITools.hxx>
22#include <CondFormat.hxx>
23#include <core_resource.hxx>
24#include <strings.hrc>
25#include <ReportController.hxx>
26#include <reportformula.hxx>
27
29#include <svx/svxids.hrc>
31#include <vcl/svapp.hxx>
32#include <vcl/settings.hxx>
33
35
36namespace rptui
37{
38using namespace ::com::sun::star;
39using namespace ::com::sun::star::uno;
40using namespace ::com::sun::star::beans;
41
42ConditionField::ConditionField(Condition* pParent, std::unique_ptr<weld::Entry> xSubEdit,
43 std::unique_ptr<weld::Button> xFormula)
44 : m_pParent(pParent)
45 , m_xSubEdit(std::move(xSubEdit))
46 , m_xFormula(std::move(xFormula))
47{
48 m_xFormula->set_label("...");
49 m_xFormula->connect_clicked( LINK( this, ConditionField, OnFormula ) );
50}
51
53{
54 OUString sFormula(m_xSubEdit->get_text());
55 const sal_Int32 nLen = sFormula.getLength();
56 if ( nLen )
57 {
58 ReportFormula aFormula( sFormula );
59 sFormula = aFormula.getCompleteFormula();
60 }
61 uno::Reference< awt::XWindow> xInspectorWindow = m_pParent->GetXWindow();
62 uno::Reference< beans::XPropertySet> xProp(m_pParent->getController().getRowSet(),uno::UNO_QUERY);
63 if ( rptui::openDialogFormula_nothrow( sFormula, m_pParent->getController().getContext(),xInspectorWindow,xProp ) )
64 {
65 ReportFormula aFormula( sFormula );
66 m_xSubEdit->set_text(aFormula.getUndecoratedContent());
67 }
68}
69
71 : mpControl(pControl)
72 , mnSlotId(nSlotId)
73{
74}
75
77 [[maybe_unused]] const OUString& /*rCommand*/, const NamedColor& rNamedColor)
78{
79 mpControl->ApplyCommand(mnSlotId, rNamedColor);
80}
81
82// = Condition
84 : m_xPaletteManager(std::make_shared<PaletteManager>())
85 , m_aBackColorWrapper(this, SID_BACKGROUND_COLOR)
86 , m_aForeColorWrapper(this, SID_ATTR_CHAR_COLOR2)
87 , m_rController(_rController)
88 , m_rAction(_rAction)
89 , m_nCondIndex(0)
90 , m_pDialog(pDialog)
91 , m_xBuilder(Application::CreateBuilder(pParent, "modules/dbreport/ui/conditionwin.ui"))
92 , m_xContainer(m_xBuilder->weld_container("ConditionWin"))
93 , m_xHeader(m_xBuilder->weld_label("headerLabel"))
94 , m_xConditionType(m_xBuilder->weld_combo_box("typeCombobox"))
95 , m_xOperationList(m_xBuilder->weld_combo_box("opCombobox"))
96 , m_xOperandGlue(m_xBuilder->weld_label("andLabel"))
97 , m_xActions(m_xBuilder->weld_toolbar("formatToolbox"))
98 , m_xPreview(new weld::CustomWeld(*m_xBuilder, "previewDrawingarea", m_aPreview))
99 , m_xMoveUp(m_xBuilder->weld_button("upButton"))
100 , m_xMoveDown(m_xBuilder->weld_button("downButton"))
101 , m_xAddCondition(m_xBuilder->weld_button("addButton"))
102 , m_xRemoveCondition(m_xBuilder->weld_button("removeButton"))
103{
104 m_xCondLHS.reset(new ConditionField(this, m_xBuilder->weld_entry("lhsEntry"), m_xBuilder->weld_button("lhsButton")));
105 m_xCondRHS.reset(new ConditionField(this, m_xBuilder->weld_entry("rhsEntry"), m_xBuilder->weld_button("rhsButton")));
106
107 m_xCondLHS->grab_focus();
108
109 m_xConditionType->connect_changed( LINK( this, Condition, OnTypeSelected ) );
110
111 m_xOperationList->connect_changed( LINK( this, Condition, OnOperationSelected ) );
112
113 m_xActions->connect_clicked(LINK(this, Condition, OnFormatAction));
114
115 m_xMoveUp->connect_clicked( LINK( this, Condition, OnConditionAction ) );
116 m_xMoveDown->connect_clicked( LINK( this, Condition, OnConditionAction ) );
117 m_xAddCondition->connect_clicked( LINK( this, Condition, OnConditionAction ) );
118 m_xRemoveCondition->connect_clicked( LINK( this, Condition, OnConditionAction ) );
119
120 m_xConditionType->set_active(0);
121 m_xOperationList->set_active(0);
122
125
126 m_xContainer->show();
127
129}
130
131sal_uInt16 Condition::mapToolbarItemToSlotId(std::u16string_view rItemId)
132{
133 if (rItemId == u"bold")
134 return SID_ATTR_CHAR_WEIGHT;
135 if (rItemId == u"italic")
136 return SID_ATTR_CHAR_POSTURE;
137 if (rItemId == u"underline")
138 return SID_ATTR_CHAR_UNDERLINE;
139 if (rItemId == u"background")
140 return SID_BACKGROUND_COLOR;
141 if (rItemId == u"foreground")
142 return SID_ATTR_CHAR_COLOR2;
143 if (rItemId == u"fontdialog")
144 return SID_CHAR_DLG;
145 return 0;
146}
147
149{
150}
151
153{
155 OUString() /*m_aCommandURL*/,
158 SID_BACKGROUND_COLOR,
159 nullptr,
160 MenuOrToolMenuButton(m_xActions.get(), "background"),
161 [this]{ return m_pDialog; },
163
164 m_xActions->set_item_popover("background", m_xBackColorFloat->getTopLevel());
165}
166
168{
170 OUString() /*m_aCommandURL*/,
173 SID_ATTR_CHAR_COLOR2,
174 nullptr,
175 MenuOrToolMenuButton(m_xActions.get(), "foreground"),
176 [this]{ return m_pDialog; },
178
179 m_xActions->set_item_popover("foreground", m_xForeColorFloat->getTopLevel());
180}
181
182
183IMPL_LINK(Condition, OnFormatAction, const OUString&, rIdent, void)
184{
185 ApplyCommand(mapToolbarItemToSlotId(rIdent),
187}
188
189IMPL_LINK(Condition, OnConditionAction, weld::Button&, rClickedButton, void)
190{
191 if ( &rClickedButton == m_xMoveUp.get() )
192 m_rAction.moveConditionUp( getConditionIndex() );
193 else if ( &rClickedButton == m_xMoveDown.get() )
194 m_rAction.moveConditionDown( getConditionIndex() );
195 else if ( &rClickedButton == m_xAddCondition.get() )
196 m_rAction.addCondition( getConditionIndex() );
197 else if ( &rClickedButton == m_xRemoveCondition.get() )
198 m_rAction.deleteCondition( getConditionIndex() );
199}
200
201void Condition::ApplyCommand( sal_uInt16 _nCommandId, const NamedColor& rNamedColor )
202{
203 m_rAction.applyCommand(m_nCondIndex, _nCommandId, rNamedColor.m_aColor);
204}
205
206IMPL_LINK_NOARG( Condition, OnTypeSelected, weld::ComboBox&, void )
207{
208 impl_layoutOperands();
209}
210
211IMPL_LINK_NOARG( Condition, OnOperationSelected, weld::ComboBox&, void )
212{
213 impl_layoutOperands();
214}
215
217{
220
221 const bool bIsExpression = ( eType == eExpression );
222 const bool bHaveRHS =
224 && ( ( eOperation == eBetween )
225 || ( eOperation == eNotBetween )
226 )
227 );
228
229 // the "condition type" list box
230 m_xOperationList->set_visible( !bIsExpression );
231 m_xOperandGlue->set_visible( bHaveRHS );
232 m_xCondRHS->set_visible( bHaveRHS );
233}
234
235void Condition::impl_setCondition( const OUString& _rConditionFormula )
236{
237 // determine the condition's type and comparison operation
239 ComparisonOperation eOperation( eBetween );
240
241 // LHS and RHS, matched below
242 OUString sLHS, sRHS;
243
244 if ( !_rConditionFormula.isEmpty() )
245 {
246 // the unprefixed expression which forms the condition
247 ReportFormula aFormula( _rConditionFormula );
248 OSL_ENSURE( aFormula.getType() == ReportFormula::Expression, "Condition::setCondition: illegal formula!" );
249 OUString sExpression;
250 if ( aFormula.getType() == ReportFormula::Expression )
251 sExpression = aFormula.getExpression();
252 // as fallback, if the below matching does not succeed, assume
253 // the whole expression is the LHS
255 sLHS = sExpression;
256
257 // the data field (or expression) to which our control is bound
258 const ReportFormula aFieldContentFormula( m_rAction.getDataField() );
259 const OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() );
260
261 // check whether one of the Field Value Expression Factories recognizes the expression
262 for (const auto& [rOperation, rxConditionalExpression] : m_aConditionalExpressions)
263 {
264 if ( rxConditionalExpression->matchExpression( sExpression, sUnprefixedFieldContent, sLHS, sRHS ) )
265 {
267 eOperation = rOperation;
268 break;
269 }
270 }
271 }
272
273 // update UI
274 m_xConditionType->set_active(static_cast<sal_uInt16>(eType));
275 m_xOperationList->set_active(static_cast<sal_uInt16>(eOperation));
276 m_xCondLHS->set_text( sLHS );
277 m_xCondRHS->set_text( sRHS );
278
279 // re-layout
281}
282
283
284void Condition::setCondition( const uno::Reference< report::XFormatCondition >& _rxCondition )
285{
286 OSL_PRECOND( _rxCondition.is(), "Condition::setCondition: empty condition object!" );
287 if ( !_rxCondition.is() )
288 return;
289
290 OUString sConditionFormula;
291 try
292 {
293 if ( _rxCondition.is() )
294 sConditionFormula = _rxCondition->getFormula();
295 }
296 catch( const Exception& )
297 {
298 DBG_UNHANDLED_EXCEPTION("reportdesign");
299 }
300 impl_setCondition( sConditionFormula );
301 updateToolbar( _rxCondition );
302}
303
304
305void Condition::updateToolbar(const uno::Reference< report::XReportControlFormat >& _xReportControlFormat)
306{
307 OUString aItems[] = { "bold", "italic", "underline", "fontdialog" };
308
309 OSL_ENSURE(_xReportControlFormat.is(),"XReportControlFormat is NULL!");
310 if ( !_xReportControlFormat.is() )
311 return;
312
313 for (size_t j = 0; j < SAL_N_ELEMENTS(aItems); ++j)
314 {
316 _xReportControlFormat));
317 }
318
319 try
320 {
321 vcl::Font aBaseFont( Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetAppFont() );
322 SvxFont aFont( VCLUnoHelper::CreateFont( _xReportControlFormat->getFontDescriptor(), aBaseFont ) );
323 aFont.SetFontHeight(o3tl::convert(aFont.GetFontHeight(), o3tl::Length::pt, o3tl::Length::twip));
324 aFont.SetEmphasisMark( static_cast< FontEmphasisMark >( _xReportControlFormat->getControlTextEmphasis() ) );
325 aFont.SetRelief( static_cast< FontRelief >( _xReportControlFormat->getCharRelief() ) );
326 aFont.SetColor( Color(ColorTransparency, _xReportControlFormat->getCharColor()) );
327 m_aPreview.SetFont( aFont, aFont, aFont );
328 m_aPreview.SetTextLineColor( Color( ColorTransparency, _xReportControlFormat->getCharUnderlineColor() ) );
329 }
330 catch( const Exception& )
331 {
332 DBG_UNHANDLED_EXCEPTION("reportdesign");
333 }
334}
335
336void Condition::fillFormatCondition(const uno::Reference< report::XFormatCondition >& _xCondition)
337{
340
341 const OUString sLHS( m_xCondLHS->get_text() );
342 const OUString sRHS( m_xCondRHS->get_text() );
343
344 OUString sUndecoratedFormula( sLHS );
345
347 {
348 ReportFormula aFieldContentFormula( m_rAction.getDataField() );
349 OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() );
350
351 PConditionalExpression pFactory( m_aConditionalExpressions[ eOperation ] );
352 sUndecoratedFormula = pFactory->assembleExpression( sUnprefixedFieldContent, sLHS, sRHS );
353 }
354
355 ReportFormula aFormula( ReportFormula::Expression, sUndecoratedFormula );
356 _xCondition->setFormula( aFormula.getCompleteFormula() );
357}
358
359void Condition::setConditionIndex( size_t _nCondIndex, size_t _nCondCount )
360{
361 m_nCondIndex = _nCondIndex;
362 OUString sHeader( RptResId( STR_NUMBERED_CONDITION ) );
363 sHeader = sHeader.replaceFirst( "$number$", OUString::number( _nCondIndex + 1) );
364 m_xHeader->set_label( sHeader );
365
366 m_xMoveUp->set_sensitive(_nCondIndex > 0);
367 OSL_PRECOND( _nCondCount > 0, "Condition::setConditionIndex: having no conditions at all is nonsense!" );
368 m_xMoveDown->set_sensitive(_nCondIndex < _nCondCount - 1);
369}
370
372{
373 return m_xCondLHS->get_text().isEmpty();
374}
375
376} // rptui
377
378
379/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static OutputDevice * GetDefaultDevice()
OUString AsRGBHexString() const
void SetFont(const SvxFont &rNormalFont, const SvxFont &rCJKFont, const SvxFont &rCTLFont)
void SetTextLineColor(const Color &rColor)
static vcl::Font CreateFont(const css::awt::FontDescriptor &rDescr, const vcl::Font &rInitFont)
ClassificationCategoriesController & m_rController
ConditionColorWrapper(Condition *pControl, sal_uInt16 nSlotId)
Definition: Condition.cxx:70
void operator()(const OUString &rCommand, const NamedColor &rColor)
Definition: Condition.cxx:76
std::unique_ptr< weld::Button > m_xFormula
Definition: Condition.hxx:46
ConditionField(Condition *pParent, std::unique_ptr< weld::Entry > xSubEdit, std::unique_ptr< weld::Button > xFormula)
Definition: Condition.cxx:42
std::unique_ptr< weld::ComboBox > m_xConditionType
Definition: Condition.hxx:89
ConditionType impl_getCurrentConditionType() const
Definition: Condition.hxx:169
void updateToolbar(const css::uno::Reference< css::report::XReportControlFormat > &_xCondition)
updates the toolbar _xCondition the destination
Definition: Condition.cxx:305
std::unique_ptr< weld::Toolbar > m_xActions
Definition: Condition.hxx:94
void SetBackgroundDropdownClick()
Definition: Condition.cxx:152
void fillFormatCondition(const css::uno::Reference< css::report::XFormatCondition > &_xCondition)
fills from the control _xCondition the destination
Definition: Condition.cxx:336
ConditionalExpressions m_aConditionalExpressions
Definition: Condition.hxx:82
Condition(weld::Container *pParent, weld::Window *pDialog, IConditionalFormatAction &rAction, ::rptui::OReportController &rController)
Definition: Condition.cxx:83
std::unique_ptr< weld::Label > m_xOperandGlue
Definition: Condition.hxx:92
ConditionColorWrapper m_aBackColorWrapper
Definition: Condition.hxx:74
void setConditionIndex(size_t _nCondIndex, size_t _nCondCount)
tells the condition its new index within the dialog's condition array
Definition: Condition.cxx:359
std::unique_ptr< weld::Label > m_xHeader
Definition: Condition.hxx:88
void setCondition(const css::uno::Reference< css::report::XFormatCondition > &_xCondition)
sets the props at the control
Definition: Condition.cxx:284
ComparisonOperation impl_getCurrentComparisonOperation() const
Definition: Condition.hxx:174
std::unique_ptr< weld::ComboBox > m_xOperationList
Definition: Condition.hxx:90
std::unique_ptr< ConditionField > m_xCondLHS
Definition: Condition.hxx:91
void impl_layoutOperands()
Definition: Condition.cxx:216
std::unique_ptr< weld::Container > m_xContainer
Definition: Condition.hxx:87
void SetForegroundDropdownClick()
Definition: Condition.cxx:167
std::unique_ptr< weld::Builder > m_xBuilder
Definition: Condition.hxx:86
void ApplyCommand(sal_uInt16 _nCommandId, const NamedColor &rNamedColor)
forward to the parent class
Definition: Condition.cxx:201
std::unique_ptr< weld::Button > m_xMoveDown
Definition: Condition.hxx:97
void impl_setCondition(const OUString &_rConditionFormula)
Definition: Condition.cxx:235
SvxFontPrevWindow m_aPreview
Definition: Condition.hxx:84
std::unique_ptr< ColorWindow > m_xForeColorFloat
Definition: Condition.hxx:101
bool isEmpty() const
determines whether the condition is actually empty
Definition: Condition.cxx:371
std::unique_ptr< ConditionField > m_xCondRHS
Definition: Condition.hxx:93
ColorStatus m_aColorStatus
Definition: Condition.hxx:73
std::shared_ptr< PaletteManager > m_xPaletteManager
Definition: Condition.hxx:72
std::unique_ptr< ColorWindow > m_xBackColorFloat
Definition: Condition.hxx:100
std::unique_ptr< weld::Button > m_xAddCondition
Definition: Condition.hxx:98
std::unique_ptr< weld::Button > m_xRemoveCondition
Definition: Condition.hxx:99
size_t m_nCondIndex
Definition: Condition.hxx:80
std::unique_ptr< weld::Button > m_xMoveUp
Definition: Condition.hxx:96
static sal_uInt16 mapToolbarItemToSlotId(std::u16string_view rItemId)
Definition: Condition.cxx:131
ConditionColorWrapper m_aForeColorWrapper
Definition: Condition.hxx:75
IConditionalFormatAction & m_rAction
Definition: Condition.hxx:78
static size_t getKnownConditionalExpressions(ConditionalExpressions &_out_rCondExp)
fills the given map with all ConditionalExpressions which we know
virtual void applyCommand(size_t _nCondIndex, sal_uInt16 _nCommandId, const ::Color &rColor)=0
virtual OUString getDataField() const =0
static bool isFormatCommandEnabled(sal_uInt16 _nCommand, const css::uno::Reference< css::report::XReportControlFormat > &_xControlFormat)
returns <TRUE> when the command is enabled
BindType getType() const
returns the type of the binding represented by the formula
const OUString & getUndecoratedContent() const
gets the undecorated formula content
OUString getBracketedFieldOrExpression() const
returns a bracketed field name of the formula denotes a field reference, or the undecorated expressio...
const OUString & getCompleteFormula() const
returns the complete formula represented by the object
OUString const & getExpression() const
convenience alias for getUndecoratedContent, which asserts (in a non-product build) when used on a fi...
ColorTransparency
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
OUString RptResId(TranslateId aId)
#define DBG_UNHANDLED_EXCEPTION(...)
OString sFormula
float u
DocumentType eType
FontRelief
FontEmphasisMark
#define SAL_N_ELEMENTS(arr)
@ Exception
std::shared_ptr< T > make_shared(Args &&... args)
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
std::shared_ptr< ConditionalExpression > PConditionalExpression
IMPL_LINK_NOARG(OAddFieldWindow, FocusChangeHdl, weld::Container &, void)
Definition: AddField.cxx:120
bool openDialogFormula_nothrow(OUString &_in_out_rFormula, const css::uno::Reference< css::uno::XComponentContext > &_xContext, const css::uno::Reference< css::awt::XWindow > &_xWindow, const css::uno::Reference< css::beans::XPropertySet > &_xRowSet)
opens the formula dialog
IMPL_LINK(OAddFieldWindow, DragBeginHdl, bool &, rUnsetDragIcon, bool)
Definition: AddField.cxx:50
Reference< XNameAccess > m_xContainer
Color m_aColor