Updated core
[LibreOffice.git] / toolkit / source / controls / grid / defaultgridcolumnmodel.cxx
blob37e8b8fb6a0e0605d9dab1d0eaf15d2de2e916eb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "defaultgridcolumnmodel.hxx"
22 #include "gridcolumn.hxx"
24 #include <com/sun/star/awt/XVclWindowPeer.hpp>
26 #include <comphelper/sequence.hxx>
27 #include <comphelper/componentguard.hxx>
28 #include <comphelper/processfactory.hxx>
29 #include <toolkit/helper/servicenames.hxx>
30 #include <rtl/ustrbuf.hxx>
31 #include <tools/diagnose_ex.h>
33 //......................................................................................................................
34 namespace toolkit
35 //......................................................................................................................
37 using ::com::sun::star::uno::Reference;
38 using ::com::sun::star::uno::XComponentContext;
39 using ::com::sun::star::lang::XMultiServiceFactory;
40 using ::com::sun::star::uno::RuntimeException;
41 using ::com::sun::star::uno::Sequence;
42 using ::com::sun::star::uno::UNO_QUERY_THROW;
43 using ::com::sun::star::uno::UNO_QUERY;
44 using ::com::sun::star::awt::grid::XGridColumn;
45 using ::com::sun::star::uno::XInterface;
46 using ::com::sun::star::lang::XComponent;
47 using ::com::sun::star::lang::EventObject;
48 using ::com::sun::star::container::XContainerListener;
49 using ::com::sun::star::container::ContainerEvent;
50 using ::com::sun::star::uno::Exception;
51 using ::com::sun::star::lang::IndexOutOfBoundsException;
52 using ::com::sun::star::util::XCloneable;
53 using ::com::sun::star::lang::IllegalArgumentException;
55 //==================================================================================================================
56 //= DefaultGridColumnModel
57 //==================================================================================================================
58 //------------------------------------------------------------------------------------------------------------------
59 DefaultGridColumnModel::DefaultGridColumnModel( const Reference< XComponentContext >& i_context )
60 :DefaultGridColumnModel_Base( m_aMutex )
61 ,m_aContext( i_context )
62 ,m_aContainerListeners( m_aMutex )
63 ,m_aColumns()
67 //------------------------------------------------------------------------------------------------------------------
68 DefaultGridColumnModel::DefaultGridColumnModel( DefaultGridColumnModel const & i_copySource )
69 :cppu::BaseMutex()
70 ,DefaultGridColumnModel_Base( m_aMutex )
71 ,m_aContext( i_copySource.m_aContext )
72 ,m_aContainerListeners( m_aMutex )
73 ,m_aColumns()
75 Columns aColumns;
76 aColumns.reserve( i_copySource.m_aColumns.size() );
77 try
79 for ( Columns::const_iterator col = i_copySource.m_aColumns.begin();
80 col != i_copySource.m_aColumns.end();
81 ++col
84 Reference< XCloneable > const xCloneable( *col, UNO_QUERY_THROW );
85 Reference< XGridColumn > const xClone( xCloneable->createClone(), UNO_QUERY_THROW );
87 GridColumn* const pGridColumn = GridColumn::getImplementation( xClone );
88 if ( pGridColumn == NULL )
89 throw RuntimeException( "invalid clone source implementation", *this );
90 // that's indeed a RuntimeException, not an IllegalArgumentException or some such:
91 // a DefaultGridColumnModel implementation whose columns are not GridColumn implementations
92 // is borked.
93 pGridColumn->setIndex( col - i_copySource.m_aColumns.begin() );
95 aColumns.push_back( xClone );
98 catch( const Exception& )
100 DBG_UNHANDLED_EXCEPTION();
102 if ( aColumns.size() == i_copySource.m_aColumns.size() )
103 m_aColumns.swap( aColumns );
106 //------------------------------------------------------------------------------------------------------------------
107 DefaultGridColumnModel::~DefaultGridColumnModel()
111 //------------------------------------------------------------------------------------------------------------------
112 ::sal_Int32 SAL_CALL DefaultGridColumnModel::getColumnCount() throw (RuntimeException)
114 return m_aColumns.size();
117 //------------------------------------------------------------------------------------------------------------------
118 Reference< XGridColumn > SAL_CALL DefaultGridColumnModel::createColumn( ) throw (RuntimeException)
120 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
121 return new GridColumn();
124 //------------------------------------------------------------------------------------------------------------------
125 ::sal_Int32 SAL_CALL DefaultGridColumnModel::addColumn( const Reference< XGridColumn > & i_column ) throw (RuntimeException, IllegalArgumentException)
127 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
129 GridColumn* const pGridColumn = GridColumn::getImplementation( i_column );
130 if ( pGridColumn == NULL )
131 throw IllegalArgumentException( "invalid column implementation", *this, 1 );
133 m_aColumns.push_back( i_column );
134 sal_Int32 index = m_aColumns.size() - 1;
135 pGridColumn->setIndex( index );
137 // fire insertion notifications
138 ContainerEvent aEvent;
139 aEvent.Source = *this;
140 aEvent.Accessor <<= index;
141 aEvent.Element <<= i_column;
143 aGuard.clear();
144 m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
146 return index;
149 //------------------------------------------------------------------------------------------------------------------
150 void SAL_CALL DefaultGridColumnModel::removeColumn( ::sal_Int32 i_columnIndex ) throw (RuntimeException, IndexOutOfBoundsException)
152 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
154 if ( ( i_columnIndex < 0 ) || ( size_t( i_columnIndex ) >= m_aColumns.size() ) )
155 throw IndexOutOfBoundsException( OUString(), *this );
157 Columns::iterator const pos = m_aColumns.begin() + i_columnIndex;
158 Reference< XGridColumn > const xColumn( *pos );
159 m_aColumns.erase( pos );
161 // update indexes of all subsequent columns
162 sal_Int32 columnIndex( i_columnIndex );
163 for ( Columns::iterator updatePos = m_aColumns.begin() + columnIndex;
164 updatePos != m_aColumns.end();
165 ++updatePos, ++columnIndex
168 GridColumn* pColumnImpl = GridColumn::getImplementation( *updatePos );
169 if ( !pColumnImpl )
171 SAL_WARN( "toolkit.controls", "DefaultGridColumnModel::removeColumn: invalid column implementation!" );
172 continue;
175 pColumnImpl->setIndex( columnIndex );
178 // fire removal notifications
179 ContainerEvent aEvent;
180 aEvent.Source = *this;
181 aEvent.Accessor <<= i_columnIndex;
182 aEvent.Element <<= xColumn;
184 aGuard.clear();
185 m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
187 // dispose the removed column
190 Reference< XComponent > const xColComp( xColumn, UNO_QUERY_THROW );
191 xColComp->dispose();
193 catch( const Exception& )
195 DBG_UNHANDLED_EXCEPTION();
199 //------------------------------------------------------------------------------------------------------------------
200 Sequence< Reference< XGridColumn > > SAL_CALL DefaultGridColumnModel::getColumns() throw (RuntimeException)
202 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
203 return ::comphelper::containerToSequence( m_aColumns );
206 //------------------------------------------------------------------------------------------------------------------
207 Reference< XGridColumn > SAL_CALL DefaultGridColumnModel::getColumn(::sal_Int32 index) throw (IndexOutOfBoundsException, RuntimeException)
209 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
211 if ( index >=0 && index < ((sal_Int32)m_aColumns.size()))
212 return m_aColumns[index];
214 throw IndexOutOfBoundsException();
217 //------------------------------------------------------------------------------------------------------------------
218 void SAL_CALL DefaultGridColumnModel::setDefaultColumns(sal_Int32 rowElements) throw (RuntimeException)
220 ::std::vector< ContainerEvent > aRemovedColumns;
221 ::std::vector< ContainerEvent > aInsertedColumns;
224 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
226 // remove existing columns
227 while ( !m_aColumns.empty() )
229 const size_t lastColIndex = m_aColumns.size() - 1;
231 ContainerEvent aEvent;
232 aEvent.Source = *this;
233 aEvent.Accessor <<= sal_Int32( lastColIndex );
234 aEvent.Element <<= m_aColumns[ lastColIndex ];
235 aRemovedColumns.push_back( aEvent );
237 m_aColumns.erase( m_aColumns.begin() + lastColIndex );
240 // add new columns
241 for ( sal_Int32 i=0; i<rowElements; ++i )
243 ::rtl::Reference< GridColumn > const pGridColumn = new GridColumn();
244 Reference< XGridColumn > const xColumn( pGridColumn.get() );
245 OUStringBuffer colTitle;
246 colTitle.appendAscii( "Column " );
247 colTitle.append( i + 1 );
248 pGridColumn->setTitle( colTitle.makeStringAndClear() );
249 pGridColumn->setColumnWidth( 80 /* APPFONT */ );
250 pGridColumn->setFlexibility( 1 );
251 pGridColumn->setResizeable( sal_True );
252 pGridColumn->setDataColumnIndex( i );
254 ContainerEvent aEvent;
255 aEvent.Source = *this;
256 aEvent.Accessor <<= i;
257 aEvent.Element <<= xColumn;
258 aInsertedColumns.push_back( aEvent );
260 m_aColumns.push_back( xColumn );
261 pGridColumn->setIndex( i );
265 // fire removal notifications
266 for ( ::std::vector< ContainerEvent >::const_iterator event = aRemovedColumns.begin();
267 event != aRemovedColumns.end();
268 ++event
271 m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, *event );
274 // fire insertion notifications
275 for ( ::std::vector< ContainerEvent >::const_iterator event = aInsertedColumns.begin();
276 event != aInsertedColumns.end();
277 ++event
280 m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, *event );
283 // dispose removed columns
284 for ( ::std::vector< ContainerEvent >::const_iterator event = aRemovedColumns.begin();
285 event != aRemovedColumns.end();
286 ++event
291 const Reference< XComponent > xColComp( event->Element, UNO_QUERY_THROW );
292 xColComp->dispose();
294 catch( const Exception& )
296 DBG_UNHANDLED_EXCEPTION();
301 //------------------------------------------------------------------------------------------------------------------
302 OUString SAL_CALL DefaultGridColumnModel::getImplementationName( ) throw (RuntimeException)
304 return OUString( "org.openoffice.comp.toolkit.DefaultGridColumnModel" );
307 //------------------------------------------------------------------------------------------------------------------
308 sal_Bool SAL_CALL DefaultGridColumnModel::supportsService( const OUString& i_serviceName ) throw (RuntimeException)
310 const Sequence< OUString > aServiceNames( getSupportedServiceNames() );
311 for ( sal_Int32 i=0; i<aServiceNames.getLength(); ++i )
312 if ( aServiceNames[i] == i_serviceName )
313 return sal_True;
314 return sal_False;
317 //------------------------------------------------------------------------------------------------------------------
318 Sequence< OUString > SAL_CALL DefaultGridColumnModel::getSupportedServiceNames( ) throw (RuntimeException)
320 const OUString aServiceName( OUString::createFromAscii( szServiceName_DefaultGridColumnModel ) );
321 const Sequence< OUString > aSeq( &aServiceName, 1 );
322 return aSeq;
325 //------------------------------------------------------------------------------------------------------------------
326 void SAL_CALL DefaultGridColumnModel::addContainerListener( const Reference< XContainerListener >& i_listener ) throw (RuntimeException)
328 if ( i_listener.is() )
329 m_aContainerListeners.addInterface( i_listener );
332 //------------------------------------------------------------------------------------------------------------------
333 void SAL_CALL DefaultGridColumnModel::removeContainerListener( const Reference< XContainerListener >& i_listener ) throw (RuntimeException)
335 if ( i_listener.is() )
336 m_aContainerListeners.removeInterface( i_listener );
339 //------------------------------------------------------------------------------------------------------------------
340 void SAL_CALL DefaultGridColumnModel::disposing()
342 DefaultGridColumnModel_Base::disposing();
344 EventObject aEvent( *this );
345 m_aContainerListeners.disposeAndClear( aEvent );
347 ::osl::MutexGuard aGuard( m_aMutex );
349 // remove, dispose and clear columns
350 while ( !m_aColumns.empty() )
354 const Reference< XComponent > xColComponent( m_aColumns[ 0 ], UNO_QUERY_THROW );
355 xColComponent->dispose();
357 catch( const Exception& )
359 DBG_UNHANDLED_EXCEPTION();
362 m_aColumns.erase( m_aColumns.begin() );
365 Columns aEmpty;
366 m_aColumns.swap( aEmpty );
369 //------------------------------------------------------------------------------------------------------------------
370 Reference< XCloneable > SAL_CALL DefaultGridColumnModel::createClone( ) throw (RuntimeException)
372 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
373 return new DefaultGridColumnModel( *this );
376 //......................................................................................................................
377 } // namespace toolkit
378 //......................................................................................................................
380 //----------------------------------------------------------------------------------------------------------------------
381 ::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)
383 return ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::DefaultGridColumnModel( comphelper::getComponentContext(_rFactory) ) );
385 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */