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 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_forms.hxx"
30 
31 #include "navtoolbar.hxx"
32 #include "frm_resource.hxx"
33 #include "featuredispatcher.hxx"
34 #include "frm_resource.hrc"
35 #include "commandimageprovider.hxx"
36 #include "commanddescriptionprovider.hxx"
37 
38 #include <com/sun/star/uno/Any.hxx>
39 #include <com/sun/star/form/runtime/FormFeature.hpp>
40 
41 #include <sfx2/imgmgr.hxx>
42 #include <vcl/fixed.hxx>
43 
44 #include <memory>
45 
46 #define LID_RECORD_LABEL    1000
47 #define LID_RECORD_FILLER   1001
48 
49 //.........................................................................
50 namespace frm
51 {
52 //.........................................................................
53 
54     using ::com::sun::star::uno::makeAny;
55     namespace FormFeature = ::com::sun::star::form::runtime::FormFeature;
56 
57     //=====================================================================
58     //.....................................................................
59     namespace
60     {
61         static bool isArtificialItem( sal_Int16 _nFeatureId )
62         {
63             return ( _nFeatureId == LID_RECORD_LABEL )
64                 || ( _nFeatureId == LID_RECORD_FILLER );
65         }
66 
67         static String getLabelString( sal_uInt16 _nResId )
68         {
69             String sLabel = String::CreateFromAscii( " " );
70             sLabel += String( FRM_RES_STRING( _nResId ) );
71             sLabel += String::CreateFromAscii( " " );
72             return sLabel;
73         }
74 
75         ::rtl::OUString lcl_getCommandURL( const sal_Int16 _nFormFeature )
76         {
77             const sal_Char* pAsciiCommandName = NULL;
78             switch ( _nFormFeature )
79             {
80                 case FormFeature::MoveAbsolute          : pAsciiCommandName = "AbsoluteRecord";     break;
81                 case FormFeature::TotalRecords          : pAsciiCommandName = "RecTotal";           break;
82                 case FormFeature::MoveToFirst           : pAsciiCommandName = "FirstRecord";        break;
83                 case FormFeature::MoveToPrevious        : pAsciiCommandName = "PrevRecord";         break;
84                 case FormFeature::MoveToNext            : pAsciiCommandName = "NextRecord";         break;
85                 case FormFeature::MoveToLast            : pAsciiCommandName = "LastRecord";         break;
86                 case FormFeature::SaveRecordChanges     : pAsciiCommandName = "RecSave";            break;
87                 case FormFeature::UndoRecordChanges     : pAsciiCommandName = "RecUndo";            break;
88                 case FormFeature::MoveToInsertRow       : pAsciiCommandName = "NewRecord";          break;
89                 case FormFeature::DeleteRecord          : pAsciiCommandName = "DeleteRecord";       break;
90                 case FormFeature::ReloadForm            : pAsciiCommandName = "Refresh";            break;
91                 case FormFeature::RefreshCurrentControl : pAsciiCommandName = "RefreshFormControl"; break;
92                 case FormFeature::SortAscending         : pAsciiCommandName = "Sortup";             break;
93                 case FormFeature::SortDescending        : pAsciiCommandName = "SortDown";           break;
94                 case FormFeature::InteractiveSort       : pAsciiCommandName = "OrderCrit";          break;
95                 case FormFeature::AutoFilter            : pAsciiCommandName = "AutoFilter";         break;
96                 case FormFeature::InteractiveFilter     : pAsciiCommandName = "FilterCrit";         break;
97                 case FormFeature::ToggleApplyFilter     : pAsciiCommandName = "FormFiltered";       break;
98                 case FormFeature::RemoveFilterAndSort   : pAsciiCommandName = "RemoveFilterSort";   break;
99             }
100             if ( pAsciiCommandName != NULL )
101                 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ) ) + ::rtl::OUString::createFromAscii( pAsciiCommandName );
102 
103             OSL_ENSURE( false, "lcl_getCommandURL: unknown FormFeature!" );
104             return ::rtl::OUString();
105         }
106     }
107 
108     //=====================================================================
109     //= ImplNavToolBar
110     //=====================================================================
111     class ImplNavToolBar : public ToolBox
112     {
113     protected:
114         const IFeatureDispatcher*   m_pDispatcher;
115 
116     public:
117         ImplNavToolBar( Window* _pParent )
118             :ToolBox( _pParent, WB_3DLOOK )
119             ,m_pDispatcher( NULL )
120         {
121         }
122 
123         void setDispatcher( const IFeatureDispatcher* _pDispatcher )
124         {
125             m_pDispatcher = _pDispatcher;
126         }
127 
128     protected:
129         // ToolBox overridables
130         virtual void        Select();
131 
132     };
133 
134     //---------------------------------------------------------------------
135     void ImplNavToolBar::Select()
136     {
137         if ( m_pDispatcher )
138         {
139             if ( !m_pDispatcher->isEnabled( GetCurItemId() ) )
140                 // the toolbox is a little bit buggy: With TIB_REPEAT, it sometimes
141                 // happens that a select is reported, even though the respective
142                 // item has just been disabled.
143                 return;
144             m_pDispatcher->dispatch( GetCurItemId() );
145         }
146     }
147 
148     //=====================================================================
149     //= NavigationToolBar
150     //=====================================================================
151     DBG_NAME( NavigationToolBar )
152     //---------------------------------------------------------------------
153     NavigationToolBar::NavigationToolBar( Window* _pParent, WinBits _nStyle, const PCommandImageProvider& _pImageProvider,
154             const PCommandDescriptionProvider& _pDescriptionProvider )
155         :Window( _pParent, _nStyle )
156         ,m_pDispatcher( NULL )
157         ,m_pImageProvider( _pImageProvider )
158         ,m_pDescriptionProvider( _pDescriptionProvider )
159         ,m_eImageSize( eSmall )
160         ,m_pToolbar( NULL )
161     {
162         DBG_CTOR( NavigationToolBar, NULL );
163         implInit( );
164     }
165 
166     //---------------------------------------------------------------------
167     NavigationToolBar::~NavigationToolBar( )
168     {
169         for (   ::std::vector< Window* >::iterator loopChildWins = m_aChildWins.begin();
170                 loopChildWins != m_aChildWins.end();
171                 ++loopChildWins
172             )
173         {
174             delete *loopChildWins;
175         }
176         delete m_pToolbar;
177         DBG_DTOR( NavigationToolBar, NULL );
178     }
179 
180     //---------------------------------------------------------------------
181     void NavigationToolBar::setDispatcher( const IFeatureDispatcher* _pDispatcher )
182     {
183         m_pDispatcher = _pDispatcher;
184 
185         m_pToolbar->setDispatcher( _pDispatcher );
186 
187         RecordPositionInput* pPositionWindow = static_cast< RecordPositionInput* >( m_pToolbar->GetItemWindow( FormFeature::MoveAbsolute ) );
188         OSL_ENSURE( pPositionWindow, "NavigationToolBar::setDispatcher: can't forward the dispatcher to the position window!" );
189         if ( pPositionWindow )
190             pPositionWindow->setDispatcher( _pDispatcher );
191 
192         updateFeatureStates( );
193     }
194 
195     //---------------------------------------------------------------------
196     void NavigationToolBar::updateFeatureStates( )
197     {
198         for ( sal_uInt16 nPos = 0; nPos < m_pToolbar->GetItemCount(); ++nPos )
199         {
200             sal_uInt16 nItemId = m_pToolbar->GetItemId( nPos );
201 
202             if ( ( nItemId == LID_RECORD_LABEL ) || ( nItemId == LID_RECORD_FILLER ) )
203                 continue;
204 
205             // is this item enabled?
206             bool bEnabled = m_pDispatcher ? m_pDispatcher->isEnabled( nItemId ) : false;
207             implEnableItem( nItemId, bEnabled );
208         }
209     }
210 
211     //---------------------------------------------------------------------
212     void NavigationToolBar::implEnableItem( sal_uInt16 _nItemId, bool _bEnabled )
213     {
214         m_pToolbar->EnableItem( _nItemId, _bEnabled );
215 
216         if ( _nItemId == FormFeature::MoveAbsolute )
217             m_pToolbar->EnableItem( LID_RECORD_LABEL, _bEnabled );
218 
219         if ( _nItemId == FormFeature::TotalRecords )
220             m_pToolbar->EnableItem( LID_RECORD_FILLER, _bEnabled );
221     }
222 
223     //---------------------------------------------------------------------
224     void NavigationToolBar::enableFeature( sal_Int16 _nFeatureId, bool _bEnabled )
225     {
226         DBG_ASSERT( m_pToolbar->GetItemPos( (sal_uInt16)_nFeatureId ) != TOOLBOX_ITEM_NOTFOUND,
227             "NavigationToolBar::enableFeature: invalid id!" );
228 
229         implEnableItem( (sal_uInt16)_nFeatureId, _bEnabled );
230     }
231 
232     //---------------------------------------------------------------------
233     void NavigationToolBar::checkFeature( sal_Int16 _nFeatureId, bool _bEnabled )
234     {
235         DBG_ASSERT( m_pToolbar->GetItemPos( (sal_uInt16)_nFeatureId ) != TOOLBOX_ITEM_NOTFOUND,
236             "NavigationToolBar::checkFeature: invalid id!" );
237 
238         m_pToolbar->CheckItem( (sal_uInt16)_nFeatureId, _bEnabled );
239     }
240 
241     //---------------------------------------------------------------------
242     void NavigationToolBar::setFeatureText( sal_Int16 _nFeatureId, const ::rtl::OUString& _rText )
243     {
244         DBG_ASSERT( m_pToolbar->GetItemPos( (sal_uInt16)_nFeatureId ) != TOOLBOX_ITEM_NOTFOUND,
245             "NavigationToolBar::checkFeature: invalid id!" );
246 
247         Window* pItemWindow = m_pToolbar->GetItemWindow( (sal_uInt16)_nFeatureId );
248         if ( pItemWindow )
249             pItemWindow->SetText( _rText );
250         else
251             m_pToolbar->SetItemText( (sal_uInt16)_nFeatureId, _rText );
252     }
253 
254     //---------------------------------------------------------------------
255     void NavigationToolBar::implInit( )
256     {
257         m_pToolbar = new ImplNavToolBar( this );
258         m_pToolbar->SetOutStyle( TOOLBOX_STYLE_FLAT );
259         m_pToolbar->Show();
260 
261         // need the SfxApplication for retrieving informations about our
262         // items. We could duplicate all the information here in our lib
263         // (such as the item text and the image), but why should we?
264 
265         struct FeatureDescription
266         {
267             sal_uInt16      nId;
268             bool        bRepeat;
269             bool        bItemWindow;
270         } aSupportedFeatures[] =
271         {
272             { LID_RECORD_LABEL,                     false, true },
273             { FormFeature::MoveAbsolute,            false, true },
274             { LID_RECORD_FILLER,                    false, true },
275             { FormFeature::TotalRecords,            false, true },
276             { FormFeature::MoveToFirst,             true,  false },
277             { FormFeature::MoveToPrevious,          true,  false },
278             { FormFeature::MoveToNext,              true,  false },
279             { FormFeature::MoveToLast,              true,  false },
280             { FormFeature::MoveToInsertRow,         false, false },
281             { 0, false, false },
282             { FormFeature::SaveRecordChanges,       false, false },
283             { FormFeature::UndoRecordChanges,       false, false },
284             { FormFeature::DeleteRecord,            false, false },
285             { FormFeature::ReloadForm,              false, false },
286             { FormFeature::RefreshCurrentControl,   false, false },
287             { 0, false, false },
288             { FormFeature::SortAscending,           false, false },
289             { FormFeature::SortDescending,          false, false },
290             { FormFeature::InteractiveSort,         false, false },
291             { FormFeature::AutoFilter,              false, false },
292             { FormFeature::InteractiveFilter,       false, false },
293             { FormFeature::ToggleApplyFilter,       false, false },
294             { FormFeature::RemoveFilterAndSort,     false, false },
295         };
296 
297         size_t nSupportedFeatures = sizeof( aSupportedFeatures ) / sizeof( aSupportedFeatures[0] );
298         FeatureDescription* pSupportedFeatures = aSupportedFeatures;
299         FeatureDescription* pSupportedFeaturesEnd = aSupportedFeatures + nSupportedFeatures;
300         for ( ; pSupportedFeatures < pSupportedFeaturesEnd; ++pSupportedFeatures )
301         {
302             if ( pSupportedFeatures->nId )
303             {   // it's _not_ a separator
304 
305                 // insert the entry
306                 m_pToolbar->InsertItem( pSupportedFeatures->nId, String(), pSupportedFeatures->bRepeat ? TIB_REPEAT : 0 );
307                 m_pToolbar->SetQuickHelpText( pSupportedFeatures->nId, String() );  // TODO
308 
309                 if ( !isArtificialItem( pSupportedFeatures->nId ) )
310                 {
311                     ::rtl::OUString sCommandURL( lcl_getCommandURL( pSupportedFeatures->nId ) );
312                     m_pToolbar->SetItemCommand( pSupportedFeatures->nId, sCommandURL );
313                     if ( m_pDescriptionProvider )
314                         m_pToolbar->SetQuickHelpText( pSupportedFeatures->nId, m_pDescriptionProvider->getCommandDescription( sCommandURL ) );
315                 }
316 
317                 if ( pSupportedFeatures->bItemWindow )
318                 {
319                     Window* pItemWindow = NULL;
320                     if ( FormFeature::MoveAbsolute == pSupportedFeatures->nId )
321                     {
322                         pItemWindow = new RecordPositionInput( m_pToolbar );
323                         static_cast< RecordPositionInput* >( pItemWindow )->setDispatcher( m_pDispatcher );
324                     }
325                     else if ( LID_RECORD_FILLER == pSupportedFeatures->nId )
326                     {
327                         pItemWindow = new FixedText( m_pToolbar, WB_CENTER | WB_VCENTER );
328 						pItemWindow->SetBackground(Wallpaper(Color(COL_TRANSPARENT)));
329                     }
330                     else
331                     {
332                         pItemWindow = new FixedText( m_pToolbar, WB_VCENTER );
333 						pItemWindow->SetBackground();
334                         pItemWindow->SetPaintTransparent(sal_True);
335                     }
336                     m_aChildWins.push_back( pItemWindow );
337 
338                     switch ( pSupportedFeatures->nId )
339                     {
340                     case LID_RECORD_LABEL:
341                         pItemWindow->SetText( getLabelString( RID_STR_LABEL_RECORD ) );
342                         break;
343 
344                     case LID_RECORD_FILLER:
345                         pItemWindow->SetText( getLabelString( RID_STR_LABEL_OF ) );
346                         break;
347                     }
348 
349                     m_pToolbar->SetItemWindow( pSupportedFeatures->nId, pItemWindow );
350                 }
351             }
352             else
353             {   // a separator
354                 m_pToolbar->InsertSeparator( );
355             }
356         }
357 
358         forEachItemWindow( &NavigationToolBar::adjustItemWindowWidth, NULL );
359 
360         implUpdateImages();
361     }
362 
363     //---------------------------------------------------------------------
364     void NavigationToolBar::implUpdateImages()
365     {
366         OSL_ENSURE( m_pImageProvider, "NavigationToolBar::implUpdateImages: no image provider => no images!" );
367         if ( !m_pImageProvider )
368             return;
369 
370         const bool bIsHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
371 
372         const sal_uInt16 nItemCount = m_pToolbar->GetItemCount();
373 
374         // collect the FormFeatures in the toolbar
375         typedef ::std::vector< sal_Int16 >  FormFeatures;
376         FormFeatures aFormFeatures;
377         aFormFeatures.reserve( nItemCount );
378 
379         for ( sal_uInt16 i=0; i<nItemCount; ++i )
380         {
381             sal_uInt16 nId = m_pToolbar->GetItemId( i );
382             if ( ( TOOLBOXITEM_BUTTON == m_pToolbar->GetItemType( i ) ) && !isArtificialItem( nId ) )
383                 aFormFeatures.push_back( nId );
384         }
385 
386         // translate them into command URLs
387         CommandURLs aCommandURLs( aFormFeatures.size() );
388         for (   FormFeatures::const_iterator formFeature = aFormFeatures.begin();
389                 formFeature != aFormFeatures.end();
390                 ++formFeature
391             )
392         {
393             aCommandURLs[ formFeature - aFormFeatures.begin() ] = lcl_getCommandURL( *formFeature );
394         }
395 
396         // retrieve the images for the command URLs
397         CommandImages aCommandImages = m_pImageProvider->getCommandImages( aCommandURLs, m_eImageSize == eLarge, bIsHighContrast );
398 
399         // and set them at the toolbar
400         CommandImages::const_iterator commandImage = aCommandImages.begin();
401         for (   FormFeatures::const_iterator formFeature = aFormFeatures.begin();
402                 formFeature != aFormFeatures.end();
403                 ++formFeature, ++commandImage
404             )
405         {
406             m_pToolbar->SetItemImage( *formFeature, *commandImage );
407         }
408 
409         // parts of our layout is dependent on the size of our icons
410         Resize();
411     }
412 
413     //---------------------------------------------------------------------
414     void NavigationToolBar::implSetImageSize( ImageSize _eSize )
415     {
416         if ( _eSize != m_eImageSize )
417         {
418             m_eImageSize = _eSize;
419             implUpdateImages();
420         }
421     }
422 
423     //---------------------------------------------------------------------
424     void NavigationToolBar::SetImageSize( ImageSize _eSize )
425     {
426         implSetImageSize( _eSize );
427     }
428 
429     //---------------------------------------------------------------------
430     void NavigationToolBar::ShowFunctionGroup( FunctionGroup _eGroup, bool _bShow )
431     {
432         const sal_uInt16* pGroupIds = NULL;
433 
434         switch ( _eGroup )
435         {
436         case ePosition:
437         {
438             static const sal_uInt16 aPositionIds[] = {
439                 LID_RECORD_LABEL, FormFeature::MoveAbsolute, LID_RECORD_FILLER, FormFeature::TotalRecords, 0
440             };
441             pGroupIds = aPositionIds;
442         }
443         break;
444         case eNavigation:
445         {
446             static const sal_uInt16 aNavigationIds[] = {
447                 FormFeature::MoveToFirst, FormFeature::MoveToPrevious, FormFeature::MoveToNext, FormFeature::MoveToLast, FormFeature::MoveToInsertRow, 0
448             };
449             pGroupIds = aNavigationIds;
450         }
451         break;
452         case eRecordActions:
453         {
454             static const sal_uInt16 aActionIds[] = {
455                 FormFeature::SaveRecordChanges, FormFeature::UndoRecordChanges, FormFeature::DeleteRecord, FormFeature::ReloadForm, FormFeature::RefreshCurrentControl, 0
456             };
457             pGroupIds = aActionIds;
458         }
459         break;
460         case eFilterSort:
461         {
462             static const sal_uInt16 aFilterSortIds[] = {
463                 FormFeature::SortAscending, FormFeature::SortDescending, FormFeature::InteractiveSort, FormFeature::AutoFilter, FormFeature::InteractiveFilter, FormFeature::ToggleApplyFilter, FormFeature::RemoveFilterAndSort, 0
464             };
465             pGroupIds = aFilterSortIds;
466         }
467         break;
468         default:
469             OSL_ENSURE( sal_False, "NavigationToolBar::ShowFunctionGroup: invalid group id!" );
470         }
471 
472         if ( pGroupIds )
473             while ( *pGroupIds )
474                 m_pToolbar->ShowItem( *pGroupIds++, _bShow );
475     }
476 
477     //---------------------------------------------------------------------
478     bool NavigationToolBar::IsFunctionGroupVisible( FunctionGroup _eGroup )
479     {
480         sal_uInt16 nIndicatorItem = 0;
481         switch ( _eGroup )
482         {
483         case ePosition      : nIndicatorItem = LID_RECORD_LABEL;    break;
484         case eNavigation    : nIndicatorItem = FormFeature::MoveToFirst; break;
485         case eRecordActions : nIndicatorItem = FormFeature::SaveRecordChanges;  break;
486         case eFilterSort    : nIndicatorItem = FormFeature::SortAscending;       break;
487         default:
488             OSL_ENSURE( sal_False, "NavigationToolBar::IsFunctionGroupVisible: invalid group id!" );
489         }
490 
491         return m_pToolbar->IsItemVisible( nIndicatorItem );
492     }
493 
494     //------------------------------------------------------------------------------
495     void NavigationToolBar::StateChanged( StateChangedType nType )
496     {
497 	    Window::StateChanged( nType );
498 
499         switch ( nType )
500 	    {
501 		    case STATE_CHANGE_ZOOM:
502 //                m_pToolbar->SetZoom( GetZoom() );
503 //                forEachItemWindow( setItemWindowZoom, NULL );
504                 // the ToolBox class is not zoomable at the moment, so
505                 // we better have no zoom at all instead of only half a zoom ...
506                 break;
507 
508             case STATE_CHANGE_CONTROLFONT:
509                 forEachItemWindow( &NavigationToolBar::setItemControlFont, NULL );
510                 forEachItemWindow( &NavigationToolBar::adjustItemWindowWidth, NULL );
511                 break;
512 
513             case STATE_CHANGE_CONTROLFOREGROUND:
514                 forEachItemWindow( &NavigationToolBar::setItemControlForeground, NULL );
515                 break;
516 
517             case STATE_CHANGE_MIRRORING:
518             {
519                 sal_Bool bIsRTLEnabled( IsRTLEnabled() );
520                 m_pToolbar->EnableRTL( bIsRTLEnabled );
521                 forEachItemWindow( &NavigationToolBar::enableItemRTL, &bIsRTLEnabled );
522                 Resize();
523             }
524             break;
525         }
526     }
527 
528     //---------------------------------------------------------------------
529     void NavigationToolBar::Resize()
530     {
531         // resize/position the toolbox as a whole
532         sal_Int32 nToolbarHeight = m_pToolbar->CalcWindowSizePixel().Height();
533 
534         sal_Int32 nMyHeight = GetOutputSizePixel().Height();
535         m_pToolbar->SetPosSizePixel( Point( 0, ( nMyHeight - nToolbarHeight ) / 2 ),
536                                      Size( GetSizePixel().Width(), nToolbarHeight ) );
537 
538         Window::Resize();
539     }
540 
541     //---------------------------------------------------------------------
542     void NavigationToolBar::SetControlBackground()
543     {
544         Window::SetControlBackground();
545         m_pToolbar->SetControlBackground();
546         forEachItemWindow( &NavigationToolBar::setItemBackground, NULL );
547 
548         // the contrast of the background color may have changed, so force
549         // the images to be rebuild (high contrast requires a possibly different
550         // image set)
551         implUpdateImages();
552     }
553 
554     //---------------------------------------------------------------------
555     void NavigationToolBar::SetControlBackground( const Color& _rColor )
556     {
557         Window::SetControlBackground( _rColor );
558         m_pToolbar->SetControlBackground( _rColor );
559         forEachItemWindow( &NavigationToolBar::setItemBackground, &_rColor );
560 
561         // the contrast of the background color may have changed, so force
562         // the images to be rebuild (high contrast requires a possibly different
563         // image set)
564         implUpdateImages();
565     }
566 
567     //---------------------------------------------------------------------
568     void NavigationToolBar::SetTextLineColor( )
569     {
570         Window::SetTextLineColor( );
571         m_pToolbar->SetTextLineColor( );
572         forEachItemWindow( &NavigationToolBar::setTextLineColor, NULL );
573     }
574 
575     //---------------------------------------------------------------------
576     void NavigationToolBar::SetTextLineColor( const Color& _rColor )
577     {
578         Window::SetTextLineColor( _rColor );
579         m_pToolbar->SetTextLineColor( _rColor );
580         forEachItemWindow( &NavigationToolBar::setTextLineColor, &_rColor );
581     }
582 
583     //---------------------------------------------------------------------
584     void NavigationToolBar::forEachItemWindow( ItemWindowHandler _handler, const void* _pParam )
585     {
586         for ( sal_uInt16 item = 0; item < m_pToolbar->GetItemCount(); ++item )
587         {
588             sal_uInt16 nItemId = m_pToolbar->GetItemId( item );
589             Window* pItemWindow = m_pToolbar->GetItemWindow( nItemId );
590             if ( pItemWindow )
591                 (this->*_handler)( nItemId, pItemWindow, _pParam );
592         }
593     }
594 
595     //---------------------------------------------------------------------
596     void NavigationToolBar::setItemBackground( sal_uInt16 /* _nItemId */, Window* _pItemWindow, const void* _pColor ) const
597     {
598         if ( _pColor )
599             _pItemWindow->SetControlBackground( *static_cast< const Color* >( _pColor ) );
600         else
601             _pItemWindow->SetControlBackground();
602     }
603 
604     //---------------------------------------------------------------------
605     void NavigationToolBar::setTextLineColor( sal_uInt16 /* _nItemId */, Window* _pItemWindow, const void* _pColor ) const
606     {
607         if ( _pColor )
608             _pItemWindow->SetTextLineColor( *static_cast< const Color* >( _pColor ) );
609         else
610             _pItemWindow->SetTextLineColor();
611     }
612 #if 0
613     //---------------------------------------------------------------------
614     void NavigationToolBar::setItemWindowZoom( sal_uInt16 /* _nItemId */, Window* _pItemWindow, const void* /* _pParam */ ) const
615     {
616         _pItemWindow->SetZoom( GetZoom() );
617         _pItemWindow->SetZoomedPointFont( IsControlFont() ? GetControlFont() : GetPointFont() );
618     }
619 #endif
620     //---------------------------------------------------------------------
621     void NavigationToolBar::setItemControlFont( sal_uInt16 /* _nItemId */, Window* _pItemWindow, const void* /* _pParam */ ) const
622     {
623         if ( IsControlFont() )
624             _pItemWindow->SetControlFont( GetControlFont() );
625         else
626             _pItemWindow->SetControlFont( );
627     }
628 
629     //---------------------------------------------------------------------
630     void NavigationToolBar::setItemControlForeground( sal_uInt16 /* _nItemId */, Window* _pItemWindow, const void* /* _pParam */ ) const
631     {
632         if ( IsControlForeground() )
633             _pItemWindow->SetControlForeground( GetControlForeground() );
634         else
635             _pItemWindow->SetControlForeground( );
636         _pItemWindow->SetTextColor( GetTextColor() );
637     }
638 
639     //---------------------------------------------------------------------
640     void NavigationToolBar::adjustItemWindowWidth( sal_uInt16 _nItemId, Window* _pItemWindow, const void* /* _pParam */ ) const
641     {
642         String sItemText;
643         switch ( _nItemId )
644         {
645         case LID_RECORD_LABEL:
646             sItemText = getLabelString( RID_STR_LABEL_RECORD );
647             break;
648 
649         case LID_RECORD_FILLER:
650             sItemText = getLabelString( RID_STR_LABEL_OF );
651             break;
652 
653         case FormFeature::MoveAbsolute:
654             sItemText = String::CreateFromAscii( "12345678" );
655             break;
656 
657         case FormFeature::TotalRecords:
658             sItemText = String::CreateFromAscii( "123456" );
659             break;
660         }
661 
662         Size aSize( _pItemWindow->GetTextWidth( sItemText ), /* _pItemWindow->GetSizePixel( ).Height() */ _pItemWindow->GetTextHeight() + 4 );
663         aSize.Width() += 6;
664         _pItemWindow->SetSizePixel( aSize );
665 
666         m_pToolbar->SetItemWindow( _nItemId, _pItemWindow );
667     }
668 
669     //---------------------------------------------------------------------
670     void NavigationToolBar::enableItemRTL( sal_uInt16 /*_nItemId*/, Window* _pItemWindow, const void* _pIsRTLEnabled ) const
671     {
672         _pItemWindow->EnableRTL( *static_cast< const sal_Bool* >( _pIsRTLEnabled ) );
673     }
674 
675     //=====================================================================
676     //= RecordPositionInput
677     //=====================================================================
678     //---------------------------------------------------------------------
679     RecordPositionInput::RecordPositionInput( Window* _pParent )
680 	    :NumericField( _pParent, WB_BORDER | WB_VCENTER )
681         ,m_pDispatcher( NULL )
682     {
683 	    SetMin( 1 );
684 	    SetFirst( 1 );
685 	    SetSpinSize( 1 );
686 	    SetDecimalDigits( 0 );
687 	    SetStrictFormat( sal_True );
688         SetBorderStyle( WINDOW_BORDER_MONO );
689     }
690 
691     //---------------------------------------------------------------------
692     RecordPositionInput::~RecordPositionInput()
693     {
694     }
695 
696     //---------------------------------------------------------------------
697     void RecordPositionInput::setDispatcher( const IFeatureDispatcher* _pDispatcher )
698     {
699         m_pDispatcher = _pDispatcher;
700     }
701 
702     //---------------------------------------------------------------------
703     void RecordPositionInput::FirePosition( sal_Bool _bForce )
704     {
705 	    if ( _bForce || ( GetText() != GetSavedValue() ) )
706 	    {
707 		    sal_Int64 nRecord = GetValue();
708 		    if ( nRecord < GetMin() || nRecord > GetMax() )
709 			    return;
710 
711             if ( m_pDispatcher )
712                 m_pDispatcher->dispatchWithArgument( FormFeature::MoveAbsolute, "Position", makeAny( (sal_Int32)nRecord ) );
713 
714             SaveValue();
715 	    }
716     }
717 
718     //---------------------------------------------------------------------
719     void RecordPositionInput::LoseFocus()
720     {
721 	    FirePosition( sal_False );
722     }
723 
724     //---------------------------------------------------------------------
725     void RecordPositionInput::KeyInput( const KeyEvent& rKeyEvent )
726     {
727 	    if( rKeyEvent.GetKeyCode() == KEY_RETURN && GetText().Len() )
728 		    FirePosition( sal_True );
729 	    else
730 		    NumericField::KeyInput( rKeyEvent );
731     }
732 
733 
734 //.........................................................................
735 }   // namespace frm
736 //.........................................................................
737