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