1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 "CondFormat.hrc"
24 #include "RptResId.hrc"
25 #include "ReportController.hxx"
26 #include "ModuleHelper.hxx"
27 #include "ColorChanger.hxx"
28 #include "helpids.hrc"
29 #include "reportformula.hxx"
30 #include <com/sun/star/util/URL.hpp>
31 #include <com/sun/star/beans/PropertyValue.hpp>
32 #include <com/sun/star/ui/XUIConfigurationManager.hpp>
33 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
34 #include <com/sun/star/ui/XImageManager.hpp>
35 #include <com/sun/star/awt/FontDescriptor.hpp>
36 #include <com/sun/star/ui/ImageType.hpp>
38 #include <svx/tbcontrl.hxx>
39 #include <svx/svxids.hrc>
40 #include <svx/xtable.hxx>
41 #include <svx/tbxcolorupdate.hxx>
42 #include <toolkit/helper/vclunohelper.hxx>
43 #include <svtools/imgdef.hxx>
44 #include <unotools/pathoptions.hxx>
45 #include <vcl/svapp.hxx>
46 #include <vcl/bmpacc.hxx>
47 #include <vcl/settings.hxx>
49 #include <tools/diagnose_ex.h>
50 #include <rtl/ustrbuf.hxx>
51 #include <svtools/valueset.hxx>
55 using namespace ::com::sun::star
;
56 using namespace ::com::sun::star::uno
;
57 using namespace ::com::sun::star::beans
;
59 ConditionField::ConditionField(Condition
* pParent
, Edit
* pSubEdit
, PushButton
*pFormula
)
61 , m_pSubEdit(pSubEdit
)
62 , m_pFormula(pFormula
)
64 m_pSubEdit
->EnableRTL( false );
66 m_pFormula
->SetText(OUString("..."));
67 m_pFormula
->SetClickHdl( LINK( this, ConditionField
, OnFormula
) );
70 IMPL_LINK( ConditionField
, OnFormula
, Button
*, _pClickedButton
)
72 OUString
sFormula(m_pSubEdit
->GetText());
73 const sal_Int32 nLen
= sFormula
.getLength();
76 ReportFormula
aFormula( sFormula
);
77 sFormula
= aFormula
.getCompleteFormula();
79 uno::Reference
< awt::XWindow
> xInspectorWindow
= VCLUnoHelper::GetInterface(_pClickedButton
);
80 uno::Reference
< beans::XPropertySet
> xProp(m_pParent
->getController().getRowSet(),uno::UNO_QUERY
);
81 if ( rptui::openDialogFormula_nothrow( sFormula
, m_pParent
->getController().getContext(),xInspectorWindow
,xProp
) )
83 ReportFormula
aFormula( sFormula
);
84 m_pSubEdit
->SetText(aFormula
.getUndecoratedContent());
89 // class SvxColorWindow_Impl --------------------------------------------------
90 #ifndef WB_NO_DIRECTSELECT
91 #define WB_NO_DIRECTSELECT ((WinBits)0x04000000)
96 #define PALETTE_SIZE (PALETTE_X * PALETTE_Y)
97 class OColorPopup
: public FloatingWindow
99 DECL_LINK( SelectHdl
, void * );
100 VclPtr
<Condition
> m_pCondition
;
101 sal_uInt16 m_nSlotId
;
103 OColorPopup(vcl::Window
* _pParent
,Condition
* _pCondition
);
104 virtual ~OColorPopup();
105 virtual void dispose() SAL_OVERRIDE
;
106 VclPtr
<ValueSet
> m_aColorSet
;
108 virtual void KeyInput( const KeyEvent
& rKEvt
) SAL_OVERRIDE
;
109 virtual void Resize() SAL_OVERRIDE
;
111 void StartSelection();
112 void SetSlotId(sal_uInt16 _nSlotId
);
115 OColorPopup::OColorPopup(vcl::Window
* _pParent
,Condition
* _pCondition
)
116 :FloatingWindow(_pParent
, WinBits( WB_BORDER
| WB_STDFLOATWIN
| WB_3DLOOK
|WB_DIALOGCONTROL
))
117 ,m_pCondition(_pCondition
)
119 ,m_aColorSet( VclPtr
<ValueSet
>::Create(this, WinBits( WB_ITEMBORDER
| WB_NAMEFIELD
| WB_3DLOOK
| WB_NO_DIRECTSELECT
)) )
121 m_aColorSet
->SetHelpId( HID_RPT_POPUP_COLOR_CTRL
);
122 SetHelpId( HID_RPT_POPUP_COLOR
);
123 const Size
aSize12( 13, 13 );
125 XColorListRef
pColorList( XColorList::CreateStdColorList() );
126 long nCount
= pColorList
->Count();
127 Color
aColWhite( COL_WHITE
);
128 OUString
aStrWhite( ModuleRes(STR_COLOR_WHITE
) );
130 if ( nCount
> PALETTE_SIZE
)
131 // Show scrollbar if more than PALLETTE_SIZE colors are available
132 m_aColorSet
->SetStyle( m_aColorSet
->GetStyle() | WB_VSCROLL
);
134 for ( i
= 0; i
< nCount
; i
++ )
136 XColorEntry
* pEntry
= pColorList
->GetColor(i
);
137 m_aColorSet
->InsertItem( i
+1, pEntry
->GetColor(), pEntry
->GetName() );
140 while ( i
< PALETTE_SIZE
)
142 // fill empty elements if less then PALLETTE_SIZE colors are available
143 m_aColorSet
->InsertItem( i
+1, aColWhite
, aStrWhite
);
147 m_aColorSet
->SetSelectHdl( LINK( this, OColorPopup
, SelectHdl
) );
148 m_aColorSet
->SetColCount( PALETTE_X
);
149 m_aColorSet
->SetLineCount( PALETTE_Y
);
150 Size aSize
= m_aColorSet
->CalcWindowSizePixel( aSize12
);
153 SetOutputSizePixel( aSize
);
157 OColorPopup::~OColorPopup()
162 void OColorPopup::dispose()
166 m_pCondition
.clear();
167 FloatingWindow::dispose();
170 void OColorPopup::KeyInput( const KeyEvent
& rKEvt
)
172 m_aColorSet
->KeyInput(rKEvt
);
175 void OColorPopup::Resize()
177 Size aSize
= GetOutputSizePixel();
180 m_aColorSet
->SetPosSizePixel( Point(2,2), aSize
);
183 void OColorPopup::StartSelection()
185 m_aColorSet
->StartSelection();
188 void OColorPopup::SetSlotId(sal_uInt16 _nSlotId
)
190 m_nSlotId
= _nSlotId
;
191 if ( SID_ATTR_CHAR_COLOR_BACKGROUND
== _nSlotId
|| SID_BACKGROUND_COLOR
== _nSlotId
)
193 m_aColorSet
->SetStyle( m_aColorSet
->GetStyle() | WB_NONEFIELD
);
194 m_aColorSet
->SetText( OUString(ModuleRes( STR_TRANSPARENT
)) );
198 IMPL_LINK_NOARG(OColorPopup
, SelectHdl
)
200 sal_uInt16 nItemId
= m_aColorSet
->GetSelectItemId();
201 Color
aColor( nItemId
== 0 ? Color( COL_TRANSPARENT
) : m_aColorSet
->GetItemColor( nItemId
) );
203 /* #i33380# Moved the following line above the Dispatch() calls.
204 This instance may be deleted in the meantime (i.e. when a dialog is opened
205 while in Dispatch()), accessing members will crash in this case. */
206 m_aColorSet
->SetNoSelection();
208 if ( IsInPopupMode() )
211 m_pCondition
->ApplyCommand( m_nSlotId
, aColor
);
219 Condition::Condition( vcl::Window
* _pParent
, IConditionalFormatAction
& _rAction
, ::rptui::OReportController
& _rController
)
221 ,m_rController( _rController
)
222 ,m_rAction( _rAction
)
224 ,m_pBtnUpdaterFontColor(NULL
)
225 ,m_pBtnUpdaterBackgroundColor(NULL
)
227 ,m_bInDestruction( false )
229 m_pUIBuilder
= new VclBuilder(this, getUIRootDir(), "modules/dbreport/ui/conditionwin.ui");
231 get(m_pHeader
, "headerLabel");
232 get(m_pConditionType
, "typeCombobox");
233 get(m_pOperationList
, "opCombobox");
234 m_pCondLHS
= new ConditionField(this, get
<Edit
>("lhsEntry"), get
<PushButton
>("lhsButton"));
235 get(m_pOperandGlue
, "andLabel");
236 m_pCondRHS
= new ConditionField(this, get
<Edit
>("rhsEntry"), get
<PushButton
>("rhsButton"));
237 get(m_pActions
, "formatToolbox");
238 get(m_pPreview
, "previewDrawingarea");
239 get(m_pMoveUp
, "upButton");
240 get(m_pMoveDown
, "downButton");
241 get(m_pAddCondition
, "addButton");
242 get(m_pRemoveCondition
, "removeButton");
244 m_pActions
->SetStyle(m_pActions
->GetStyle()|WB_LINESPACING
);
245 m_pCondLHS
->GrabFocus();
247 m_pConditionType
->SetSelectHdl( LINK( this, Condition
, OnTypeSelected
) );
249 m_pOperationList
->SetDropDownLineCount( 10 );
250 m_pOperationList
->SetSelectHdl( LINK( this, Condition
, OnOperationSelected
) );
252 m_pActions
->SetSelectHdl(LINK(this, Condition
, OnFormatAction
));
253 m_pActions
->SetDropdownClickHdl( LINK( this, Condition
, DropdownClick
) );
254 setToolBox(m_pActions
);
256 m_pMoveUp
->SetClickHdl( LINK( this, Condition
, OnConditionAction
) );
257 m_pMoveDown
->SetClickHdl( LINK( this, Condition
, OnConditionAction
) );
258 m_pAddCondition
->SetClickHdl( LINK( this, Condition
, OnConditionAction
) );
259 m_pRemoveCondition
->SetClickHdl( LINK( this, Condition
, OnConditionAction
) );
261 m_pMoveUp
->SetStyle( m_pMoveUp
->GetStyle() | WB_NOPOINTERFOCUS
);
262 m_pMoveDown
->SetStyle( m_pMoveDown
->GetStyle() | WB_NOPOINTERFOCUS
);
263 m_pAddCondition
->SetStyle( m_pAddCondition
->GetStyle() | WB_NOPOINTERFOCUS
);
264 m_pRemoveCondition
->SetStyle( m_pRemoveCondition
->GetStyle() | WB_NOPOINTERFOCUS
);
266 vcl::Font
aFont( m_pAddCondition
->GetFont() );
267 aFont
.SetWeight( WEIGHT_BOLD
);
268 m_pAddCondition
->SetFont( aFont
);
269 m_pRemoveCondition
->SetFont( aFont
);
271 m_pOperandGlue
->SetStyle( m_pOperandGlue
->GetStyle() | WB_VCENTER
);
273 m_pConditionType
->SelectEntryPos( 0 );
274 m_pOperationList
->SelectEntryPos( 0 );
276 m_nBoldId
= m_pActions
->GetItemId(".uno:Bold");
277 m_nItalicId
= m_pActions
->GetItemId(".uno:Italic");
278 m_nUnderLineId
= m_pActions
->GetItemId(".uno:Underline");
279 m_nBackgroundColorId
= m_pActions
->GetItemId(".uno:BackgroundColor");
280 m_nFontColorId
= m_pActions
->GetItemId(".uno:FontColor");
281 m_nFontDialogId
= m_pActions
->GetItemId(".uno:FontDialog");
283 m_pBtnUpdaterBackgroundColor
= new svx::ToolboxButtonColorUpdater(
284 SID_BACKGROUND_COLOR
, m_nBackgroundColorId
, m_pActions
);
285 m_pBtnUpdaterFontColor
= new svx::ToolboxButtonColorUpdater(
286 SID_ATTR_CHAR_COLOR2
, m_nFontColorId
, m_pActions
);
290 ConditionalExpressionFactory::getKnownConditionalExpressions( m_aConditionalExpressions
);
293 sal_uInt16
Condition::mapToolbarItemToSlotId(sal_uInt16 nItemId
) const
295 if (nItemId
== m_nBoldId
)
296 return SID_ATTR_CHAR_WEIGHT
;
297 if (nItemId
== m_nItalicId
)
298 return SID_ATTR_CHAR_POSTURE
;
299 if (nItemId
== m_nUnderLineId
)
300 return SID_ATTR_CHAR_UNDERLINE
;
301 if (nItemId
== m_nBackgroundColorId
)
302 return SID_BACKGROUND_COLOR
;
303 if (nItemId
== m_nFontColorId
)
304 return SID_ATTR_CHAR_COLOR2
;
305 if (nItemId
== m_nFontDialogId
)
310 Condition::~Condition()
315 void Condition::dispose()
317 m_bInDestruction
= true;
319 delete m_pBtnUpdaterFontColor
;
322 delete m_pBtnUpdaterBackgroundColor
;
324 m_pConditionType
.clear();
325 m_pOperationList
.clear();
326 m_pOperandGlue
.clear();
331 m_pAddCondition
.clear();
332 m_pRemoveCondition
.clear();
333 m_pColorFloat
.disposeAndClear();
337 IMPL_LINK_NOARG_TYPED( Condition
, DropdownClick
, ToolBox
*, void )
339 sal_uInt16
nId( m_pActions
->GetCurItemId() );
340 if ( !m_pColorFloat
)
341 m_pColorFloat
= VclPtr
<OColorPopup
>::Create(m_pActions
,this);
343 sal_uInt16 nTextId
= 0;
344 if (nId
== m_nFontColorId
)
346 nTextId
= STR_CHARCOLOR
;
348 else if (nId
== m_nBackgroundColorId
)
350 nTextId
= STR_CHARBACKGROUND
;
353 m_pColorFloat
->SetText(OUString(ModuleRes(nTextId
)));
354 m_pColorFloat
->SetSlotId(mapToolbarItemToSlotId(nId
));
355 m_pColorFloat
->SetPosPixel(m_pActions
->GetItemPopupPosition(nId
,m_pColorFloat
->GetSizePixel()));
356 m_pColorFloat
->StartPopupMode(m_pActions
);
357 m_pColorFloat
->StartSelection();
360 IMPL_LINK_NOARG_TYPED( Condition
, OnFormatAction
, ToolBox
*, void )
362 Color
aCol(COL_AUTO
);
363 ApplyCommand(mapToolbarItemToSlotId(m_pActions
->GetCurItemId()),aCol
);
366 IMPL_LINK( Condition
, OnConditionAction
, Button
*, _pClickedButton
)
368 if ( _pClickedButton
== m_pMoveUp
)
369 m_rAction
.moveConditionUp( getConditionIndex() );
370 else if ( _pClickedButton
== m_pMoveDown
)
371 m_rAction
.moveConditionDown( getConditionIndex() );
372 else if ( _pClickedButton
== m_pAddCondition
)
373 m_rAction
.addCondition( getConditionIndex() );
374 else if ( _pClickedButton
== m_pRemoveCondition
)
375 m_rAction
.deleteCondition( getConditionIndex() );
379 void Condition::ApplyCommand( sal_uInt16 _nCommandId
, const ::Color
& _rColor
)
381 if ( _nCommandId
== SID_ATTR_CHAR_COLOR2
)
382 m_pBtnUpdaterFontColor
->Update( _rColor
);
383 else if ( _nCommandId
== SID_BACKGROUND_COLOR
)
384 m_pBtnUpdaterBackgroundColor
->Update( _rColor
);
386 m_rAction
.applyCommand( m_nCondIndex
, _nCommandId
, _rColor
);
389 void Condition::setImageList(sal_Int16
/*_eBitmapSet*/)
393 void Condition::resizeControls(const Size
& /*_rDiff*/)
397 void Condition::GetFocus()
400 if ( !m_bInDestruction
)
401 m_pCondLHS
->GrabFocus();
404 IMPL_LINK( Condition
, OnTypeSelected
, ListBox
*, /*_pNotInterestedIn*/ )
406 impl_layoutOperands();
411 IMPL_LINK( Condition
, OnOperationSelected
, ListBox
*, /*_pNotInterestedIn*/ )
413 impl_layoutOperands();
417 void Condition::impl_layoutOperands()
419 const ConditionType
eType( impl_getCurrentConditionType() );
420 const ComparisonOperation
eOperation( impl_getCurrentComparisonOperation() );
422 const bool bIsExpression
= ( eType
== eExpression
);
423 const bool bHaveRHS
=
424 ( ( eType
== eFieldValueComparison
)
425 && ( ( eOperation
== eBetween
)
426 || ( eOperation
== eNotBetween
)
430 // the "condition type" list box
431 m_pOperationList
->Show( !bIsExpression
);
432 m_pOperandGlue
->Show( bHaveRHS
);
433 m_pCondRHS
->Show( bHaveRHS
);
436 void Condition::impl_setCondition( const OUString
& _rConditionFormula
)
438 // determine the condition's type and comparison operation
439 ConditionType
eType( eFieldValueComparison
);
440 ComparisonOperation
eOperation( eBetween
);
442 // LHS and RHS, matched below
445 if ( !_rConditionFormula
.isEmpty() )
447 // the unprefixed expression which forms the condition
448 ReportFormula
aFormula( _rConditionFormula
);
449 OSL_ENSURE( aFormula
.getType() == ReportFormula::Expression
, "Condition::setCondition: illegal formula!" );
450 OUString sExpression
;
451 if ( aFormula
.getType() == ReportFormula::Expression
)
452 sExpression
= aFormula
.getExpression();
453 // as fallback, if the below matching does not succeed, assume
454 // the whole expression is the LHS
458 // the data field (or expression) to which our control is bound
459 const ReportFormula
aFieldContentFormula( m_rAction
.getDataField() );
460 const OUString
sUnprefixedFieldContent( aFieldContentFormula
.getBracketedFieldOrExpression() );
462 // check whether one of the Field Value Expression Factories recognizes the expression
463 for ( ConditionalExpressions::const_iterator exp
= m_aConditionalExpressions
.begin();
464 exp
!= m_aConditionalExpressions
.end();
468 if ( exp
->second
->matchExpression( sExpression
, sUnprefixedFieldContent
, sLHS
, sRHS
) )
470 eType
= eFieldValueComparison
;
471 eOperation
= exp
->first
;
478 m_pConditionType
->SelectEntryPos( (sal_uInt16
)eType
);
479 m_pOperationList
->SelectEntryPos( (sal_uInt16
)eOperation
);
480 m_pCondLHS
->SetText( sLHS
);
481 m_pCondRHS
->SetText( sRHS
);
484 impl_layoutOperands();
488 void Condition::setCondition( const uno::Reference
< report::XFormatCondition
>& _rxCondition
)
490 OSL_PRECOND( _rxCondition
.is(), "Condition::setCondition: empty condition object!" );
491 if ( !_rxCondition
.is() )
494 OUString sConditionFormula
;
497 if ( _rxCondition
.is() )
498 sConditionFormula
= _rxCondition
->getFormula();
500 catch( const Exception
& )
502 DBG_UNHANDLED_EXCEPTION();
504 impl_setCondition( sConditionFormula
);
505 updateToolbar( _rxCondition
.get() );
509 void Condition::updateToolbar(const uno::Reference
< report::XReportControlFormat
>& _xReportControlFormat
)
511 OSL_ENSURE(_xReportControlFormat
.is(),"XReportControlFormat is NULL!");
512 if ( _xReportControlFormat
.is() )
514 sal_uInt16 nItemCount
= m_pActions
->GetItemCount();
515 for (sal_uInt16 j
= 0; j
< nItemCount
; ++j
)
517 sal_uInt16 nItemId
= m_pActions
->GetItemId(j
);
518 m_pActions
->CheckItem( nItemId
, OReportController::isFormatCommandEnabled(mapToolbarItemToSlotId(nItemId
),
519 _xReportControlFormat
) );
524 vcl::Font
aBaseFont( Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetAppFont() );
525 SvxFont
aFont( VCLUnoHelper::CreateFont( _xReportControlFormat
->getFontDescriptor(), aBaseFont
) );
526 aFont
.SetHeight( OutputDevice::LogicToLogic( Size( 0, (sal_Int32
)aFont
.GetHeight() ), MAP_POINT
, MAP_TWIP
).Height());
527 aFont
.SetEmphasisMark( static_cast< FontEmphasisMark
>( _xReportControlFormat
->getControlTextEmphasis() ) );
528 aFont
.SetRelief( static_cast< FontRelief
>( _xReportControlFormat
->getCharRelief() ) );
529 aFont
.SetColor( _xReportControlFormat
->getCharColor() );
530 m_pPreview
->SetFont( aFont
, aFont
, aFont
);
531 m_pPreview
->SetBackColor( _xReportControlFormat
->getControlBackground() );
532 m_pPreview
->SetTextLineColor( Color( _xReportControlFormat
->getCharUnderlineColor() ) );
534 catch( const Exception
& )
536 DBG_UNHANDLED_EXCEPTION();
541 void Condition::fillFormatCondition(const uno::Reference
< report::XFormatCondition
>& _xCondition
)
543 const ConditionType
eType( impl_getCurrentConditionType() );
544 const ComparisonOperation
eOperation( impl_getCurrentComparisonOperation() );
546 const OUString
sLHS( m_pCondLHS
->GetText() );
547 const OUString
sRHS( m_pCondRHS
->GetText() );
549 OUString
sUndecoratedFormula( sLHS
);
551 if ( eType
== eFieldValueComparison
)
553 ReportFormula
aFieldContentFormula( m_rAction
.getDataField() );
554 OUString
sUnprefixedFieldContent( aFieldContentFormula
.getBracketedFieldOrExpression() );
556 PConditionalExpression
pFactory( m_aConditionalExpressions
[ eOperation
] );
557 sUndecoratedFormula
= pFactory
->assembleExpression( sUnprefixedFieldContent
, sLHS
, sRHS
);
560 ReportFormula
aFormula( ReportFormula::Expression
, sUndecoratedFormula
);
561 _xCondition
->setFormula( aFormula
.getCompleteFormula() );
564 void Condition::setConditionIndex( size_t _nCondIndex
, size_t _nCondCount
)
566 m_nCondIndex
= _nCondIndex
;
567 OUString
sHeader( ModuleRes( STR_NUMBERED_CONDITION
) );
568 sHeader
= sHeader
.replaceFirst( "$number$", OUString::number( _nCondIndex
+ 1) );
569 m_pHeader
->SetText( sHeader
);
571 m_pMoveUp
->Enable( _nCondIndex
> 0 );
572 OSL_PRECOND( _nCondCount
> 0, "Condition::setConditionIndex: having no conditions at all is nonsense!" );
573 m_pMoveDown
->Enable( _nCondIndex
< _nCondCount
- 1 );
577 bool Condition::isEmpty() const
579 return m_pCondLHS
->GetText().isEmpty();
586 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */