1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include "vbapagebreaks.hxx"
31 #include "vbapagebreak.hxx"
32 #include <ooo/vba/excel/XWorksheet.hpp>
33 using namespace ::com::sun::star
;
34 using namespace ::ooo::vba
;
36 typedef ::cppu::WeakImplHelper1
<container::XIndexAccess
> RangePageBreaks_Base
;
37 class RangePageBreaks
: public RangePageBreaks_Base
40 uno::Reference
< XHelperInterface
> mxParent
;
41 uno::Reference
< uno::XComponentContext
> mxContext
;
42 uno::Reference
< sheet::XSheetPageBreak
> mxSheetPageBreak
;
46 RangePageBreaks( const uno::Reference
< XHelperInterface
>& xParent
,
47 const uno::Reference
< uno::XComponentContext
>& xContext
,
48 uno::Reference
< sheet::XSheetPageBreak
>& xSheetPageBreak
,
49 sal_Bool bColumn
) : mxParent( xParent
), mxContext( xContext
), mxSheetPageBreak( xSheetPageBreak
), m_bColumn( bColumn
)
53 sal_Int32
getAPIStartofRange( const uno::Reference
< excel::XRange
>& xRange
) throw (css::uno::RuntimeException
)
56 return xRange
->getColumn() - 1;
57 return xRange
->getRow() - 1;
60 sal_Int32
getAPIEndIndexofRange( const uno::Reference
< excel::XRange
>& xRange
, sal_Int32 nUsedStart
) throw (uno::RuntimeException
)
63 return nUsedStart
+ xRange
->Columns( uno::Any() )->getCount();
64 return nUsedStart
+ xRange
->Rows( uno::Any() )->getCount();
67 uno::Sequence
<sheet::TablePageBreakData
> getAllPageBreaks() throw (uno::RuntimeException
)
70 return mxSheetPageBreak
->getColumnPageBreaks();
71 return mxSheetPageBreak
->getRowPageBreaks();
74 uno::Reference
<container::XIndexAccess
> getRowColContainer() throw (uno::RuntimeException
)
76 uno::Reference
< table::XColumnRowRange
> xColumnRowRange( mxSheetPageBreak
, uno::UNO_QUERY_THROW
);
77 uno::Reference
<container::XIndexAccess
> xIndexAccess
;
79 xIndexAccess
.set( xColumnRowRange
->getColumns(), uno::UNO_QUERY_THROW
);
81 xIndexAccess
.set( xColumnRowRange
->getRows(), uno::UNO_QUERY_THROW
);
85 sheet::TablePageBreakData
getTablePageBreakData( sal_Int32 nAPIItemIndex
) throw ( script::BasicErrorException
, uno::RuntimeException
);
86 uno::Any
Add( const css::uno::Any
& Before
) throw ( css::script::BasicErrorException
, css::uno::RuntimeException
);
89 virtual sal_Int32 SAL_CALL
getCount( ) throw (uno::RuntimeException
);
90 virtual uno::Any SAL_CALL
getByIndex( sal_Int32 Index
) throw (lang::IndexOutOfBoundsException
, lang::WrappedTargetException
, uno::RuntimeException
);
91 virtual uno::Type SAL_CALL
getElementType( ) throw (uno::RuntimeException
)
94 return excel::XVPageBreak::static_type(0);
95 return excel::XHPageBreak::static_type(0);
97 virtual sal_Bool SAL_CALL
hasElements( ) throw (uno::RuntimeException
)
103 /** @TODO Unlike MS Excel this method only considers the pagebreaks that intersect the used range
104 * To become completely compatible the print area has to be considered. As far as I found out this printarea
105 * also considers the position and sizes of shapes and manually inserted page breaks
106 * Note: In MS there is a limit of 1026 horizontal page breaks per sheet.
108 sal_Int32 SAL_CALL
RangePageBreaks::getCount( ) throw (uno::RuntimeException
)
110 sal_Int32 nCount
= 0;
111 uno::Reference
< excel::XWorksheet
> xWorksheet( mxParent
, uno::UNO_QUERY_THROW
);
112 uno::Reference
< excel::XRange
> xRange
= xWorksheet
->getUsedRange();
113 sal_Int32 nUsedStart
= getAPIStartofRange( xRange
);
114 sal_Int32 nUsedEnd
= getAPIEndIndexofRange( xRange
, nUsedStart
);
115 uno::Sequence
<sheet::TablePageBreakData
> aTablePageBreakData
= getAllPageBreaks();
117 sal_Int32 nLength
= aTablePageBreakData
.getLength();
118 for( sal_Int32 i
=0; i
<nLength
; i
++ )
120 sal_Int32 nPos
= aTablePageBreakData
[i
].Position
;
122 // VBA. minz@cn.ibm.com. All page breaks before the used range should be counted.
123 // And the page break at the end of the used range also should be counted.
124 if( nPos
<= nUsedEnd
+ 1 )
133 uno::Any SAL_CALL
RangePageBreaks::getByIndex( sal_Int32 Index
) throw (lang::IndexOutOfBoundsException
, lang::WrappedTargetException
, uno::RuntimeException
)
135 if( (Index
< getCount()) && ( Index
>= 0 ))
137 sheet::TablePageBreakData aTablePageBreakData
= getTablePageBreakData( Index
);
138 uno::Reference
< container::XIndexAccess
> xIndexAccess
= getRowColContainer();
139 sal_Int32 nPos
= aTablePageBreakData
.Position
;
140 if( (nPos
< xIndexAccess
->getCount()) && (nPos
> -1) )
142 uno::Reference
< beans::XPropertySet
> xRowColPropertySet( xIndexAccess
->getByIndex(nPos
), uno::UNO_QUERY_THROW
);
144 return uno::makeAny( uno::Reference
< excel::XVPageBreak
>( new ScVbaVPageBreak( mxParent
, mxContext
, xRowColPropertySet
, aTablePageBreakData
) ));
145 return uno::makeAny( uno::Reference
< excel::XHPageBreak
>( new ScVbaHPageBreak( mxParent
, mxContext
, xRowColPropertySet
, aTablePageBreakData
) ));
148 throw lang::IndexOutOfBoundsException();
151 sheet::TablePageBreakData
RangePageBreaks::getTablePageBreakData( sal_Int32 nAPIItemIndex
) throw ( script::BasicErrorException
, uno::RuntimeException
)
153 sal_Int32 index
= -1;
154 sheet::TablePageBreakData aTablePageBreakData
;
155 uno::Reference
< excel::XWorksheet
> xWorksheet( mxParent
, uno::UNO_QUERY_THROW
);
156 uno::Reference
< excel::XRange
> xRange
= xWorksheet
->getUsedRange();
157 sal_Int32 nUsedStart
= getAPIStartofRange( xRange
);
158 sal_Int32 nUsedEnd
= getAPIEndIndexofRange( xRange
, nUsedStart
);
159 uno::Sequence
<sheet::TablePageBreakData
> aTablePageBreakDataList
= getAllPageBreaks();
161 sal_Int32 nLength
= aTablePageBreakDataList
.getLength();
162 //VBA. minz@cn.ibm.com. No need to filter the page break. All page breaks before the used range are counted.
163 if ( nAPIItemIndex
< nLength
&& nAPIItemIndex
>=0 )
164 aTablePageBreakData
= aTablePageBreakDataList
[nAPIItemIndex
];
166 return aTablePageBreakData
;
169 uno::Any
RangePageBreaks::Add( const css::uno::Any
& Before
) throw ( css::script::BasicErrorException
, css::uno::RuntimeException
)
171 uno::Reference
< excel::XRange
> xRange
;
175 DebugHelper::exception(SbERR_BAD_ARGUMENT
, rtl::OUString());
178 sal_Int32 nAPIRowColIndex
= getAPIStartofRange( xRange
);
179 uno::Reference
< container::XIndexAccess
> xIndexAccess
= getRowColContainer();
180 uno::Reference
< beans::XPropertySet
> xRowColPropertySet( xIndexAccess
->getByIndex(nAPIRowColIndex
), uno::UNO_QUERY_THROW
);
181 xRowColPropertySet
->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsStartOfNewPage" )), uno::makeAny(sal_True
));
182 sheet::TablePageBreakData aTablePageBreakData
;
183 aTablePageBreakData
.ManualBreak
= sal_True
;
184 aTablePageBreakData
.Position
= nAPIRowColIndex
;
186 return uno::makeAny( uno::Reference
< excel::XVPageBreak
>( new ScVbaVPageBreak( mxParent
, mxContext
, xRowColPropertySet
, aTablePageBreakData
) ));
187 return uno::makeAny( uno::Reference
< excel::XHPageBreak
>( new ScVbaHPageBreak( mxParent
, mxContext
, xRowColPropertySet
, aTablePageBreakData
) ));
191 class RangePageBreaksEnumWrapper
: public EnumerationHelper_BASE
193 uno::Reference
<container::XIndexAccess
> m_xIndexAccess
;
196 RangePageBreaksEnumWrapper( const uno::Reference
< container::XIndexAccess
>& xIndexAccess
) : m_xIndexAccess( xIndexAccess
), nIndex( 0 ) {}
197 virtual ::sal_Bool SAL_CALL
hasMoreElements( ) throw (uno::RuntimeException
)
199 return ( nIndex
< m_xIndexAccess
->getCount() );
202 virtual uno::Any SAL_CALL
nextElement( ) throw (container::NoSuchElementException
, lang::WrappedTargetException
, uno::RuntimeException
)
204 if ( nIndex
< m_xIndexAccess
->getCount() )
205 return m_xIndexAccess
->getByIndex( nIndex
++ );
206 throw container::NoSuchElementException();
210 ScVbaHPageBreaks::ScVbaHPageBreaks( const uno::Reference
< XHelperInterface
>& xParent
,
211 const uno::Reference
< uno::XComponentContext
>& xContext
,
212 uno::Reference
< sheet::XSheetPageBreak
>& xSheetPageBreak
) throw (uno::RuntimeException
):
213 ScVbaHPageBreaks_BASE( xParent
,xContext
, new RangePageBreaks( xParent
, xContext
, xSheetPageBreak
, sal_False
)),
214 mxSheetPageBreak( xSheetPageBreak
)
218 uno::Any SAL_CALL
ScVbaHPageBreaks::Add( const uno::Any
& Before
) throw ( script::BasicErrorException
, uno::RuntimeException
)
220 RangePageBreaks
* pPageBreaks
= dynamic_cast< RangePageBreaks
* >( m_xIndexAccess
.get() );
223 return pPageBreaks
->Add( Before
);
228 uno::Reference
< container::XEnumeration
>
229 ScVbaHPageBreaks::createEnumeration() throw (uno::RuntimeException
)
231 return new RangePageBreaksEnumWrapper( m_xIndexAccess
);
235 ScVbaHPageBreaks::createCollectionObject( const css::uno::Any
& aSource
)
237 return aSource
; // its already a pagebreak object
241 ScVbaHPageBreaks::getElementType() throw (uno::RuntimeException
)
243 return excel::XHPageBreak::static_type(0);
247 ScVbaHPageBreaks::getServiceImplName()
249 static rtl::OUString
sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaHPageBreaks") );
253 uno::Sequence
< rtl::OUString
>
254 ScVbaHPageBreaks::getServiceNames()
256 static uno::Sequence
< rtl::OUString
> aServiceNames
;
257 if ( aServiceNames
.getLength() == 0 )
259 aServiceNames
.realloc( 1 );
260 aServiceNames
[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.HPageBreaks" ) );
262 return aServiceNames
;
266 ScVbaVPageBreaks::ScVbaVPageBreaks( const uno::Reference
< XHelperInterface
>& xParent
,
267 const uno::Reference
< uno::XComponentContext
>& xContext
,
268 uno::Reference
< sheet::XSheetPageBreak
>& xSheetPageBreak
) throw ( uno::RuntimeException
)
269 : ScVbaVPageBreaks_BASE( xParent
, xContext
, new RangePageBreaks( xParent
, xContext
, xSheetPageBreak
, sal_True
) ),
270 mxSheetPageBreak( xSheetPageBreak
)
274 ScVbaVPageBreaks::~ScVbaVPageBreaks()
279 ScVbaVPageBreaks::Add( const uno::Any
& Before
) throw ( script::BasicErrorException
, uno::RuntimeException
)
281 RangePageBreaks
* pPageBreaks
= dynamic_cast< RangePageBreaks
* >( m_xIndexAccess
.get() );
284 return pPageBreaks
->Add( Before
);
289 uno::Reference
< container::XEnumeration
>
290 ScVbaVPageBreaks::createEnumeration() throw ( uno::RuntimeException
)
292 return new RangePageBreaksEnumWrapper( m_xIndexAccess
);
296 ScVbaVPageBreaks::createCollectionObject( const css::uno::Any
& aSource
)
298 return aSource
; // its already a pagebreak object
302 ScVbaVPageBreaks::getElementType() throw ( uno::RuntimeException
)
304 return excel::XVPageBreak::static_type( 0 );
308 ScVbaVPageBreaks::getServiceImplName()
310 static rtl::OUString
sImplName( RTL_CONSTASCII_USTRINGPARAM( "ScVbaVPageBreaks" ) );
314 uno::Sequence
< rtl::OUString
>
315 ScVbaVPageBreaks::getServiceNames()
317 static uno::Sequence
< rtl::OUString
> aServiceNames
;
318 if ( aServiceNames
.getLength() == 0 )
320 aServiceNames
.realloc( 1 );
321 aServiceNames
[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.VPageBreaks" ) );
323 return aServiceNames
;