Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : : #include "vbapagebreaks.hxx"
29 : : #include "vbapagebreak.hxx"
30 : : #include <ooo/vba/excel/XWorksheet.hpp>
31 : : using namespace ::com::sun::star;
32 : : using namespace ::ooo::vba;
33 : :
34 : : typedef ::cppu::WeakImplHelper1<container::XIndexAccess > RangePageBreaks_Base;
35 [ # # ]: 0 : class RangePageBreaks : public RangePageBreaks_Base
36 : : {
37 : : private:
38 : : uno::Reference< XHelperInterface > mxParent;
39 : : uno::Reference< uno::XComponentContext > mxContext;
40 : : uno::Reference< sheet::XSheetPageBreak > mxSheetPageBreak;
41 : : sal_Bool m_bColumn;
42 : :
43 : : public:
44 : 0 : RangePageBreaks( const uno::Reference< XHelperInterface >& xParent,
45 : : const uno::Reference< uno::XComponentContext >& xContext,
46 : : uno::Reference< sheet::XSheetPageBreak >& xSheetPageBreak,
47 : 0 : sal_Bool bColumn ) : mxParent( xParent ), mxContext( xContext ), mxSheetPageBreak( xSheetPageBreak ), m_bColumn( bColumn )
48 : : {
49 : 0 : }
50 : :
51 : 0 : sal_Int32 getAPIStartofRange( const uno::Reference< excel::XRange >& xRange ) throw (css::uno::RuntimeException)
52 : : {
53 [ # # ]: 0 : if( m_bColumn )
54 : 0 : return xRange->getColumn() - 1;
55 : 0 : return xRange->getRow() - 1;
56 : : }
57 : :
58 : 0 : sal_Int32 getAPIEndIndexofRange( const uno::Reference< excel::XRange >& xRange, sal_Int32 nUsedStart ) throw (uno::RuntimeException)
59 : : {
60 [ # # ]: 0 : if( m_bColumn )
61 [ # # ][ # # ]: 0 : return nUsedStart + xRange->Columns( uno::Any() )->getCount();
[ # # ]
62 [ # # ][ # # ]: 0 : return nUsedStart + xRange->Rows( uno::Any() )->getCount();
[ # # ]
63 : : }
64 : :
65 : 0 : uno::Sequence<sheet::TablePageBreakData> getAllPageBreaks() throw (uno::RuntimeException)
66 : : {
67 [ # # ]: 0 : if( m_bColumn )
68 : 0 : return mxSheetPageBreak->getColumnPageBreaks();
69 : 0 : return mxSheetPageBreak->getRowPageBreaks();
70 : : }
71 : :
72 : 0 : uno::Reference<container::XIndexAccess> getRowColContainer() throw (uno::RuntimeException)
73 : : {
74 [ # # ]: 0 : uno::Reference< table::XColumnRowRange > xColumnRowRange( mxSheetPageBreak, uno::UNO_QUERY_THROW );
75 : 0 : uno::Reference<container::XIndexAccess> xIndexAccess;
76 [ # # ]: 0 : if( m_bColumn )
77 [ # # ][ # # ]: 0 : xIndexAccess.set( xColumnRowRange->getColumns(), uno::UNO_QUERY_THROW );
[ # # ]
78 : : else
79 [ # # ][ # # ]: 0 : xIndexAccess.set( xColumnRowRange->getRows(), uno::UNO_QUERY_THROW );
[ # # ]
80 : 0 : return xIndexAccess;
81 : : }
82 : :
83 : : sheet::TablePageBreakData getTablePageBreakData( sal_Int32 nAPIItemIndex ) throw ( script::BasicErrorException, uno::RuntimeException);
84 : : uno::Any Add( const css::uno::Any& Before ) throw ( css::script::BasicErrorException, css::uno::RuntimeException);
85 : :
86 : : // XIndexAccess
87 : : virtual sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException);
88 : : virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException);
89 : 0 : virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException)
90 : : {
91 [ # # ]: 0 : if( m_bColumn )
92 : 0 : return excel::XVPageBreak::static_type(0);
93 : 0 : return excel::XHPageBreak::static_type(0);
94 : : }
95 : 0 : virtual sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException)
96 : : {
97 : 0 : return sal_True;
98 : : }
99 : : };
100 : :
101 : : /** @TODO Unlike MS Excel this method only considers the pagebreaks that intersect the used range
102 : : * To become completely compatible the print area has to be considered. As far as I found out this printarea
103 : : * also considers the position and sizes of shapes and manually inserted page breaks
104 : : * Note: In MS there is a limit of 1026 horizontal page breaks per sheet.
105 : : */
106 : 0 : sal_Int32 SAL_CALL RangePageBreaks::getCount( ) throw (uno::RuntimeException)
107 : : {
108 : 0 : sal_Int32 nCount = 0;
109 [ # # ]: 0 : uno::Reference< excel::XWorksheet > xWorksheet( mxParent, uno::UNO_QUERY_THROW );
110 [ # # ][ # # ]: 0 : uno::Reference< excel::XRange > xRange = xWorksheet->getUsedRange();
111 [ # # ]: 0 : sal_Int32 nUsedStart = getAPIStartofRange( xRange );
112 [ # # ]: 0 : sal_Int32 nUsedEnd = getAPIEndIndexofRange( xRange, nUsedStart );
113 [ # # ]: 0 : uno::Sequence<sheet::TablePageBreakData> aTablePageBreakData = getAllPageBreaks();
114 : :
115 : 0 : sal_Int32 nLength = aTablePageBreakData.getLength();
116 [ # # ]: 0 : for( sal_Int32 i=0; i<nLength; i++ )
117 : : {
118 [ # # ]: 0 : sal_Int32 nPos = aTablePageBreakData[i].Position;
119 : :
120 : : // All page breaks before the used range should be counted.
121 : : // And the page break at the end of the used range also should be counted.
122 [ # # ]: 0 : if( nPos <= nUsedEnd + 1 )
123 : 0 : nCount++;
124 : : else
125 : 0 : return nCount;
126 : : }
127 : :
128 [ # # ]: 0 : return nCount;
129 : : }
130 : :
131 : 0 : uno::Any SAL_CALL RangePageBreaks::getByIndex( sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
132 : : {
133 [ # # ][ # # ]: 0 : if( (Index < getCount()) && ( Index >= 0 ))
[ # # ]
134 : : {
135 [ # # ]: 0 : sheet::TablePageBreakData aTablePageBreakData = getTablePageBreakData( Index );
136 [ # # ]: 0 : uno::Reference< container::XIndexAccess > xIndexAccess = getRowColContainer();
137 : 0 : sal_Int32 nPos = aTablePageBreakData.Position;
138 [ # # ][ # # ]: 0 : if( (nPos < xIndexAccess->getCount()) && (nPos > -1) )
[ # # ][ # # ]
[ # # ]
139 : : {
140 [ # # ][ # # ]: 0 : uno::Reference< beans::XPropertySet > xRowColPropertySet( xIndexAccess->getByIndex(nPos), uno::UNO_QUERY_THROW );
[ # # ]
141 [ # # ]: 0 : if( m_bColumn )
142 [ # # ][ # # ]: 0 : return uno::makeAny( uno::Reference< excel::XVPageBreak >( new ScVbaVPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
[ # # ][ # # ]
143 [ # # ][ # # ]: 0 : return uno::makeAny( uno::Reference< excel::XHPageBreak >( new ScVbaHPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
[ # # ][ # # ]
144 [ # # ]: 0 : }
145 : : }
146 [ # # ]: 0 : throw lang::IndexOutOfBoundsException();
147 : : }
148 : :
149 : 0 : sheet::TablePageBreakData RangePageBreaks::getTablePageBreakData( sal_Int32 nAPIItemIndex ) throw ( script::BasicErrorException, uno::RuntimeException)
150 : : {
151 : 0 : sheet::TablePageBreakData aTablePageBreakData;
152 [ # # ]: 0 : uno::Reference< excel::XWorksheet > xWorksheet( mxParent, uno::UNO_QUERY_THROW );
153 [ # # ][ # # ]: 0 : uno::Reference< excel::XRange > xRange = xWorksheet->getUsedRange();
154 [ # # ]: 0 : uno::Sequence<sheet::TablePageBreakData> aTablePageBreakDataList = getAllPageBreaks();
155 : :
156 : 0 : sal_Int32 nLength = aTablePageBreakDataList.getLength();
157 : : // No need to filter the page break. All page breaks before the used range are counted.
158 [ # # ][ # # ]: 0 : if ( nAPIItemIndex < nLength && nAPIItemIndex>=0 )
159 [ # # ]: 0 : aTablePageBreakData = aTablePageBreakDataList[nAPIItemIndex];
160 : :
161 [ # # ]: 0 : return aTablePageBreakData;
162 : : }
163 : :
164 : 0 : uno::Any RangePageBreaks::Add( const css::uno::Any& Before ) throw ( css::script::BasicErrorException, css::uno::RuntimeException)
165 : : {
166 : 0 : uno::Reference< excel::XRange > xRange;
167 [ # # ]: 0 : Before >>= xRange;
168 [ # # ]: 0 : if( !xRange.is() )
169 : : {
170 [ # # ]: 0 : DebugHelper::exception(SbERR_BAD_ARGUMENT, rtl::OUString());
171 : : }
172 : :
173 [ # # ]: 0 : sal_Int32 nAPIRowColIndex = getAPIStartofRange( xRange );
174 [ # # ]: 0 : uno::Reference< container::XIndexAccess > xIndexAccess = getRowColContainer();
175 [ # # ][ # # ]: 0 : uno::Reference< beans::XPropertySet > xRowColPropertySet( xIndexAccess->getByIndex(nAPIRowColIndex), uno::UNO_QUERY_THROW );
[ # # ]
176 [ # # ][ # # ]: 0 : xRowColPropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsStartOfNewPage" )), uno::makeAny(sal_True));
[ # # ][ # # ]
177 : 0 : sheet::TablePageBreakData aTablePageBreakData;
178 : 0 : aTablePageBreakData.ManualBreak = sal_True;
179 : 0 : aTablePageBreakData.Position = nAPIRowColIndex;
180 [ # # ]: 0 : if( m_bColumn )
181 [ # # ][ # # ]: 0 : return uno::makeAny( uno::Reference< excel::XVPageBreak >( new ScVbaVPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
[ # # ][ # # ]
182 [ # # ][ # # ]: 0 : return uno::makeAny( uno::Reference< excel::XHPageBreak >( new ScVbaHPageBreak( mxParent, mxContext, xRowColPropertySet, aTablePageBreakData) ));
[ # # ][ # # ]
183 : : }
184 : :
185 : :
186 [ # # ]: 0 : class RangePageBreaksEnumWrapper : public EnumerationHelper_BASE
187 : : {
188 : : uno::Reference<container::XIndexAccess > m_xIndexAccess;
189 : : sal_Int32 nIndex;
190 : : public:
191 : 0 : RangePageBreaksEnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {}
192 : 0 : virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
193 : : {
194 : 0 : return ( nIndex < m_xIndexAccess->getCount() );
195 : : }
196 : :
197 : 0 : virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
198 : : {
199 [ # # ]: 0 : if ( nIndex < m_xIndexAccess->getCount() )
200 : 0 : return m_xIndexAccess->getByIndex( nIndex++ );
201 [ # # ]: 0 : throw container::NoSuchElementException();
202 : : }
203 : : };
204 : :
205 : 0 : ScVbaHPageBreaks::ScVbaHPageBreaks( const uno::Reference< XHelperInterface >& xParent,
206 : : const uno::Reference< uno::XComponentContext >& xContext,
207 : : uno::Reference< sheet::XSheetPageBreak >& xSheetPageBreak) throw (uno::RuntimeException):
208 [ # # ]: 0 : ScVbaHPageBreaks_BASE( xParent,xContext, new RangePageBreaks( xParent, xContext, xSheetPageBreak, false )),
209 [ # # ][ # # ]: 0 : mxSheetPageBreak( xSheetPageBreak )
210 : : {
211 : 0 : }
212 : :
213 : 0 : uno::Any SAL_CALL ScVbaHPageBreaks::Add( const uno::Any& Before) throw ( script::BasicErrorException, uno::RuntimeException)
214 : : {
215 [ # # ]: 0 : RangePageBreaks* pPageBreaks = dynamic_cast< RangePageBreaks* >( m_xIndexAccess.get() );
216 [ # # ]: 0 : if( pPageBreaks )
217 : : {
218 : 0 : return pPageBreaks->Add( Before );
219 : : }
220 : 0 : return uno::Any();
221 : : }
222 : :
223 : : uno::Reference< container::XEnumeration >
224 : 0 : ScVbaHPageBreaks::createEnumeration() throw (uno::RuntimeException)
225 : : {
226 [ # # ][ # # ]: 0 : return new RangePageBreaksEnumWrapper( m_xIndexAccess );
227 : : }
228 : :
229 : : uno::Any
230 : 0 : ScVbaHPageBreaks::createCollectionObject( const css::uno::Any& aSource )
231 : : {
232 : 0 : return aSource; // its already a pagebreak object
233 : : }
234 : :
235 : : uno::Type
236 : 0 : ScVbaHPageBreaks::getElementType() throw (uno::RuntimeException)
237 : : {
238 : 0 : return excel::XHPageBreak::static_type(0);
239 : : }
240 : :
241 : : rtl::OUString
242 : 0 : ScVbaHPageBreaks::getServiceImplName()
243 : : {
244 : 0 : return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScVbaHPageBreaks"));
245 : : }
246 : :
247 : : uno::Sequence< rtl::OUString >
248 : 0 : ScVbaHPageBreaks::getServiceNames()
249 : : {
250 [ # # ][ # # ]: 0 : static uno::Sequence< rtl::OUString > aServiceNames;
[ # # ][ # # ]
251 [ # # ]: 0 : if ( aServiceNames.getLength() == 0 )
252 : : {
253 : 0 : aServiceNames.realloc( 1 );
254 [ # # ]: 0 : aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.HPageBreaks" ) );
255 : : }
256 : 0 : return aServiceNames;
257 : : }
258 : :
259 : : //VPageBreak
260 : 0 : ScVbaVPageBreaks::ScVbaVPageBreaks( const uno::Reference< XHelperInterface >& xParent,
261 : : const uno::Reference< uno::XComponentContext >& xContext,
262 : : uno::Reference< sheet::XSheetPageBreak >& xSheetPageBreak ) throw ( uno::RuntimeException )
263 [ # # ]: 0 : : ScVbaVPageBreaks_BASE( xParent, xContext, new RangePageBreaks( xParent, xContext, xSheetPageBreak, sal_True ) ),
264 [ # # ][ # # ]: 0 : mxSheetPageBreak( xSheetPageBreak )
265 : : {
266 : 0 : }
267 : :
268 : 0 : ScVbaVPageBreaks::~ScVbaVPageBreaks()
269 : : {
270 [ # # ]: 0 : }
271 : :
272 : : uno::Any SAL_CALL
273 : 0 : ScVbaVPageBreaks::Add( const uno::Any& Before ) throw ( script::BasicErrorException, uno::RuntimeException )
274 : : {
275 [ # # ]: 0 : RangePageBreaks* pPageBreaks = dynamic_cast< RangePageBreaks* >( m_xIndexAccess.get() );
276 [ # # ]: 0 : if( pPageBreaks )
277 : : {
278 : 0 : return pPageBreaks->Add( Before );
279 : : }
280 : 0 : return uno::Any();
281 : : }
282 : :
283 : : uno::Reference< container::XEnumeration >
284 : 0 : ScVbaVPageBreaks::createEnumeration() throw ( uno::RuntimeException )
285 : : {
286 [ # # ][ # # ]: 0 : return new RangePageBreaksEnumWrapper( m_xIndexAccess );
287 : : }
288 : :
289 : : uno::Any
290 : 0 : ScVbaVPageBreaks::createCollectionObject( const css::uno::Any& aSource )
291 : : {
292 : 0 : return aSource; // its already a pagebreak object
293 : : }
294 : :
295 : : uno::Type
296 : 0 : ScVbaVPageBreaks::getElementType() throw ( uno::RuntimeException )
297 : : {
298 : 0 : return excel::XVPageBreak::static_type( 0 );
299 : : }
300 : :
301 : : rtl::OUString
302 : 0 : ScVbaVPageBreaks::getServiceImplName()
303 : : {
304 : 0 : return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScVbaVPageBreaks"));
305 : : }
306 : :
307 : : uno::Sequence< rtl::OUString >
308 : 0 : ScVbaVPageBreaks::getServiceNames()
309 : : {
310 [ # # ][ # # ]: 0 : static uno::Sequence< rtl::OUString > aServiceNames;
[ # # ][ # # ]
311 [ # # ]: 0 : if ( aServiceNames.getLength() == 0 )
312 : : {
313 : 0 : aServiceNames.realloc( 1 );
314 [ # # ]: 0 : aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.VPageBreaks" ) );
315 : : }
316 : 0 : return aServiceNames;
317 : : }
318 : :
319 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|