Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / toolkit / source / controls / grid / defaultgridcolumnmodel.cxx
blobf8eb9121f2a2b9959531dc8e3ac9c933fe0bd30b
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 "gridcolumn.hxx"
23 #include <com/sun/star/awt/XVclWindowPeer.hpp>
24 #include <com/sun/star/awt/grid/XGridColumnModel.hpp>
25 #include <com/sun/star/awt/grid/XGridColumn.hpp>
26 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
27 #include <com/sun/star/lang/XServiceInfo.hpp>
28 #include <com/sun/star/uno/XComponentContext.hpp>
30 #include <comphelper/sequence.hxx>
31 #include <comphelper/componentguard.hxx>
32 #include <comphelper/interfacecontainer2.hxx>
33 #include <cppuhelper/basemutex.hxx>
34 #include <cppuhelper/compbase.hxx>
35 #include <cppuhelper/supportsservice.hxx>
36 #include <rtl/ustrbuf.hxx>
37 #include <tools/diagnose_ex.h>
39 #include <vector>
41 using namespace css::awt;
42 using namespace css::awt::grid;
43 using namespace css::container;
44 using namespace css::lang;
45 using namespace css::uno;
46 using namespace toolkit;
48 namespace {
50 typedef ::cppu::WeakComponentImplHelper < css::awt::grid::XGridColumnModel
51 , css::lang::XServiceInfo
52 > DefaultGridColumnModel_Base;
54 class DefaultGridColumnModel :public ::cppu::BaseMutex
55 ,public DefaultGridColumnModel_Base
57 public:
58 DefaultGridColumnModel();
59 DefaultGridColumnModel( DefaultGridColumnModel const & i_copySource );
61 // XGridColumnModel
62 virtual ::sal_Int32 SAL_CALL getColumnCount() override;
63 virtual css::uno::Reference< css::awt::grid::XGridColumn > SAL_CALL createColumn( ) override;
64 virtual ::sal_Int32 SAL_CALL addColumn(const css::uno::Reference< css::awt::grid::XGridColumn > & column) override;
65 virtual void SAL_CALL removeColumn( ::sal_Int32 i_columnIndex ) override;
66 virtual css::uno::Sequence< css::uno::Reference< css::awt::grid::XGridColumn > > SAL_CALL getColumns() override;
67 virtual css::uno::Reference< css::awt::grid::XGridColumn > SAL_CALL getColumn(::sal_Int32 index) override;
68 virtual void SAL_CALL setDefaultColumns(sal_Int32 rowElements) override;
70 // XServiceInfo
71 virtual OUString SAL_CALL getImplementationName( ) override;
72 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
73 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
75 // XContainer
76 virtual void SAL_CALL addContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override;
77 virtual void SAL_CALL removeContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override;
79 // XCloneable
80 virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone( ) override;
82 // OComponentHelper
83 virtual void SAL_CALL disposing() override;
85 private:
86 typedef ::std::vector< css::uno::Reference< css::awt::grid::XGridColumn > > Columns;
88 ::comphelper::OInterfaceContainerHelper2 m_aContainerListeners;
89 Columns m_aColumns;
92 DefaultGridColumnModel::DefaultGridColumnModel()
93 :DefaultGridColumnModel_Base( m_aMutex )
94 ,m_aContainerListeners( m_aMutex )
95 ,m_aColumns()
99 DefaultGridColumnModel::DefaultGridColumnModel( DefaultGridColumnModel const & i_copySource )
100 :cppu::BaseMutex()
101 ,DefaultGridColumnModel_Base( m_aMutex )
102 ,m_aContainerListeners( m_aMutex )
103 ,m_aColumns()
105 Columns aColumns;
106 aColumns.reserve( i_copySource.m_aColumns.size() );
109 for ( Columns::const_iterator col = i_copySource.m_aColumns.begin();
110 col != i_copySource.m_aColumns.end();
111 ++col
114 Reference< css::util::XCloneable > const xCloneable( *col, UNO_QUERY_THROW );
115 Reference< XGridColumn > const xClone( xCloneable->createClone(), UNO_QUERY_THROW );
117 GridColumn* const pGridColumn = GridColumn::getImplementation( xClone );
118 if ( pGridColumn == nullptr )
119 throw RuntimeException( "invalid clone source implementation", *this );
120 // that's indeed a RuntimeException, not an IllegalArgumentException or some such:
121 // a DefaultGridColumnModel implementation whose columns are not GridColumn implementations
122 // is borked.
123 pGridColumn->setIndex( col - i_copySource.m_aColumns.begin() );
125 aColumns.push_back( xClone );
128 catch( const Exception& )
130 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
132 if ( aColumns.size() == i_copySource.m_aColumns.size() )
133 m_aColumns.swap( aColumns );
136 ::sal_Int32 SAL_CALL DefaultGridColumnModel::getColumnCount()
138 return m_aColumns.size();
142 Reference< XGridColumn > SAL_CALL DefaultGridColumnModel::createColumn( )
144 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
145 return new GridColumn();
149 ::sal_Int32 SAL_CALL DefaultGridColumnModel::addColumn( const Reference< XGridColumn > & i_column )
151 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
153 GridColumn* const pGridColumn = GridColumn::getImplementation( i_column );
154 if ( pGridColumn == nullptr )
155 throw css::lang::IllegalArgumentException( "invalid column implementation", *this, 1 );
157 m_aColumns.push_back( i_column );
158 sal_Int32 index = m_aColumns.size() - 1;
159 pGridColumn->setIndex( index );
161 // fire insertion notifications
162 ContainerEvent aEvent;
163 aEvent.Source = *this;
164 aEvent.Accessor <<= index;
165 aEvent.Element <<= i_column;
167 aGuard.clear();
168 m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
170 return index;
174 void SAL_CALL DefaultGridColumnModel::removeColumn( ::sal_Int32 i_columnIndex )
176 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
178 if ( ( i_columnIndex < 0 ) || ( size_t( i_columnIndex ) >= m_aColumns.size() ) )
179 throw css::lang::IndexOutOfBoundsException( OUString(), *this );
181 Columns::iterator const pos = m_aColumns.begin() + i_columnIndex;
182 Reference< XGridColumn > const xColumn( *pos );
183 m_aColumns.erase( pos );
185 // update indexes of all subsequent columns
186 sal_Int32 columnIndex( i_columnIndex );
187 for ( Columns::iterator updatePos = m_aColumns.begin() + columnIndex;
188 updatePos != m_aColumns.end();
189 ++updatePos, ++columnIndex
192 GridColumn* pColumnImpl = GridColumn::getImplementation( *updatePos );
193 if ( !pColumnImpl )
195 SAL_WARN( "toolkit.controls", "DefaultGridColumnModel::removeColumn: invalid column implementation!" );
196 continue;
199 pColumnImpl->setIndex( columnIndex );
202 // fire removal notifications
203 ContainerEvent aEvent;
204 aEvent.Source = *this;
205 aEvent.Accessor <<= i_columnIndex;
206 aEvent.Element <<= xColumn;
208 aGuard.clear();
209 m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
211 // dispose the removed column
214 xColumn->dispose();
216 catch( const Exception& )
218 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
223 Sequence< Reference< XGridColumn > > SAL_CALL DefaultGridColumnModel::getColumns()
225 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
226 return ::comphelper::containerToSequence( m_aColumns );
230 Reference< XGridColumn > SAL_CALL DefaultGridColumnModel::getColumn(::sal_Int32 index)
232 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
234 if ( index >=0 && index < static_cast<sal_Int32>(m_aColumns.size()))
235 return m_aColumns[index];
237 throw css::lang::IndexOutOfBoundsException();
241 void SAL_CALL DefaultGridColumnModel::setDefaultColumns(sal_Int32 rowElements)
243 ::std::vector< ContainerEvent > aRemovedColumns;
244 ::std::vector< ContainerEvent > aInsertedColumns;
247 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
249 // remove existing columns
250 while ( !m_aColumns.empty() )
252 const size_t lastColIndex = m_aColumns.size() - 1;
254 ContainerEvent aEvent;
255 aEvent.Source = *this;
256 aEvent.Accessor <<= sal_Int32( lastColIndex );
257 aEvent.Element <<= m_aColumns[ lastColIndex ];
258 aRemovedColumns.push_back( aEvent );
260 m_aColumns.erase( m_aColumns.begin() + lastColIndex );
263 // add new columns
264 for ( sal_Int32 i=0; i<rowElements; ++i )
266 ::rtl::Reference< GridColumn > const pGridColumn = new GridColumn();
267 Reference< XGridColumn > const xColumn( pGridColumn.get() );
268 OUStringBuffer colTitle;
269 colTitle.append( "Column " );
270 colTitle.append( i + 1 );
271 pGridColumn->setTitle( colTitle.makeStringAndClear() );
272 pGridColumn->setColumnWidth( 80 /* APPFONT */ );
273 pGridColumn->setFlexibility( 1 );
274 pGridColumn->setResizeable( true );
275 pGridColumn->setDataColumnIndex( i );
277 ContainerEvent aEvent;
278 aEvent.Source = *this;
279 aEvent.Accessor <<= i;
280 aEvent.Element <<= xColumn;
281 aInsertedColumns.push_back( aEvent );
283 m_aColumns.push_back( xColumn );
284 pGridColumn->setIndex( i );
288 // fire removal notifications
289 for ( ::std::vector< ContainerEvent >::const_iterator event = aRemovedColumns.begin();
290 event != aRemovedColumns.end();
291 ++event
294 m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, *event );
297 // fire insertion notifications
298 for ( ::std::vector< ContainerEvent >::const_iterator event = aInsertedColumns.begin();
299 event != aInsertedColumns.end();
300 ++event
303 m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, *event );
306 // dispose removed columns
307 for ( ::std::vector< ContainerEvent >::const_iterator event = aRemovedColumns.begin();
308 event != aRemovedColumns.end();
309 ++event
314 const Reference< XComponent > xColComp( event->Element, UNO_QUERY_THROW );
315 xColComp->dispose();
317 catch( const Exception& )
319 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
325 OUString SAL_CALL DefaultGridColumnModel::getImplementationName( )
327 return OUString("stardiv.Toolkit.DefaultGridColumnModel");
330 sal_Bool SAL_CALL DefaultGridColumnModel::supportsService( const OUString& i_serviceName )
332 return cppu::supportsService(this, i_serviceName);
335 Sequence< OUString > SAL_CALL DefaultGridColumnModel::getSupportedServiceNames( )
337 const OUString aServiceName("com.sun.star.awt.grid.DefaultGridColumnModel");
338 const Sequence< OUString > aSeq( &aServiceName, 1 );
339 return aSeq;
343 void SAL_CALL DefaultGridColumnModel::addContainerListener( const Reference< XContainerListener >& i_listener )
345 if ( i_listener.is() )
346 m_aContainerListeners.addInterface( i_listener );
350 void SAL_CALL DefaultGridColumnModel::removeContainerListener( const Reference< XContainerListener >& i_listener )
352 if ( i_listener.is() )
353 m_aContainerListeners.removeInterface( i_listener );
357 void SAL_CALL DefaultGridColumnModel::disposing()
359 DefaultGridColumnModel_Base::disposing();
361 EventObject aEvent( *this );
362 m_aContainerListeners.disposeAndClear( aEvent );
364 ::osl::MutexGuard aGuard( m_aMutex );
366 // remove, dispose and clear columns
367 while ( !m_aColumns.empty() )
371 const Reference< XComponent > xColComponent( m_aColumns[ 0 ], UNO_QUERY_THROW );
372 xColComponent->dispose();
374 catch( const Exception& )
376 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
379 m_aColumns.erase( m_aColumns.begin() );
382 Columns aEmpty;
383 m_aColumns.swap( aEmpty );
387 Reference< css::util::XCloneable > SAL_CALL DefaultGridColumnModel::createClone( )
389 ::comphelper::ComponentGuard aGuard( *this, rBHelper );
390 return new DefaultGridColumnModel( *this );
395 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
396 stardiv_Toolkit_DefaultGridColumnModel_get_implementation(
397 css::uno::XComponentContext *,
398 css::uno::Sequence<css::uno::Any> const &)
400 return cppu::acquire(new DefaultGridColumnModel());
403 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */