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 "navbarcontrol.hxx"
32 #include "frm_strings.hxx"
33 #include "frm_module.hxx"
34 #include "FormComponent.hxx"
35 #include "componenttools.hxx"
36 #include "navtoolbar.hxx"
37 #include "commandimageprovider.hxx"
38 #include "commanddescriptionprovider.hxx"
39 
40 /** === begin UNO includes === **/
41 #include <com/sun/star/awt/XView.hpp>
42 #include <com/sun/star/awt/PosSize.hpp>
43 #include <com/sun/star/form/runtime/FormFeature.hpp>
44 #include <com/sun/star/awt/XControlModel.hpp>
45 #include <com/sun/star/graphic/XGraphic.hpp>
46 /** === end UNO includes === **/
47 
48 #include <tools/debug.hxx>
49 #include <tools/diagnose_ex.h>
50 #include <vcl/svapp.hxx>
51 
52 //--------------------------------------------------------------------------
53 extern "C" void SAL_CALL createRegistryInfo_ONavigationBarControl()
54 {
55     static ::frm::OMultiInstanceAutoRegistration< ::frm::ONavigationBarControl > aAutoRegistration;
56 }
57 
58 //.........................................................................
59 namespace frm
60 {
61 //.........................................................................
62 
63     using namespace ::com::sun::star::uno;
64     using namespace ::com::sun::star::beans;
65     using namespace ::com::sun::star::awt;
66     using namespace ::com::sun::star::lang;
67     using namespace ::com::sun::star::frame;
68     using namespace ::com::sun::star::graphic;
69     namespace FormFeature = ::com::sun::star::form::runtime::FormFeature;
70 
71 #define FORWARD_TO_PEER_1( unoInterface, method, param1 )   \
72     Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY );   \
73     if ( xTypedPeer.is() )  \
74     {   \
75         xTypedPeer->method( param1 );  \
76     }
77 
78 #define FORWARD_TO_PEER_1_RET( returnType, unoInterface, method, param1 )   \
79     returnType aReturn; \
80     Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY );   \
81     if ( xTypedPeer.is() )  \
82     {   \
83         aReturn = xTypedPeer->method( param1 );  \
84     }   \
85     return aReturn;
86 
87 #define FORWARD_TO_PEER_3( unoInterface, method, param1, param2, param3 )   \
88     Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY );   \
89     if ( xTypedPeer.is() )  \
90     {   \
91         xTypedPeer->method( param1, param2, param3 );  \
92     }
93 
94 #define FORWARD_TO_PEER_3_RET( returnType, unoInterface, method, param1, param2, param3 )   \
95     returnType aReturn; \
96     Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY );   \
97     if ( xTypedPeer.is() )  \
98     {   \
99         aReturn = xTypedPeer->method( param1, param2, param3 );  \
100     }   \
101     return aReturn;
102 
103     //==================================================================
104     // ONavigationBarControl
105     //==================================================================
106     DBG_NAME( ONavigationBarControl )
107     //------------------------------------------------------------------
108     ONavigationBarControl::ONavigationBarControl( const Reference< XMultiServiceFactory >& _rxORB )
109         :UnoControl( _rxORB )
110     {
111         DBG_CTOR( ONavigationBarControl, NULL );
112     }
113 
114     //------------------------------------------------------------------
115     ONavigationBarControl::~ONavigationBarControl()
116     {
117         DBG_DTOR( ONavigationBarControl, NULL );
118     }
119 
120     //------------------------------------------------------------------
121     IMPLEMENT_FORWARD_XTYPEPROVIDER2( ONavigationBarControl, UnoControl, ONavigationBarControl_Base )
122 
123     //------------------------------------------------------------------
124     Any SAL_CALL ONavigationBarControl::queryAggregation( const Type& _rType ) throw ( RuntimeException )
125     {
126         Any aReturn = UnoControl::queryAggregation( _rType );
127 
128         if ( !aReturn.hasValue() )
129             aReturn = ONavigationBarControl_Base::queryInterface( _rType );
130 
131         return aReturn;
132     }
133 
134     //------------------------------------------------------------------
135     namespace
136     {
137         //..............................................................
138         static WinBits lcl_getWinBits_nothrow( const Reference< XControlModel >& _rxModel )
139         {
140             WinBits nBits = 0;
141             try
142             {
143                 Reference< XPropertySet > xProps( _rxModel, UNO_QUERY );
144                 if ( xProps.is() )
145                 {
146                     sal_Int16 nBorder = 0;
147                     xProps->getPropertyValue( PROPERTY_BORDER ) >>= nBorder;
148                     if ( nBorder )
149                         nBits |= WB_BORDER;
150 
151                     sal_Bool bTabStop = sal_False;
152                     if ( xProps->getPropertyValue( PROPERTY_TABSTOP ) >>= bTabStop )
153                         nBits |= ( bTabStop ? WB_TABSTOP : WB_NOTABSTOP );
154                 }
155             }
156             catch( const Exception& )
157             {
158                 DBG_UNHANDLED_EXCEPTION();
159             }
160             return nBits;
161         }
162     }
163 
164     //------------------------------------------------------------------
165     void SAL_CALL ONavigationBarControl::createPeer( const Reference< XToolkit >& /*_rToolkit*/, const Reference< XWindowPeer >& _rParentPeer ) throw( RuntimeException )
166     {
167     	::vos::OGuard aGuard( Application::GetSolarMutex() );
168 
169 	    if (!getPeer().is())
170 	    {
171 		    mbCreatingPeer = sal_True;
172 
173             // determine the VLC window for the parent
174 		    Window* pParentWin = NULL;
175 		    if ( _rParentPeer.is() )
176 		    {
177 			    VCLXWindow* pParentXWin = VCLXWindow::GetImplementation( _rParentPeer );
178 			    if ( pParentXWin )
179 				    pParentWin = pParentXWin->GetWindow();
180                 DBG_ASSERT( pParentWin, "ONavigationBarControl::createPeer: could not obtain the VCL-level parent window!" );
181 		    }
182 
183             // create the peer
184             ONavigationBarPeer* pPeer = ONavigationBarPeer::Create( maContext.getLegacyServiceFactory(), pParentWin, getModel() );
185             DBG_ASSERT( pPeer, "ONavigationBarControl::createPeer: invalid peer returned!" );
186             if ( pPeer )
187                 // by definition, the returned component is aquired once
188                 pPeer->release();
189 
190             // announce the peer to the base class
191             setPeer( pPeer );
192 
193             // initialize ourself (and thus the peer) with the model properties
194     		updateFromModel();
195 
196             Reference< XView >  xPeerView( getPeer(), UNO_QUERY );
197             if ( xPeerView.is() )
198             {
199 			    xPeerView->setZoom( maComponentInfos.nZoomX, maComponentInfos.nZoomY );
200 			    xPeerView->setGraphics( mxGraphics );
201             }
202 
203             // a lot of initial settings from our component infos
204 	        setPosSize( maComponentInfos.nX, maComponentInfos.nY, maComponentInfos.nWidth, maComponentInfos.nHeight, PosSize::POSSIZE );
205 
206             pPeer->setVisible   ( maComponentInfos.bVisible && !mbDesignMode );
207             pPeer->setEnable    ( maComponentInfos.bEnable                   );
208             pPeer->setDesignMode( mbDesignMode                               );
209 
210             peerCreated();
211 
212 		    mbCreatingPeer = sal_False;
213 
214             OControl::initFormControlPeer( getPeer() );
215         }
216     }
217 
218     //------------------------------------------------------------------
219     ::rtl::OUString	SAL_CALL ONavigationBarControl::getImplementationName()  throw( RuntimeException )
220     {
221         return getImplementationName_Static();
222     }
223 
224     //------------------------------------------------------------------
225     Sequence< ::rtl::OUString > SAL_CALL ONavigationBarControl::getSupportedServiceNames()  throw( RuntimeException )
226     {
227         return getSupportedServiceNames_Static();
228     }
229 
230     //------------------------------------------------------------------
231     ::rtl::OUString	SAL_CALL ONavigationBarControl::getImplementationName_Static()
232     {
233         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.form.ONavigationBarControl" ) );
234     }
235 
236     //------------------------------------------------------------------
237     Sequence< ::rtl::OUString > SAL_CALL ONavigationBarControl::getSupportedServiceNames_Static()
238     {
239         Sequence< ::rtl::OUString > aServices( 2 );
240         aServices[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControl" ) );
241         aServices[ 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.control.NavigationToolBar" ) );
242         return aServices;
243     }
244 
245     //------------------------------------------------------------------
246     Reference< XInterface > SAL_CALL ONavigationBarControl::Create( const Reference< XMultiServiceFactory >& _rxFactory )
247     {
248         return *( new ONavigationBarControl( _rxFactory ) );
249     }
250 
251     //------------------------------------------------------------------
252     void SAL_CALL ONavigationBarControl::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
253     {
254         FORWARD_TO_PEER_1( XDispatchProviderInterception, registerDispatchProviderInterceptor, _rxInterceptor );
255     }
256 
257     //------------------------------------------------------------------
258     void SAL_CALL ONavigationBarControl::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
259     {
260         FORWARD_TO_PEER_1( XDispatchProviderInterception, releaseDispatchProviderInterceptor, _rxInterceptor );
261     }
262 
263     //------------------------------------------------------------------
264     void SAL_CALL ONavigationBarControl::setDesignMode( sal_Bool _bOn ) throw( RuntimeException )
265     {
266         UnoControl::setDesignMode( _bOn );
267         FORWARD_TO_PEER_1( XVclWindowPeer, setDesignMode, _bOn );
268     }
269 
270     //==================================================================
271     // ONavigationBarPeer
272     //==================================================================
273     DBG_NAME( ONavigationBarPeer )
274     //------------------------------------------------------------------
275     ONavigationBarPeer* ONavigationBarPeer::Create( const Reference< XMultiServiceFactory >& _rxORB,
276         Window* _pParentWindow, const Reference< XControlModel >& _rxModel )
277     {
278         DBG_TESTSOLARMUTEX();
279 
280         // the peer itself
281         ONavigationBarPeer* pPeer = new ONavigationBarPeer( _rxORB );
282         pPeer->acquire();   // by definition, the returned object is aquired once
283 
284         // the VCL control for the peer
285         Reference< XModel > xContextDocument( getXModel( _rxModel ) );
286         NavigationToolBar* pNavBar = new NavigationToolBar(
287             _pParentWindow,
288             lcl_getWinBits_nothrow( _rxModel ),
289             createDocumentCommandImageProvider( _rxORB, xContextDocument ),
290             createDocumentCommandDescriptionProvider( _rxORB, xContextDocument )
291         );
292 
293         // some knittings
294         pNavBar->setDispatcher( pPeer );
295         pNavBar->SetComponentInterface( pPeer );
296 
297         // we want a faster repeating rate for the slots in this
298         // toolbox
299 	    AllSettings	aSettings = pNavBar->GetSettings();
300 	    MouseSettings aMouseSettings = aSettings.GetMouseSettings();
301 	    aMouseSettings.SetButtonRepeat( 10 );
302 	    aSettings.SetMouseSettings( aMouseSettings );
303 	    pNavBar->SetSettings( aSettings, sal_True );
304 
305         // outta here
306         return pPeer;
307     }
308 
309     //------------------------------------------------------------------
310     ONavigationBarPeer::ONavigationBarPeer( const Reference< XMultiServiceFactory >& _rxORB )
311         :OFormNavigationHelper( _rxORB )
312     {
313         DBG_CTOR( ONavigationBarPeer, NULL );
314     }
315 
316     //------------------------------------------------------------------
317     ONavigationBarPeer::~ONavigationBarPeer()
318     {
319         DBG_DTOR( ONavigationBarPeer, NULL );
320     }
321 
322     //------------------------------------------------------------------
323     IMPLEMENT_FORWARD_XINTERFACE2( ONavigationBarPeer, VCLXWindow, OFormNavigationHelper )
324 
325     //------------------------------------------------------------------
326     IMPLEMENT_FORWARD_XTYPEPROVIDER2( ONavigationBarPeer, VCLXWindow, OFormNavigationHelper )
327 
328     //------------------------------------------------------------------
329     void SAL_CALL ONavigationBarPeer::dispose(  ) throw( RuntimeException )
330     {
331         VCLXWindow::dispose();
332         OFormNavigationHelper::dispose();
333     }
334 
335     //------------------------------------------------------------------
336     void SAL_CALL ONavigationBarPeer::setProperty( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw( RuntimeException )
337     {
338     	::vos::OGuard aGuard( Application::GetSolarMutex() );
339 
340     	NavigationToolBar* pNavBar = static_cast< NavigationToolBar* >( GetWindow() );
341         if ( !pNavBar )
342         {
343             VCLXWindow::setProperty( _rPropertyName, _rValue );
344             return;
345         }
346 
347         bool bVoid = !_rValue.hasValue();
348 
349         sal_Bool  bBoolValue = sal_False;
350         sal_Int32 nColor = COL_TRANSPARENT;
351 
352         // TODO: more generic mechanisms for this (the grid control implementation,
353         // when used herein, will do the same stuff for lot of these)
354 
355         if ( _rPropertyName.equals( PROPERTY_BACKGROUNDCOLOR ) )
356         {
357             Wallpaper aTest = pNavBar->GetBackground();
358 		    if ( bVoid )
359 		    {
360 			    pNavBar->SetBackground( pNavBar->GetSettings().GetStyleSettings().GetFaceColor() );
361 			    pNavBar->SetControlBackground();
362 		    }
363 		    else
364 		    {
365                 OSL_VERIFY( _rValue >>= nColor );
366 			    Color aColor( nColor );
367 			    pNavBar->SetBackground( aColor );
368 			    pNavBar->SetControlBackground( aColor );
369 		    }
370         }
371         else if ( _rPropertyName.equals( PROPERTY_TEXTLINECOLOR ) )
372         {
373 		    if ( bVoid )
374 		    {
375 			    pNavBar->SetTextLineColor();
376 		    }
377 		    else
378 		    {
379                 OSL_VERIFY( _rValue >>= nColor );
380 			    Color aColor( nColor );
381                 pNavBar->SetTextLineColor( nColor );
382             }
383         }
384         else if ( _rPropertyName.equals( PROPERTY_ICONSIZE ) )
385         {
386             sal_Int16 nInt16Value = 0;
387             OSL_VERIFY( _rValue >>= nInt16Value );
388             pNavBar->SetImageSize( nInt16Value ? NavigationToolBar::eLarge : NavigationToolBar::eSmall );
389         }
390         else if ( _rPropertyName.equals( PROPERTY_SHOW_POSITION ) )
391         {
392             OSL_VERIFY( _rValue >>= bBoolValue );
393             pNavBar->ShowFunctionGroup( NavigationToolBar::ePosition, bBoolValue );
394         }
395         else if ( _rPropertyName.equals( PROPERTY_SHOW_NAVIGATION ) )
396         {
397             OSL_VERIFY( _rValue >>= bBoolValue );
398             pNavBar->ShowFunctionGroup( NavigationToolBar::eNavigation, bBoolValue );
399         }
400         else if ( _rPropertyName.equals( PROPERTY_SHOW_RECORDACTIONS ) )
401         {
402             OSL_VERIFY( _rValue >>= bBoolValue );
403             pNavBar->ShowFunctionGroup( NavigationToolBar::eRecordActions, bBoolValue );
404         }
405         else if ( _rPropertyName.equals( PROPERTY_SHOW_FILTERSORT ) )
406         {
407             OSL_VERIFY( _rValue >>= bBoolValue );
408             pNavBar->ShowFunctionGroup( NavigationToolBar::eFilterSort, bBoolValue );
409         }
410         else
411         {
412             VCLXWindow::setProperty( _rPropertyName, _rValue );
413         }
414     }
415 
416     //------------------------------------------------------------------
417     Any SAL_CALL ONavigationBarPeer::getProperty( const ::rtl::OUString& _rPropertyName ) throw( RuntimeException )
418     {
419     	::vos::OGuard aGuard( Application::GetSolarMutex() );
420 
421         Any aReturn;
422     	NavigationToolBar* pNavBar = static_cast< NavigationToolBar* >( GetWindow() );
423 
424         if ( _rPropertyName.equals( PROPERTY_BACKGROUNDCOLOR ) )
425         {
426             aReturn <<= (sal_Int32)pNavBar->GetControlBackground().GetColor();
427         }
428         else if ( _rPropertyName.equals( PROPERTY_TEXTLINECOLOR ) )
429         {
430             aReturn <<= (sal_Int32)pNavBar->GetTextLineColor().GetColor();
431         }
432         else if ( _rPropertyName.equals( PROPERTY_ICONSIZE ) )
433         {
434             sal_Int16 nIconType = ( NavigationToolBar::eLarge == pNavBar->GetImageSize() )
435                                 ? 1 : 0;
436             aReturn <<= nIconType;
437         }
438         else if ( _rPropertyName.equals( PROPERTY_SHOW_POSITION ) )
439         {
440             aReturn <<= (sal_Bool)( pNavBar->IsFunctionGroupVisible( NavigationToolBar::ePosition ) );
441         }
442         else if ( _rPropertyName.equals( PROPERTY_SHOW_NAVIGATION ) )
443         {
444             aReturn <<= (sal_Bool)( pNavBar->IsFunctionGroupVisible( NavigationToolBar::eNavigation ) );
445         }
446         else if ( _rPropertyName.equals( PROPERTY_SHOW_RECORDACTIONS ) )
447         {
448             aReturn <<= (sal_Bool)( pNavBar->IsFunctionGroupVisible( NavigationToolBar::eRecordActions ) );
449         }
450         else if ( _rPropertyName.equals( PROPERTY_SHOW_FILTERSORT ) )
451         {
452             aReturn <<= (sal_Bool)( pNavBar->IsFunctionGroupVisible( NavigationToolBar::eFilterSort ) );
453         }
454         else
455             aReturn = VCLXWindow::getProperty( _rPropertyName );
456 
457         return aReturn;
458     }
459 
460     //------------------------------------------------------------------
461     void ONavigationBarPeer::interceptorsChanged( )
462     {
463 		if ( isDesignMode() )
464             // not interested in if we're in design mode
465             return;
466 
467         OFormNavigationHelper::interceptorsChanged();
468     }
469 
470     //------------------------------------------------------------------
471     void ONavigationBarPeer::featureStateChanged( sal_Int16 _nFeatureId, sal_Bool _bEnabled )
472     {
473         // enable this button on the toolbox
474         NavigationToolBar* pNavBar = static_cast< NavigationToolBar* >( GetWindow() );
475         if ( pNavBar )
476         {
477             pNavBar->enableFeature( _nFeatureId, _bEnabled );
478 
479             // is it a feature with additional state information?
480             if ( _nFeatureId == FormFeature::ToggleApplyFilter )
481             {   // additional boolean state
482                 pNavBar->checkFeature( _nFeatureId, getBooleanState( _nFeatureId ) );
483             }
484             else if ( _nFeatureId == FormFeature::TotalRecords )
485             {
486                 pNavBar->setFeatureText( _nFeatureId, getStringState( _nFeatureId ) );
487             }
488             else if ( _nFeatureId == FormFeature::MoveAbsolute )
489             {
490                 pNavBar->setFeatureText( _nFeatureId, String::CreateFromInt32( getIntegerState( _nFeatureId ) ) );
491             }
492         }
493 
494         // base class
495         OFormNavigationHelper::featureStateChanged( _nFeatureId, _bEnabled );
496     }
497 
498     //------------------------------------------------------------------
499     void ONavigationBarPeer::allFeatureStatesChanged( )
500     {
501         // force the control to update it's states
502     	NavigationToolBar* pNavBar = static_cast< NavigationToolBar* >( GetWindow() );
503         if ( pNavBar )
504             pNavBar->setDispatcher( this );
505 
506         // base class
507         OFormNavigationHelper::allFeatureStatesChanged( );
508     }
509 
510     //------------------------------------------------------------------
511     bool ONavigationBarPeer::isEnabled( sal_Int16 _nFeatureId ) const
512     {
513         if ( const_cast< ONavigationBarPeer* >( this )->isDesignMode() )
514            return false;
515 
516         return OFormNavigationHelper::isEnabled( _nFeatureId );
517     }
518 
519     //------------------------------------------------------------------
520     void SAL_CALL ONavigationBarPeer::setDesignMode( sal_Bool _bOn ) throw( RuntimeException )
521     {
522         VCLXWindow::setDesignMode( _bOn  );
523 
524         if ( _bOn )
525 		    disconnectDispatchers();
526 	    else
527 		    connectDispatchers();
528             // this will connect if not already connected and just update else
529     }
530 
531     //------------------------------------------------------------------
532     void SAL_CALL ONavigationBarPeer::disposing( const EventObject& _rSource ) throw (RuntimeException)
533     {
534         VCLXWindow::disposing( _rSource );
535         OFormNavigationHelper::disposing( _rSource );
536     }
537 
538     //------------------------------------------------------------------
539     void ONavigationBarPeer::getSupportedFeatures( ::std::vector< sal_Int16 >& _rFeatureIds )
540     {
541         _rFeatureIds.push_back( FormFeature::MoveAbsolute );
542         _rFeatureIds.push_back( FormFeature::TotalRecords );
543         _rFeatureIds.push_back( FormFeature::MoveToFirst );
544         _rFeatureIds.push_back( FormFeature::MoveToPrevious );
545         _rFeatureIds.push_back( FormFeature::MoveToNext );
546         _rFeatureIds.push_back( FormFeature::MoveToLast );
547         _rFeatureIds.push_back( FormFeature::SaveRecordChanges );
548         _rFeatureIds.push_back( FormFeature::UndoRecordChanges );
549         _rFeatureIds.push_back( FormFeature::MoveToInsertRow );
550         _rFeatureIds.push_back( FormFeature::DeleteRecord );
551         _rFeatureIds.push_back( FormFeature::ReloadForm );
552         _rFeatureIds.push_back( FormFeature::RefreshCurrentControl );
553         _rFeatureIds.push_back( FormFeature::SortAscending );
554         _rFeatureIds.push_back( FormFeature::SortDescending );
555         _rFeatureIds.push_back( FormFeature::InteractiveSort );
556         _rFeatureIds.push_back( FormFeature::AutoFilter );
557         _rFeatureIds.push_back( FormFeature::InteractiveFilter );
558         _rFeatureIds.push_back( FormFeature::ToggleApplyFilter );
559         _rFeatureIds.push_back( FormFeature::RemoveFilterAndSort );
560     }
561 
562 //.........................................................................
563 }   // namespace frm
564 //.........................................................................
565