1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21 #include "navbarcontrol.hxx"
22 #include <frm_strings.hxx>
23 #include <componenttools.hxx>
24 #include <navtoolbar.hxx>
25 #include <commandimageprovider.hxx>
26
27 #include <com/sun/star/awt/XView.hpp>
28 #include <com/sun/star/awt/PosSize.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/form/runtime/FormFeature.hpp>
31 #include <com/sun/star/awt/XControlModel.hpp>
32 #include <com/sun/star/frame/ModuleManager.hpp>
33
34 #include <tools/debug.hxx>
35 #include <tools/diagnose_ex.h>
36 #include <vcl/svapp.hxx>
37 #include <vcl/settings.hxx>
38
39
40 namespace frm
41 {
42
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::beans;
45 using namespace ::com::sun::star::awt;
46 using namespace ::com::sun::star::lang;
47 using namespace ::com::sun::star::frame;
48 using namespace ::com::sun::star::graphic;
49 namespace FormFeature = ::com::sun::star::form::runtime::FormFeature;
50
51 #define FORWARD_TO_PEER_1( unoInterface, method, param1 ) \
52 Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
53 if ( xTypedPeer.is() ) \
54 { \
55 xTypedPeer->method( param1 ); \
56 }
57
ONavigationBarControl(const Reference<XComponentContext> & _rxORB)58 ONavigationBarControl::ONavigationBarControl( const Reference< XComponentContext >& _rxORB)
59 :UnoControl(), m_xContext(_rxORB)
60 {
61 }
62
63
~ONavigationBarControl()64 ONavigationBarControl::~ONavigationBarControl()
65 {
66 }
67
68
IMPLEMENT_FORWARD_XTYPEPROVIDER2(ONavigationBarControl,UnoControl,ONavigationBarControl_Base)69 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ONavigationBarControl, UnoControl, ONavigationBarControl_Base )
70
71
72 Any SAL_CALL ONavigationBarControl::queryAggregation( const Type& _rType )
73 {
74 Any aReturn = UnoControl::queryAggregation( _rType );
75
76 if ( !aReturn.hasValue() )
77 aReturn = ONavigationBarControl_Base::queryInterface( _rType );
78
79 return aReturn;
80 }
81
82
83 namespace
84 {
85
lcl_getWinBits_nothrow(const Reference<XControlModel> & _rxModel)86 WinBits lcl_getWinBits_nothrow( const Reference< XControlModel >& _rxModel )
87 {
88 WinBits nBits = 0;
89 try
90 {
91 Reference< XPropertySet > xProps( _rxModel, UNO_QUERY );
92 if ( xProps.is() )
93 {
94 sal_Int16 nBorder = 0;
95 xProps->getPropertyValue( PROPERTY_BORDER ) >>= nBorder;
96 if ( nBorder )
97 nBits |= WB_BORDER;
98
99 bool bTabStop = false;
100 if ( xProps->getPropertyValue( PROPERTY_TABSTOP ) >>= bTabStop )
101 nBits |= ( bTabStop ? WB_TABSTOP : WB_NOTABSTOP );
102 }
103 }
104 catch( const Exception& )
105 {
106 DBG_UNHANDLED_EXCEPTION("forms.component");
107 }
108 return nBits;
109 }
110 }
111
112
createPeer(const Reference<XToolkit> &,const Reference<XWindowPeer> & _rParentPeer)113 void SAL_CALL ONavigationBarControl::createPeer( const Reference< XToolkit >& /*_rToolkit*/, const Reference< XWindowPeer >& _rParentPeer )
114 {
115 SolarMutexGuard aGuard;
116
117 if (getPeer().is())
118 return;
119
120 mbCreatingPeer = true;
121
122 // determine the VCL window for the parent
123 vcl::Window* pParentWin = nullptr;
124 if ( _rParentPeer.is() )
125 {
126 VCLXWindow* pParentXWin = comphelper::getUnoTunnelImplementation<VCLXWindow>( _rParentPeer );
127 if ( pParentXWin )
128 pParentWin = pParentXWin->GetWindow();
129 DBG_ASSERT( pParentWin, "ONavigationBarControl::createPeer: could not obtain the VCL-level parent window!" );
130 }
131
132 // create the peer
133 rtl::Reference<ONavigationBarPeer> pPeer = ONavigationBarPeer::Create( m_xContext, pParentWin, getModel() );
134 assert(pPeer && "ONavigationBarControl::createPeer: invalid peer returned!");
135
136 // announce the peer to the base class
137 setPeer( pPeer );
138
139 // initialize ourself (and thus the peer) with the model properties
140 updateFromModel();
141
142 Reference< XView > xPeerView( getPeer(), UNO_QUERY );
143 if ( xPeerView.is() )
144 {
145 xPeerView->setZoom( maComponentInfos.nZoomX, maComponentInfos.nZoomY );
146 xPeerView->setGraphics( mxGraphics );
147 }
148
149 // a lot of initial settings from our component infos
150 setPosSize( maComponentInfos.nX, maComponentInfos.nY, maComponentInfos.nWidth, maComponentInfos.nHeight, PosSize::POSSIZE );
151
152 pPeer->setVisible ( maComponentInfos.bVisible && !mbDesignMode );
153 pPeer->setEnable ( maComponentInfos.bEnable );
154 pPeer->setDesignMode( mbDesignMode );
155
156 peerCreated();
157
158 mbCreatingPeer = false;
159 }
160
161
getImplementationName()162 OUString SAL_CALL ONavigationBarControl::getImplementationName()
163 {
164 return "com.sun.star.comp.form.ONavigationBarControl";
165 }
166
167
getSupportedServiceNames()168 Sequence< OUString > SAL_CALL ONavigationBarControl::getSupportedServiceNames()
169 {
170 return { "com.sun.star.awt.UnoControl",
171 "com.sun.star.form.control.NavigationToolBar" };
172 }
173
174
registerDispatchProviderInterceptor(const Reference<XDispatchProviderInterceptor> & _rxInterceptor)175 void SAL_CALL ONavigationBarControl::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor )
176 {
177 FORWARD_TO_PEER_1( XDispatchProviderInterception, registerDispatchProviderInterceptor, _rxInterceptor );
178 }
179
180
releaseDispatchProviderInterceptor(const Reference<XDispatchProviderInterceptor> & _rxInterceptor)181 void SAL_CALL ONavigationBarControl::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor )
182 {
183 FORWARD_TO_PEER_1( XDispatchProviderInterception, releaseDispatchProviderInterceptor, _rxInterceptor );
184 }
185
186
setDesignMode(sal_Bool _bOn)187 void SAL_CALL ONavigationBarControl::setDesignMode( sal_Bool _bOn )
188 {
189 UnoControl::setDesignMode( _bOn );
190 FORWARD_TO_PEER_1( XVclWindowPeer, setDesignMode, _bOn );
191 }
192
193
194 // ONavigationBarPeer
195
196
Create(const Reference<XComponentContext> & _rxORB,vcl::Window * _pParentWindow,const Reference<XControlModel> & _rxModel)197 rtl::Reference<ONavigationBarPeer> ONavigationBarPeer::Create( const Reference< XComponentContext >& _rxORB,
198 vcl::Window* _pParentWindow, const Reference< XControlModel >& _rxModel )
199 {
200 DBG_TESTSOLARMUTEX();
201
202 // the peer itself
203 rtl::Reference<ONavigationBarPeer> pPeer(new ONavigationBarPeer( _rxORB ));
204
205 // the VCL control for the peer
206 Reference< XModel > xContextDocument( getXModel( _rxModel ) );
207 Reference< XModuleManager2 > xModuleManager( ModuleManager::create(_rxORB) );
208 OUString sModuleID = xModuleManager->identify( xContextDocument );
209
210 VclPtrInstance<NavigationToolBar> pNavBar(
211 _pParentWindow,
212 lcl_getWinBits_nothrow( _rxModel ),
213 std::make_shared<DocumentCommandImageProvider>( _rxORB, xContextDocument ),
214 sModuleID
215 );
216
217 // some knittings
218 pNavBar->setDispatcher( pPeer.get() );
219 pNavBar->SetComponentInterface( pPeer );
220
221 // we want a faster repeating rate for the slots in this
222 // toolbox
223 AllSettings aSettings = pNavBar->GetSettings();
224 MouseSettings aMouseSettings = aSettings.GetMouseSettings();
225 aMouseSettings.SetButtonRepeat( 10 );
226 aSettings.SetMouseSettings( aMouseSettings );
227 pNavBar->SetSettings( aSettings, true );
228
229 // outta here
230 return pPeer;
231 }
232
233
ONavigationBarPeer(const Reference<XComponentContext> & _rxORB)234 ONavigationBarPeer::ONavigationBarPeer( const Reference< XComponentContext >& _rxORB )
235 :OFormNavigationHelper( _rxORB )
236 {
237 }
238
239
~ONavigationBarPeer()240 ONavigationBarPeer::~ONavigationBarPeer()
241 {
242 }
243
244
IMPLEMENT_FORWARD_XINTERFACE2(ONavigationBarPeer,VCLXWindow,OFormNavigationHelper)245 IMPLEMENT_FORWARD_XINTERFACE2( ONavigationBarPeer, VCLXWindow, OFormNavigationHelper )
246
247
248 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ONavigationBarPeer, VCLXWindow, OFormNavigationHelper )
249
250
251 void SAL_CALL ONavigationBarPeer::dispose( )
252 {
253 VCLXWindow::dispose();
254 OFormNavigationHelper::dispose();
255 }
256
257
setProperty(const OUString & _rPropertyName,const Any & _rValue)258 void SAL_CALL ONavigationBarPeer::setProperty( const OUString& _rPropertyName, const Any& _rValue )
259 {
260 SolarMutexGuard aGuard;
261
262 VclPtr< NavigationToolBar > pNavBar = GetAs< NavigationToolBar >();
263 if ( !pNavBar )
264 {
265 VCLXWindow::setProperty( _rPropertyName, _rValue );
266 return;
267 }
268
269 bool bVoid = !_rValue.hasValue();
270
271 bool bBoolValue = false;
272 Color nColor = COL_TRANSPARENT;
273
274 // TODO: more generic mechanisms for this (the grid control implementation,
275 // when used herein, will do the same stuff for lot of these)
276
277 if ( _rPropertyName == PROPERTY_BACKGROUNDCOLOR )
278 {
279 if ( bVoid )
280 {
281 pNavBar->SetBackground( pNavBar->GetSettings().GetStyleSettings().GetFaceColor() );
282 pNavBar->SetControlBackground();
283 }
284 else
285 {
286 OSL_VERIFY( _rValue >>= nColor );
287 Color aColor( nColor );
288 pNavBar->SetBackground( aColor );
289 pNavBar->SetControlBackground( aColor );
290 }
291 }
292 else if ( _rPropertyName == PROPERTY_TEXTLINECOLOR )
293 {
294 if ( bVoid )
295 {
296 pNavBar->SetTextLineColor();
297 }
298 else
299 {
300 OSL_VERIFY( _rValue >>= nColor );
301 pNavBar->SetTextLineColor( nColor );
302 }
303 }
304 else if ( _rPropertyName == PROPERTY_ICONSIZE )
305 {
306 sal_Int16 nInt16Value = 0;
307 OSL_VERIFY( _rValue >>= nInt16Value );
308 pNavBar->SetImageSize( nInt16Value ? NavigationToolBar::eLarge : NavigationToolBar::eSmall );
309 }
310 else if ( _rPropertyName == PROPERTY_SHOW_POSITION )
311 {
312 OSL_VERIFY( _rValue >>= bBoolValue );
313 pNavBar->ShowFunctionGroup( NavigationToolBar::ePosition, bBoolValue );
314 }
315 else if ( _rPropertyName == PROPERTY_SHOW_NAVIGATION )
316 {
317 OSL_VERIFY( _rValue >>= bBoolValue );
318 pNavBar->ShowFunctionGroup( NavigationToolBar::eNavigation, bBoolValue );
319 }
320 else if ( _rPropertyName == PROPERTY_SHOW_RECORDACTIONS )
321 {
322 OSL_VERIFY( _rValue >>= bBoolValue );
323 pNavBar->ShowFunctionGroup( NavigationToolBar::eRecordActions, bBoolValue );
324 }
325 else if ( _rPropertyName == PROPERTY_SHOW_FILTERSORT )
326 {
327 OSL_VERIFY( _rValue >>= bBoolValue );
328 pNavBar->ShowFunctionGroup( NavigationToolBar::eFilterSort, bBoolValue );
329 }
330 else
331 {
332 VCLXWindow::setProperty( _rPropertyName, _rValue );
333 }
334 }
335
336
getProperty(const OUString & _rPropertyName)337 Any SAL_CALL ONavigationBarPeer::getProperty( const OUString& _rPropertyName )
338 {
339 SolarMutexGuard aGuard;
340
341 Any aReturn;
342 VclPtr< NavigationToolBar > pNavBar = GetAs< NavigationToolBar >();
343
344 if ( _rPropertyName == PROPERTY_BACKGROUNDCOLOR )
345 {
346 aReturn <<= pNavBar->GetControlBackground();
347 }
348 else if ( _rPropertyName == PROPERTY_TEXTLINECOLOR )
349 {
350 aReturn <<= pNavBar->GetTextLineColor();
351 }
352 else if ( _rPropertyName == PROPERTY_ICONSIZE )
353 {
354 sal_Int16 nIconType = ( NavigationToolBar::eLarge == pNavBar->GetImageSize() )
355 ? 1 : 0;
356 aReturn <<= nIconType;
357 }
358 else if ( _rPropertyName == PROPERTY_SHOW_POSITION )
359 {
360 aReturn <<= pNavBar->IsFunctionGroupVisible( NavigationToolBar::ePosition );
361 }
362 else if ( _rPropertyName == PROPERTY_SHOW_NAVIGATION )
363 {
364 aReturn <<= pNavBar->IsFunctionGroupVisible( NavigationToolBar::eNavigation );
365 }
366 else if ( _rPropertyName == PROPERTY_SHOW_RECORDACTIONS )
367 {
368 aReturn <<= pNavBar->IsFunctionGroupVisible( NavigationToolBar::eRecordActions );
369 }
370 else if ( _rPropertyName == PROPERTY_SHOW_FILTERSORT )
371 {
372 aReturn <<= pNavBar->IsFunctionGroupVisible( NavigationToolBar::eFilterSort );
373 }
374 else
375 aReturn = VCLXWindow::getProperty( _rPropertyName );
376
377 return aReturn;
378 }
379
380
interceptorsChanged()381 void ONavigationBarPeer::interceptorsChanged( )
382 {
383 if ( isDesignMode() )
384 // not interested in if we're in design mode
385 return;
386
387 OFormNavigationHelper::interceptorsChanged();
388 }
389
390
featureStateChanged(sal_Int16 _nFeatureId,bool _bEnabled)391 void ONavigationBarPeer::featureStateChanged( sal_Int16 _nFeatureId, bool _bEnabled )
392 {
393 // enable this button on the toolbox
394 VclPtr< NavigationToolBar > pNavBar = GetAs< NavigationToolBar >();
395 if ( pNavBar )
396 {
397 pNavBar->enableFeature( _nFeatureId, _bEnabled );
398
399 // is it a feature with additional state information?
400 if ( _nFeatureId == FormFeature::ToggleApplyFilter )
401 { // additional boolean state
402 pNavBar->checkFeature( _nFeatureId, getBooleanState( _nFeatureId ) );
403 }
404 else if ( _nFeatureId == FormFeature::TotalRecords )
405 {
406 pNavBar->setFeatureText( _nFeatureId, getStringState( _nFeatureId ) );
407 }
408 else if ( _nFeatureId == FormFeature::MoveAbsolute )
409 {
410 pNavBar->setFeatureText( _nFeatureId, OUString::number(getIntegerState(_nFeatureId)) );
411 }
412 }
413
414 // base class
415 OFormNavigationHelper::featureStateChanged( _nFeatureId, _bEnabled );
416 }
417
418
allFeatureStatesChanged()419 void ONavigationBarPeer::allFeatureStatesChanged( )
420 {
421 {
422 // force the control to update it's states
423 SolarMutexGuard g;
424 VclPtr< NavigationToolBar > pNavBar = GetAs< NavigationToolBar >();
425 if ( pNavBar )
426 pNavBar->setDispatcher( this );
427 }
428
429 // base class
430 OFormNavigationHelper::allFeatureStatesChanged( );
431 }
432
433
isEnabled(sal_Int16 _nFeatureId) const434 bool ONavigationBarPeer::isEnabled( sal_Int16 _nFeatureId ) const
435 {
436 if ( const_cast< ONavigationBarPeer* >( this )->isDesignMode() )
437 return false;
438
439 return OFormNavigationHelper::isEnabled( _nFeatureId );
440 }
441
442
setDesignMode(sal_Bool _bOn)443 void SAL_CALL ONavigationBarPeer::setDesignMode( sal_Bool _bOn )
444 {
445 VCLXWindow::setDesignMode( _bOn );
446
447 if ( _bOn )
448 disconnectDispatchers();
449 else
450 connectDispatchers();
451 // this will connect if not already connected and just update else
452 }
453
454
disposing(const EventObject & _rSource)455 void SAL_CALL ONavigationBarPeer::disposing( const EventObject& _rSource )
456 {
457 VCLXWindow::disposing( _rSource );
458 OFormNavigationHelper::disposing( _rSource );
459 }
460
461
getSupportedFeatures(::std::vector<sal_Int16> & _rFeatureIds)462 void ONavigationBarPeer::getSupportedFeatures( ::std::vector< sal_Int16 >& _rFeatureIds )
463 {
464 _rFeatureIds.push_back( FormFeature::MoveAbsolute );
465 _rFeatureIds.push_back( FormFeature::TotalRecords );
466 _rFeatureIds.push_back( FormFeature::MoveToFirst );
467 _rFeatureIds.push_back( FormFeature::MoveToPrevious );
468 _rFeatureIds.push_back( FormFeature::MoveToNext );
469 _rFeatureIds.push_back( FormFeature::MoveToLast );
470 _rFeatureIds.push_back( FormFeature::SaveRecordChanges );
471 _rFeatureIds.push_back( FormFeature::UndoRecordChanges );
472 _rFeatureIds.push_back( FormFeature::MoveToInsertRow );
473 _rFeatureIds.push_back( FormFeature::DeleteRecord );
474 _rFeatureIds.push_back( FormFeature::ReloadForm );
475 _rFeatureIds.push_back( FormFeature::RefreshCurrentControl );
476 _rFeatureIds.push_back( FormFeature::SortAscending );
477 _rFeatureIds.push_back( FormFeature::SortDescending );
478 _rFeatureIds.push_back( FormFeature::InteractiveSort );
479 _rFeatureIds.push_back( FormFeature::AutoFilter );
480 _rFeatureIds.push_back( FormFeature::InteractiveFilter );
481 _rFeatureIds.push_back( FormFeature::ToggleApplyFilter );
482 _rFeatureIds.push_back( FormFeature::RemoveFilterAndSort );
483 }
484
485 } // namespace frm
486
487
488 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
com_sun_star_comp_form_ONavigationBarControl_get_implementation(css::uno::XComponentContext * context,css::uno::Sequence<css::uno::Any> const &)489 com_sun_star_comp_form_ONavigationBarControl_get_implementation (css::uno::XComponentContext* context,
490 css::uno::Sequence<css::uno::Any> const &)
491 {
492 return cppu::acquire(new frm::ONavigationBarControl(context));
493 }
494
495 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
496