Line data Source code
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 <toolkit/controls/roadmapcontrol.hxx>
22 : #include <toolkit/helper/property.hxx>
23 : #include <com/sun/star/awt/XVclWindowPeer.hpp>
24 : #include <com/sun/star/uno/XComponentContext.hpp>
25 : #include <osl/diagnose.h>
26 :
27 : #include "helper/unopropertyarrayhelper.hxx"
28 :
29 : namespace toolkit
30 : {
31 :
32 :
33 : using namespace ::com::sun::star::uno;
34 : using namespace ::com::sun::star::awt;
35 : using namespace ::com::sun::star::lang;
36 : using namespace ::com::sun::star::beans;
37 : using namespace ::com::sun::star::container;
38 :
39 :
40 : // helper
41 :
42 :
43 0 : static void lcl_throwIllegalArgumentException( )
44 : { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
45 0 : throw IllegalArgumentException();
46 : }
47 :
48 0 : static void lcl_throwIndexOutOfBoundsException( )
49 : { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
50 0 : throw IndexOutOfBoundsException();
51 : }
52 :
53 :
54 : // = UnoControlRoadmapModel
55 :
56 :
57 2 : UnoControlRoadmapModel::UnoControlRoadmapModel( const Reference< XComponentContext >& i_factory )
58 : :UnoControlRoadmapModel_Base( i_factory )
59 2 : ,maContainerListeners( *this )
60 : {
61 2 : ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR );
62 2 : ImplRegisterProperty( BASEPROPERTY_BORDER );
63 2 : ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR );
64 2 : ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL );
65 2 : ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR );
66 2 : ImplRegisterProperty( BASEPROPERTY_HELPTEXT );
67 2 : ImplRegisterProperty( BASEPROPERTY_HELPURL );
68 2 : ImplRegisterProperty( BASEPROPERTY_IMAGEURL );
69 2 : ImplRegisterProperty( BASEPROPERTY_GRAPHIC );
70 2 : ImplRegisterProperty( BASEPROPERTY_PRINTABLE );
71 2 : ImplRegisterProperty( BASEPROPERTY_COMPLETE );
72 2 : ImplRegisterProperty( BASEPROPERTY_ACTIVATED );
73 2 : ImplRegisterProperty( BASEPROPERTY_CURRENTITEMID );
74 2 : ImplRegisterProperty( BASEPROPERTY_TABSTOP );
75 2 : ImplRegisterProperty( BASEPROPERTY_TEXT );
76 2 : }
77 :
78 :
79 0 : OUString UnoControlRoadmapModel::getServiceName() throw(RuntimeException, std::exception)
80 : {
81 0 : return OUString::createFromAscii( szServiceName_UnoControlRoadmapModel );
82 : }
83 :
84 :
85 :
86 38 : Any UnoControlRoadmapModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
87 : {
88 38 : Any aReturn;
89 38 : switch (nPropId)
90 : {
91 : case BASEPROPERTY_COMPLETE:
92 2 : aReturn <<= true;
93 2 : break;
94 : case BASEPROPERTY_ACTIVATED:
95 2 : aReturn <<= true;
96 2 : break;
97 : case BASEPROPERTY_CURRENTITEMID:
98 2 : aReturn <<= (sal_Int16) -1;
99 2 : break;
100 : case BASEPROPERTY_TEXT:
101 2 : break;
102 : case BASEPROPERTY_BORDER:
103 2 : aReturn <<= (sal_Int16) 2; // No Border
104 2 : break;
105 : case BASEPROPERTY_DEFAULTCONTROL:
106 2 : aReturn <<= OUString( OUString::createFromAscii( szServiceName_UnoControlRoadmap ) );
107 2 : break;
108 26 : default : aReturn = UnoControlRoadmapModel_Base::ImplGetDefaultValue( nPropId ); break;
109 : }
110 :
111 38 : return aReturn;
112 : }
113 :
114 :
115 0 : Reference< XInterface > SAL_CALL UnoControlRoadmapModel::createInstance( ) throw (Exception, ::com::sun::star::uno::RuntimeException, std::exception)
116 : {
117 0 : ORoadmapEntry* pRoadmapItem = new ORoadmapEntry();
118 0 : Reference< XInterface > xNewRoadmapItem = (::cppu::OWeakObject*)pRoadmapItem;
119 0 : return xNewRoadmapItem;
120 : }
121 :
122 :
123 0 : Reference< XInterface > SAL_CALL UnoControlRoadmapModel::createInstanceWithArguments( const Sequence< Any >& /*aArguments*/ ) throw (Exception, RuntimeException, std::exception)
124 : {
125 : // Todo: implementation of the arguments handling
126 0 : ORoadmapEntry* pRoadmapItem = new ORoadmapEntry();
127 0 : Reference< XInterface > xNewRoadmapItem = (::cppu::OWeakObject*)pRoadmapItem;
128 0 : return xNewRoadmapItem;
129 : }
130 :
131 :
132 0 : IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlRoadmapModel, UnoControlRoadmapModel_Base, UnoControlRoadmapModel_IBase )
133 :
134 :
135 :
136 14 : ::com::sun::star::uno::Any SAL_CALL UnoControlRoadmapModel::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException, std::exception)
137 : {
138 14 : Any aRet = UnoControlRoadmapModel_Base::queryAggregation( rType );
139 14 : if ( !aRet.hasValue() )
140 0 : aRet = UnoControlRoadmapModel_IBase::queryInterface( rType );
141 14 : return aRet;
142 : }
143 :
144 :
145 :
146 0 : ::cppu::IPropertyArrayHelper& UnoControlRoadmapModel::getInfoHelper()
147 : {
148 : static UnoPropertyArrayHelper* pHelper = NULL;
149 0 : if ( !pHelper )
150 : {
151 0 : Sequence<sal_Int32> aIDs = ImplGetPropertyIds();
152 0 : pHelper = new UnoPropertyArrayHelper( aIDs );
153 : }
154 0 : return *pHelper;
155 : }
156 :
157 :
158 : // beans::XMultiPropertySet
159 :
160 0 : Reference< XPropertySetInfo > UnoControlRoadmapModel::getPropertySetInfo( ) throw(RuntimeException, std::exception)
161 : {
162 0 : static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
163 0 : return xInfo;
164 : }
165 :
166 :
167 0 : sal_Int32 SAL_CALL UnoControlRoadmapModel::getCount() throw(RuntimeException, std::exception)
168 : {
169 0 : return maRoadmapItems.size();
170 : }
171 :
172 0 : Any SAL_CALL UnoControlRoadmapModel::getByIndex( sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
173 : {
174 0 : if (( Index >= (sal_Int32)maRoadmapItems.size()) || (Index < 0))
175 0 : lcl_throwIndexOutOfBoundsException( );
176 0 : Any aAny;
177 0 : aAny = makeAny( maRoadmapItems.at( Index ));
178 0 : return aAny;
179 : }
180 :
181 :
182 :
183 0 : void UnoControlRoadmapModel::MakeRMItemValidation( sal_Int32 Index, Reference< XInterface > xRoadmapItem )
184 : {
185 0 : if ((Index > (sal_Int32)maRoadmapItems.size()) || ( Index < 0 ) )
186 0 : lcl_throwIndexOutOfBoundsException( );
187 0 : if ( !xRoadmapItem.is() )
188 0 : lcl_throwIllegalArgumentException();
189 0 : Reference< XServiceInfo > xServiceInfo( xRoadmapItem, UNO_QUERY );
190 0 : bool bIsRoadmapItem = xServiceInfo->supportsService("com.sun.star.awt.RoadmapItem");
191 0 : if ( !bIsRoadmapItem )
192 0 : lcl_throwIllegalArgumentException();
193 0 : }
194 :
195 :
196 0 : void UnoControlRoadmapModel::SetRMItemDefaultProperties( const sal_Int32 , Reference< XInterface > xRoadmapItem)
197 : {
198 0 : Any aAny;
199 0 : Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY );
200 0 : Reference< XPropertySet > xProps( xRoadmapItem, UNO_QUERY );
201 0 : if ( xProps.is() )
202 : {
203 0 : sal_Int32 LocID = 0;
204 0 : Any aValue = xPropertySet->getPropertyValue("ID");
205 0 : aValue >>= LocID;
206 0 : if (LocID < 0) // index may not be smaller than zero
207 : {
208 0 : aAny <<= GetUniqueID();
209 0 : xPropertySet->setPropertyValue("ID", aAny );
210 0 : }
211 0 : }
212 0 : }
213 :
214 :
215 : // The performance of this method could certainly be improved.
216 : // As long as only vectors with up to 10 elements are
217 : // involved it should be sufficient
218 0 : sal_Int32 UnoControlRoadmapModel::GetUniqueID()
219 : {
220 0 : Any aAny;
221 0 : bool bIncrement = true;
222 0 : sal_Int32 CurID = 0;
223 0 : sal_Int32 n_CurItemID = 0;
224 0 : Reference< XInterface > CurRoadmapItem;
225 0 : while ( bIncrement )
226 : {
227 0 : bIncrement = false;
228 0 : for ( RoadmapItemHolderList::iterator i = maRoadmapItems.begin(); i < maRoadmapItems.end(); ++i )
229 : {
230 0 : CurRoadmapItem = *i;
231 0 : Reference< XPropertySet > xPropertySet( CurRoadmapItem, UNO_QUERY );
232 0 : aAny = xPropertySet->getPropertyValue("ID");
233 0 : aAny >>= n_CurItemID;
234 0 : if (n_CurItemID == CurID)
235 : {
236 0 : bIncrement = true;
237 0 : CurID++;
238 0 : break;
239 : }
240 0 : }
241 : }
242 0 : return CurID;
243 : }
244 :
245 :
246 0 : ContainerEvent UnoControlRoadmapModel::GetContainerEvent(sal_Int32 Index, Reference< XInterface > xRoadmapItem)
247 : {
248 0 : ContainerEvent aEvent;
249 0 : aEvent.Source = *this;
250 0 : aEvent.Element <<= xRoadmapItem;
251 0 : aEvent.Accessor = makeAny(Index);
252 0 : return aEvent;
253 : }
254 :
255 :
256 0 : sal_Int16 UnoControlRoadmapModel::GetCurrentItemID( Reference< XPropertySet > xPropertySet )
257 : {
258 0 : Any aAny = xPropertySet->getPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ) );
259 0 : sal_Int16 n_CurrentItemID = 0;
260 0 : aAny >>= n_CurrentItemID;
261 0 : return n_CurrentItemID;
262 : }
263 :
264 :
265 0 : void SAL_CALL UnoControlRoadmapModel::insertByIndex( const sal_Int32 Index, const Any& _Element)
266 : throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
267 : {
268 0 : if ( ( Index >= ( (sal_Int32)maRoadmapItems.size() + 1 ) ) || (Index < 0))
269 0 : lcl_throwIndexOutOfBoundsException( );
270 0 : Reference< XInterface > xRoadmapItem;
271 0 : _Element >>= xRoadmapItem;
272 0 : MakeRMItemValidation( Index, xRoadmapItem);
273 0 : SetRMItemDefaultProperties( Index, xRoadmapItem );
274 0 : maRoadmapItems.insert( maRoadmapItems.begin() + Index, xRoadmapItem);
275 0 : ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem);
276 0 : maContainerListeners.elementInserted( aEvent );
277 0 : Reference< XPropertySet > xPropertySet( (XAggregation*) (::cppu::OWeakAggObject*)this, UNO_QUERY );
278 0 : sal_Int16 n_CurrentItemID = GetCurrentItemID( xPropertySet );
279 0 : if ( Index <= n_CurrentItemID )
280 : {
281 0 : Any aAny;
282 0 : aAny <<= ( sal_Int16 ) ( n_CurrentItemID + 1 );
283 0 : xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny );
284 0 : }
285 0 : }
286 :
287 :
288 :
289 0 : void SAL_CALL UnoControlRoadmapModel::removeByIndex( sal_Int32 Index)
290 : throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
291 : {
292 0 : if (( Index > (sal_Int32)maRoadmapItems.size()) || (Index < 0))
293 0 : lcl_throwIndexOutOfBoundsException( );
294 0 : Reference< XInterface > xRoadmapItem;
295 0 : maRoadmapItems.erase( maRoadmapItems.begin() + Index );
296 0 : ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem);
297 0 : maContainerListeners.elementRemoved( aEvent );
298 0 : Reference< XPropertySet > xPropertySet( (XAggregation*) (::cppu::OWeakAggObject*)this, UNO_QUERY );
299 0 : sal_Int16 n_CurrentItemID = GetCurrentItemID( xPropertySet );
300 0 : Any aAny;
301 0 : if ( Index <= n_CurrentItemID )
302 : {
303 0 : if ( n_CurrentItemID >= (sal_Int32)maRoadmapItems.size() )
304 : {
305 : n_CurrentItemID = sal::static_int_cast< sal_Int16 >(
306 0 : maRoadmapItems.size()-1);
307 0 : if ( n_CurrentItemID < 0 )
308 0 : return;
309 0 : aAny <<= n_CurrentItemID;
310 : }
311 0 : else if (Index == n_CurrentItemID)
312 0 : aAny <<= ( sal_Int16 ) -1;
313 0 : else if( Index < n_CurrentItemID)
314 0 : aAny <<= ( sal_Int16 ) ( n_CurrentItemID - 1 );
315 0 : xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny );
316 0 : }
317 : }
318 :
319 :
320 0 : void SAL_CALL UnoControlRoadmapModel::replaceByIndex( const sal_Int32 Index, const Any& _Element)
321 : throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
322 : {
323 0 : Reference< XInterface > xRoadmapItem;
324 0 : _Element >>= xRoadmapItem;
325 0 : MakeRMItemValidation( Index, xRoadmapItem);
326 0 : SetRMItemDefaultProperties( Index, xRoadmapItem );
327 0 : maRoadmapItems.erase( maRoadmapItems.begin() + Index );
328 0 : maRoadmapItems.insert( maRoadmapItems.begin() + Index, xRoadmapItem); //push_back( xRoadmapItem );
329 0 : ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem);
330 0 : maContainerListeners.elementReplaced( aEvent );
331 0 : }
332 :
333 :
334 0 : Type SAL_CALL UnoControlRoadmapModel::getElementType() throw(RuntimeException, std::exception)
335 : {
336 0 : Type aType = cppu::UnoType<XPropertySet>::get();
337 0 : return aType;
338 : }
339 :
340 :
341 0 : sal_Bool SAL_CALL UnoControlRoadmapModel::hasElements() throw(RuntimeException, std::exception)
342 : {
343 0 : return !maRoadmapItems.empty();
344 : }
345 :
346 :
347 0 : void SAL_CALL UnoControlRoadmapModel::addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
348 : {
349 0 : maContainerListeners.addInterface( xListener );
350 0 : }
351 :
352 0 : void SAL_CALL UnoControlRoadmapModel::removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
353 : {
354 0 : maContainerListeners.removeInterface( xListener );
355 0 : }
356 :
357 :
358 : // = UnoRoadmapControl
359 :
360 :
361 0 : UnoRoadmapControl::UnoRoadmapControl()
362 : :UnoControlRoadmap_Base()
363 0 : ,maItemListeners( *this )
364 : {
365 0 : }
366 :
367 0 : IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoRoadmapControl, UnoControlRoadmap_Base, UnoControlRoadmap_IBase )
368 0 : IMPLEMENT_FORWARD_XINTERFACE2( UnoRoadmapControl, UnoControlRoadmap_Base, UnoControlRoadmap_IBase )
369 :
370 :
371 0 : sal_Bool SAL_CALL UnoRoadmapControl::setModel(const Reference< XControlModel >& _rModel) throw ( RuntimeException, std::exception )
372 : {
373 :
374 :
375 0 : Reference< XContainer > xC( getModel(), UNO_QUERY );
376 0 : if ( xC.is() )
377 0 : xC->removeContainerListener( this );
378 :
379 0 : bool bReturn = UnoControlBase::setModel( _rModel );
380 :
381 0 : xC.set(getModel(), css::uno::UNO_QUERY);
382 0 : if ( xC.is() )
383 0 : xC->addContainerListener( this );
384 :
385 0 : return bReturn;
386 : }
387 :
388 :
389 :
390 0 : OUString UnoRoadmapControl::GetComponentServiceName()
391 : {
392 0 : return OUString("Roadmap");
393 : }
394 :
395 :
396 :
397 0 : void UnoRoadmapControl::dispose() throw(RuntimeException, std::exception)
398 : {
399 0 : EventObject aEvt;
400 0 : aEvt.Source = (::cppu::OWeakObject*)this;
401 0 : maItemListeners.disposeAndClear( aEvt );
402 0 : UnoControl::dispose();
403 0 : }
404 :
405 :
406 :
407 0 : void UnoRoadmapControl::elementInserted( const ContainerEvent& rEvent )throw(RuntimeException, std::exception)
408 : {
409 0 : Reference< XInterface > xRoadmapItem;
410 0 : rEvent.Element >>= xRoadmapItem;
411 0 : Reference< XPropertySet > xRoadmapPropertySet( xRoadmapItem, UNO_QUERY );
412 0 : if ( xRoadmapPropertySet.is() )
413 0 : xRoadmapPropertySet->addPropertyChangeListener( OUString(), this );
414 :
415 0 : Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY);
416 0 : if ( xPeer.is() )
417 : {
418 0 : xPeer->elementInserted( rEvent );
419 0 : Reference < XPropertySet > xPropertySet( xPeer, UNO_QUERY );
420 0 : if ( xPropertySet.is() )
421 0 : xPropertySet->addPropertyChangeListener( OUString(), this );
422 0 : }
423 0 : }
424 :
425 :
426 0 : void UnoRoadmapControl::elementRemoved( const ContainerEvent& rEvent )throw(RuntimeException, std::exception)
427 : {
428 0 : Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY);
429 0 : if ( xPeer.is() )
430 0 : xPeer->elementRemoved( rEvent );
431 0 : Reference< XInterface > xRoadmapItem;
432 0 : rEvent.Element >>= xRoadmapItem;
433 0 : Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY );
434 0 : if ( xPropertySet.is() )
435 0 : xPropertySet->removePropertyChangeListener( OUString(), this );
436 0 : }
437 :
438 :
439 0 : void UnoRoadmapControl::elementReplaced( const ContainerEvent& rEvent )throw(RuntimeException, std::exception)
440 : {
441 0 : Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY);
442 0 : if ( xPeer.is() )
443 0 : xPeer->elementReplaced( rEvent );
444 0 : }
445 :
446 :
447 0 : void SAL_CALL UnoRoadmapControl::itemStateChanged( const ItemEvent& rEvent ) throw (RuntimeException, std::exception)
448 : {
449 0 : sal_Int16 CurItemIndex = sal::static_int_cast< sal_Int16 >(rEvent.ItemId);
450 0 : Any aAny;
451 0 : aAny <<= CurItemIndex;
452 0 : Reference< XControlModel > xModel( getModel( ), UNO_QUERY );
453 0 : Reference< XPropertySet > xPropertySet( xModel, UNO_QUERY );
454 0 : xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny );
455 0 : if ( maItemListeners.getLength() )
456 0 : maItemListeners.itemStateChanged( rEvent );
457 0 : }
458 :
459 :
460 0 : void SAL_CALL UnoRoadmapControl::addItemListener( const Reference< XItemListener >& l ) throw (RuntimeException, std::exception)
461 : {
462 0 : maItemListeners.addInterface( l );
463 0 : if( getPeer().is() && maItemListeners.getLength() == 1 )
464 : {
465 0 : Reference < XItemEventBroadcaster > xRoadmap( getPeer(), UNO_QUERY );
466 0 : xRoadmap->addItemListener( this );
467 : }
468 0 : }
469 :
470 :
471 0 : void SAL_CALL UnoRoadmapControl::removeItemListener( const Reference< XItemListener >& l ) throw (RuntimeException, std::exception)
472 : {
473 0 : if( getPeer().is() && maItemListeners.getLength() == 1 )
474 : {
475 0 : Reference < XItemEventBroadcaster > xRoadmap( getPeer(), UNO_QUERY );
476 0 : xRoadmap->removeItemListener( this );
477 : }
478 :
479 0 : maItemListeners.removeInterface( l );
480 0 : }
481 :
482 :
483 0 : void SAL_CALL UnoRoadmapControl::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException, std::exception)
484 : {
485 0 : Reference< XPropertyChangeListener > xPeer(getPeer(), UNO_QUERY);
486 0 : if ( xPeer.is() )
487 0 : xPeer->propertyChange( evt );
488 0 : }
489 :
490 : }
491 :
492 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
493 0 : stardiv_Toolkit_UnoControlRoadmapModel_get_implementation(
494 : css::uno::XComponentContext *context,
495 : css::uno::Sequence<css::uno::Any> const &)
496 : {
497 0 : return cppu::acquire(new toolkit::UnoControlRoadmapModel(context));
498 : }
499 :
500 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
501 0 : stardiv_Toolkit_UnoRoadmapControl_get_implementation(
502 : css::uno::XComponentContext *,
503 : css::uno::Sequence<css::uno::Any> const &)
504 : {
505 0 : return cppu::acquire(new toolkit::UnoRoadmapControl());
506 1227 : }
507 :
508 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|