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>
32 #include <unotxdoc.hxx>
33 #include <unocoll.hxx>
37 using namespace ::ooo::vba
;
40 static uno::Any
lcl_createTable( const uno::Reference
< XHelperInterface
>& xParent
,
41 const uno::Reference
< uno::XComponentContext
>& xContext
,
42 const rtl::Reference
< SwXTextDocument
>& xDocument
,
43 const uno::Any
& aSource
)
45 uno::Reference
< text::XTextTable
> xTextTable( aSource
, uno::UNO_QUERY_THROW
);
46 uno::Reference
< word::XTable
> xTable( new SwVbaTable( xParent
, xContext
, xDocument
, xTextTable
) );
47 return uno::Any( xTable
);
50 static bool lcl_isInHeaderFooter( const uno::Reference
< text::XTextTable
>& xTable
)
52 uno::Reference
< text::XTextContent
> xTextContent( xTable
, uno::UNO_QUERY_THROW
);
53 uno::Reference
< text::XText
> xText
= xTextContent
->getAnchor()->getText();
54 uno::Reference
< lang::XServiceInfo
> xServiceInfo( xText
, uno::UNO_QUERY
);
57 OUString aImplName
= xServiceInfo
->getImplementationName();
58 return aImplName
== "SwXHeadFootText";
63 class TableCollectionHelper
: public ::cppu::WeakImplHelper
< container::XIndexAccess
,
64 container::XNameAccess
>
66 std::vector
<rtl::Reference
<SwXTextTable
>> mxTables
;
67 std::vector
<rtl::Reference
<SwXTextTable
>>::iterator m_cachePos
;
70 explicit TableCollectionHelper( const rtl::Reference
< SwXTextDocument
>& xDocument
)
72 // only count the tables in the body text, not in the header/footer
73 rtl::Reference
< SwXTextTables
> xTables
= xDocument
->getSwTextTables();
74 sal_Int32 nCount
= xTables
->getCount();
75 for( sal_Int32 i
= 0; i
< nCount
; i
++ )
77 rtl::Reference
< SwXTextTable
> xTable
= xTables
->getTextTableByIndex( i
);
78 if( !lcl_isInHeaderFooter( xTable
) )
79 mxTables
.push_back( xTable
);
81 m_cachePos
= mxTables
.begin();
84 virtual sal_Int32 SAL_CALL
getCount( ) override
86 return mxTables
.size();
88 virtual uno::Any SAL_CALL
getByIndex( sal_Int32 Index
) override
90 if ( Index
< 0 || Index
>= getCount() )
91 throw lang::IndexOutOfBoundsException();
92 uno::Reference
< text::XTextTable
> xTable( mxTables
[ Index
] );
93 return uno::Any( xTable
);
96 virtual uno::Type SAL_CALL
getElementType( ) override
{ return cppu::UnoType
<text::XTextTable
>::get(); }
97 virtual sal_Bool SAL_CALL
hasElements( ) override
{ return getCount() > 0 ; }
99 virtual uno::Any SAL_CALL
getByName( const OUString
& aName
) override
101 if ( !hasByName(aName
) )
102 throw container::NoSuchElementException();
103 uno::Reference
< text::XTextTable
> xTable( *m_cachePos
, uno::UNO_SET_THROW
);
104 return uno::Any( xTable
);
106 virtual uno::Sequence
< OUString
> SAL_CALL
getElementNames( ) override
108 uno::Sequence
< OUString
> sNames( mxTables
.size() );
109 OUString
* pString
= sNames
.getArray();
110 for ( const auto& rxTable
: mxTables
)
112 *pString
= rxTable
->getName();
117 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) override
119 m_cachePos
= mxTables
.begin();
120 auto it_end
= mxTables
.end();
121 for ( ; m_cachePos
!= it_end
; ++m_cachePos
)
123 if ( aName
.equalsIgnoreAsciiCase( (*m_cachePos
)->getName() ) )
126 return ( m_cachePos
!= it_end
);
130 class TableEnumerationImpl
: public ::cppu::WeakImplHelper
< css::container::XEnumeration
>
132 uno::Reference
< XHelperInterface
> mxParent
;
133 uno::Reference
< uno::XComponentContext
> mxContext
;
134 rtl::Reference
< SwXTextDocument
> mxDocument
;
135 uno::Reference
< container::XIndexAccess
> mxIndexAccess
;
136 sal_Int32 mnCurIndex
;
138 TableEnumerationImpl( uno::Reference
< XHelperInterface
> xParent
,
139 uno::Reference
< uno::XComponentContext
> xContext
,
140 rtl::Reference
< SwXTextDocument
> xDocument
,
141 uno::Reference
< container::XIndexAccess
> xIndexAccess
)
142 : mxParent(std::move( xParent
)), mxContext(std::move( xContext
)),
143 mxDocument(std::move( xDocument
)), mxIndexAccess(std::move( xIndexAccess
)), mnCurIndex(0)
146 virtual sal_Bool SAL_CALL
hasMoreElements( ) override
148 return ( mnCurIndex
< mxIndexAccess
->getCount() );
150 virtual uno::Any SAL_CALL
nextElement( ) override
152 if ( !hasMoreElements() )
153 throw container::NoSuchElementException();
154 return lcl_createTable( mxParent
, mxContext
, mxDocument
, mxIndexAccess
->getByIndex( mnCurIndex
++ ) );
161 SwVbaTables::SwVbaTables( const uno::Reference
< XHelperInterface
>& xParent
,
162 const uno::Reference
< uno::XComponentContext
> & xContext
,
163 const rtl::Reference
< SwXTextDocument
>& xDocument
)
164 : SwVbaTables_BASE( xParent
, xContext
, uno::Reference
< container::XIndexAccess
>( new TableCollectionHelper( xDocument
) ) ),
165 mxDocument( xDocument
)
169 uno::Reference
< word::XTable
> SAL_CALL
170 SwVbaTables::Add( const uno::Reference
< word::XRange
>& Range
, const uno::Any
& NumRows
, const uno::Any
& NumColumns
, const uno::Any
& /*DefaultTableBehavior*/, const uno::Any
& /*AutoFitBehavior*/ )
174 SwVbaRange
* pVbaRange
= dynamic_cast< SwVbaRange
* >( Range
.get() );
176 if ( !( pVbaRange
&& ( NumRows
>>= nRows
) && ( NumColumns
>>= nCols
) ) )
177 throw uno::RuntimeException(); // #FIXME better exception??
178 if ( nCols
<= 0 || nRows
<= 0 )
179 throw uno::RuntimeException(); // #FIXME better exception??
181 rtl::Reference
< SwXTextDocument
> xModel( pVbaRange
->getDocument() );
182 uno::Reference
< text::XTextRange
> xTextRange
= pVbaRange
->getXTextRange();
184 uno::Reference
< text::XTextTable
> xTable
;
185 xTable
.set( xModel
->createInstance(u
"com.sun.star.text.TextTable"_ustr
), 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 u
"SwVbaTables"_ustr
;
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 u
"ooo.vba.word.Tables"_ustr
236 return aServiceNames
;
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */