bump product version to 6.3.0.0.beta1
[LibreOffice.git] / reportdesign / source / ui / dlg / Condition.cxx
blob878c31748cf0a8748237ac80eb670171cae5bce7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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 <ColorChanger.hxx>
27 #include <reportformula.hxx>
28 #include <com/sun/star/util/URL.hpp>
29 #include <com/sun/star/beans/PropertyValue.hpp>
30 #include <com/sun/star/ui/XUIConfigurationManager.hpp>
31 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
32 #include <com/sun/star/ui/XImageManager.hpp>
33 #include <com/sun/star/awt/FontDescriptor.hpp>
34 #include <com/sun/star/ui/ImageType.hpp>
36 #include <svx/PaletteManager.hxx>
37 #include <svx/tbcontrl.hxx>
38 #include <svx/svxids.hrc>
39 #include <svx/xtable.hxx>
40 #include <svx/tbxcolorupdate.hxx>
41 #include <toolkit/helper/vclunohelper.hxx>
42 #include <svtools/imgdef.hxx>
43 #include <unotools/pathoptions.hxx>
44 #include <vcl/svapp.hxx>
45 #include <vcl/bitmapaccess.hxx>
46 #include <vcl/settings.hxx>
48 #include <tools/diagnose_ex.h>
49 #include <rtl/ustrbuf.hxx>
50 #include <svtools/valueset.hxx>
52 namespace rptui
54 using namespace ::com::sun::star;
55 using namespace ::com::sun::star::uno;
56 using namespace ::com::sun::star::beans;
58 ConditionField::ConditionField(Condition* pParent, Edit* pSubEdit, PushButton *pFormula)
59 : m_pParent(pParent)
60 , m_pSubEdit(pSubEdit)
61 , m_pFormula(pFormula)
63 m_pSubEdit->EnableRTL( false );
65 m_pFormula->SetText("...");
66 m_pFormula->SetClickHdl( LINK( this, ConditionField, OnFormula ) );
69 IMPL_LINK( ConditionField, OnFormula, Button*, _pClickedButton, void )
71 OUString sFormula(m_pSubEdit->GetText());
72 const sal_Int32 nLen = sFormula.getLength();
73 if ( nLen )
75 ReportFormula aFormula( sFormula );
76 sFormula = aFormula.getCompleteFormula();
78 uno::Reference< awt::XWindow> xInspectorWindow = VCLUnoHelper::GetInterface(_pClickedButton);
79 uno::Reference< beans::XPropertySet> xProp(m_pParent->getController().getRowSet(),uno::UNO_QUERY);
80 if ( rptui::openDialogFormula_nothrow( sFormula, m_pParent->getController().getContext(),xInspectorWindow,xProp ) )
82 ReportFormula aFormula( sFormula );
83 m_pSubEdit->SetText(aFormula.getUndecoratedContent());
87 ConditionColorWrapper::ConditionColorWrapper(Condition* pControl)
88 : mxControl(pControl)
89 , mnSlotId(0)
93 void ConditionColorWrapper::dispose()
95 mxControl.clear();
98 void ConditionColorWrapper::operator()(const OUString& /*rCommand*/, const NamedColor& rNamedColor)
100 mxControl->ApplyCommand(mnSlotId, rNamedColor);
103 // = Condition
106 Condition::Condition( vcl::Window* _pParent, IConditionalFormatAction& _rAction, ::rptui::OReportController& _rController )
107 : VclHBox(_pParent)
108 , m_xPaletteManager(new PaletteManager)
109 , m_aColorWrapper(this)
110 , m_rController(_rController)
111 , m_rAction(_rAction)
112 , m_nCondIndex(0)
113 , m_bInDestruction(false)
115 m_pUIBuilder.reset(new VclBuilder(this, getUIRootDir(), "modules/dbreport/ui/conditionwin.ui"));
117 get(m_pHeader, "headerLabel");
118 get(m_pConditionType, "typeCombobox");
119 get(m_pOperationList, "opCombobox");
120 m_pCondLHS.reset( new ConditionField(this, get<Edit>("lhsEntry"), get<PushButton>("lhsButton")) );
121 get(m_pOperandGlue, "andLabel");
122 m_pCondRHS.reset( new ConditionField(this, get<Edit>("rhsEntry"), get<PushButton>("rhsButton")) );
123 get(m_pActions, "formatToolbox");
124 get(m_pPreview, "previewDrawingarea");
125 get(m_pMoveUp, "upButton");
126 get(m_pMoveDown, "downButton");
127 get(m_pAddCondition, "addButton");
128 get(m_pRemoveCondition, "removeButton");
130 m_pActions->SetLineSpacing(true);
131 m_pCondLHS->GrabFocus();
133 m_pConditionType->SetSelectHdl( LINK( this, Condition, OnTypeSelected ) );
135 m_pOperationList->SetDropDownLineCount( 10 );
136 m_pOperationList->SetSelectHdl( LINK( this, Condition, OnOperationSelected ) );
138 m_pActions->SetSelectHdl(LINK(this, Condition, OnFormatAction));
139 m_pActions->SetDropdownClickHdl( LINK( this, Condition, DropdownClick ) );
140 setToolBox(m_pActions);
142 m_pMoveUp->SetClickHdl( LINK( this, Condition, OnConditionAction ) );
143 m_pMoveDown->SetClickHdl( LINK( this, Condition, OnConditionAction ) );
144 m_pAddCondition->SetClickHdl( LINK( this, Condition, OnConditionAction ) );
145 m_pRemoveCondition->SetClickHdl( LINK( this, Condition, OnConditionAction ) );
147 vcl::Font aFont( m_pAddCondition->GetFont() );
148 aFont.SetWeight( WEIGHT_BOLD );
149 m_pAddCondition->SetFont( aFont );
150 m_pRemoveCondition->SetFont( aFont );
152 m_pOperandGlue->SetStyle( m_pOperandGlue->GetStyle() | WB_VCENTER );
154 m_pConditionType->SelectEntryPos( 0 );
155 m_pOperationList->SelectEntryPos( 0 );
157 m_nBoldId = m_pActions->GetItemId(".uno:Bold");
158 m_nItalicId = m_pActions->GetItemId(".uno:Italic");
159 m_nUnderLineId = m_pActions->GetItemId(".uno:Underline");
160 m_nBackgroundColorId = m_pActions->GetItemId(".uno:BackgroundColor");
161 m_nFontColorId = m_pActions->GetItemId(".uno:FontColor");
162 m_nFontDialogId = m_pActions->GetItemId(".uno:FontDialog");
164 m_pBtnUpdaterBackgroundColor.reset( new svx::ToolboxButtonColorUpdater(
165 SID_BACKGROUND_COLOR, m_nBackgroundColorId, m_pActions, false,
166 m_pActions->GetItemText( m_nBackgroundColorId ) ) );
167 m_pBtnUpdaterFontColor.reset( new svx::ToolboxButtonColorUpdater(
168 SID_ATTR_CHAR_COLOR2, m_nFontColorId, m_pActions, false,
169 m_pActions->GetItemText( m_nFontColorId ) ) );
171 Show();
173 ConditionalExpressionFactory::getKnownConditionalExpressions( m_aConditionalExpressions );
176 sal_uInt16 Condition::mapToolbarItemToSlotId(sal_uInt16 nItemId) const
178 if (nItemId == m_nBoldId)
179 return SID_ATTR_CHAR_WEIGHT;
180 if (nItemId == m_nItalicId)
181 return SID_ATTR_CHAR_POSTURE;
182 if (nItemId == m_nUnderLineId)
183 return SID_ATTR_CHAR_UNDERLINE;
184 if (nItemId == m_nBackgroundColorId)
185 return SID_BACKGROUND_COLOR;
186 if (nItemId == m_nFontColorId)
187 return SID_ATTR_CHAR_COLOR2;
188 if (nItemId == m_nFontDialogId)
189 return SID_CHAR_DLG;
190 return 0;
193 Condition::~Condition()
195 disposeOnce();
198 void Condition::dispose()
200 m_bInDestruction = true;
202 m_pBtnUpdaterFontColor.reset();
203 m_pCondLHS.reset();
204 m_pCondRHS.reset();
205 m_pBtnUpdaterBackgroundColor.reset();
206 m_pHeader.clear();
207 m_pConditionType.clear();
208 m_pOperationList.clear();
209 m_pOperandGlue.clear();
210 m_pActions.clear();
211 m_pPreview.clear();
212 m_pMoveUp.clear();
213 m_pMoveDown.clear();
214 m_pAddCondition.clear();
215 m_pRemoveCondition.clear();
216 m_pColorFloat.disposeAndClear();
217 m_aColorWrapper.dispose();
218 disposeBuilder();
219 VclHBox::dispose();
222 IMPL_LINK(Condition, DropdownClick, ToolBox*, pToolBox, void)
224 sal_uInt16 nId( m_pActions->GetCurItemId() );
225 m_pColorFloat.disposeAndClear();
226 sal_uInt16 nSlotId(mapToolbarItemToSlotId(nId));
227 m_aColorWrapper.SetSlotId(nSlotId);
228 m_pColorFloat = VclPtr<SvxColorWindow>::Create(
229 OUString() /*m_aCommandURL*/,
230 m_xPaletteManager,
231 m_aColorStatus,
232 nSlotId,
233 nullptr,
234 pToolBox,
235 false,
236 m_aColorWrapper);
238 m_pColorFloat->EnableDocking();
239 vcl::Window::GetDockingManager()->StartPopupMode(pToolBox, m_pColorFloat, FloatWinPopupFlags::GrabFocus);
242 IMPL_LINK_NOARG( Condition, OnFormatAction, ToolBox*, void )
244 ApplyCommand(mapToolbarItemToSlotId(m_pActions->GetCurItemId()),
245 NamedColor(COL_AUTO, "#" + COL_AUTO.AsRGBHexString()));
248 IMPL_LINK( Condition, OnConditionAction, Button*, _pClickedButton, void )
250 if ( _pClickedButton == m_pMoveUp )
251 m_rAction.moveConditionUp( getConditionIndex() );
252 else if ( _pClickedButton == m_pMoveDown )
253 m_rAction.moveConditionDown( getConditionIndex() );
254 else if ( _pClickedButton == m_pAddCondition )
255 m_rAction.addCondition( getConditionIndex() );
256 else if ( _pClickedButton == m_pRemoveCondition )
257 m_rAction.deleteCondition( getConditionIndex() );
260 void Condition::ApplyCommand( sal_uInt16 _nCommandId, const NamedColor& rNamedColor )
262 if ( _nCommandId == SID_ATTR_CHAR_COLOR2 )
263 m_pBtnUpdaterFontColor->Update( rNamedColor );
264 else if ( _nCommandId == SID_BACKGROUND_COLOR )
265 m_pBtnUpdaterBackgroundColor->Update( rNamedColor );
267 m_rAction.applyCommand( m_nCondIndex, _nCommandId, rNamedColor.first );
270 void Condition::setImageList(sal_Int16 /*_eBitmapSet*/)
274 void Condition::resizeControls(const Size& /*_rDiff*/)
278 void Condition::GetFocus()
280 VclHBox::GetFocus();
281 if ( !m_bInDestruction )
282 m_pCondLHS->GrabFocus();
285 IMPL_LINK_NOARG( Condition, OnTypeSelected, ListBox&, void )
287 impl_layoutOperands();
291 IMPL_LINK_NOARG( Condition, OnOperationSelected, ListBox&, void )
293 impl_layoutOperands();
296 void Condition::impl_layoutOperands()
298 const ConditionType eType( impl_getCurrentConditionType() );
299 const ComparisonOperation eOperation( impl_getCurrentComparisonOperation() );
301 const bool bIsExpression = ( eType == eExpression );
302 const bool bHaveRHS =
303 ( ( eType == eFieldValueComparison )
304 && ( ( eOperation == eBetween )
305 || ( eOperation == eNotBetween )
309 // the "condition type" list box
310 m_pOperationList->Show( !bIsExpression );
311 m_pOperandGlue->Show( bHaveRHS );
312 m_pCondRHS->Show( bHaveRHS );
315 void Condition::impl_setCondition( const OUString& _rConditionFormula )
317 // determine the condition's type and comparison operation
318 ConditionType eType( eFieldValueComparison );
319 ComparisonOperation eOperation( eBetween );
321 // LHS and RHS, matched below
322 OUString sLHS, sRHS;
324 if ( !_rConditionFormula.isEmpty() )
326 // the unprefixed expression which forms the condition
327 ReportFormula aFormula( _rConditionFormula );
328 OSL_ENSURE( aFormula.getType() == ReportFormula::Expression, "Condition::setCondition: illegal formula!" );
329 OUString sExpression;
330 if ( aFormula.getType() == ReportFormula::Expression )
331 sExpression = aFormula.getExpression();
332 // as fallback, if the below matching does not succeed, assume
333 // the whole expression is the LHS
334 eType = eExpression;
335 sLHS = sExpression;
337 // the data field (or expression) to which our control is bound
338 const ReportFormula aFieldContentFormula( m_rAction.getDataField() );
339 const OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() );
341 // check whether one of the Field Value Expression Factories recognizes the expression
342 for (const auto& [rOperation, rxConditionalExpression] : m_aConditionalExpressions)
344 if ( rxConditionalExpression->matchExpression( sExpression, sUnprefixedFieldContent, sLHS, sRHS ) )
346 eType = eFieldValueComparison;
347 eOperation = rOperation;
348 break;
353 // update UI
354 m_pConditionType->SelectEntryPos( static_cast<sal_uInt16>(eType) );
355 m_pOperationList->SelectEntryPos( static_cast<sal_uInt16>(eOperation) );
356 m_pCondLHS->SetText( sLHS );
357 m_pCondRHS->SetText( sRHS );
359 // re-layout
360 impl_layoutOperands();
364 void Condition::setCondition( const uno::Reference< report::XFormatCondition >& _rxCondition )
366 OSL_PRECOND( _rxCondition.is(), "Condition::setCondition: empty condition object!" );
367 if ( !_rxCondition.is() )
368 return;
370 OUString sConditionFormula;
373 if ( _rxCondition.is() )
374 sConditionFormula = _rxCondition->getFormula();
376 catch( const Exception& )
378 DBG_UNHANDLED_EXCEPTION("reportdesign");
380 impl_setCondition( sConditionFormula );
381 updateToolbar( _rxCondition.get() );
385 void Condition::updateToolbar(const uno::Reference< report::XReportControlFormat >& _xReportControlFormat)
387 OSL_ENSURE(_xReportControlFormat.is(),"XReportControlFormat is NULL!");
388 if ( _xReportControlFormat.is() )
390 ToolBox::ImplToolItems::size_type nItemCount = m_pActions->GetItemCount();
391 for (ToolBox::ImplToolItems::size_type j = 0; j< nItemCount; ++j)
393 sal_uInt16 nItemId = m_pActions->GetItemId(j);
394 m_pActions->CheckItem( nItemId, OReportController::isFormatCommandEnabled(mapToolbarItemToSlotId(nItemId),
395 _xReportControlFormat ) );
400 vcl::Font aBaseFont( Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetAppFont() );
401 SvxFont aFont( VCLUnoHelper::CreateFont( _xReportControlFormat->getFontDescriptor(), aBaseFont ) );
402 aFont.SetFontHeight(OutputDevice::LogicToLogic(Size(0, aFont.GetFontHeight()), MapMode(MapUnit::MapPoint), MapMode(MapUnit::MapTwip)).Height());
403 aFont.SetEmphasisMark( static_cast< FontEmphasisMark >( _xReportControlFormat->getControlTextEmphasis() ) );
404 aFont.SetRelief( static_cast< FontRelief >( _xReportControlFormat->getCharRelief() ) );
405 aFont.SetColor( Color(_xReportControlFormat->getCharColor()) );
406 m_pPreview->SetFont( aFont, aFont, aFont );
407 m_pPreview->SetBackColor( Color(_xReportControlFormat->getControlBackground()) );
408 m_pPreview->SetTextLineColor( Color( _xReportControlFormat->getCharUnderlineColor() ) );
410 catch( const Exception& )
412 DBG_UNHANDLED_EXCEPTION("reportdesign");
417 void Condition::fillFormatCondition(const uno::Reference< report::XFormatCondition >& _xCondition)
419 const ConditionType eType( impl_getCurrentConditionType() );
420 const ComparisonOperation eOperation( impl_getCurrentComparisonOperation() );
422 const OUString sLHS( m_pCondLHS->GetText() );
423 const OUString sRHS( m_pCondRHS->GetText() );
425 OUString sUndecoratedFormula( sLHS );
427 if ( eType == eFieldValueComparison )
429 ReportFormula aFieldContentFormula( m_rAction.getDataField() );
430 OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() );
432 PConditionalExpression pFactory( m_aConditionalExpressions[ eOperation ] );
433 sUndecoratedFormula = pFactory->assembleExpression( sUnprefixedFieldContent, sLHS, sRHS );
436 ReportFormula aFormula( ReportFormula::Expression, sUndecoratedFormula );
437 _xCondition->setFormula( aFormula.getCompleteFormula() );
440 void Condition::setConditionIndex( size_t _nCondIndex, size_t _nCondCount )
442 m_nCondIndex = _nCondIndex;
443 OUString sHeader( RptResId( STR_NUMBERED_CONDITION ) );
444 sHeader = sHeader.replaceFirst( "$number$", OUString::number( _nCondIndex + 1) );
445 m_pHeader->SetText( sHeader );
447 m_pMoveUp->Enable( _nCondIndex > 0 );
448 OSL_PRECOND( _nCondCount > 0, "Condition::setConditionIndex: having no conditions at all is nonsense!" );
449 m_pMoveDown->Enable( _nCondIndex < _nCondCount - 1 );
453 bool Condition::isEmpty() const
455 return m_pCondLHS->GetText().isEmpty();
459 } // rptui
462 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */