1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
20 #include "vbatables.hxx"
21 #include "vbatable.hxx"
22 #include "vbarange.hxx"
23 #include "wordvbahelper.hxx"
24 #include <com/sun/star/text/XTextTable.hpp>
25 #include <com/sun/star/text/XTextTablesSupplier.hpp>
26 #include <com/sun/star/text/XTextDocument.hpp>
27 #include <com/sun/star/lang/XServiceInfo.hpp>
28 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 #include <com/sun/star/text/XText.hpp>
30 #include <com/sun/star/table/XCellRange.hpp>
31 #include <cppuhelper/implbase.hxx>
34 using namespace ::ooo::vba
;
37 static uno::Reference
< container::XIndexAccess
> lcl_getTables( const uno::Reference
< frame::XModel
>& xDoc
)
39 uno::Reference
< container::XIndexAccess
> xTables
;
40 uno::Reference
< text::XTextTablesSupplier
> xSupp( xDoc
, uno::UNO_QUERY
);
42 xTables
.set( xSupp
->getTextTables(), uno::UNO_QUERY_THROW
);
46 static uno::Any
lcl_createTable( const uno::Reference
< XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
>& xContext
, const uno::Reference
< frame::XModel
>& xDocument
, const uno::Any
& aSource
)
48 uno::Reference
< text::XTextTable
> xTextTable( aSource
, uno::UNO_QUERY_THROW
);
49 uno::Reference
< text::XTextDocument
> xTextDocument( xDocument
, uno::UNO_QUERY_THROW
);
50 uno::Reference
< word::XTable
> xTable( new SwVbaTable( xParent
, xContext
, xTextDocument
, xTextTable
) );
51 return uno::Any( xTable
);
54 static bool lcl_isInHeaderFooter( const uno::Reference
< text::XTextTable
>& xTable
)
56 uno::Reference
< text::XTextContent
> xTextContent( xTable
, uno::UNO_QUERY_THROW
);
57 uno::Reference
< text::XText
> xText
= xTextContent
->getAnchor()->getText();
58 uno::Reference
< lang::XServiceInfo
> xServiceInfo( xText
, uno::UNO_QUERY
);
61 OUString aImplName
= xServiceInfo
->getImplementationName();
62 return aImplName
== "SwXHeadFootText";
65 typedef std::vector
< uno::Reference
< text::XTextTable
> > XTextTableVec
;
69 class TableCollectionHelper
: public ::cppu::WeakImplHelper
< container::XIndexAccess
,
70 container::XNameAccess
>
72 XTextTableVec mxTables
;
73 XTextTableVec::iterator m_cachePos
;
76 explicit TableCollectionHelper( const uno::Reference
< frame::XModel
>& xDocument
)
78 // only count the tables in the body text, not in the header/footer
79 uno::Reference
< container::XIndexAccess
> xTables
= lcl_getTables( xDocument
);
80 sal_Int32 nCount
= xTables
->getCount();
81 for( sal_Int32 i
= 0; i
< nCount
; i
++ )
83 uno::Reference
< text::XTextTable
> xTable( xTables
->getByIndex( i
) , uno::UNO_QUERY_THROW
);
84 if( !lcl_isInHeaderFooter( xTable
) )
85 mxTables
.push_back( xTable
);
87 m_cachePos
= mxTables
.begin();
90 virtual sal_Int32 SAL_CALL
getCount( ) override
92 return mxTables
.size();
94 virtual uno::Any SAL_CALL
getByIndex( sal_Int32 Index
) override
96 if ( Index
< 0 || Index
>= getCount() )
97 throw lang::IndexOutOfBoundsException();
98 uno::Reference
< text::XTextTable
> xTable( mxTables
[ Index
], uno::UNO_SET_THROW
);
99 return uno::Any( xTable
);
102 virtual uno::Type SAL_CALL
getElementType( ) override
{ return cppu::UnoType
<text::XTextTable
>::get(); }
103 virtual sal_Bool SAL_CALL
hasElements( ) override
{ return getCount() > 0 ; }
105 virtual uno::Any SAL_CALL
getByName( const OUString
& aName
) override
107 if ( !hasByName(aName
) )
108 throw container::NoSuchElementException();
109 uno::Reference
< text::XTextTable
> xTable( *m_cachePos
, uno::UNO_SET_THROW
);
110 return uno::Any( xTable
);
112 virtual uno::Sequence
< OUString
> SAL_CALL
getElementNames( ) override
114 uno::Sequence
< OUString
> sNames( mxTables
.size() );
115 OUString
* pString
= sNames
.getArray();
116 for ( const auto& rxTable
: mxTables
)
118 uno::Reference
< container::XNamed
> xName( rxTable
, uno::UNO_QUERY_THROW
);
119 *pString
= xName
->getName();
124 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) override
126 m_cachePos
= mxTables
.begin();
127 XTextTableVec::iterator it_end
= mxTables
.end();
128 for ( ; m_cachePos
!= it_end
; ++m_cachePos
)
130 uno::Reference
< container::XNamed
> xName( *m_cachePos
, uno::UNO_QUERY_THROW
);
131 if ( aName
.equalsIgnoreAsciiCase( xName
->getName() ) )
134 return ( m_cachePos
!= it_end
);
138 class TableEnumerationImpl
: public ::cppu::WeakImplHelper
< css::container::XEnumeration
>
140 uno::Reference
< XHelperInterface
> mxParent
;
141 uno::Reference
< uno::XComponentContext
> mxContext
;
142 uno::Reference
< frame::XModel
> mxDocument
;
143 uno::Reference
< container::XIndexAccess
> mxIndexAccess
;
144 sal_Int32 mnCurIndex
;
146 TableEnumerationImpl( uno::Reference
< XHelperInterface
> xParent
, uno::Reference
< uno::XComponentContext
> xContext
, uno::Reference
< frame::XModel
> xDocument
, uno::Reference
< container::XIndexAccess
> xIndexAccess
) : mxParent(std::move( xParent
)), mxContext(std::move( xContext
)), mxDocument(std::move( xDocument
)), mxIndexAccess(std::move( xIndexAccess
)), mnCurIndex(0)
149 virtual sal_Bool SAL_CALL
hasMoreElements( ) override
151 return ( mnCurIndex
< mxIndexAccess
->getCount() );
153 virtual uno::Any SAL_CALL
nextElement( ) override
155 if ( !hasMoreElements() )
156 throw container::NoSuchElementException();
157 return lcl_createTable( mxParent
, mxContext
, mxDocument
, mxIndexAccess
->getByIndex( mnCurIndex
++ ) );
164 SwVbaTables::SwVbaTables( const uno::Reference
< XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
> & xContext
, const uno::Reference
< frame::XModel
>& xDocument
) : SwVbaTables_BASE( xParent
, xContext
, uno::Reference
< container::XIndexAccess
>( new TableCollectionHelper( xDocument
) ) ), mxDocument( xDocument
)
168 uno::Reference
< word::XTable
> SAL_CALL
169 SwVbaTables::Add( const uno::Reference
< word::XRange
>& Range
, const uno::Any
& NumRows
, const uno::Any
& NumColumns
, const uno::Any
& /*DefaultTableBehavior*/, const uno::Any
& /*AutoFitBehavior*/ )
173 SwVbaRange
* pVbaRange
= dynamic_cast< SwVbaRange
* >( Range
.get() );
175 if ( !( pVbaRange
&& ( NumRows
>>= nRows
) && ( NumColumns
>>= nCols
) ) )
176 throw uno::RuntimeException(); // #FIXME better exception??
177 if ( nCols
<= 0 || nRows
<= 0 )
178 throw uno::RuntimeException(); // #FIXME better exception??
180 uno::Reference
< frame::XModel
> xModel( pVbaRange
->getDocument(), uno::UNO_QUERY_THROW
);
181 uno::Reference
< lang::XMultiServiceFactory
> xMsf( xModel
, uno::UNO_QUERY_THROW
);
182 uno::Reference
< text::XTextRange
> xTextRange
= pVbaRange
->getXTextRange();
184 uno::Reference
< text::XTextTable
> xTable
;
185 xTable
.set( xMsf
->createInstance("com.sun.star.text.TextTable"), uno::UNO_QUERY_THROW
);
187 xTable
->initialize( nRows
, nCols
);
188 uno::Reference
< text::XText
> xText
= xTextRange
->getText();
189 uno::Reference
< text::XTextContent
> xContext( xTable
, uno::UNO_QUERY_THROW
);
191 xText
->insertTextContent( xTextRange
, xContext
, true );
193 // move the current cursor to the first table cell
194 uno::Reference
< table::XCellRange
> xCellRange( xTable
, uno::UNO_QUERY_THROW
);
195 uno::Reference
< text::XText
> xFirstCellText( xCellRange
->getCellByPosition(0, 0), uno::UNO_QUERY_THROW
);
196 word::getXTextViewCursor( mxDocument
)->gotoRange( xFirstCellText
->getStart(), false );
198 uno::Reference
< word::XTable
> xVBATable( new SwVbaTable( mxParent
, mxContext
, pVbaRange
->getDocument(), xTable
) );
202 uno::Reference
< container::XEnumeration
> SAL_CALL
203 SwVbaTables::createEnumeration()
205 return new TableEnumerationImpl( mxParent
, mxContext
, mxDocument
, m_xIndexAccess
);
208 // ScVbaCollectionBaseImpl
210 SwVbaTables::createCollectionObject( const uno::Any
& aSource
)
212 return lcl_createTable( mxParent
, mxContext
, mxDocument
, aSource
);
217 SwVbaTables::getServiceImplName()
219 return "SwVbaTables";
222 // XEnumerationAccess
224 SwVbaTables::getElementType()
226 return cppu::UnoType
<word::XTable
>::get();
229 uno::Sequence
<OUString
>
230 SwVbaTables::getServiceNames()
232 static uno::Sequence
< OUString
> const aServiceNames
234 "ooo.vba.word.Tables"
236 return aServiceNames
;
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */