1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #include "precompiled_reportdesign.hxx"
28 
29 #include "Condition.hxx"
30 #include "UITools.hxx"
31 #include "CondFormat.hxx"
32 #include "CondFormat.hrc"
33 #include "RptResId.hrc"
34 #include "ReportController.hxx"
35 #include "ModuleHelper.hxx"
36 #include "ColorChanger.hxx"
37 #include "RptResId.hrc"
38 #include "helpids.hrc"
39 #include "reportformula.hxx"
40 #include <com/sun/star/util/URL.hpp>
41 #include <com/sun/star/beans/PropertyValue.hpp>
42 #include <com/sun/star/ui/XUIConfigurationManager.hpp>
43 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
44 #include <com/sun/star/ui/XImageManager.hpp>
45 #include <com/sun/star/awt/FontDescriptor.hpp>
46 #include <com/sun/star/ui/ImageType.hpp>
47 
48 #define ITEMID_COLOR
49 #define ITEMID_BRUSH
50 #include <svx/tbcontrl.hxx>
51 #include <svx/svxids.hrc>
52 #include <svx/xtable.hxx>
53 #include <svx/tbxcolorupdate.hxx>
54 #include <toolkit/helper/vclunohelper.hxx>
55 #include <svtools/imgdef.hxx>
56 #include <unotools/pathoptions.hxx>
57 #include <vcl/svapp.hxx>
58 #include <vcl/bmpacc.hxx>
59 #include <tools/diagnose_ex.h>
60 #include <rtl/ustrbuf.hxx>
61 
62 namespace rptui
63 {
64 using namespace ::com::sun::star;
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::beans;
67 
68 ConditionField::ConditionField( Condition* _pParent, const ResId& _rResId ) : Edit(_pParent,_rResId)
69 ,m_pParent(_pParent)
70 ,m_aFormula(this)
71 {
72     m_pSubEdit = new Edit(this,0);
73     SetSubEdit(m_pSubEdit);
74     m_pSubEdit->EnableRTL( sal_False );
75     m_pSubEdit->SetPosPixel( Point() );
76 
77     m_aFormula.SetText(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("...")));
78     m_aFormula.SetClickHdl( LINK( this, ConditionField, OnFormula ) );
79     m_aFormula.Show();
80     m_pSubEdit->Show();
81     Resize();
82 }
83 // -----------------------------------------------------------------------------
84 ConditionField::~ConditionField()
85 {
86     SetSubEdit(NULL);
87     delete m_pSubEdit;
88 }
89 // -----------------------------------------------------------------------------
90 void ConditionField::Resize()
91 {
92     Edit::Resize();
93     const Size aSize = GetOutputSizePixel();
94     const Size aButtonSize( LogicToPixel( Size( 12, 0 ), MAP_APPFONT ).Width(),aSize.Height());
95     const Point aButtonPos(aSize.Width() - aButtonSize.Width(), 0);
96     m_aFormula.SetPosSizePixel(aButtonPos,aButtonSize);
97     m_pSubEdit->SetPosSizePixel(Point(0,0),Size(aButtonPos.X() ,aSize.Height()));
98 }
99 // -----------------------------------------------------------------------------
100 IMPL_LINK( ConditionField, OnFormula, Button*, /*_pClickedButton*/ )
101 {
102     ::rtl::OUString sFormula(m_pSubEdit->GetText());
103     const sal_Int32 nLen = sFormula.getLength();
104     if ( nLen )
105     {
106         ReportFormula aFormula( sFormula );
107         sFormula = aFormula.getCompleteFormula();
108     } // if ( nLen )
109     uno::Reference< awt::XWindow> xInspectorWindow = VCLUnoHelper::GetInterface(this);
110     uno::Reference< beans::XPropertySet> xProp(m_pParent->getController().getRowSet(),uno::UNO_QUERY);
111     if ( rptui::openDialogFormula_nothrow( sFormula, m_pParent->getController().getContext(),xInspectorWindow,xProp ) )
112     {
113         ReportFormula aFormula( sFormula );
114         m_pSubEdit->SetText(aFormula.getUndecoratedContent());
115     }
116     return 0L;
117 }
118 //========================================================================
119 // class SvxColorWindow_Impl --------------------------------------------------
120 //========================================================================
121 #ifndef WB_NO_DIRECTSELECT
122 #define WB_NO_DIRECTSELECT      ((WinBits)0x04000000)
123 #endif
124 
125 #define PALETTE_X 10
126 #define PALETTE_Y 10
127 #define PALETTE_SIZE (PALETTE_X * PALETTE_Y)
128 class OColorPopup : public FloatingWindow
129 {
130     DECL_LINK( SelectHdl, void * );
131     Condition* m_pCondition;
132     sal_uInt16      m_nSlotId;
133 public:
134     OColorPopup(Window* _pParent,Condition* _pCondition);
135     ValueSet        m_aColorSet;
136 
137     virtual void KeyInput( const KeyEvent& rKEvt );
138     virtual void Resize();
139 
140     void StartSelection();
141     void SetSlotId(sal_uInt16 _nSlotId);
142 };
143 // -----------------------------------------------------------------------------
144 OColorPopup::OColorPopup(Window* _pParent,Condition* _pCondition)
145 :FloatingWindow(_pParent, WinBits( WB_BORDER | WB_STDFLOATWIN | WB_3DLOOK|WB_DIALOGCONTROL ))
146 ,m_pCondition(_pCondition)
147 ,m_nSlotId(0)
148 ,m_aColorSet( this, WinBits( WB_ITEMBORDER | WB_NAMEFIELD | WB_3DLOOK | WB_NO_DIRECTSELECT) )
149 {
150     m_aColorSet.SetHelpId( HID_RPT_POPUP_COLOR_CTRL );
151     SetHelpId( HID_RPT_POPUP_COLOR );
152     const Size aSize12( 13, 13 );
153     ::std::auto_ptr<XColorTable> pColorTable(new XColorTable( SvtPathOptions().GetPalettePath() ));
154     short i = 0;
155     long nCount = pColorTable->Count();
156     XColorEntry* pEntry = NULL;
157     Color aColWhite( COL_WHITE );
158     String aStrWhite( ModuleRes(STR_COLOR_WHITE) );
159 
160     if ( nCount > PALETTE_SIZE )
161         // Show scrollbar if more than PALLETTE_SIZE colors are available
162         m_aColorSet.SetStyle( m_aColorSet.GetStyle() | WB_VSCROLL );
163 
164     for ( i = 0; i < nCount; i++ )
165     {
166         pEntry = pColorTable->GetColor(i);
167         m_aColorSet.InsertItem( i+1, pEntry->GetColor(), pEntry->GetName() );
168     }
169 
170     while ( i < PALETTE_SIZE )
171     {
172         // fill empty elements if less then PALLETTE_SIZE colors are available
173         m_aColorSet.InsertItem( i+1, aColWhite, aStrWhite );
174         i++;
175     }
176 
177     m_aColorSet.SetSelectHdl( LINK( this, OColorPopup, SelectHdl ) );
178     m_aColorSet.SetColCount( PALETTE_X );
179     m_aColorSet.SetLineCount( PALETTE_Y );
180     Size aSize = m_aColorSet.CalcWindowSizePixel( aSize12 );
181     aSize.Width()  += 4;
182     aSize.Height() += 4;
183     SetOutputSizePixel( aSize );
184     m_aColorSet.Show();
185 }
186 // -----------------------------------------------------------------------------
187 void OColorPopup::KeyInput( const KeyEvent& rKEvt )
188 {
189     m_aColorSet.KeyInput(rKEvt);
190 }
191 
192 // -----------------------------------------------------------------------------
193 void OColorPopup::Resize()
194 {
195     Size aSize = GetOutputSizePixel();
196     aSize.Width()  -= 4;
197     aSize.Height() -= 4;
198     m_aColorSet.SetPosSizePixel( Point(2,2), aSize );
199 }
200 
201 // -----------------------------------------------------------------------------
202 void OColorPopup::StartSelection()
203 {
204     m_aColorSet.StartSelection();
205 }
206 // -----------------------------------------------------------------------------
207 void OColorPopup::SetSlotId(sal_uInt16 _nSlotId)
208 {
209     m_nSlotId = _nSlotId;
210     if ( SID_ATTR_CHAR_COLOR_BACKGROUND == _nSlotId || SID_BACKGROUND_COLOR == _nSlotId )
211     {
212         m_aColorSet.SetStyle( m_aColorSet.GetStyle() | WB_NONEFIELD );
213         m_aColorSet.SetText( String(ModuleRes( STR_TRANSPARENT )) );
214     } // if ( SID_ATTR_CHAR_COLOR_BACKGROUND == theSlotId || SID_BACKGROUND_COLOR == theSlotId )
215 }
216 // -----------------------------------------------------------------------------
217 IMPL_LINK( OColorPopup, SelectHdl, void *, EMPTYARG )
218 {
219     sal_uInt16 nItemId = m_aColorSet.GetSelectItemId();
220     Color aColor( nItemId == 0 ? Color( COL_TRANSPARENT ) : m_aColorSet.GetItemColor( nItemId ) );
221 
222     /*  #i33380# DR 2004-09-03 Moved the following line above the Dispatch() calls.
223         This instance may be deleted in the meantime (i.e. when a dialog is opened
224         while in Dispatch()), accessing members will crash in this case. */
225     m_aColorSet.SetNoSelection();
226 
227     if ( IsInPopupMode() )
228         EndPopupMode();
229 
230     m_pCondition->ApplyCommand( m_nSlotId, aColor );
231     return 0;
232 }
233 
234 // =============================================================================
235 // = Condition
236 // =============================================================================
237 // -----------------------------------------------------------------------------
238 Condition::Condition( Window* _pParent, IConditionalFormatAction& _rAction, ::rptui::OReportController& _rController )
239     :Control(_pParent, ModuleRes(WIN_CONDITION))
240     ,m_rController( _rController )
241     ,m_rAction( _rAction )
242     ,m_aHeader(this,            ModuleRes(FL_CONDITION_HEADER))
243     ,m_aConditionType(this,       ModuleRes(LB_COND_TYPE))
244     ,m_aOperationList( this,    ModuleRes(LB_OP))
245     ,m_aCondLHS(this,           ModuleRes(ED_CONDITION_LHS))
246     ,m_aOperandGlue(this,            ModuleRes(FT_AND))
247     ,m_aCondRHS(this,           ModuleRes(ED_CONDITION_RHS))
248     ,m_aActions(this,           ModuleRes(TB_FORMAT))
249     ,m_aPreview(this,           ModuleRes(CRTL_FORMAT_PREVIEW))
250     ,m_aMoveUp( this,           ModuleRes( BTN_MOVE_UP ) )
251     ,m_aMoveDown( this,         ModuleRes( BTN_MOVE_DOWN ) )
252     ,m_aAddCondition( this,     ModuleRes( BTN_ADD_CONDITION ) )
253     ,m_aRemoveCondition( this,  ModuleRes( BTN_REMOVE_CONDITION ) )
254     ,m_pColorFloat(NULL)
255     ,m_pBtnUpdaterFontColor(NULL)
256     ,m_pBtnUpdaterBackgroundColor(NULL)
257     ,m_nCondIndex( 0 )
258     ,m_nLastKnownWindowWidth( -1 )
259     ,m_bInDestruction( false )
260 {
261     m_aMoveUp.SetModeImage( ModuleRes( IMG_MOVE_UP_HC ), BMP_COLOR_HIGHCONTRAST );
262     m_aMoveDown.SetModeImage( ModuleRes( IMG_MOVE_DOWN_HC ), BMP_COLOR_HIGHCONTRAST );
263 
264     FreeResource();
265     m_aActions.SetStyle(m_aActions.GetStyle()|WB_LINESPACING);
266     m_aCondLHS.GrabFocus();
267 
268     m_aConditionType.SetSelectHdl( LINK( this, Condition, OnTypeSelected ) );
269 
270     m_aOperationList.SetDropDownLineCount( 10 );
271     m_aOperationList.SetSelectHdl( LINK( this, Condition, OnOperationSelected ) );
272 
273     m_aActions.SetSelectHdl(LINK(this, Condition, OnFormatAction));
274     m_aActions.SetDropdownClickHdl( LINK( this, Condition, DropdownClick ) );
275     setToolBox(&m_aActions);
276 
277     m_aMoveUp.SetClickHdl( LINK( this, Condition, OnConditionAction ) );
278     m_aMoveDown.SetClickHdl( LINK( this, Condition, OnConditionAction ) );
279     m_aAddCondition.SetClickHdl( LINK( this, Condition, OnConditionAction ) );
280     m_aRemoveCondition.SetClickHdl( LINK( this, Condition, OnConditionAction ) );
281 
282     m_aMoveUp.SetStyle( m_aMoveUp.GetStyle() | WB_NOPOINTERFOCUS );
283     m_aMoveDown.SetStyle( m_aMoveDown.GetStyle() | WB_NOPOINTERFOCUS );
284     m_aAddCondition.SetStyle( m_aMoveUp.GetStyle() | WB_NOPOINTERFOCUS | WB_CENTER | WB_VCENTER );
285     m_aRemoveCondition.SetStyle( m_aMoveDown.GetStyle() | WB_NOPOINTERFOCUS | WB_CENTER | WB_VCENTER );
286 
287     Font aFont( m_aAddCondition.GetFont() );
288     aFont.SetWeight( WEIGHT_BOLD );
289     m_aAddCondition.SetFont( aFont );
290     m_aRemoveCondition.SetFont( aFont );
291 
292     m_aOperandGlue.SetStyle( m_aOperandGlue.GetStyle() | WB_VCENTER );
293 
294     m_aConditionType.SelectEntryPos( 0 );
295     m_aOperationList.SelectEntryPos( 0 );
296 
297     // the toolbar got its site automatically, ensure that the preview is positioned
298     // right of it
299     Size aRelatedControls( LogicToPixel( Size( RELATED_CONTROLS, 0 ), MAP_APPFONT ) );
300     Point aToolbarPos( m_aActions.GetPosPixel() );
301     Size aToolbarSize( m_aActions.GetSizePixel() );
302     m_aPreview.SetPosSizePixel( aToolbarPos.X() + aToolbarSize.Width() + 2 * aRelatedControls.Width(),
303         0, 0, 0, WINDOW_POSSIZE_X );
304 
305     // ensure the toolbar is vertically centered, relative to the preview
306     Size aPreviewSize( m_aPreview.GetSizePixel() );
307     m_aActions.SetPosSizePixel( 0, aToolbarPos.Y() + ( aPreviewSize.Height() - aToolbarSize.Height() ) / 2, 0, 0, WINDOW_POSSIZE_Y );
308 
309     m_pBtnUpdaterBackgroundColor = new ::svx::ToolboxButtonColorUpdater(
310                                             SID_BACKGROUND_COLOR, SID_BACKGROUND_COLOR, &m_aActions );
311     m_pBtnUpdaterFontColor = new ::svx::ToolboxButtonColorUpdater(
312                                             SID_ATTR_CHAR_COLOR2, SID_ATTR_CHAR_COLOR2, &m_aActions, TBX_UPDATER_MODE_CHAR_COLOR_NEW );
313 
314     Show();
315 
316     impl_layoutAll();
317 
318     ConditionalExpressionFactory::getKnownConditionalExpressions( m_aConditionalExpressions );
319 }
320 
321 // -----------------------------------------------------------------------------
322 Condition::~Condition()
323 {
324     m_bInDestruction = true;
325 
326     delete m_pColorFloat;
327     delete m_pBtnUpdaterFontColor;
328     delete m_pBtnUpdaterBackgroundColor;
329 }
330 // -----------------------------------------------------------------------------
331 IMPL_LINK( Condition, DropdownClick, ToolBox*, /*pToolBar*/ )
332 {
333     sal_uInt16 nId( m_aActions.GetCurItemId() );
334     if ( !m_pColorFloat )
335         m_pColorFloat = new OColorPopup(&m_aActions,this);
336 
337     sal_uInt16 nTextId = 0;
338     switch(nId)
339     {
340         case SID_ATTR_CHAR_COLOR2:
341             nTextId = STR_CHARCOLOR;
342             break;
343         case SID_BACKGROUND_COLOR:
344             nTextId = STR_CHARBACKGROUND;
345             break;
346         default:
347             break;
348     } // switch(nId)
349     if ( nTextId )
350         m_pColorFloat->SetText(String(ModuleRes(nTextId)));
351     m_pColorFloat->SetSlotId(nId);
352     m_pColorFloat->SetPosPixel(m_aActions.GetItemPopupPosition(nId,m_pColorFloat->GetSizePixel()));
353     m_pColorFloat->StartPopupMode(&m_aActions);
354     m_pColorFloat->StartSelection();
355 
356     return 1;
357 }
358 //------------------------------------------------------------------
359 IMPL_LINK( Condition, OnFormatAction, ToolBox*, /*NOTINTERESTEDIN*/ )
360 {
361     Color aCol(COL_AUTO);
362     ApplyCommand(m_aActions.GetCurItemId(),aCol);
363     return 0L;
364 }
365 
366 //------------------------------------------------------------------
367 IMPL_LINK( Condition, OnConditionAction, Button*, _pClickedButton )
368 {
369     if ( _pClickedButton == &m_aMoveUp )
370         m_rAction.moveConditionUp( getConditionIndex() );
371     else if ( _pClickedButton == &m_aMoveDown )
372         m_rAction.moveConditionDown( getConditionIndex() );
373     else if ( _pClickedButton == &m_aAddCondition )
374         m_rAction.addCondition( getConditionIndex() );
375     else if ( _pClickedButton == &m_aRemoveCondition )
376         m_rAction.deleteCondition( getConditionIndex() );
377     return 0L;
378 }
379 
380 //------------------------------------------------------------------------------
381 void Condition::ApplyCommand( sal_uInt16 _nCommandId, const ::Color& _rColor)
382 {
383     if ( _nCommandId == SID_ATTR_CHAR_COLOR2 )
384         m_pBtnUpdaterFontColor->Update( _rColor );
385     else if ( _nCommandId == SID_BACKGROUND_COLOR )
386         m_pBtnUpdaterBackgroundColor->Update( _rColor );
387 
388     m_rAction.applyCommand( m_nCondIndex, _nCommandId, _rColor );
389 }
390 //------------------------------------------------------------------------------
391 ImageList Condition::getImageList(sal_Int16 _eBitmapSet,sal_Bool _bHiContast) const
392 {
393     sal_Int16 nN = IMG_CONDFORMAT_DLG_SC;
394     sal_Int16 nH = IMG_CONDFORMAT_DLG_SCH;
395     if ( _eBitmapSet == SFX_SYMBOLS_SIZE_LARGE )
396     {
397         nN = IMG_CONDFORMAT_DLG_LC;
398         nH = IMG_CONDFORMAT_DLG_LCH;
399     }
400     return ImageList(ModuleRes( _bHiContast ? nH : nN ));
401 }
402 //------------------------------------------------------------------
403 void Condition::resizeControls(const Size& _rDiff)
404 {
405     // we use large images so we must change them
406     if ( _rDiff.Width() || _rDiff.Height() )
407     {
408         Point aPos = LogicToPixel( Point( 2*RELATED_CONTROLS , 0), MAP_APPFONT );
409         Invalidate();
410     }
411 }
412 // -----------------------------------------------------------------------------
413 void Condition::Paint( const Rectangle& rRect )
414 {
415     Control::Paint(rRect);
416 
417     // draw border
418     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
419     ColorChanger aColors( this, rStyleSettings.GetShadowColor(), rStyleSettings.GetDialogColor() );
420     DrawRect( impl_getToolBarBorderRect() );
421 }
422 // -----------------------------------------------------------------------------
423 void Condition::StateChanged( StateChangedType nType )
424 {
425     Control::StateChanged( nType );
426 
427     if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
428     {
429         // Check if we need to get new images for normal/high contrast mode
430         checkImageList();
431     }
432     else if ( nType == STATE_CHANGE_TEXT )
433     {
434         // The physical toolbar changed its outlook and shows another logical toolbar!
435         // We have to set the correct high contrast mode on the new tbx manager.
436         //  pMgr->SetHiContrast( IsHiContrastMode() );
437         checkImageList();
438     }
439 }
440 // -----------------------------------------------------------------------------
441 void Condition::DataChanged( const DataChangedEvent& rDCEvt )
442 {
443     Control::DataChanged( rDCEvt );
444 
445     if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS )   ||
446         ( rDCEvt.GetType() == DATACHANGED_DISPLAY   ))  &&
447         ( rDCEvt.GetFlags() & SETTINGS_STYLE        ))
448     {
449         // Check if we need to get new images for normal/high contrast mode
450         checkImageList();
451     }
452 }
453 
454 // -----------------------------------------------------------------------------
455 void Condition::GetFocus()
456 {
457     Control::GetFocus();
458     if ( !m_bInDestruction )
459         m_aCondLHS.GrabFocus();
460 }
461 
462 // -----------------------------------------------------------------------------
463 void Condition::Resize()
464 {
465     Control::Resize();
466     impl_layoutAll();
467 }
468 
469 // -----------------------------------------------------------------------------
470 Rectangle Condition::impl_getToolBarBorderRect() const
471 {
472     const Point aToolbarPos( m_aActions.GetPosPixel() );
473     const Size aToolbarSize( m_aActions.GetSizePixel() );
474     const Size aRelatedControls = LogicToPixel( Size( RELATED_CONTROLS, RELATED_CONTROLS ), MAP_APPFONT );
475 
476     Rectangle aBorderRect( aToolbarPos, aToolbarSize );
477     aBorderRect.Left() -= aRelatedControls.Width();
478     aBorderRect.Top() -= aRelatedControls.Height();
479     aBorderRect.Right() += aRelatedControls.Width();
480     aBorderRect.Bottom() += aRelatedControls.Height();
481 
482     return aBorderRect;
483 }
484 
485 // -----------------------------------------------------------------------------
486 void Condition::impl_layoutAll()
487 {
488     // if our width changed, resize/-position some controls
489     const Size aSize( GetOutputSizePixel() );
490     if ( aSize.Width() == m_nLastKnownWindowWidth )
491         return;
492 
493     m_nLastKnownWindowWidth = aSize.Width();
494 
495     const Size aRelatedControls( LogicToPixel( Size( RELATED_CONTROLS, RELATED_CONTROLS ), MAP_APPFONT ) );
496     const Size aUnrelatedControls( LogicToPixel( Size( UNRELATED_CONTROLS, 0 ), MAP_APPFONT ) );
497     const Point aRow1( LogicToPixel( Point( 0, ROW_1_POS ), MAP_APPFONT ) );
498     const Point aRow3( LogicToPixel( Point( 0, ROW_3_POS ), MAP_APPFONT ) );
499 
500     // resize the header line
501     m_aHeader.SetPosSizePixel( 0, 0, aSize.Width() - 2 * aRelatedControls.Width(), 0, WINDOW_POSSIZE_WIDTH );
502 
503     // position the up/down buttons
504     const Size aButtonSize( LogicToPixel( Size( IMAGE_BUTTON_WIDTH, IMAGE_BUTTON_HEIGHT ), MAP_APPFONT ) );
505     Point aButtonPos( aSize.Width() - aUnrelatedControls.Width() - aButtonSize.Width(), aRow1.Y() );
506     m_aMoveUp.SetPosSizePixel( aButtonPos.X(), aButtonPos.Y(), aButtonSize.Width(), aButtonSize.Height() );
507     aButtonPos.Move( 0, aButtonSize.Height() + aRelatedControls.Height() );
508     m_aMoveDown.SetPosSizePixel( aButtonPos.X(), aButtonPos.Y(), aButtonSize.Width(), aButtonSize.Height() );
509 
510     // resize the preview
511     const long nNewPreviewRight = aButtonPos.X() - aRelatedControls.Width();
512 
513     const Point aPreviewPos( m_aPreview.GetPosPixel() );
514     OSL_ENSURE( aPreviewPos.X() < nNewPreviewRight, "Condition::impl_layoutAll: being *that* small should not be allowed!" );
515     m_aPreview.SetPosSizePixel( 0, 0, nNewPreviewRight - aPreviewPos.X(), 0, WINDOW_POSSIZE_WIDTH );
516 
517     // position the add/remove buttons
518     aButtonPos = Point( nNewPreviewRight - aButtonSize.Width(), aRow3.Y() );
519     m_aRemoveCondition.SetPosSizePixel( aButtonPos.X(), aButtonPos.Y(), aButtonSize.Width(), aButtonSize.Height() );
520     aButtonPos.Move( -( aButtonSize.Width() + aRelatedControls.Width() ), 0 );
521     m_aAddCondition.SetPosSizePixel( aButtonPos.X(), aButtonPos.Y(), aButtonSize.Width(), aButtonSize.Height() );
522 
523     // layout the operands input controls
524     impl_layoutOperands();
525 }
526 
527 // -----------------------------------------------------------------------------
528 IMPL_LINK( Condition, OnTypeSelected, ListBox*, /*_pNotInterestedIn*/ )
529 {
530     impl_layoutOperands();
531     return 0L;
532 }
533 
534 // -----------------------------------------------------------------------------
535 IMPL_LINK( Condition, OnOperationSelected, ListBox*, /*_pNotInterestedIn*/ )
536 {
537     impl_layoutOperands();
538     return 0L;
539 }
540 
541 // -----------------------------------------------------------------------------
542 void Condition::impl_layoutOperands()
543 {
544     const ConditionType eType( impl_getCurrentConditionType() );
545     const ComparisonOperation eOperation( impl_getCurrentComparisonOperation() );
546 
547     const bool bIsExpression = ( eType == eExpression );
548     const bool bHaveRHS =
549             (   ( eType == eFieldValueComparison )
550             &&  (   ( eOperation == eBetween )
551                 ||  ( eOperation == eNotBetween )
552                 )
553             );
554 
555     const Size aRelatedControls( LogicToPixel( Size( RELATED_CONTROLS, 0 ), MAP_APPFONT ) );
556     const Rectangle aPreviewRect( m_aPreview.GetPosPixel(), m_aPreview.GetSizePixel() );
557 
558     // the "condition type" list box
559     const Rectangle aCondTypeRect( m_aConditionType.GetPosPixel(), m_aConditionType.GetSizePixel() );
560     const Point aOpListPos( aCondTypeRect.Right() + aRelatedControls.Width(), aCondTypeRect.Top() );
561     const Size aOpListSize( LogicToPixel( Size( COND_OP_WIDTH, 60 ), MAP_APPFONT ) );
562     m_aOperationList.SetPosSizePixel( aOpListPos.X(), aOpListPos.Y(),aOpListSize.Width(), aOpListSize.Height() );
563     m_aOperationList.Show( !bIsExpression );
564 
565     // the LHS input field
566     Point aLHSPos( aOpListPos.X() + aOpListSize.Width() + aRelatedControls.Width(), aOpListPos.Y() );
567     if ( bIsExpression )
568         aLHSPos.X() = aOpListPos.X();
569     Size aLHSSize( LogicToPixel( Size( EDIT_WIDTH, EDIT_HEIGHT ), MAP_APPFONT ) );
570     if ( !bHaveRHS )
571         aLHSSize.Width() = aPreviewRect.Right() - aLHSPos.X();
572     m_aCondLHS.SetPosSizePixel( aLHSPos.X(), aLHSPos.Y(), aLHSSize.Width(), aLHSSize.Height() );
573 
574     if ( bHaveRHS )
575     {
576         // the "and" text being the glue between LHS and RHS
577         const Point aOpGluePos( aLHSPos.X() + aLHSSize.Width() + aRelatedControls.Width(), aLHSPos.Y() );
578         const Size aOpGlueSize( m_aOperandGlue.GetTextWidth( m_aOperandGlue.GetText() ) + aRelatedControls.Width(), aLHSSize.Height() );
579         m_aOperandGlue.SetPosSizePixel( aOpGluePos.X(), aOpGluePos.Y(), aOpGlueSize.Width(), aOpGlueSize.Height() );
580 
581         // the RHS input field
582         const Point aRHSPos( aOpGluePos.X() + aOpGlueSize.Width() + aRelatedControls.Width(), aOpGluePos.Y() );
583         const Size aRHSSize( aPreviewRect.Right() - aRHSPos.X(), aLHSSize.Height() );
584         m_aCondRHS.SetPosSizePixel( aRHSPos.X(), aRHSPos.Y(), aRHSSize.Width(), aRHSSize.Height() );
585     }
586 
587     m_aOperandGlue.Show( bHaveRHS );
588     m_aCondRHS.Show( bHaveRHS );
589 }
590 
591 // -----------------------------------------------------------------------------
592 void Condition::impl_setCondition( const ::rtl::OUString& _rConditionFormula )
593 {
594     // determine the condition's type and comparison operation
595     ConditionType eType( eFieldValueComparison );
596     ComparisonOperation eOperation( eBetween );
597 
598     // LHS and RHS, matched below
599     ::rtl::OUString sLHS, sRHS;
600 
601     if ( _rConditionFormula.getLength() )
602     {
603         // the unprefixed expression which forms the condition
604         ReportFormula aFormula( _rConditionFormula );
605         OSL_ENSURE( aFormula.getType() == ReportFormula::Expression, "Condition::setCondition: illegal formula!" );
606         ::rtl::OUString sExpression;
607         if ( aFormula.getType() == ReportFormula::Expression )
608             sExpression = aFormula.getExpression();
609         // as fallback, if the below matching does not succeed, assume
610         // the whole expression is the LHS
611         eType = eExpression;
612         sLHS = sExpression;
613 
614         // the data field (or expression) to which our control is bound
615         const ReportFormula aFieldContentFormula( m_rAction.getDataField() );
616         const ::rtl::OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() );
617 
618         // check whether one of the Field Value Expression Factories recognizes the expression
619         for (   ConditionalExpressions::const_iterator exp = m_aConditionalExpressions.begin();
620                 exp != m_aConditionalExpressions.end();
621                 ++exp
622             )
623         {
624             if ( exp->second->matchExpression( sExpression, sUnprefixedFieldContent, sLHS, sRHS ) )
625             {
626                 eType = eFieldValueComparison;
627                 eOperation = exp->first;
628                 break;
629             }
630         }
631     }
632 
633     // update UI
634     m_aConditionType.SelectEntryPos( (sal_uInt16)eType );
635     m_aOperationList.SelectEntryPos( (sal_uInt16)eOperation );
636     m_aCondLHS.SetText( sLHS );
637     m_aCondRHS.SetText( sRHS );
638 
639     // re-layout
640     impl_layoutOperands();
641 }
642 
643 // -----------------------------------------------------------------------------
644 void Condition::setCondition( const uno::Reference< report::XFormatCondition >& _rxCondition )
645 {
646     OSL_PRECOND( _rxCondition.is(), "Condition::setCondition: empty condition object!" );
647     if ( !_rxCondition.is() )
648         return;
649 
650     ::rtl::OUString sConditionFormula;
651     try
652     {
653         if ( _rxCondition.is() )
654             sConditionFormula =  _rxCondition->getFormula();
655     }
656     catch( const Exception& )
657     {
658     	DBG_UNHANDLED_EXCEPTION();
659     }
660     impl_setCondition( sConditionFormula );
661     updateToolbar( _rxCondition.get() );
662 }
663 
664 // -----------------------------------------------------------------------------
665 void Condition::updateToolbar(const uno::Reference< report::XReportControlFormat >& _xReportControlFormat)
666 {
667     OSL_ENSURE(_xReportControlFormat.is(),"XReportControlFormat is NULL!");
668     if ( _xReportControlFormat.is() )
669     {
670         sal_uInt16 nItemCount = m_aActions.GetItemCount();
671         for (sal_uInt16 j = 0; j< nItemCount; ++j)
672         {
673             sal_uInt16 nItemId = m_aActions.GetItemId(j);
674             m_aActions.CheckItem( nItemId, m_rController.isFormatCommandEnabled( nItemId, _xReportControlFormat ) );
675         }
676 
677         try
678         {
679             Font aBaseFont( Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetAppFont() );
680             SvxFont aFont( VCLUnoHelper::CreateFont( _xReportControlFormat->getFontDescriptor(), aBaseFont ) );
681             aFont.SetHeight( OutputDevice::LogicToLogic( Size( 0, (sal_Int32)aFont.GetHeight() ), MAP_POINT, MAP_TWIP ).Height());
682             aFont.SetEmphasisMark( static_cast< FontEmphasisMark >( _xReportControlFormat->getControlTextEmphasis() ) );
683             aFont.SetRelief( static_cast< FontRelief >( _xReportControlFormat->getCharRelief() ) );
684             aFont.SetColor( _xReportControlFormat->getCharColor() );
685             m_aPreview.SetFont( aFont );
686             m_aPreview.SetBackColor( _xReportControlFormat->getControlBackground() );
687             m_aPreview.SetTextLineColor( Color( _xReportControlFormat->getCharUnderlineColor() ) );
688         }
689         catch( const Exception& )
690         {
691             DBG_UNHANDLED_EXCEPTION();
692         }
693     }
694 }
695 // -----------------------------------------------------------------------------
696 void Condition::fillFormatCondition(const uno::Reference< report::XFormatCondition >& _xCondition)
697 {
698     const ConditionType eType( impl_getCurrentConditionType() );
699     const ComparisonOperation eOperation( impl_getCurrentComparisonOperation() );
700 
701     const ::rtl::OUString sLHS( m_aCondLHS.GetText() );
702     const ::rtl::OUString sRHS( m_aCondRHS.GetText() );
703 
704     ::rtl::OUString sUndecoratedFormula( sLHS );
705 
706     if ( eType == eFieldValueComparison )
707     {
708         ReportFormula aFieldContentFormula( m_rAction.getDataField() );
709         ::rtl::OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() );
710 
711         PConditionalExpression pFactory( m_aConditionalExpressions[ eOperation ] );
712         sUndecoratedFormula = pFactory->assembleExpression( sUnprefixedFieldContent, sLHS, sRHS );
713     }
714 
715     ReportFormula aFormula( ReportFormula::Expression, sUndecoratedFormula );
716     _xCondition->setFormula( aFormula.getCompleteFormula() );
717 }
718 // -----------------------------------------------------------------------------
719 void Condition::setConditionIndex( size_t _nCondIndex, size_t _nCondCount )
720 {
721     m_nCondIndex = _nCondIndex;
722     String sHeader( ModuleRes( STR_NUMBERED_CONDITION ) );
723     sHeader.SearchAndReplaceAscii( "$number$", String::CreateFromInt32( _nCondIndex + 1 ) );
724     m_aHeader.SetText( sHeader );
725 
726     m_aMoveUp.Enable( _nCondIndex > 0 );
727     OSL_PRECOND( _nCondCount > 0, "Condition::setConditionIndex: having no conditions at all is nonsense!" );
728     m_aMoveDown.Enable( _nCondIndex < _nCondCount - 1 );
729 }
730 
731 // -----------------------------------------------------------------------------
732 bool Condition::isEmpty() const
733 {
734     return m_aCondLHS.GetText().Len() == 0;
735 }
736 
737 // =============================================================================
738 } // rptui
739 // =============================================================================
740 
741