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 "CondFormat.hxx"
26 #include "CondFormat.hrc"
27 
28 #include "uistrings.hrc"
29 #include "RptResId.hrc"
30 #include "rptui_slotid.hrc"
31 #include "ModuleHelper.hxx"
32 #include "helpids.hrc"
33 #include "UITools.hxx"
34 #include "uistrings.hrc"
35 #include "ReportController.hxx"
36 #include "Condition.hxx"
37 
38 /** === begin UNO includes === **/
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/lang/IllegalArgumentException.hpp>
41 /** === end UNO includes === **/
42 
43 #include <svx/globlmn.hrc>
44 #include <svx/svxids.hrc>
45 
46 #include <toolkit/helper/vclunohelper.hxx>
47 
48 #include <vcl/msgbox.hxx>
49 
50 #include <tools/debug.hxx>
51 #include <tools/diagnose_ex.h>
52 
53 #include <comphelper/property.hxx>
54 
55 #include <algorithm>
56 #include "UndoActions.hxx"
57 
58 // .............................................................................
59 namespace rptui
60 {
61 // .............................................................................
62 
63     /** === begin UNO using === **/
64     using ::com::sun::star::uno::Reference;
65     using ::com::sun::star::uno::UNO_QUERY_THROW;
66     using ::com::sun::star::uno::UNO_QUERY;
67     using ::com::sun::star::uno::Exception;
68     using ::com::sun::star::lang::IllegalArgumentException;
69     using ::com::sun::star::uno::Sequence;
70     using ::com::sun::star::beans::PropertyValue;
71     using ::com::sun::star::uno::Any;
72     /** === end UNO using === **/
73     using namespace ::com::sun::star::report;
74 
75     //========================================================================
76     // UpdateLocker
77     //========================================================================
78     class UpdateLocker
79     {
80         Window& m_rWindow;
81 
82     public:
UpdateLocker(Window & _rWindow)83         UpdateLocker( Window& _rWindow )
84             :m_rWindow( _rWindow )
85         {
86             _rWindow.SetUpdateMode( sal_False );
87         }
~UpdateLocker()88         ~UpdateLocker()
89         {
90             m_rWindow.SetUpdateMode( sal_True );
91         }
92     };
93 
94     //========================================================================
95     // class ConditionalFormattingDialog
96     //========================================================================
DBG_NAME(rpt_ConditionalFormattingDialog)97     DBG_NAME(rpt_ConditionalFormattingDialog)
98     ConditionalFormattingDialog::ConditionalFormattingDialog(
99             Window* _pParent, const Reference< XReportControlModel >& _rxFormatConditions, ::rptui::OReportController& _rController )
100         :ModalDialog( _pParent, ModuleRes(RID_CONDFORMAT) )
101         ,m_aConditionPlayground( this, ModuleRes( WND_COND_PLAYGROUND ) )
102         ,m_aSeparator(this,     ModuleRes(FL_SEPARATOR1))
103         ,m_aPB_OK(this,         ModuleRes(PB_OK))
104         ,m_aPB_CANCEL(this,     ModuleRes(PB_CANCEL))
105         ,m_aPB_Help(this,       ModuleRes(PB_HELP))
106         ,m_aCondScroll( this,   ModuleRes( SB_ALL_CONDITIONS ) )
107         ,m_rController( _rController )
108         ,m_xFormatConditions( _rxFormatConditions )
109         ,m_bDeletingCondition( false )
110     {
111         DBG_CTOR(rpt_ConditionalFormattingDialog,NULL);
112         OSL_ENSURE( m_xFormatConditions.is(), "ConditionalFormattingDialog::ConditionalFormattingDialog: ReportControlModel is NULL -> Prepare for GPF!" );
113 
114         m_xCopy.set( m_xFormatConditions->createClone(), UNO_QUERY_THROW );
115 
116         m_aCondScroll.SetScrollHdl( LINK( this, ConditionalFormattingDialog, OnScroll ) );
117 
118         impl_initializeConditions();
119 
120         FreeResource();
121     }
122 
123     //------------------------------------------------------------------------
~ConditionalFormattingDialog()124     ConditionalFormattingDialog::~ConditionalFormattingDialog()
125     {
126         m_aConditions.clear();
127         DBG_DTOR(rpt_ConditionalFormattingDialog,NULL);
128     }
129 
130     // -----------------------------------------------------------------------------
impl_updateConditionIndicies()131     void ConditionalFormattingDialog::impl_updateConditionIndicies()
132     {
133         sal_Int32 nIndex = 0;
134         for (   Conditions::const_iterator cond = m_aConditions.begin();
135                 cond != m_aConditions.end();
136                 ++cond, ++nIndex
137             )
138         {
139             (*cond)->setConditionIndex( nIndex, impl_getConditionCount() );
140         }
141     }
142 
143     // -----------------------------------------------------------------------------
impl_conditionCountChanged()144     void ConditionalFormattingDialog::impl_conditionCountChanged()
145     {
146         if ( m_aConditions.empty() )
147             impl_addCondition_nothrow( 0 );
148 
149         impl_updateScrollBarRange();
150         impl_updateConditionIndicies();
151         impl_layoutAll();
152     }
153 
154     // -----------------------------------------------------------------------------
addCondition(size_t _nAddAfterIndex)155     void ConditionalFormattingDialog::addCondition( size_t _nAddAfterIndex )
156     {
157         OSL_PRECOND( _nAddAfterIndex < impl_getConditionCount(), "ConditionalFormattingDialog::addCondition: illegal condition index!" );
158         impl_addCondition_nothrow( _nAddAfterIndex + 1 );
159     }
160 
161     // -----------------------------------------------------------------------------
deleteCondition(size_t _nCondIndex)162     void ConditionalFormattingDialog::deleteCondition( size_t _nCondIndex )
163     {
164         impl_deleteCondition_nothrow( _nCondIndex );
165     }
166 
167     // -----------------------------------------------------------------------------
impl_addCondition_nothrow(size_t _nNewCondIndex)168     void ConditionalFormattingDialog::impl_addCondition_nothrow( size_t _nNewCondIndex )
169     {
170         UpdateLocker aLockUpdates( *this );
171 
172         try
173         {
174             if ( _nNewCondIndex > (size_t)m_xCopy->getCount() )
175                 throw IllegalArgumentException();
176 
177             Reference< XFormatCondition > xCond = m_xCopy->createFormatCondition();
178             ::comphelper::copyProperties(m_xCopy.get(),xCond.get());
179             m_xCopy->insertByIndex( _nNewCondIndex, makeAny( xCond ) );
180 
181             ConditionPtr pCon( new Condition( &m_aConditionPlayground, *this, m_rController ) );
182             pCon->setCondition( xCond );
183             m_aConditions.insert( m_aConditions.begin() + _nNewCondIndex, pCon );
184 
185             pCon->SetPosSizePixel( 0, 0, impl_getConditionWidth(), 0, WINDOW_POSSIZE_WIDTH );
186         }
187         catch( const Exception& )
188         {
189             DBG_UNHANDLED_EXCEPTION();
190         }
191 
192         impl_conditionCountChanged();
193 
194         impl_ensureConditionVisible( _nNewCondIndex );
195     }
196 
197     // -----------------------------------------------------------------------------
impl_focusCondition(size_t _nCondIndex)198     void ConditionalFormattingDialog::impl_focusCondition( size_t _nCondIndex )
199     {
200         OSL_PRECOND( _nCondIndex < impl_getConditionCount(),
201             "ConditionalFormattingDialog::impl_focusCondition: illegal index!" );
202 
203         impl_ensureConditionVisible( _nCondIndex );
204         m_aConditions[ _nCondIndex ]->GrabFocus();
205     }
206 
207     // -----------------------------------------------------------------------------
impl_deleteCondition_nothrow(size_t _nCondIndex)208     void ConditionalFormattingDialog::impl_deleteCondition_nothrow( size_t _nCondIndex )
209     {
210         UpdateLocker aLockUpdates( *this );
211 
212         OSL_PRECOND( _nCondIndex < impl_getConditionCount(),
213             "ConditionalFormattingDialog::impl_deleteCondition_nothrow: illegal index!" );
214 
215         bool bLastCondition = ( impl_getConditionCount() == 1 );
216 
217         bool bSetNewFocus = false;
218         size_t nNewFocusIndex( _nCondIndex );
219         try
220         {
221             if ( !bLastCondition )
222                 m_xCopy->removeByIndex( _nCondIndex );
223 
224             Conditions::iterator pos = m_aConditions.begin() + _nCondIndex;
225             if ( bLastCondition )
226             {
227                 Reference< XFormatCondition > xFormatCondition( m_xCopy->getByIndex( 0 ), UNO_QUERY_THROW );
228                 xFormatCondition->setFormula( ::rtl::OUString() );
229                 (*pos)->setCondition( xFormatCondition );
230             }
231             else
232             {
233                 bSetNewFocus = (*pos)->HasChildPathFocus();
234                 m_bDeletingCondition = true;
235                 m_aConditions.erase( pos );
236                 m_bDeletingCondition = false;
237             }
238 
239             if ( bSetNewFocus )
240             {
241                 if ( nNewFocusIndex >= impl_getConditionCount() )
242                     nNewFocusIndex = impl_getConditionCount() - 1;
243             }
244         }
245         catch( const Exception& )
246         {
247             DBG_UNHANDLED_EXCEPTION();
248         }
249 
250         impl_conditionCountChanged();
251         if ( bSetNewFocus )
252             impl_focusCondition( nNewFocusIndex );
253     }
254 
255     // -----------------------------------------------------------------------------
impl_moveCondition_nothrow(size_t _nCondIndex,bool _bMoveUp)256     void ConditionalFormattingDialog::impl_moveCondition_nothrow( size_t _nCondIndex, bool _bMoveUp )
257     {
258         size_t nOldConditionIndex( _nCondIndex );
259         size_t nNewConditionIndex( _bMoveUp ? _nCondIndex - 1 : _nCondIndex + 1 );
260 
261         // do this in two steps, so we don't become inconsistent if any of the UNO actions fails
262         Any aMovedCondition;
263         ConditionPtr pMovedCondition;
264         try
265         {
266             aMovedCondition = m_xCopy->getByIndex( (sal_Int32)nOldConditionIndex );
267             m_xCopy->removeByIndex( (sal_Int32)nOldConditionIndex );
268 
269             Conditions::iterator aRemovePos( m_aConditions.begin() + nOldConditionIndex );
270             pMovedCondition = *aRemovePos;
271             m_aConditions.erase( aRemovePos );
272         }
273         catch( const Exception& )
274         {
275         	DBG_UNHANDLED_EXCEPTION();
276             return;
277         }
278 
279         try
280         {
281             m_xCopy->insertByIndex( (sal_Int32)nNewConditionIndex, aMovedCondition );
282             m_aConditions.insert( m_aConditions.begin() + nNewConditionIndex, pMovedCondition );
283         }
284         catch( const Exception& )
285         {
286         	DBG_UNHANDLED_EXCEPTION();
287         }
288 
289         // at least the two swapped conditions need to know their new index
290         impl_updateConditionIndicies();
291 
292         // re-layout all conditions
293         Point aDummy;
294         impl_layoutConditions( aDummy );
295 
296         // ensure the moved condition is visible
297         impl_ensureConditionVisible( nNewConditionIndex );
298     }
299 
300     // -----------------------------------------------------------------------------
impl_getConditionWidth() const301     long ConditionalFormattingDialog::impl_getConditionWidth() const
302     {
303         const Size aDialogSize( GetOutputSizePixel() );
304         const Size aScrollBarWidth( LogicToPixel( Size( SCROLLBAR_WIDTH + UNRELATED_CONTROLS, 0 ), MAP_APPFONT ) );
305         return aDialogSize.Width() - aScrollBarWidth.Width();
306     }
307 
308     // -----------------------------------------------------------------------------
309     IMPL_LINK( ConditionalFormattingDialog, OnScroll, ScrollBar*, /*_pNotInterestedIn*/ )
310     {
311         size_t nFirstCondIndex( impl_getFirstVisibleConditionIndex() );
312         size_t nFocusCondIndex = impl_getFocusedConditionIndex( nFirstCondIndex );
313 
314         Point aDummy;
315         impl_layoutConditions( aDummy );
316 
317         if ( nFocusCondIndex < nFirstCondIndex )
318             impl_focusCondition( nFirstCondIndex );
319         else if ( nFocusCondIndex >= nFirstCondIndex + MAX_CONDITIONS )
320             impl_focusCondition( nFirstCondIndex + MAX_CONDITIONS - 1 );
321 
322         return 0;
323     }
324 
325     // -----------------------------------------------------------------------------
impl_layoutConditions(Point & _out_rBelowLastVisible)326     void ConditionalFormattingDialog::impl_layoutConditions( Point& _out_rBelowLastVisible )
327     {
328         // position the condition's playground
329         long nConditionWidth = impl_getConditionWidth();
330         long nConditionHeight = LogicToPixel( Size( 0, CONDITION_HEIGHT ), MAP_APPFONT ).Height();
331         size_t nVisibleConditions = ::std::min( impl_getConditionCount(), MAX_CONDITIONS );
332         Size aPlaygroundSize( nConditionWidth, nVisibleConditions * nConditionHeight );
333         m_aConditionPlayground.SetSizePixel( aPlaygroundSize );
334         _out_rBelowLastVisible = Point( 0, aPlaygroundSize.Height() );
335 
336         // position the single conditions
337         Point aConditionPos( 0, -1 * nConditionHeight * impl_getFirstVisibleConditionIndex() );
338         for (   Conditions::const_iterator cond = m_aConditions.begin();
339                 cond != m_aConditions.end();
340                 ++cond
341             )
342         {
343             (*cond)->SetPosSizePixel( aConditionPos.X(), aConditionPos.Y(), nConditionWidth, nConditionHeight );
344             aConditionPos.Move( 0, nConditionHeight );
345         }
346     }
347 
348     // -----------------------------------------------------------------------------
impl_layoutAll()349     void ConditionalFormattingDialog::impl_layoutAll()
350     {
351         // condition's positions
352         Point aPos;
353         impl_layoutConditions( aPos );
354 
355         // scrollbar size and visibility
356         m_aCondScroll.SetPosSizePixel( 0, 0, 0, aPos.Y(), WINDOW_POSSIZE_HEIGHT );
357         if ( !impl_needScrollBar() )
358             // normalize the position, so it can, in all situations, be used as top index
359             m_aCondScroll.SetThumbPos( 0 );
360 
361         // the separator and the buttons below it
362         aPos += LogicToPixel( Point( 0 , RELATED_CONTROLS ), MAP_APPFONT );
363         m_aSeparator.SetPosSizePixel( 0, aPos.Y(), 0, 0, WINDOW_POSSIZE_Y );
364 
365         aPos += LogicToPixel( Point( 0 , UNRELATED_CONTROLS ), MAP_APPFONT );
366         Window* pWindows[] = { &m_aPB_OK, &m_aPB_CANCEL, &m_aPB_Help };
367         for ( size_t i= 0; i < sizeof(pWindows)/sizeof(pWindows[0]); ++i )
368         {
369             pWindows[i]->SetPosSizePixel( 0, aPos.Y(), 0, 0, WINDOW_POSSIZE_Y );
370         }
371 
372         aPos += LogicToPixel( Point( 0, BUTTON_HEIGHT + RELATED_CONTROLS ), MAP_APPFONT );
373         SetPosSizePixel( 0, 0, 0, aPos.Y(), WINDOW_POSSIZE_HEIGHT );
374     }
375     // -----------------------------------------------------------------------------
impl_initializeConditions()376     void ConditionalFormattingDialog::impl_initializeConditions()
377     {
378         try
379         {
380             sal_Int32 nCount = m_xCopy->getCount();
381             for ( sal_Int32 i = 0; i < nCount ; ++i )
382             {
383                 ConditionPtr pCon( new Condition( &m_aConditionPlayground, *this, m_rController ) );
384                 Reference< XFormatCondition > xCond( m_xCopy->getByIndex(i), UNO_QUERY );
385                 pCon->setCondition( xCond );
386                 pCon->updateToolbar( xCond.get() );
387                 m_aConditions.push_back( pCon );
388             }
389         }
390         catch(Exception&)
391         {
392             OSL_ENSURE(0,"Can not access format condition!");
393         }
394 
395         impl_conditionCountChanged();
396     }
397 
398     // -----------------------------------------------------------------------------
applyCommand(size_t _nCondIndex,sal_uInt16 _nCommandId,const::Color _aColor)399     void ConditionalFormattingDialog::applyCommand( size_t _nCondIndex, sal_uInt16 _nCommandId, const ::Color _aColor )
400     {
401         OSL_PRECOND( _nCommandId, "ConditionalFormattingDialog::applyCommand: illegal command id!" );
402         try
403         {
404             Reference< XReportControlFormat > xReportControlFormat( m_xCopy->getByIndex( _nCondIndex ), UNO_QUERY_THROW );
405 
406             Sequence< PropertyValue > aArgs(3);
407 
408             aArgs[0].Name = REPORTCONTROLFORMAT;
409             aArgs[0].Value <<= xReportControlFormat;
410 
411             aArgs[1].Name = CURRENT_WINDOW;
412             aArgs[1].Value <<= VCLUnoHelper::GetInterface(this);
413 
414             aArgs[2].Name = PROPERTY_FONTCOLOR;
415             aArgs[2].Value <<= (sal_uInt32)_aColor.GetColor();
416 
417             // we use this way to create undo actions
418             m_rController.executeUnChecked(_nCommandId,aArgs);
419             m_aConditions[ _nCondIndex ]->updateToolbar(xReportControlFormat);
420         }
421         catch( Exception& )
422         {
423             DBG_UNHANDLED_EXCEPTION();
424         }
425     }
426 
427     // -----------------------------------------------------------------------------
moveConditionUp(size_t _nCondIndex)428     void ConditionalFormattingDialog::moveConditionUp( size_t _nCondIndex )
429     {
430         OSL_PRECOND( _nCondIndex > 0, "ConditionalFormattingDialog::moveConditionUp: cannot move up the first condition!" );
431         if ( _nCondIndex > 0 )
432             impl_moveCondition_nothrow( _nCondIndex, true );
433     }
434 
435     // -----------------------------------------------------------------------------
moveConditionDown(size_t _nCondIndex)436     void ConditionalFormattingDialog::moveConditionDown( size_t _nCondIndex )
437     {
438         OSL_PRECOND( _nCondIndex < impl_getConditionCount(), "ConditionalFormattingDialog::moveConditionDown: cannot move down the last condition!" );
439         if ( _nCondIndex < impl_getConditionCount() )
440             impl_moveCondition_nothrow( _nCondIndex, false );
441     }
442 
443     // -----------------------------------------------------------------------------
getDataField() const444     ::rtl::OUString ConditionalFormattingDialog::getDataField() const
445     {
446         ::rtl::OUString sDataField;
447         try
448         {
449             sDataField = m_xFormatConditions->getDataField();
450         }
451         catch( const Exception& )
452         {
453         	DBG_UNHANDLED_EXCEPTION();
454         }
455         return sDataField;
456     }
457 
458     // -----------------------------------------------------------------------------
Execute()459     short ConditionalFormattingDialog::Execute()
460     {
461         short nRet = ModalDialog::Execute();
462         if ( nRet == RET_OK )
463         {
464             const String sUndoAction( ModuleRes( RID_STR_UNDO_CONDITIONAL_FORMATTING ) );
465             const UndoContext aUndoContext( m_rController.getUndoManager(), sUndoAction );
466             try
467             {
468                 sal_Int32 j(0), i(0);;
469                 for (   Conditions::const_iterator cond = m_aConditions.begin();
470                         cond != m_aConditions.end();
471                         ++cond, ++i
472                     )
473                 {
474                     Reference< XFormatCondition > xCond( m_xCopy->getByIndex(i), UNO_QUERY_THROW );
475                     (*cond)->fillFormatCondition( xCond );
476 
477                     if ( (*cond)->isEmpty() )
478                         continue;
479 
480                     Reference< XFormatCondition > xNewCond;
481                     sal_Bool bAppend = j >= m_xFormatConditions->getCount();
482                     if ( bAppend )
483                     {
484                         xNewCond = m_xFormatConditions->createFormatCondition();
485                         m_xFormatConditions->insertByIndex( i, makeAny( xNewCond ) );
486                     }
487                     else
488                         xNewCond.set( m_xFormatConditions->getByIndex(j), UNO_QUERY );
489                     ++j;
490 
491                     ::comphelper::copyProperties(xCond.get(),xNewCond.get());
492                 }
493 
494                 for ( sal_Int32 k = m_xFormatConditions->getCount()-1; k >= j; --k )
495                     m_xFormatConditions->removeByIndex(k);
496 
497                 ::comphelper::copyProperties( m_xCopy.get(), m_xFormatConditions.get() );
498             }
499             catch ( const Exception& )
500             {
501                 DBG_UNHANDLED_EXCEPTION();
502                 nRet = RET_NO;
503             }
504         }
505         return nRet;
506     }
507 
508     // -----------------------------------------------------------------------------
PreNotify(NotifyEvent & _rNEvt)509     long ConditionalFormattingDialog::PreNotify( NotifyEvent& _rNEvt )
510     {
511         switch ( _rNEvt.GetType() )
512         {
513         case EVENT_KEYINPUT:
514         {
515             const KeyEvent* pKeyEvent( _rNEvt.GetKeyEvent() );
516             const KeyCode& rKeyCode = pKeyEvent->GetKeyCode();
517             if ( rKeyCode.IsMod1() && rKeyCode.IsMod2() )
518             {
519                 if ( rKeyCode.GetCode() == 0x0508 ) // -
520                 {
521                     impl_deleteCondition_nothrow( impl_getFocusedConditionIndex( 0 ) );
522                     return 1;
523                 }
524                 if ( rKeyCode.GetCode() == 0x0507 ) // +
525                 {
526                     impl_addCondition_nothrow( impl_getFocusedConditionIndex( impl_getConditionCount() - 1 ) + 1 );
527                     return 1;
528                 }
529             }
530         }
531         break;
532         case EVENT_GETFOCUS:
533         {
534             if ( m_bDeletingCondition )
535                 break;
536 
537             const Window* pGetFocusWindow( _rNEvt.GetWindow() );
538 
539             // determine whether the new focus window is part of an (currently invisible) condition
540             const Window* pConditionCandidate = pGetFocusWindow->GetParent();
541             const Window* pPlaygroundCandidate = pConditionCandidate ? pConditionCandidate->GetParent() : NULL;
542             while   (   ( pPlaygroundCandidate )
543                     &&  ( pPlaygroundCandidate != this )
544                     &&  ( pPlaygroundCandidate != &m_aConditionPlayground )
545                     )
546             {
547                 pConditionCandidate = pConditionCandidate->GetParent();
548                 pPlaygroundCandidate = pConditionCandidate ? pConditionCandidate->GetParent() : NULL;
549             }
550             if ( pPlaygroundCandidate == &m_aConditionPlayground )
551             {
552                 impl_ensureConditionVisible( dynamic_cast< const Condition& >( *pConditionCandidate ).getConditionIndex() );
553             }
554         }
555         break;
556         }
557 
558         return ModalDialog::PreNotify( _rNEvt );
559     }
560 
561     // -----------------------------------------------------------------------------
impl_getFirstVisibleConditionIndex() const562     size_t ConditionalFormattingDialog::impl_getFirstVisibleConditionIndex() const
563     {
564         return (size_t)m_aCondScroll.GetThumbPos();
565     }
566 
567     // -----------------------------------------------------------------------------
impl_getLastVisibleConditionIndex() const568     size_t ConditionalFormattingDialog::impl_getLastVisibleConditionIndex() const
569     {
570         return ::std::min( impl_getFirstVisibleConditionIndex() + MAX_CONDITIONS, impl_getConditionCount() ) - 1;
571     }
572 
573     // -----------------------------------------------------------------------------
impl_getFocusedConditionIndex(sal_Int32 _nFallBackIfNone) const574     size_t ConditionalFormattingDialog::impl_getFocusedConditionIndex( sal_Int32 _nFallBackIfNone ) const
575     {
576         size_t nIndex( 0 );
577         for (   Conditions::const_iterator cond = m_aConditions.begin();
578                 cond != m_aConditions.end();
579                 ++cond, ++nIndex
580             )
581         {
582             if ( (*cond)->HasChildPathFocus() )
583                 return nIndex;
584         }
585         return _nFallBackIfNone;
586     }
587 
588     // -----------------------------------------------------------------------------
impl_updateScrollBarRange()589     void ConditionalFormattingDialog::impl_updateScrollBarRange()
590     {
591         long nMax = ( impl_getConditionCount() > MAX_CONDITIONS ) ? impl_getConditionCount() - MAX_CONDITIONS + 1 : 0;
592 
593         m_aCondScroll.SetRangeMin( 0 );
594         m_aCondScroll.SetRangeMax( nMax );
595         m_aCondScroll.SetVisibleSize( 1 );
596     }
597 
598     // -----------------------------------------------------------------------------
impl_scrollTo(size_t _nTopCondIndex)599     void ConditionalFormattingDialog::impl_scrollTo( size_t _nTopCondIndex )
600     {
601         OSL_PRECOND( _nTopCondIndex + MAX_CONDITIONS <= impl_getConditionCount(),
602             "ConditionalFormattingDialog::impl_scrollTo: illegal index!" );
603         m_aCondScroll.SetThumbPos( _nTopCondIndex );
604         OnScroll( &m_aCondScroll );
605     }
606 
607     // -----------------------------------------------------------------------------
impl_ensureConditionVisible(size_t _nCondIndex)608     void ConditionalFormattingDialog::impl_ensureConditionVisible( size_t _nCondIndex )
609     {
610         OSL_PRECOND( _nCondIndex < impl_getConditionCount(),
611             "ConditionalFormattingDialog::impl_ensureConditionVisible: illegal index!" );
612 
613         if ( _nCondIndex < impl_getFirstVisibleConditionIndex() )
614             impl_scrollTo( _nCondIndex );
615         else if ( _nCondIndex > impl_getLastVisibleConditionIndex() )
616             impl_scrollTo( _nCondIndex - MAX_CONDITIONS + 1 );
617     }
618 
619 // .............................................................................
620 } // rptui
621 // .............................................................................
622