LCOV - code coverage report
Current view: top level - toolkit/source/controls/grid - defaultgridcolumnmodel.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 144 154 93.5 %
Date: 2015-06-13 12:38:46 Functions: 18 19 94.7 %
Legend: Lines: hit not hit

          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 "gridcolumn.hxx"
      22             : 
      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/XServiceInfo.hpp>
      27             : #include <com/sun/star/uno/XComponentContext.hpp>
      28             : 
      29             : #include <comphelper/sequence.hxx>
      30             : #include <comphelper/componentguard.hxx>
      31             : #include <cppuhelper/basemutex.hxx>
      32             : #include <cppuhelper/compbase2.hxx>
      33             : #include <cppuhelper/supportsservice.hxx>
      34             : #include <rtl/ustrbuf.hxx>
      35             : #include <tools/diagnose_ex.h>
      36             : 
      37             : #include <vector>
      38             : 
      39             : using namespace css::awt;
      40             : using namespace css::awt::grid;
      41             : using namespace css::container;
      42             : using namespace css::lang;
      43             : using namespace css::uno;
      44             : using namespace toolkit;
      45             : 
      46             : namespace {
      47             : 
      48             : typedef ::cppu::WeakComponentImplHelper2    <   css::awt::grid::XGridColumnModel
      49             :                                             ,   css::lang::XServiceInfo
      50             :                                             >   DefaultGridColumnModel_Base;
      51             : 
      52             : class DefaultGridColumnModel    :public ::cppu::BaseMutex
      53             :                                 ,public DefaultGridColumnModel_Base
      54             : {
      55             : public:
      56             :     DefaultGridColumnModel();
      57             :     DefaultGridColumnModel( DefaultGridColumnModel const & i_copySource );
      58             :     virtual ~DefaultGridColumnModel();
      59             : 
      60             :     // XGridColumnModel
      61             :     virtual ::sal_Int32 SAL_CALL getColumnCount() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      62             :     virtual css::uno::Reference< css::awt::grid::XGridColumn > SAL_CALL createColumn(  ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      63             :     virtual ::sal_Int32 SAL_CALL addColumn(const css::uno::Reference< css::awt::grid::XGridColumn > & column) throw (css::uno::RuntimeException, css::lang::IllegalArgumentException, std::exception) SAL_OVERRIDE;
      64             :     virtual void SAL_CALL removeColumn( ::sal_Int32 i_columnIndex )  throw (css::uno::RuntimeException, css::lang::IndexOutOfBoundsException, std::exception) SAL_OVERRIDE;
      65             :     virtual css::uno::Sequence< css::uno::Reference< css::awt::grid::XGridColumn > > SAL_CALL getColumns() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      66             :     virtual css::uno::Reference< css::awt::grid::XGridColumn > SAL_CALL getColumn(::sal_Int32 index) throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      67             :     virtual void SAL_CALL setDefaultColumns(sal_Int32 rowElements) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      68             : 
      69             :     // XServiceInfo
      70             :     virtual OUString SAL_CALL getImplementationName(  ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      71             :     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      72             :     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      73             : 
      74             :     // XContainer
      75             :     virtual void SAL_CALL addContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      76             :     virtual void SAL_CALL removeContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      77             : 
      78             :     // XCloneable
      79             :     virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone(  ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      80             : 
      81             :     // OComponentHelper
      82             :     virtual void SAL_CALL disposing() SAL_OVERRIDE;
      83             : 
      84             : private:
      85             :     typedef ::std::vector< css::uno::Reference< css::awt::grid::XGridColumn > >   Columns;
      86             : 
      87             :     ::cppu::OInterfaceContainerHelper   m_aContainerListeners;
      88             :     Columns                             m_aColumns;
      89             : };
      90             : 
      91          11 :     DefaultGridColumnModel::DefaultGridColumnModel()
      92             :         :DefaultGridColumnModel_Base( m_aMutex )
      93             :         ,m_aContainerListeners( m_aMutex )
      94          11 :         ,m_aColumns()
      95             :     {
      96          11 :     }
      97             : 
      98           1 :     DefaultGridColumnModel::DefaultGridColumnModel( DefaultGridColumnModel const & i_copySource )
      99             :         :cppu::BaseMutex()
     100             :         ,DefaultGridColumnModel_Base( m_aMutex )
     101             :         ,m_aContainerListeners( m_aMutex )
     102           1 :         ,m_aColumns()
     103             :     {
     104           1 :         Columns aColumns;
     105           1 :         aColumns.reserve( i_copySource.m_aColumns.size() );
     106             :         try
     107             :         {
     108          33 :             for (   Columns::const_iterator col = i_copySource.m_aColumns.begin();
     109          22 :                     col != i_copySource.m_aColumns.end();
     110             :                     ++col
     111             :                 )
     112             :             {
     113          10 :                 Reference< css::util::XCloneable > const xCloneable( *col, UNO_QUERY_THROW );
     114          20 :                 Reference< XGridColumn > const xClone( xCloneable->createClone(), UNO_QUERY_THROW );
     115             : 
     116          10 :                 GridColumn* const pGridColumn = GridColumn::getImplementation( xClone );
     117          10 :                 if ( pGridColumn == NULL )
     118           0 :                     throw RuntimeException( "invalid clone source implementation", *this );
     119             :                     // that's indeed a RuntimeException, not an IllegalArgumentException or some such:
     120             :                     // a DefaultGridColumnModel implementation whose columns are not GridColumn implementations
     121             :                     // is borked.
     122          10 :                 pGridColumn->setIndex( col - i_copySource.m_aColumns.begin() );
     123             : 
     124          10 :                 aColumns.push_back( xClone );
     125          10 :             }
     126             :         }
     127           0 :         catch( const Exception& )
     128             :         {
     129             :             DBG_UNHANDLED_EXCEPTION();
     130             :         }
     131           1 :         if ( aColumns.size() == i_copySource.m_aColumns.size() )
     132           1 :             m_aColumns.swap( aColumns );
     133           1 :     }
     134             : 
     135             : 
     136          24 :     DefaultGridColumnModel::~DefaultGridColumnModel()
     137             :     {
     138          24 :     }
     139             : 
     140             : 
     141          56 :     ::sal_Int32 SAL_CALL DefaultGridColumnModel::getColumnCount() throw (RuntimeException, std::exception)
     142             :     {
     143          56 :         return m_aColumns.size();
     144             :     }
     145             : 
     146             : 
     147           2 :     Reference< XGridColumn > SAL_CALL DefaultGridColumnModel::createColumn(  ) throw (RuntimeException, std::exception)
     148             :     {
     149           2 :         ::comphelper::ComponentGuard aGuard( *this, rBHelper );
     150           2 :         return new GridColumn();
     151             :     }
     152             : 
     153             : 
     154           3 :     ::sal_Int32 SAL_CALL DefaultGridColumnModel::addColumn( const Reference< XGridColumn > & i_column )
     155             :         throw (RuntimeException, css::lang::IllegalArgumentException, std::exception)
     156             :     {
     157           3 :         ::comphelper::ComponentGuard aGuard( *this, rBHelper );
     158             : 
     159           3 :         GridColumn* const pGridColumn = GridColumn::getImplementation( i_column );
     160           3 :         if ( pGridColumn == NULL )
     161           1 :             throw css::lang::IllegalArgumentException( "invalid column implementation", *this, 1 );
     162             : 
     163           2 :         m_aColumns.push_back( i_column );
     164           2 :         sal_Int32 index = m_aColumns.size() - 1;
     165           2 :         pGridColumn->setIndex( index );
     166             : 
     167             :         // fire insertion notifications
     168           4 :         ContainerEvent aEvent;
     169           2 :         aEvent.Source = *this;
     170           2 :         aEvent.Accessor <<= index;
     171           2 :         aEvent.Element <<= i_column;
     172             : 
     173           2 :         aGuard.clear();
     174           2 :         m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
     175             : 
     176           5 :         return index;
     177             :     }
     178             : 
     179             : 
     180           7 :     void SAL_CALL DefaultGridColumnModel::removeColumn( ::sal_Int32 i_columnIndex )
     181             :         throw (RuntimeException, css::lang::IndexOutOfBoundsException, std::exception)
     182             :     {
     183           7 :         ::comphelper::ComponentGuard aGuard( *this, rBHelper );
     184             : 
     185           7 :         if ( ( i_columnIndex < 0 ) || ( size_t( i_columnIndex ) >= m_aColumns.size() ) )
     186           0 :             throw css::lang::IndexOutOfBoundsException( OUString(), *this );
     187             : 
     188           7 :         Columns::iterator const pos = m_aColumns.begin() + i_columnIndex;
     189          14 :         Reference< XGridColumn > const xColumn( *pos );
     190           7 :         m_aColumns.erase( pos );
     191             : 
     192             :         // update indexes of all subsequent columns
     193           7 :         sal_Int32 columnIndex( i_columnIndex );
     194          42 :         for (   Columns::iterator updatePos = m_aColumns.begin() + columnIndex;
     195          28 :                 updatePos != m_aColumns.end();
     196             :                 ++updatePos, ++columnIndex
     197             :             )
     198             :         {
     199           7 :             GridColumn* pColumnImpl = GridColumn::getImplementation( *updatePos );
     200           7 :             if ( !pColumnImpl )
     201             :             {
     202             :                 SAL_WARN( "toolkit.controls", "DefaultGridColumnModel::removeColumn: invalid column implementation!" );
     203           0 :                 continue;
     204             :             }
     205             : 
     206           7 :             pColumnImpl->setIndex( columnIndex );
     207             :         }
     208             : 
     209             :         // fire removal notifications
     210          14 :         ContainerEvent aEvent;
     211           7 :         aEvent.Source = *this;
     212           7 :         aEvent.Accessor <<= i_columnIndex;
     213           7 :         aEvent.Element <<= xColumn;
     214             : 
     215           7 :         aGuard.clear();
     216           7 :         m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
     217             : 
     218             :         // dispose the removed column
     219             :         try
     220             :         {
     221           7 :             xColumn->dispose();
     222             :         }
     223           0 :         catch( const Exception& )
     224             :         {
     225             :             DBG_UNHANDLED_EXCEPTION();
     226           7 :         }
     227           7 :     }
     228             : 
     229             : 
     230           5 :     Sequence< Reference< XGridColumn > > SAL_CALL DefaultGridColumnModel::getColumns() throw (RuntimeException, std::exception)
     231             :     {
     232           5 :         ::comphelper::ComponentGuard aGuard( *this, rBHelper );
     233           5 :         return ::comphelper::containerToSequence( m_aColumns );
     234             :     }
     235             : 
     236             : 
     237          42 :     Reference< XGridColumn > SAL_CALL DefaultGridColumnModel::getColumn(::sal_Int32 index)
     238             :         throw (css::lang::IndexOutOfBoundsException, RuntimeException, std::exception)
     239             :     {
     240          42 :         ::comphelper::ComponentGuard aGuard( *this, rBHelper );
     241             : 
     242          42 :         if ( index >=0 && index < ((sal_Int32)m_aColumns.size()))
     243          84 :             return m_aColumns[index];
     244             : 
     245           0 :         throw css::lang::IndexOutOfBoundsException();
     246             :     }
     247             : 
     248             : 
     249           5 :     void SAL_CALL DefaultGridColumnModel::setDefaultColumns(sal_Int32 rowElements) throw (RuntimeException, std::exception)
     250             :     {
     251           5 :         ::std::vector< ContainerEvent > aRemovedColumns;
     252          10 :         ::std::vector< ContainerEvent > aInsertedColumns;
     253             : 
     254             :         {
     255           5 :             ::comphelper::ComponentGuard aGuard( *this, rBHelper );
     256             : 
     257             :             // remove existing columns
     258          13 :             while ( !m_aColumns.empty() )
     259             :             {
     260           3 :                 const size_t lastColIndex = m_aColumns.size() - 1;
     261             : 
     262           3 :                 ContainerEvent aEvent;
     263           3 :                 aEvent.Source = *this;
     264           3 :                 aEvent.Accessor <<= sal_Int32( lastColIndex );
     265           3 :                 aEvent.Element <<= m_aColumns[ lastColIndex ];
     266           3 :                 aRemovedColumns.push_back( aEvent );
     267             : 
     268           3 :                 m_aColumns.erase( m_aColumns.begin() + lastColIndex );
     269           3 :             }
     270             : 
     271             :             // add new columns
     272          29 :             for ( sal_Int32 i=0; i<rowElements; ++i )
     273             :             {
     274          24 :                 ::rtl::Reference< GridColumn > const pGridColumn = new GridColumn();
     275          48 :                 Reference< XGridColumn > const xColumn( pGridColumn.get() );
     276          48 :                 OUStringBuffer colTitle;
     277          24 :                 colTitle.appendAscii( "Column " );
     278          24 :                 colTitle.append( i + 1 );
     279          24 :                 pGridColumn->setTitle( colTitle.makeStringAndClear() );
     280          24 :                 pGridColumn->setColumnWidth( 80 /* APPFONT */ );
     281          24 :                 pGridColumn->setFlexibility( 1 );
     282          24 :                 pGridColumn->setResizeable( sal_True );
     283          24 :                 pGridColumn->setDataColumnIndex( i );
     284             : 
     285          48 :                 ContainerEvent aEvent;
     286          24 :                 aEvent.Source = *this;
     287          24 :                 aEvent.Accessor <<= i;
     288          24 :                 aEvent.Element <<= xColumn;
     289          24 :                 aInsertedColumns.push_back( aEvent );
     290             : 
     291          24 :                 m_aColumns.push_back( xColumn );
     292          24 :                 pGridColumn->setIndex( i );
     293          29 :             }
     294             :         }
     295             : 
     296             :         // fire removal notifications
     297          24 :         for (   ::std::vector< ContainerEvent >::const_iterator event = aRemovedColumns.begin();
     298          16 :                 event != aRemovedColumns.end();
     299             :                 ++event
     300             :             )
     301             :         {
     302           3 :             m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, *event );
     303             :         }
     304             : 
     305             :         // fire insertion notifications
     306          87 :         for (   ::std::vector< ContainerEvent >::const_iterator event = aInsertedColumns.begin();
     307          58 :                 event != aInsertedColumns.end();
     308             :                 ++event
     309             :             )
     310             :         {
     311          24 :             m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, *event );
     312             :         }
     313             : 
     314             :         // dispose removed columns
     315          24 :         for (   ::std::vector< ContainerEvent >::const_iterator event = aRemovedColumns.begin();
     316          16 :                 event != aRemovedColumns.end();
     317             :                 ++event
     318             :             )
     319             :         {
     320             :             try
     321             :             {
     322           3 :                 const Reference< XComponent > xColComp( event->Element, UNO_QUERY_THROW );
     323           3 :                 xColComp->dispose();
     324             :             }
     325           0 :             catch( const Exception& )
     326             :             {
     327             :                 DBG_UNHANDLED_EXCEPTION();
     328             :             }
     329           5 :         }
     330           5 :     }
     331             : 
     332             : 
     333           1 :     OUString SAL_CALL DefaultGridColumnModel::getImplementationName(  ) throw (RuntimeException, std::exception)
     334             :     {
     335           1 :         return OUString("stardiv.Toolkit.DefaultGridColumnModel");
     336             :     }
     337             : 
     338           0 :     sal_Bool SAL_CALL DefaultGridColumnModel::supportsService( const OUString& i_serviceName ) throw (RuntimeException, std::exception)
     339             :     {
     340           0 :         return cppu::supportsService(this, i_serviceName);
     341             :     }
     342             : 
     343           1 :     Sequence< OUString > SAL_CALL DefaultGridColumnModel::getSupportedServiceNames(  ) throw (RuntimeException, std::exception)
     344             :     {
     345           1 :         const OUString aServiceName("com.sun.star.awt.grid.DefaultGridColumnModel");
     346           1 :         const Sequence< OUString > aSeq( &aServiceName, 1 );
     347           1 :         return aSeq;
     348             :     }
     349             : 
     350             : 
     351           2 :     void SAL_CALL DefaultGridColumnModel::addContainerListener( const Reference< XContainerListener >& i_listener ) throw (RuntimeException, std::exception)
     352             :     {
     353           2 :         if ( i_listener.is() )
     354           2 :             m_aContainerListeners.addInterface( i_listener );
     355           2 :     }
     356             : 
     357             : 
     358           1 :     void SAL_CALL DefaultGridColumnModel::removeContainerListener( const Reference< XContainerListener >& i_listener ) throw (RuntimeException, std::exception)
     359             :     {
     360           1 :         if ( i_listener.is() )
     361           1 :             m_aContainerListeners.removeInterface( i_listener );
     362           1 :     }
     363             : 
     364             : 
     365          12 :     void SAL_CALL DefaultGridColumnModel::disposing()
     366             :     {
     367          12 :         DefaultGridColumnModel_Base::disposing();
     368             : 
     369          12 :         EventObject aEvent( *this );
     370          12 :         m_aContainerListeners.disposeAndClear( aEvent );
     371             : 
     372          24 :         ::osl::MutexGuard aGuard( m_aMutex );
     373             : 
     374             :         // remove, dispose and clear columns
     375          50 :         while ( !m_aColumns.empty() )
     376             :         {
     377             :             try
     378             :             {
     379          26 :                 const Reference< XComponent > xColComponent( m_aColumns[ 0 ], UNO_QUERY_THROW );
     380          26 :                 xColComponent->dispose();
     381             :             }
     382           0 :             catch( const Exception& )
     383             :             {
     384             :                 DBG_UNHANDLED_EXCEPTION();
     385             :             }
     386             : 
     387          26 :             m_aColumns.erase( m_aColumns.begin() );
     388             :         }
     389             : 
     390          24 :         Columns aEmpty;
     391          24 :         m_aColumns.swap( aEmpty );
     392          12 :     }
     393             : 
     394             : 
     395           1 :     Reference< css::util::XCloneable > SAL_CALL DefaultGridColumnModel::createClone(  ) throw (RuntimeException, std::exception)
     396             :     {
     397           1 :         ::comphelper::ComponentGuard aGuard( *this, rBHelper );
     398           1 :         return new DefaultGridColumnModel( *this );
     399             :     }
     400             : 
     401             : }
     402             : 
     403             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
     404          11 : stardiv_Toolkit_DefaultGridColumnModel_get_implementation(
     405             :     css::uno::XComponentContext *,
     406             :     css::uno::Sequence<css::uno::Any> const &)
     407             : {
     408          11 :     return cppu::acquire(new DefaultGridColumnModel());
     409             : }
     410             : 
     411             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11