Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "defaultgridcolumnmodel.hxx"
31 : : #include "gridcolumn.hxx"
32 : :
33 : : #include <com/sun/star/awt/XVclWindowPeer.hpp>
34 : :
35 : : #include <comphelper/sequence.hxx>
36 : : #include <comphelper/componentguard.hxx>
37 : : #include <toolkit/helper/servicenames.hxx>
38 : : #include <rtl/ustrbuf.hxx>
39 : : #include <tools/diagnose_ex.h>
40 : :
41 : : //......................................................................................................................
42 : : namespace toolkit
43 : : //......................................................................................................................
44 : : {
45 : : /** === begin UNO using === **/
46 : : using ::com::sun::star::uno::Reference;
47 : : using ::com::sun::star::lang::XMultiServiceFactory;
48 : : using ::com::sun::star::uno::RuntimeException;
49 : : using ::com::sun::star::uno::Sequence;
50 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
51 : : using ::com::sun::star::uno::UNO_QUERY;
52 : : using ::com::sun::star::awt::grid::XGridColumn;
53 : : using ::com::sun::star::uno::XInterface;
54 : : using ::com::sun::star::lang::XMultiServiceFactory;
55 : : using ::com::sun::star::lang::XComponent;
56 : : using ::com::sun::star::lang::EventObject;
57 : : using ::com::sun::star::container::XContainerListener;
58 : : using ::com::sun::star::container::ContainerEvent;
59 : : using ::com::sun::star::uno::Exception;
60 : : using ::com::sun::star::lang::IndexOutOfBoundsException;
61 : : using ::com::sun::star::util::XCloneable;
62 : : using ::com::sun::star::lang::IllegalArgumentException;
63 : : /** === end UNO using === **/
64 : :
65 : : //==================================================================================================================
66 : : //= DefaultGridColumnModel
67 : : //==================================================================================================================
68 : : //------------------------------------------------------------------------------------------------------------------
69 : 2 : DefaultGridColumnModel::DefaultGridColumnModel( const Reference< XMultiServiceFactory >& i_factory )
70 : : :DefaultGridColumnModel_Base( m_aMutex )
71 : : ,m_aContext( i_factory )
72 : : ,m_aContainerListeners( m_aMutex )
73 [ + - ][ + - ]: 2 : ,m_aColumns()
[ + - ]
74 : : {
75 : 2 : }
76 : :
77 : : //------------------------------------------------------------------------------------------------------------------
78 : 0 : DefaultGridColumnModel::DefaultGridColumnModel( DefaultGridColumnModel const & i_copySource )
79 : : :cppu::BaseMutex()
80 : : ,DefaultGridColumnModel_Base( m_aMutex )
81 : : ,m_aContext( i_copySource.m_aContext )
82 : : ,m_aContainerListeners( m_aMutex )
83 [ # # ][ # # ]: 0 : ,m_aColumns()
[ # # ]
84 : : {
85 [ # # ]: 0 : Columns aColumns;
86 [ # # ]: 0 : aColumns.reserve( i_copySource.m_aColumns.size() );
87 : : try
88 : : {
89 [ # # ][ # # ]: 0 : for ( Columns::const_iterator col = i_copySource.m_aColumns.begin();
90 [ # # ]: 0 : col != i_copySource.m_aColumns.end();
91 : : ++col
92 : : )
93 : : {
94 [ # # ]: 0 : Reference< XCloneable > const xCloneable( *col, UNO_QUERY_THROW );
95 [ # # ][ # # ]: 0 : Reference< XGridColumn > const xClone( xCloneable->createClone(), UNO_QUERY_THROW );
[ # # ]
96 : :
97 [ # # ]: 0 : GridColumn* const pGridColumn = GridColumn::getImplementation( xClone );
98 [ # # ]: 0 : if ( pGridColumn == NULL )
99 [ # # ][ # # ]: 0 : throw RuntimeException( "invalid clone source implementation", *this );
100 : : // that's indeed a RuntimeException, not an IllegalArgumentException or some such:
101 : : // a DefaultGridColumnModel implementation whose columns are not GridColumn implementations
102 : : // is borked.
103 [ # # ][ # # ]: 0 : pGridColumn->setIndex( col - i_copySource.m_aColumns.begin() );
104 : :
105 [ # # ]: 0 : aColumns.push_back( xClone );
106 : 0 : }
107 : : }
108 [ # # ]: 0 : catch( const Exception& )
109 : : {
110 : : DBG_UNHANDLED_EXCEPTION();
111 : : }
112 [ # # ]: 0 : if ( aColumns.size() == i_copySource.m_aColumns.size() )
113 : 0 : m_aColumns.swap( aColumns );
114 : 0 : }
115 : :
116 : : //------------------------------------------------------------------------------------------------------------------
117 [ + - ][ + - ]: 2 : DefaultGridColumnModel::~DefaultGridColumnModel()
[ + - ]
118 : : {
119 [ - + ]: 4 : }
120 : :
121 : : //------------------------------------------------------------------------------------------------------------------
122 : 0 : ::sal_Int32 SAL_CALL DefaultGridColumnModel::getColumnCount() throw (RuntimeException)
123 : : {
124 : 0 : return m_aColumns.size();
125 : : }
126 : :
127 : : //------------------------------------------------------------------------------------------------------------------
128 : 0 : Reference< XGridColumn > SAL_CALL DefaultGridColumnModel::createColumn( ) throw (RuntimeException)
129 : : {
130 [ # # ]: 0 : ::comphelper::ComponentGuard aGuard( *this, rBHelper );
131 [ # # ][ # # ]: 0 : return new GridColumn();
[ # # ][ # # ]
132 : : }
133 : :
134 : : //------------------------------------------------------------------------------------------------------------------
135 : 0 : ::sal_Int32 SAL_CALL DefaultGridColumnModel::addColumn( const Reference< XGridColumn > & i_column ) throw (RuntimeException, IllegalArgumentException)
136 : : {
137 [ # # ]: 0 : ::comphelper::ComponentGuard aGuard( *this, rBHelper );
138 : :
139 [ # # ]: 0 : GridColumn* const pGridColumn = GridColumn::getImplementation( i_column );
140 [ # # ]: 0 : if ( pGridColumn == NULL )
141 [ # # ][ # # ]: 0 : throw IllegalArgumentException( "invalid column implementation", *this, 1 );
142 : :
143 [ # # ]: 0 : m_aColumns.push_back( i_column );
144 : 0 : sal_Int32 index = m_aColumns.size() - 1;
145 [ # # ]: 0 : pGridColumn->setIndex( index );
146 : :
147 : : // fire insertion notifications
148 [ # # ]: 0 : ContainerEvent aEvent;
149 [ # # ][ # # ]: 0 : aEvent.Source = *this;
150 [ # # ]: 0 : aEvent.Accessor <<= index;
151 [ # # ]: 0 : aEvent.Element <<= i_column;
152 : :
153 [ # # ]: 0 : aGuard.clear();
154 [ # # ]: 0 : m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
155 : :
156 [ # # ][ # # ]: 0 : return index;
157 : : }
158 : :
159 : : //------------------------------------------------------------------------------------------------------------------
160 : 0 : void SAL_CALL DefaultGridColumnModel::removeColumn( ::sal_Int32 i_columnIndex ) throw (RuntimeException, IndexOutOfBoundsException)
161 : : {
162 [ # # ]: 0 : ::comphelper::ComponentGuard aGuard( *this, rBHelper );
163 : :
164 [ # # ][ # # ]: 0 : if ( ( i_columnIndex < 0 ) || ( size_t( i_columnIndex ) >= m_aColumns.size() ) )
[ # # ]
165 [ # # ][ # # ]: 0 : throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
166 : :
167 [ # # ]: 0 : Columns::iterator const pos = m_aColumns.begin() + i_columnIndex;
168 : 0 : Reference< XGridColumn > const xColumn( *pos );
169 [ # # ]: 0 : m_aColumns.erase( pos );
170 : :
171 : : // update indexes of all subsequent columns
172 : 0 : sal_Int32 columnIndex( i_columnIndex );
173 [ # # ][ # # ]: 0 : for ( Columns::iterator updatePos = m_aColumns.begin() + columnIndex;
[ # # ]
174 : 0 : updatePos != m_aColumns.end();
175 : : ++updatePos, ++columnIndex
176 : : )
177 : : {
178 [ # # ]: 0 : GridColumn* pColumnImpl = GridColumn::getImplementation( *updatePos );
179 [ # # ]: 0 : if ( !pColumnImpl )
180 : : {
181 : : SAL_WARN( "toolkit.controls", "DefaultGridColumnModel::removeColumn: invalid column implementation!" );
182 : 0 : continue;
183 : : }
184 : :
185 [ # # ]: 0 : pColumnImpl->setIndex( columnIndex );
186 : : }
187 : :
188 : : // fire removal notifications
189 [ # # ]: 0 : ContainerEvent aEvent;
190 [ # # ][ # # ]: 0 : aEvent.Source = *this;
191 [ # # ]: 0 : aEvent.Accessor <<= i_columnIndex;
192 [ # # ]: 0 : aEvent.Element <<= xColumn;
193 : :
194 [ # # ]: 0 : aGuard.clear();
195 [ # # ]: 0 : m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
196 : :
197 : : // dispose the removed column
198 : : try
199 : : {
200 [ # # ]: 0 : Reference< XComponent > const xColComp( xColumn, UNO_QUERY_THROW );
201 [ # # ][ # # ]: 0 : xColComp->dispose();
[ # # ]
202 : : }
203 [ # # ]: 0 : catch( const Exception& )
204 : : {
205 : : DBG_UNHANDLED_EXCEPTION();
206 [ # # ][ # # ]: 0 : }
207 : 0 : }
208 : :
209 : : //------------------------------------------------------------------------------------------------------------------
210 : 0 : Sequence< Reference< XGridColumn > > SAL_CALL DefaultGridColumnModel::getColumns() throw (RuntimeException)
211 : : {
212 [ # # ]: 0 : ::comphelper::ComponentGuard aGuard( *this, rBHelper );
213 [ # # ][ # # ]: 0 : return ::comphelper::containerToSequence( m_aColumns );
214 : : }
215 : :
216 : : //------------------------------------------------------------------------------------------------------------------
217 : 0 : Reference< XGridColumn > SAL_CALL DefaultGridColumnModel::getColumn(::sal_Int32 index) throw (IndexOutOfBoundsException, RuntimeException)
218 : : {
219 [ # # ]: 0 : ::comphelper::ComponentGuard aGuard( *this, rBHelper );
220 : :
221 [ # # ][ # # ]: 0 : if ( index >=0 && index < ((sal_Int32)m_aColumns.size()))
[ # # ]
222 : 0 : return m_aColumns[index];
223 : :
224 [ # # ][ # # ]: 0 : throw IndexOutOfBoundsException();
225 : : }
226 : :
227 : : //------------------------------------------------------------------------------------------------------------------
228 : 0 : void SAL_CALL DefaultGridColumnModel::setDefaultColumns(sal_Int32 rowElements) throw (RuntimeException)
229 : : {
230 [ # # ]: 0 : ::std::vector< ContainerEvent > aRemovedColumns;
231 [ # # ]: 0 : ::std::vector< ContainerEvent > aInsertedColumns;
232 : :
233 : : {
234 [ # # ]: 0 : ::comphelper::ComponentGuard aGuard( *this, rBHelper );
235 : :
236 : : // remove existing columns
237 [ # # ]: 0 : while ( !m_aColumns.empty() )
238 : : {
239 : 0 : const size_t lastColIndex = m_aColumns.size() - 1;
240 : :
241 [ # # ]: 0 : ContainerEvent aEvent;
242 [ # # ][ # # ]: 0 : aEvent.Source = *this;
243 [ # # ]: 0 : aEvent.Accessor <<= sal_Int32( lastColIndex );
244 [ # # ]: 0 : aEvent.Element <<= m_aColumns[ lastColIndex ];
245 [ # # ]: 0 : aRemovedColumns.push_back( aEvent );
246 : :
247 [ # # ][ # # ]: 0 : m_aColumns.erase( m_aColumns.begin() + lastColIndex );
248 [ # # ]: 0 : }
249 : :
250 : : // add new columns
251 [ # # ]: 0 : for ( sal_Int32 i=0; i<rowElements; ++i )
252 : : {
253 [ # # ]: 0 : ::rtl::Reference< GridColumn > const pGridColumn = new GridColumn();
254 [ # # ][ # # ]: 0 : Reference< XGridColumn > const xColumn( pGridColumn.get() );
255 : 0 : ::rtl::OUStringBuffer colTitle;
256 [ # # ]: 0 : colTitle.appendAscii( "Column " );
257 [ # # ]: 0 : colTitle.append( i + 1 );
258 [ # # ][ # # ]: 0 : pGridColumn->setTitle( colTitle.makeStringAndClear() );
259 [ # # ]: 0 : pGridColumn->setColumnWidth( 80 /* APPFONT */ );
260 [ # # ]: 0 : pGridColumn->setFlexibility( 1 );
261 [ # # ]: 0 : pGridColumn->setResizeable( sal_True );
262 [ # # ]: 0 : pGridColumn->setDataColumnIndex( i );
263 : :
264 [ # # ]: 0 : ContainerEvent aEvent;
265 [ # # ][ # # ]: 0 : aEvent.Source = *this;
266 [ # # ]: 0 : aEvent.Accessor <<= i;
267 [ # # ]: 0 : aEvent.Element <<= xColumn;
268 [ # # ]: 0 : aInsertedColumns.push_back( aEvent );
269 : :
270 [ # # ]: 0 : m_aColumns.push_back( xColumn );
271 [ # # ]: 0 : pGridColumn->setIndex( i );
272 [ # # ][ # # ]: 0 : }
273 : : }
274 : :
275 : : // fire removal notifications
276 [ # # ][ # # ]: 0 : for ( ::std::vector< ContainerEvent >::const_iterator event = aRemovedColumns.begin();
[ # # ]
277 : 0 : event != aRemovedColumns.end();
278 : : ++event
279 : : )
280 : : {
281 [ # # ]: 0 : m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, *event );
282 : : }
283 : :
284 : : // fire insertion notifications
285 [ # # ][ # # ]: 0 : for ( ::std::vector< ContainerEvent >::const_iterator event = aInsertedColumns.begin();
[ # # ]
286 : 0 : event != aInsertedColumns.end();
287 : : ++event
288 : : )
289 : : {
290 [ # # ]: 0 : m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, *event );
291 : : }
292 : :
293 : : // dispose removed columns
294 [ # # ][ # # ]: 0 : for ( ::std::vector< ContainerEvent >::const_iterator event = aRemovedColumns.begin();
[ # # ]
295 : 0 : event != aRemovedColumns.end();
296 : : ++event
297 : : )
298 : : {
299 : : try
300 : : {
301 [ # # ]: 0 : const Reference< XComponent > xColComp( event->Element, UNO_QUERY_THROW );
302 [ # # ][ # # ]: 0 : xColComp->dispose();
[ # # ]
303 : : }
304 [ # # ]: 0 : catch( const Exception& )
305 : : {
306 : : DBG_UNHANDLED_EXCEPTION();
307 : : }
308 : 0 : }
309 : 0 : }
310 : :
311 : : //------------------------------------------------------------------------------------------------------------------
312 : 0 : ::rtl::OUString SAL_CALL DefaultGridColumnModel::getImplementationName( ) throw (RuntimeException)
313 : : {
314 : 0 : return ::rtl::OUString( "org.openoffice.comp.toolkit.DefaultGridColumnModel" );
315 : : }
316 : :
317 : : //------------------------------------------------------------------------------------------------------------------
318 : 0 : sal_Bool SAL_CALL DefaultGridColumnModel::supportsService( const ::rtl::OUString& i_serviceName ) throw (RuntimeException)
319 : : {
320 [ # # ]: 0 : const Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames() );
321 [ # # ]: 0 : for ( sal_Int32 i=0; i<aServiceNames.getLength(); ++i )
322 [ # # ]: 0 : if ( aServiceNames[i] == i_serviceName )
323 : 0 : return sal_True;
324 [ # # ]: 0 : return sal_False;
325 : : }
326 : :
327 : : //------------------------------------------------------------------------------------------------------------------
328 : 0 : Sequence< ::rtl::OUString > SAL_CALL DefaultGridColumnModel::getSupportedServiceNames( ) throw (RuntimeException)
329 : : {
330 : 0 : const ::rtl::OUString aServiceName( ::rtl::OUString::createFromAscii( szServiceName_DefaultGridColumnModel ) );
331 [ # # ]: 0 : const Sequence< ::rtl::OUString > aSeq( &aServiceName, 1 );
332 : 0 : return aSeq;
333 : : }
334 : :
335 : : //------------------------------------------------------------------------------------------------------------------
336 : 0 : void SAL_CALL DefaultGridColumnModel::addContainerListener( const Reference< XContainerListener >& i_listener ) throw (RuntimeException)
337 : : {
338 [ # # ]: 0 : if ( i_listener.is() )
339 : 0 : m_aContainerListeners.addInterface( i_listener );
340 : 0 : }
341 : :
342 : : //------------------------------------------------------------------------------------------------------------------
343 : 0 : void SAL_CALL DefaultGridColumnModel::removeContainerListener( const Reference< XContainerListener >& i_listener ) throw (RuntimeException)
344 : : {
345 [ # # ]: 0 : if ( i_listener.is() )
346 : 0 : m_aContainerListeners.removeInterface( i_listener );
347 : 0 : }
348 : :
349 : : //------------------------------------------------------------------------------------------------------------------
350 : 2 : void SAL_CALL DefaultGridColumnModel::disposing()
351 : : {
352 [ + - ]: 2 : DefaultGridColumnModel_Base::disposing();
353 : :
354 [ + - ][ + - ]: 2 : EventObject aEvent( *this );
355 [ + - ]: 2 : m_aContainerListeners.disposeAndClear( aEvent );
356 : :
357 [ + - ]: 2 : ::osl::MutexGuard aGuard( m_aMutex );
358 : :
359 : : // remove, dispose and clear columns
360 [ - + ]: 2 : while ( !m_aColumns.empty() )
361 : : {
362 : : try
363 : : {
364 [ # # ]: 0 : const Reference< XComponent > xColComponent( m_aColumns[ 0 ], UNO_QUERY_THROW );
365 [ # # ][ # # ]: 0 : xColComponent->dispose();
[ # # ]
366 : : }
367 [ # # ]: 0 : catch( const Exception& )
368 : : {
369 : : DBG_UNHANDLED_EXCEPTION();
370 : : }
371 : :
372 [ # # ]: 0 : m_aColumns.erase( m_aColumns.begin() );
373 : : }
374 : :
375 [ + - ]: 2 : Columns aEmpty;
376 [ + - ][ + - ]: 2 : m_aColumns.swap( aEmpty );
377 : 2 : }
378 : :
379 : : //------------------------------------------------------------------------------------------------------------------
380 : 0 : Reference< XCloneable > SAL_CALL DefaultGridColumnModel::createClone( ) throw (RuntimeException)
381 : : {
382 [ # # ]: 0 : ::comphelper::ComponentGuard aGuard( *this, rBHelper );
383 [ # # ][ # # ]: 0 : return new DefaultGridColumnModel( *this );
[ # # ][ # # ]
384 : : }
385 : :
386 : : //......................................................................................................................
387 : : } // namespace toolkit
388 : : //......................................................................................................................
389 : :
390 : : //----------------------------------------------------------------------------------------------------------------------
391 : 2 : ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL DefaultGridColumnModel_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rFactory)
392 : : {
393 [ + - ]: 2 : return ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::DefaultGridColumnModel( _rFactory ) );
394 : : }
395 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|