1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: navtoolbar.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_forms.hxx"
33 #include "navtoolbar.hxx"
34 #include "frm_resource.hxx"
35 #ifndef _FRM_RESOURCE_HRC_
36 #include "frm_resource.hrc"
38 #include <vcl/fixed.hxx>
39 #ifndef _SVX_SVXIDS_HRC
40 #include <svx/svxids.hrc>
42 #include <sfx2/msgpool.hxx>
43 #include <sfx2/imgmgr.hxx>
44 #include "featuredispatcher.hxx"
45 #include <com/sun/star/uno/Any.hxx>
49 #define LID_RECORD_LABEL 1
50 #define LID_RECORD_FILLER 2
52 //.........................................................................
55 //.........................................................................
57 //=====================================================================
58 //.....................................................................
61 static bool isSfxSlot( sal_Int32 _nFeatureId
)
63 // everything we use in this class is an SFX-slot - except the LID_* ids
64 return ( _nFeatureId
!= LID_RECORD_LABEL
)
65 && ( _nFeatureId
!= LID_RECORD_FILLER
);
68 static String
getLabelString( USHORT _nResId
)
70 String sLabel
= String::CreateFromAscii( " " );
71 sLabel
+= String( FRM_RES_STRING( _nResId
) );
72 sLabel
+= String::CreateFromAscii( " " );
75 static bool lcl_isHighContrast( const Color
& _rColor
)
77 return _rColor
.IsDark();
81 //=====================================================================
83 //=====================================================================
84 class ImplNavToolBar
: public ToolBox
87 const IFeatureDispatcher
* m_pDispatcher
;
90 ImplNavToolBar( Window
* _pParent
)
91 :ToolBox( _pParent
, WB_3DLOOK
)
92 ,m_pDispatcher( NULL
)
96 void setDispatcher( const IFeatureDispatcher
* _pDispatcher
)
98 m_pDispatcher
= _pDispatcher
;
102 // ToolBox overridables
103 virtual void Select();
107 //---------------------------------------------------------------------
108 void ImplNavToolBar::Select()
112 if ( !m_pDispatcher
->isEnabled( GetCurItemId() ) )
113 // the toolbox is a little bit buggy: With TIB_REPEAT, it sometimes
114 // happens that a select is reported, even though the respective
115 // item has just been disabled.
117 m_pDispatcher
->dispatch( GetCurItemId() );
121 //=====================================================================
122 //= NavigationToolBar
123 //=====================================================================
124 DBG_NAME( NavigationToolBar
)
125 //---------------------------------------------------------------------
126 NavigationToolBar::NavigationToolBar( Window
* _pParent
, WinBits _nStyle
)
127 :Window( _pParent
, _nStyle
)
128 ,m_pDispatcher( NULL
)
129 ,m_eImageSize( eSmall
)
132 DBG_CTOR( NavigationToolBar
, NULL
);
136 //---------------------------------------------------------------------
137 NavigationToolBar::~NavigationToolBar( )
139 for ( ::std::vector
< Window
* >::iterator loopChildWins
= m_aChildWins
.begin();
140 loopChildWins
!= m_aChildWins
.end();
144 delete *loopChildWins
;
147 DBG_DTOR( NavigationToolBar
, NULL
);
150 //---------------------------------------------------------------------
151 void NavigationToolBar::setDispatcher( const IFeatureDispatcher
* _pDispatcher
)
153 m_pDispatcher
= _pDispatcher
;
155 m_pToolbar
->setDispatcher( _pDispatcher
);
157 RecordPositionInput
* pPositionWindow
= static_cast< RecordPositionInput
* >( m_pToolbar
->GetItemWindow( SID_FM_RECORD_ABSOLUTE
) );
158 OSL_ENSURE( pPositionWindow
, "NavigationToolBar::setDispatcher: can't forward the dispatcher to the position window!" );
159 if ( pPositionWindow
)
160 pPositionWindow
->setDispatcher( _pDispatcher
);
162 updateFeatureStates( );
165 //---------------------------------------------------------------------
166 void NavigationToolBar::updateFeatureStates( )
168 for ( USHORT nPos
= 0; nPos
< m_pToolbar
->GetItemCount(); ++nPos
)
170 USHORT nItemId
= m_pToolbar
->GetItemId( nPos
);
172 if ( ( nItemId
== LID_RECORD_LABEL
) || ( nItemId
== LID_RECORD_FILLER
) )
175 // is this item enabled?
176 bool bEnabled
= m_pDispatcher
? m_pDispatcher
->isEnabled( nItemId
) : false;
177 implEnableItem( nItemId
, bEnabled
);
181 //---------------------------------------------------------------------
182 void NavigationToolBar::implEnableItem( USHORT _nItemId
, bool _bEnabled
)
184 m_pToolbar
->EnableItem( _nItemId
, _bEnabled
);
186 if ( _nItemId
== SID_FM_RECORD_ABSOLUTE
)
187 m_pToolbar
->EnableItem( LID_RECORD_LABEL
, _bEnabled
);
189 if ( _nItemId
== SID_FM_RECORD_TOTAL
)
190 m_pToolbar
->EnableItem( LID_RECORD_FILLER
, _bEnabled
);
193 //---------------------------------------------------------------------
194 void NavigationToolBar::enableFeature( sal_Int32 _nFeatureId
, bool _bEnabled
)
196 DBG_ASSERT( m_pToolbar
->GetItemPos( (USHORT
)_nFeatureId
) != TOOLBOX_ITEM_NOTFOUND
,
197 "NavigationToolBar::enableFeature: invalid id!" );
199 implEnableItem( (USHORT
)_nFeatureId
, _bEnabled
);
202 //---------------------------------------------------------------------
203 void NavigationToolBar::checkFeature( sal_Int32 _nFeatureId
, bool _bEnabled
)
205 DBG_ASSERT( m_pToolbar
->GetItemPos( (USHORT
)_nFeatureId
) != TOOLBOX_ITEM_NOTFOUND
,
206 "NavigationToolBar::checkFeature: invalid id!" );
208 m_pToolbar
->CheckItem( (USHORT
)_nFeatureId
, _bEnabled
);
211 //---------------------------------------------------------------------
212 void NavigationToolBar::setFeatureText( sal_Int32 _nFeatureId
, const ::rtl::OUString
& _rText
)
214 DBG_ASSERT( m_pToolbar
->GetItemPos( (USHORT
)_nFeatureId
) != TOOLBOX_ITEM_NOTFOUND
,
215 "NavigationToolBar::checkFeature: invalid id!" );
217 Window
* pItemWindow
= m_pToolbar
->GetItemWindow( (USHORT
)_nFeatureId
);
219 pItemWindow
->SetText( _rText
);
221 m_pToolbar
->SetItemText( (USHORT
)_nFeatureId
, _rText
);
224 //---------------------------------------------------------------------
225 void NavigationToolBar::implInit( )
227 m_pToolbar
= new ImplNavToolBar( this );
228 m_pToolbar
->SetOutStyle( TOOLBOX_STYLE_FLAT
);
231 // need the SfxApplication for retrieving informations about our
232 // items. We could duplicate all the information here in our lib
233 // (such as the item text and the image), but why should we?
235 struct SlotDescription
240 } aSupportedSlots
[] =
242 { LID_RECORD_LABEL
, false, true },
243 { SID_FM_RECORD_ABSOLUTE
, false, true },
244 { LID_RECORD_FILLER
, false, true },
245 { SID_FM_RECORD_TOTAL
, false, true },
247 { SID_FM_RECORD_FIRST
, true, false },
248 { SID_FM_RECORD_PREV
, true, false },
249 { SID_FM_RECORD_NEXT
, true, false },
250 { SID_FM_RECORD_LAST
, true, false },
252 { SID_FM_RECORD_SAVE
, false, false },
253 { SID_FM_RECORD_UNDO
, false, false },
254 { SID_FM_RECORD_NEW
, false, false },
255 { SID_FM_RECORD_DELETE
, false, false },
256 { SID_FM_REFRESH
, false, false },
257 { SID_FM_REFRESH_FORM_CONTROL
, false, false },
259 { SID_FM_SORTUP
, false, false },
260 { SID_FM_SORTDOWN
, false, false },
261 { SID_FM_ORDERCRIT
, false, false },
262 { SID_FM_AUTOFILTER
, false, false },
263 { SID_FM_FILTERCRIT
, false, false },
264 { SID_FM_FORM_FILTERED
, false, false },
265 { SID_FM_REMOVE_FILTER_SORT
, false, false },
268 size_t nSupportedSlots
= sizeof( aSupportedSlots
) / sizeof( aSupportedSlots
[0] );
269 SlotDescription
* pSupportedSlots
= aSupportedSlots
;
270 SlotDescription
* pSupportedSlotsEnd
= aSupportedSlots
+ nSupportedSlots
;
271 for ( ; pSupportedSlots
< pSupportedSlotsEnd
; ++pSupportedSlots
)
273 if ( pSupportedSlots
->nId
)
274 { // it's _not_ a separator
276 // the text(s) of the item
278 String sItemHelpText
;
280 // TODO/CLEANUP: this code does nothing(!) nowadays
281 //SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( NULL );
282 //sItemText = rSlotPool.GetSlotName( pSupportedSlots->nId, &sItemHelpText );
285 m_pToolbar
->InsertItem( pSupportedSlots
->nId
, sItemText
, pSupportedSlots
->bRepeat
? TIB_REPEAT
: 0 );
286 m_pToolbar
->SetQuickHelpText( pSupportedSlots
->nId
, sItemHelpText
);
287 if ( isSfxSlot( pSupportedSlots
->nId
) )
288 m_pToolbar
->SetHelpId( pSupportedSlots
->nId
, pSupportedSlots
->nId
);
291 if ( pSupportedSlots
->bItemWindow
)
293 Window
* pItemWindow
= NULL
;
294 if ( SID_FM_RECORD_ABSOLUTE
== pSupportedSlots
->nId
)
296 pItemWindow
= new RecordPositionInput( m_pToolbar
);
297 static_cast< RecordPositionInput
* >( pItemWindow
)->setDispatcher( m_pDispatcher
);
299 else if ( LID_RECORD_FILLER
== pSupportedSlots
->nId
)
301 pItemWindow
= new FixedText( m_pToolbar
, WB_CENTER
| WB_VCENTER
);
302 pItemWindow
->SetBackground(Wallpaper(Color(COL_TRANSPARENT
)));
306 pItemWindow
= new FixedText( m_pToolbar
, WB_VCENTER
);
307 pItemWindow
->SetBackground();
308 pItemWindow
->SetPaintTransparent(TRUE
);
310 m_aChildWins
.push_back( pItemWindow
);
312 switch ( pSupportedSlots
->nId
)
314 case LID_RECORD_LABEL
:
315 pItemWindow
->SetText( getLabelString( RID_STR_LABEL_RECORD
) );
318 case LID_RECORD_FILLER
:
319 pItemWindow
->SetText( getLabelString( RID_STR_LABEL_OF
) );
323 m_pToolbar
->SetItemWindow( pSupportedSlots
->nId
, pItemWindow
);
328 m_pToolbar
->InsertSeparator( );
332 forEachItemWindow( &NavigationToolBar::adjustItemWindowWidth
, NULL
);
334 // the image of the item
335 ::std::auto_ptr
< SfxImageManager
> pImageManager( new SfxImageManager( NULL
) );
336 pImageManager
->SetImagesForceSize( *m_pToolbar
, FALSE
, m_eImageSize
== eLarge
);
338 // parts of our layout is dependent on the size of our icons
342 //---------------------------------------------------------------------
343 void NavigationToolBar::implSetImageSize( ImageSize _eSize
, bool _bForce
)
345 if ( ( _eSize
!= m_eImageSize
) || _bForce
)
347 m_eImageSize
= _eSize
;
348 ::std::auto_ptr
< SfxImageManager
> pImageManager( new SfxImageManager( NULL
) );
349 pImageManager
->SetImagesForceSize( *m_pToolbar
, lcl_isHighContrast( GetBackground().GetColor() ), m_eImageSize
== eLarge
);
351 // parts of our layout is dependent on the size of our icons
356 //---------------------------------------------------------------------
357 void NavigationToolBar::SetImageSize( ImageSize _eSize
)
359 implSetImageSize( _eSize
);
362 //---------------------------------------------------------------------
363 void NavigationToolBar::ShowFunctionGroup( FunctionGroup _eGroup
, bool _bShow
)
365 const USHORT
* pGroupIds
= NULL
;
371 static const USHORT aPositionIds
[] = {
372 LID_RECORD_LABEL
, SID_FM_RECORD_ABSOLUTE
, LID_RECORD_FILLER
, SID_FM_RECORD_TOTAL
, 0
374 pGroupIds
= aPositionIds
;
379 static const USHORT aNavigationIds
[] = {
380 SID_FM_RECORD_FIRST
, SID_FM_RECORD_PREV
, SID_FM_RECORD_NEXT
, SID_FM_RECORD_LAST
, 0
382 pGroupIds
= aNavigationIds
;
387 static const USHORT aActionIds
[] = {
388 SID_FM_RECORD_SAVE
, SID_FM_RECORD_UNDO
, SID_FM_RECORD_NEW
, SID_FM_RECORD_DELETE
, SID_FM_REFRESH
, SID_FM_REFRESH_FORM_CONTROL
, 0
390 pGroupIds
= aActionIds
;
395 static const USHORT aFilterSortIds
[] = {
396 SID_FM_SORTUP
, SID_FM_SORTDOWN
, SID_FM_ORDERCRIT
, SID_FM_AUTOFILTER
, SID_FM_FILTERCRIT
, SID_FM_FORM_FILTERED
, SID_FM_REMOVE_FILTER_SORT
, 0
398 pGroupIds
= aFilterSortIds
;
402 OSL_ENSURE( sal_False
, "NavigationToolBar::ShowFunctionGroup: invalid group id!" );
407 m_pToolbar
->ShowItem( *pGroupIds
++, _bShow
);
410 //---------------------------------------------------------------------
411 bool NavigationToolBar::IsFunctionGroupVisible( FunctionGroup _eGroup
)
413 USHORT nIndicatorItem
= 0;
416 case ePosition
: nIndicatorItem
= LID_RECORD_LABEL
; break;
417 case eNavigation
: nIndicatorItem
= SID_FM_RECORD_FIRST
; break;
418 case eRecordActions
: nIndicatorItem
= SID_FM_RECORD_SAVE
; break;
419 case eFilterSort
: nIndicatorItem
= SID_FM_SORTUP
; break;
421 OSL_ENSURE( sal_False
, "NavigationToolBar::IsFunctionGroupVisible: invalid group id!" );
424 return m_pToolbar
->IsItemVisible( nIndicatorItem
);
427 //------------------------------------------------------------------------------
428 void NavigationToolBar::StateChanged( StateChangedType nType
)
430 Window::StateChanged( nType
);
434 case STATE_CHANGE_ZOOM
:
435 // m_pToolbar->SetZoom( GetZoom() );
436 // forEachItemWindow( setItemWindowZoom, NULL );
437 // the ToolBox class is not zoomable at the moment, so
438 // we better have no zoom at all instead of only half a zoom ...
441 case STATE_CHANGE_CONTROLFONT
:
442 forEachItemWindow( &NavigationToolBar::setItemControlFont
, NULL
);
443 forEachItemWindow( &NavigationToolBar::adjustItemWindowWidth
, NULL
);
446 case STATE_CHANGE_CONTROLFOREGROUND
:
447 forEachItemWindow( &NavigationToolBar::setItemControlForeground
, NULL
);
450 case STATE_CHANGE_MIRRORING
:
452 BOOL
bIsRTLEnabled( IsRTLEnabled() );
453 m_pToolbar
->EnableRTL( bIsRTLEnabled
);
454 forEachItemWindow( &NavigationToolBar::enableItemRTL
, &bIsRTLEnabled
);
461 //---------------------------------------------------------------------
462 void NavigationToolBar::Resize()
464 // resize/position the toolbox as a whole
465 sal_Int32 nToolbarHeight
= m_pToolbar
->CalcWindowSizePixel().Height();
467 sal_Int32 nMyHeight
= GetOutputSizePixel().Height();
468 m_pToolbar
->SetPosSizePixel( Point( 0, ( nMyHeight
- nToolbarHeight
) / 2 ),
469 Size( GetSizePixel().Width(), nToolbarHeight
) );
474 //---------------------------------------------------------------------
475 void NavigationToolBar::SetControlBackground()
477 Window::SetControlBackground();
478 m_pToolbar
->SetControlBackground();
479 forEachItemWindow( &NavigationToolBar::setItemBackground
, NULL
);
481 // the contrast of the background color may have changed, so force
482 // the images to be rebuild (high contrast requires a possibly different
484 implSetImageSize( m_eImageSize
, true );
487 //---------------------------------------------------------------------
488 void NavigationToolBar::SetControlBackground( const Color
& _rColor
)
490 Window::SetControlBackground( _rColor
);
491 m_pToolbar
->SetControlBackground( _rColor
);
492 forEachItemWindow( &NavigationToolBar::setItemBackground
, &_rColor
);
494 // the contrast of the background color may have changed, so force
495 // the images to be rebuild (high contrast requires a possibly different
497 implSetImageSize( m_eImageSize
, true );
500 //---------------------------------------------------------------------
501 void NavigationToolBar::SetTextLineColor( )
503 Window::SetTextLineColor( );
504 m_pToolbar
->SetTextLineColor( );
505 forEachItemWindow( &NavigationToolBar::setTextLineColor
, NULL
);
508 //---------------------------------------------------------------------
509 void NavigationToolBar::SetTextLineColor( const Color
& _rColor
)
511 Window::SetTextLineColor( _rColor
);
512 m_pToolbar
->SetTextLineColor( _rColor
);
513 forEachItemWindow( &NavigationToolBar::setTextLineColor
, &_rColor
);
516 //---------------------------------------------------------------------
517 void NavigationToolBar::forEachItemWindow( ItemWindowHandler _handler
, const void* _pParam
)
519 for ( USHORT item
= 0; item
< m_pToolbar
->GetItemCount(); ++item
)
521 USHORT nItemId
= m_pToolbar
->GetItemId( item
);
522 Window
* pItemWindow
= m_pToolbar
->GetItemWindow( nItemId
);
524 (this->*_handler
)( nItemId
, pItemWindow
, _pParam
);
528 //---------------------------------------------------------------------
529 void NavigationToolBar::setItemBackground( USHORT
/* _nItemId */, Window
* _pItemWindow
, const void* _pColor
) const
532 _pItemWindow
->SetControlBackground( *static_cast< const Color
* >( _pColor
) );
534 _pItemWindow
->SetControlBackground();
537 //---------------------------------------------------------------------
538 void NavigationToolBar::setTextLineColor( USHORT
/* _nItemId */, Window
* _pItemWindow
, const void* _pColor
) const
541 _pItemWindow
->SetTextLineColor( *static_cast< const Color
* >( _pColor
) );
543 _pItemWindow
->SetTextLineColor();
546 //---------------------------------------------------------------------
547 void NavigationToolBar::setItemWindowZoom( USHORT
/* _nItemId */, Window
* _pItemWindow
, const void* /* _pParam */ ) const
549 _pItemWindow
->SetZoom( GetZoom() );
550 _pItemWindow
->SetZoomedPointFont( IsControlFont() ? GetControlFont() : GetPointFont() );
553 //---------------------------------------------------------------------
554 void NavigationToolBar::setItemControlFont( USHORT
/* _nItemId */, Window
* _pItemWindow
, const void* /* _pParam */ ) const
556 if ( IsControlFont() )
557 _pItemWindow
->SetControlFont( GetControlFont() );
559 _pItemWindow
->SetControlFont( );
562 //---------------------------------------------------------------------
563 void NavigationToolBar::setItemControlForeground( USHORT
/* _nItemId */, Window
* _pItemWindow
, const void* /* _pParam */ ) const
565 if ( IsControlForeground() )
566 _pItemWindow
->SetControlForeground( GetControlForeground() );
568 _pItemWindow
->SetControlForeground( );
569 _pItemWindow
->SetTextColor( GetTextColor() );
572 //---------------------------------------------------------------------
573 void NavigationToolBar::adjustItemWindowWidth( USHORT _nItemId
, Window
* _pItemWindow
, const void* /* _pParam */ ) const
578 case LID_RECORD_LABEL
:
579 sItemText
= getLabelString( RID_STR_LABEL_RECORD
);
582 case LID_RECORD_FILLER
:
583 sItemText
= getLabelString( RID_STR_LABEL_OF
);
586 case SID_FM_RECORD_ABSOLUTE
:
587 sItemText
= String::CreateFromAscii( "12345678" );
590 case SID_FM_RECORD_TOTAL
:
591 sItemText
= String::CreateFromAscii( "123456" );
595 Size
aSize( _pItemWindow
->GetTextWidth( sItemText
), /* _pItemWindow->GetSizePixel( ).Height() */ _pItemWindow
->GetTextHeight() + 4 );
597 _pItemWindow
->SetSizePixel( aSize
);
599 m_pToolbar
->SetItemWindow( _nItemId
, _pItemWindow
);
602 //---------------------------------------------------------------------
603 void NavigationToolBar::enableItemRTL( USHORT
/*_nItemId*/, Window
* _pItemWindow
, const void* _pIsRTLEnabled
) const
605 _pItemWindow
->EnableRTL( *static_cast< const BOOL
* >( _pIsRTLEnabled
) );
608 //=====================================================================
609 //= RecordPositionInput
610 //=====================================================================
611 //---------------------------------------------------------------------
612 RecordPositionInput::RecordPositionInput( Window
* _pParent
)
613 :NumericField( _pParent
, WB_BORDER
| WB_VCENTER
)
614 ,m_pDispatcher( NULL
)
619 SetDecimalDigits( 0 );
620 SetStrictFormat( TRUE
);
621 SetBorderStyle( WINDOW_BORDER_MONO
);
624 //---------------------------------------------------------------------
625 RecordPositionInput::~RecordPositionInput()
629 //---------------------------------------------------------------------
630 void RecordPositionInput::setDispatcher( const IFeatureDispatcher
* _pDispatcher
)
632 m_pDispatcher
= _pDispatcher
;
635 //---------------------------------------------------------------------
636 void RecordPositionInput::FirePosition( sal_Bool _bForce
)
638 if ( _bForce
|| ( GetText() != GetSavedValue() ) )
640 sal_Int64 nRecord
= GetValue();
641 if ( nRecord
< GetMin() || nRecord
> GetMax() )
645 m_pDispatcher
->dispatchWithArgument( SID_FM_RECORD_ABSOLUTE
, "Position", ::com::sun::star::uno::makeAny( (sal_Int32
)nRecord
) );
651 //---------------------------------------------------------------------
652 void RecordPositionInput::LoseFocus()
654 FirePosition( sal_False
);
657 //---------------------------------------------------------------------
658 void RecordPositionInput::KeyInput( const KeyEvent
& rKeyEvent
)
660 if( rKeyEvent
.GetKeyCode() == KEY_RETURN
&& GetText().Len() )
661 FirePosition( sal_True
);
663 NumericField::KeyInput( rKeyEvent
);
667 //.........................................................................
669 //.........................................................................