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 : :
29 : : #include "worksheethelper.hxx"
30 : :
31 : : #include <algorithm>
32 : : #include <list>
33 : : #include <utility>
34 : : #include <com/sun/star/awt/Point.hpp>
35 : : #include <com/sun/star/awt/Size.hpp>
36 : : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
37 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 : : #include <com/sun/star/sheet/TableValidationVisibility.hpp>
39 : : #include <com/sun/star/sheet/ValidationType.hpp>
40 : : #include <com/sun/star/sheet/ValidationAlertStyle.hpp>
41 : : #include <com/sun/star/sheet/XCellAddressable.hpp>
42 : : #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
43 : : #include <com/sun/star/sheet/XFormulaTokens.hpp>
44 : : #include <com/sun/star/sheet/XLabelRanges.hpp>
45 : : #include <com/sun/star/sheet/XMultiFormulaTokens.hpp>
46 : : #include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
47 : : #include <com/sun/star/sheet/XSheetCondition2.hpp>
48 : : #include <com/sun/star/sheet/XSheetOutline.hpp>
49 : : #include <com/sun/star/sheet/XSpreadsheet.hpp>
50 : : #include <com/sun/star/table/XColumnRowRange.hpp>
51 : : #include <com/sun/star/text/WritingMode2.hpp>
52 : : #include <com/sun/star/text/XText.hpp>
53 : : #include <rtl/ustrbuf.hxx>
54 : : #include "oox/core/filterbase.hxx"
55 : : #include "oox/helper/propertyset.hxx"
56 : : #include "addressconverter.hxx"
57 : : #include "autofilterbuffer.hxx"
58 : : #include "cell.hxx"
59 : : #include "commentsbuffer.hxx"
60 : : #include "condformatbuffer.hxx"
61 : : #include "convuno.hxx"
62 : : #include "document.hxx"
63 : : #include "drawingfragment.hxx"
64 : : #include "drawingmanager.hxx"
65 : : #include "formulaparser.hxx"
66 : : #include "pagesettings.hxx"
67 : : #include "querytablebuffer.hxx"
68 : : #include "sharedstringsbuffer.hxx"
69 : : #include "sheetdatabuffer.hxx"
70 : : #include "stylesbuffer.hxx"
71 : : #include "tokenuno.hxx"
72 : : #include "unitconverter.hxx"
73 : : #include "viewsettings.hxx"
74 : : #include "workbooksettings.hxx"
75 : : #include "worksheetbuffer.hxx"
76 : : #include "worksheetsettings.hxx"
77 : : #include "formulabuffer.hxx"
78 : :
79 : : namespace oox {
80 : : namespace xls {
81 : :
82 : : // ============================================================================
83 : :
84 : : using namespace ::com::sun::star;
85 : : using namespace ::com::sun::star::beans;
86 : : using namespace ::com::sun::star::drawing;
87 : : using namespace ::com::sun::star::lang;
88 : : using namespace ::com::sun::star::sheet;
89 : : using namespace ::com::sun::star::table;
90 : : using namespace ::com::sun::star::text;
91 : : using namespace ::com::sun::star::uno;
92 : : using namespace ::com::sun::star::util;
93 : :
94 : : using ::rtl::OUString;
95 : : using ::rtl::OUStringBuffer;
96 : :
97 : : // ============================================================================
98 : :
99 : : namespace {
100 : :
101 : 243 : void lclUpdateProgressBar( const ISegmentProgressBarRef& rxProgressBar, const CellRangeAddress& rUsedArea, sal_Int32 nRow )
102 : : {
103 [ + - ][ + - ]: 243 : if( rxProgressBar.get() && (rUsedArea.StartRow <= nRow) && (nRow <= rUsedArea.EndRow) )
[ + - ][ + - ]
104 : : {
105 : 243 : double fPosition = static_cast< double >( nRow - rUsedArea.StartRow + 1 ) / (rUsedArea.EndRow - rUsedArea.StartRow + 1);
106 [ + - ]: 243 : if( rxProgressBar->getPosition() < fPosition )
107 : 243 : rxProgressBar->setPosition( fPosition );
108 : : }
109 : 243 : }
110 : :
111 : 300 : void lclUpdateProgressBar( const ISegmentProgressBarRef& rxProgressBar, double fPosition )
112 : : {
113 [ + - ]: 300 : if( rxProgressBar.get() )
114 : 300 : rxProgressBar->setPosition( fPosition );
115 : 300 : }
116 : :
117 : : } // namespace
118 : :
119 : : // ============================================================================
120 : : // ============================================================================
121 : :
122 : 198 : ColumnModel::ColumnModel() :
123 : : maRange( -1 ),
124 : : mfWidth( 0.0 ),
125 : : mnXfId( -1 ),
126 : : mnLevel( 0 ),
127 : : mbShowPhonetic( false ),
128 : : mbHidden( false ),
129 : 198 : mbCollapsed( false )
130 : : {
131 : 198 : }
132 : :
133 : 18 : bool ColumnModel::isMergeable( const ColumnModel& rModel ) const
134 : : {
135 : : return
136 : : (maRange.mnFirst <= rModel.maRange.mnFirst) &&
137 : : (rModel.maRange.mnFirst <= maRange.mnLast + 1) &&
138 : : (mfWidth == rModel.mfWidth) &&
139 : : // ignore mnXfId, cell formatting is always set directly
140 : : (mnLevel == rModel.mnLevel) &&
141 : : (mbHidden == rModel.mbHidden) &&
142 [ + - ][ + - ]: 18 : (mbCollapsed == rModel.mbCollapsed);
[ - + ][ # # ]
[ # # ][ # # ]
143 : : }
144 : :
145 : : // ----------------------------------------------------------------------------
146 : :
147 : 417 : RowModel::RowModel() :
148 : : mnRow( -1 ),
149 : : mfHeight( 0.0 ),
150 : : mnXfId( -1 ),
151 : : mnLevel( 0 ),
152 : : mbCustomHeight( false ),
153 : : mbCustomFormat( false ),
154 : : mbShowPhonetic( false ),
155 : : mbHidden( false ),
156 : : mbCollapsed( false ),
157 : : mbThickTop( false ),
158 : 417 : mbThickBottom( false )
159 : : {
160 : 417 : }
161 : :
162 : 33 : void RowModel::insertColSpan( const ValueRange& rColSpan )
163 : : {
164 [ + - ][ + - ]: 33 : if( (0 <= rColSpan.mnFirst) && (rColSpan.mnFirst <= rColSpan.mnLast) )
165 : 33 : maColSpans.insert( rColSpan );
166 : 33 : }
167 : :
168 : 162 : bool RowModel::isMergeable( const RowModel& rModel ) const
169 : : {
170 : : return
171 : : // ignore maColSpans - is handled separately in SheetDataBuffer class
172 : : (mfHeight == rModel.mfHeight) &&
173 : : // ignore mnXfId, mbCustomFormat, mbShowPhonetic - cell formatting is always set directly
174 : : (mnLevel == rModel.mnLevel) &&
175 : : (mbCustomHeight == rModel.mbCustomHeight) &&
176 : : (mbHidden == rModel.mbHidden) &&
177 [ + + ][ + - ]: 162 : (mbCollapsed == rModel.mbCollapsed);
[ + - ][ + + ]
[ + - ]
178 : : }
179 : :
180 : : // ----------------------------------------------------------------------------
181 : :
182 : 0 : PageBreakModel::PageBreakModel() :
183 : : mnColRow( 0 ),
184 : 0 : mbManual( false )
185 : : {
186 : 0 : }
187 : :
188 : : // ----------------------------------------------------------------------------
189 : :
190 : 0 : HyperlinkModel::HyperlinkModel()
191 : : {
192 : 0 : }
193 : :
194 : : // ----------------------------------------------------------------------------
195 : :
196 : 0 : ValidationModel::ValidationModel() :
197 : : mnType( XML_none ),
198 : : mnOperator( XML_between ),
199 : : mnErrorStyle( XML_stop ),
200 : : mbShowInputMsg( false ),
201 : : mbShowErrorMsg( false ),
202 : : mbNoDropDown( false ),
203 [ # # ][ # # ]: 0 : mbAllowBlank( false )
204 : : {
205 : 0 : }
206 : :
207 : 0 : void ValidationModel::setBiffType( sal_uInt8 nType )
208 : : {
209 : : static const sal_Int32 spnTypeIds[] = {
210 : : XML_none, XML_whole, XML_decimal, XML_list, XML_date, XML_time, XML_textLength, XML_custom };
211 [ # # ]: 0 : mnType = STATIC_ARRAY_SELECT( spnTypeIds, nType, XML_none );
212 : 0 : }
213 : :
214 : 0 : void ValidationModel::setBiffOperator( sal_uInt8 nOperator )
215 : : {
216 : : static const sal_Int32 spnOperators[] = {
217 : : XML_between, XML_notBetween, XML_equal, XML_notEqual,
218 : : XML_greaterThan, XML_lessThan, XML_greaterThanOrEqual, XML_lessThanOrEqual };
219 [ # # ]: 0 : mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID );
220 : 0 : }
221 : :
222 : 0 : void ValidationModel::setBiffErrorStyle( sal_uInt8 nErrorStyle )
223 : : {
224 : : static const sal_Int32 spnErrorStyles[] = { XML_stop, XML_warning, XML_information };
225 [ # # ]: 0 : mnErrorStyle = STATIC_ARRAY_SELECT( spnErrorStyles, nErrorStyle, XML_stop );
226 : 0 : }
227 : :
228 : : // ============================================================================
229 : : // ============================================================================
230 : :
231 [ + - ][ + - ]: 120 : class WorksheetGlobals : public WorkbookHelper
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
232 : : {
233 : : public:
234 : : explicit WorksheetGlobals(
235 : : const WorkbookHelper& rHelper,
236 : : const ISegmentProgressBarRef& rxProgressBar,
237 : : WorksheetType eSheetType,
238 : : sal_Int16 nSheet );
239 : :
240 : : /** Returns true, if this helper refers to an existing Calc sheet. */
241 : 60 : inline bool isValidSheet() const { return mxSheet.is(); }
242 : :
243 : : /** Returns the type of this sheet. */
244 : 180 : inline WorksheetType getSheetType() const { return meSheetType; }
245 : : /** Returns the index of the current sheet. */
246 : 1011 : inline sal_Int16 getSheetIndex() const { return maUsedArea.Sheet; }
247 : : /** Returns the XSpreadsheet interface of the current sheet. */
248 : 207 : inline const Reference< XSpreadsheet >& getSheet() const { return mxSheet; }
249 : :
250 : : /** Returns the XCell interface for the passed cell address. */
251 : : Reference< XCell > getCell( const CellAddress& rAddress ) const;
252 : : /** Returns the XCellRange interface for the passed cell range address. */
253 : : Reference< XCellRange > getCellRange( const CellRangeAddress& rRange ) const;
254 : : /** Returns the XSheetCellRanges interface for the passed cell range addresses. */
255 : : Reference< XSheetCellRanges > getCellRangeList( const ApiCellRangeList& rRanges ) const;
256 : :
257 : : /** Returns the XCellRange interface for a column. */
258 : : Reference< XCellRange > getColumn( sal_Int32 nCol ) const;
259 : : /** Returns the XCellRange interface for a row. */
260 : : Reference< XCellRange > getRow( sal_Int32 nRow ) const;
261 : :
262 : : /** Returns the XTableColumns interface for a range of columns. */
263 : : Reference< XTableColumns > getColumns( const ValueRange& rColRange ) const;
264 : : /** Returns the XTableRows interface for a range of rows. */
265 : : Reference< XTableRows > getRows( const ValueRange& rRowRange ) const;
266 : :
267 : : /** Returns the XDrawPage interface of the draw page of the current sheet. */
268 : : Reference< XDrawPage > getDrawPage() const;
269 : : /** Returns the size of the entire drawing page in 1/100 mm. */
270 : : const awt::Size& getDrawPageSize() const;
271 : :
272 : : /** Returns the absolute position of the top-left corner of the cell in 1/100 mm. */
273 : : awt::Point getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const;
274 : : /** Returns the size of the cell in 1/100 mm. */
275 : : awt::Size getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const;
276 : :
277 : : /** Returns the address of the cell that contains the passed point in 1/100 mm. */
278 : : CellAddress getCellAddressFromPosition( const awt::Point& rPosition ) const;
279 : : /** Returns the cell range address that contains the passed rectangle in 1/100 mm. */
280 : : CellRangeAddress getCellRangeFromRectangle( const awt::Rectangle& rRect ) const;
281 : :
282 : : /** Returns the buffer for cell contents and cell formatting. */
283 : 63 : inline SheetDataBuffer& getSheetData() { return maSheetData; }
284 : : /** Returns the conditional formatting in this sheet. */
285 : 0 : inline CondFormatBuffer& getCondFormats() { return maCondFormats; }
286 : : /** Returns the buffer for all cell comments in this sheet. */
287 : 3 : inline CommentsBuffer& getComments() { return maComments; }
288 : : /** Returns the auto filters for the sheet. */
289 : 3 : inline AutoFilterBuffer& getAutoFilters() { return maAutoFilters; }
290 : : /** Returns the buffer for all web query tables in this sheet. */
291 : 0 : inline QueryTableBuffer& getQueryTables() { return maQueryTables; }
292 : : /** Returns the worksheet settings object. */
293 : 51 : inline WorksheetSettings& getWorksheetSettings() { return maSheetSett; }
294 : : /** Returns the page/print settings for this sheet. */
295 : 342 : inline PageSettings& getPageSettings() { return maPageSett; }
296 : : /** Returns the view settings for this sheet. */
297 : 108 : inline SheetViewSettings& getSheetViewSettings() { return maSheetViewSett; }
298 : : /** Returns the VML drawing page for this sheet (OOXML/BIFF12 only). */
299 : 15 : inline VmlDrawing& getVmlDrawing() { return *mxVmlDrawing; }
300 : : /** returns the ExtLst entries that need to be filled */
301 : 0 : inline ExtLst& getExtLst() { return maExtLst; }
302 : :
303 : : /** Returns the BIFF drawing page for this sheet (BIFF2-BIFF8 only). */
304 : 0 : inline BiffSheetDrawing& getBiffDrawing() const { return *mxBiffDrawing; }
305 : :
306 : : /** Changes the current sheet type. */
307 : : inline void setSheetType( WorksheetType eSheetType ) { meSheetType = eSheetType; }
308 : : /** Sets a column or row page break described in the passed struct. */
309 : : void setPageBreak( const PageBreakModel& rModel, bool bRowBreak );
310 : : /** Inserts the hyperlink URL into the spreadsheet. */
311 : : void setHyperlink( const HyperlinkModel& rModel );
312 : : /** Inserts the data validation settings into the spreadsheet. */
313 : : void setValidation( const ValidationModel& rModel );
314 : : /** Sets the path to the DrawingML fragment of this sheet. */
315 : : void setDrawingPath( const OUString& rDrawingPath );
316 : : /** Sets the path to the legacy VML drawing fragment of this sheet. */
317 : : void setVmlDrawingPath( const OUString& rVmlDrawingPath );
318 : :
319 : : /** Extends the used area of this sheet by the passed cell position. */
320 : : void extendUsedArea( const CellAddress& rAddress );
321 : : /** Extends the used area of this sheet by the passed cell range. */
322 : : void extendUsedArea( const CellRangeAddress& rRange );
323 : : /** Extends the shape bounding box by the position and size of the passed rectangle. */
324 : : void extendShapeBoundingBox( const awt::Rectangle& rShapeRect );
325 : :
326 : : /** Sets base width for all columns (without padding pixels). This value
327 : : is only used, if base width has not been set with setDefaultColumnWidth(). */
328 : : void setBaseColumnWidth( sal_Int32 nWidth );
329 : : /** Sets default width for all columns. This function overrides the base
330 : : width set with the setBaseColumnWidth() function. */
331 : : void setDefaultColumnWidth( double fWidth );
332 : : /** Sets column settings for a specific column range.
333 : : @descr Column default formatting is converted directly, other settings
334 : : are cached and converted in the finalizeImport() call. */
335 : : void setColumnModel( const ColumnModel& rModel );
336 : : /** Converts column default cell formatting. */
337 : : void convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const;
338 : :
339 : : /** Sets default height and hidden state for all unused rows in the sheet. */
340 : : void setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom );
341 : : /** Sets row settings for a specific row.
342 : : @descr Row default formatting is converted directly, other settings
343 : : are cached and converted in the finalizeImport() call. */
344 : : void setRowModel( const RowModel& rModel );
345 : :
346 : : /** Initial conversion before importing the worksheet. */
347 : : void initializeWorksheetImport();
348 : : /** Final conversion after importing the worksheet. */
349 : : void finalizeWorksheetImport();
350 : :
351 : : private:
352 : : typedef ::std::vector< sal_Int32 > OutlineLevelVec;
353 : : typedef ::std::pair< ColumnModel, sal_Int32 > ColumnModelRange;
354 : : typedef ::std::map< sal_Int32, ColumnModelRange > ColumnModelRangeMap;
355 : : typedef ::std::pair< RowModel, sal_Int32 > RowModelRange;
356 : : typedef ::std::map< sal_Int32, RowModelRange > RowModelRangeMap;
357 : : typedef ::std::list< HyperlinkModel > HyperlinkModelList;
358 : : typedef ::std::list< ValidationModel > ValidationModelList;
359 : :
360 : : /** Inserts all imported hyperlinks into their cell ranges. */
361 : : void finalizeHyperlinkRanges() const;
362 : : /** Generates the final URL for the passed hyperlink. */
363 : : OUString getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const;
364 : : /** Inserts a hyperlinks into the specified cell. */
365 : : void insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const;
366 : :
367 : : /** Inserts all imported data validations into their cell ranges. */
368 : : void finalizeValidationRanges() const;
369 : :
370 : : /** Converts column properties for all columns in the sheet. */
371 : : void convertColumns();
372 : : /** Converts column properties. */
373 : : void convertColumns( OutlineLevelVec& orColLevels, const ValueRange& rColRange, const ColumnModel& rModel );
374 : :
375 : : /** Converts row properties for all rows in the sheet. */
376 : : void convertRows();
377 : : /** Converts row properties. */
378 : : void convertRows( OutlineLevelVec& orRowLevels, const ValueRange& rRowRange, const RowModel& rModel, double fDefHeight = -1.0 );
379 : :
380 : : /** Converts outline grouping for the passed column or row. */
381 : : void convertOutlines( OutlineLevelVec& orLevels, sal_Int32 nColRow, sal_Int32 nLevel, bool bCollapsed, bool bRows );
382 : : /** Groups columns or rows for the given range. */
383 : : void groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapsed, bool bRows );
384 : :
385 : : /** Imports the drawings of the sheet (DML, VML, DFF) and updates the used area. */
386 : : void finalizeDrawings();
387 : :
388 : : private:
389 : : typedef ::std::auto_ptr< VmlDrawing > VmlDrawingPtr;
390 : : typedef ::std::auto_ptr< BiffSheetDrawing > BiffSheetDrawingPtr;
391 : :
392 : : const OUString maSheetCellRanges; /// Service name for a SheetCellRanges object.
393 : : const OUString maUrlTextField; /// Service name for a URL text field.
394 : : const CellAddress& mrMaxApiPos; /// Reference to maximum Calc cell address from address converter.
395 : : CellRangeAddress maUsedArea; /// Used area of the sheet, and sheet index of the sheet.
396 : : ColumnModel maDefColModel; /// Default column formatting.
397 : : ColumnModelRangeMap maColModels; /// Ranges of columns sorted by first column index.
398 : : RowModel maDefRowModel; /// Default row formatting.
399 : : RowModelRangeMap maRowModels; /// Ranges of rows sorted by first row index.
400 : : HyperlinkModelList maHyperlinks; /// Cell ranges containing hyperlinks.
401 : : ValidationModelList maValidations; /// Cell ranges containing data validation settings.
402 : : SheetDataBuffer maSheetData; /// Buffer for cell contents and cell formatting.
403 : : CondFormatBuffer maCondFormats; /// Buffer for conditional formatting.
404 : : CommentsBuffer maComments; /// Buffer for all cell comments in this sheet.
405 : : AutoFilterBuffer maAutoFilters; /// Sheet auto filters (not associated to a table).
406 : : QueryTableBuffer maQueryTables; /// Buffer for all web query tables in this sheet.
407 : : WorksheetSettings maSheetSett; /// Global settings for this sheet.
408 : : PageSettings maPageSett; /// Page/print settings for this sheet.
409 : : SheetViewSettings maSheetViewSett; /// View settings for this sheet.
410 : : VmlDrawingPtr mxVmlDrawing; /// Collection of all VML shapes.
411 : : ExtLst maExtLst; /// List of extended elements
412 : : BiffSheetDrawingPtr mxBiffDrawing; /// Collection of all BIFF/DFF shapes.
413 : : OUString maDrawingPath; /// Path to DrawingML fragment.
414 : : OUString maVmlDrawingPath; /// Path to legacy VML drawing fragment.
415 : : awt::Size maDrawPageSize; /// Current size of the drawing page in 1/100 mm.
416 : : awt::Rectangle maShapeBoundingBox; /// Bounding box for all shapes from all drawings.
417 : : ISegmentProgressBarRef mxProgressBar; /// Sheet progress bar.
418 : : ISegmentProgressBarRef mxRowProgress; /// Progress bar for row/cell processing.
419 : : ISegmentProgressBarRef mxFinalProgress; /// Progress bar for finalization.
420 : : WorksheetType meSheetType; /// Type of this sheet.
421 : : Reference< XSpreadsheet > mxSheet; /// Reference to the current sheet.
422 : : bool mbHasDefWidth; /// True = default column width is set from defaultColWidth attribute.
423 : : };
424 : :
425 : : // ----------------------------------------------------------------------------
426 : :
427 : 60 : WorksheetGlobals::WorksheetGlobals( const WorkbookHelper& rHelper, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
428 : : WorkbookHelper( rHelper ),
429 : : maSheetCellRanges( CREATE_OUSTRING( "com.sun.star.sheet.SheetCellRanges" ) ),
430 : : maUrlTextField( CREATE_OUSTRING( "com.sun.star.text.TextField.URL" ) ),
431 [ + - ]: 60 : mrMaxApiPos( rHelper.getAddressConverter().getMaxApiAddress() ),
432 : : maUsedArea( nSheet, SAL_MAX_INT32, SAL_MAX_INT32, -1, -1 ),
433 : : maSheetData( *this ),
434 : : maCondFormats( *this ),
435 : : maComments( *this ),
436 : : maAutoFilters( *this ),
437 : : maQueryTables( *this ),
438 : : maSheetSett( *this ),
439 : : maPageSett( *this ),
440 : : maSheetViewSett( *this ),
441 : : mxProgressBar( rxProgressBar ),
442 : : meSheetType( eSheetType ),
443 [ + - ]: 120 : mbHasDefWidth( false )
[ + - + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
444 : : {
445 [ + - ][ + - ]: 60 : mxSheet = getSheetFromDoc( nSheet );
446 [ - + ]: 60 : if( !mxSheet.is() )
447 : 0 : maUsedArea.Sheet = -1;
448 : :
449 : : // default column settings (width and hidden state may be updated later)
450 : 60 : maDefColModel.mfWidth = 8.5;
451 : 60 : maDefColModel.mnXfId = -1;
452 : 60 : maDefColModel.mnLevel = 0;
453 : 60 : maDefColModel.mbHidden = false;
454 : 60 : maDefColModel.mbCollapsed = false;
455 : :
456 : : // default row settings (height and hidden state may be updated later)
457 : 60 : maDefRowModel.mfHeight = 0.0;
458 : 60 : maDefRowModel.mnXfId = -1;
459 : 60 : maDefRowModel.mnLevel = 0;
460 : 60 : maDefRowModel.mbCustomHeight = false;
461 : 60 : maDefRowModel.mbCustomFormat = false;
462 : 60 : maDefRowModel.mbShowPhonetic = false;
463 : 60 : maDefRowModel.mbHidden = false;
464 : 60 : maDefRowModel.mbCollapsed = false;
465 : :
466 : : // buffers
467 [ + - ]: 60 : switch( getFilterType() )
[ + - - - ]
468 : : {
469 : : case FILTER_OOXML:
470 [ + - ][ + - ]: 60 : mxVmlDrawing.reset( new VmlDrawing( *this ) );
[ + - ][ + - ]
471 : 60 : break;
472 : : case FILTER_BIFF:
473 [ # # ][ # # ]: 0 : mxBiffDrawing.reset( new BiffSheetDrawing( *this ) );
[ # # ][ # # ]
474 : 0 : break;
475 : : case FILTER_UNKNOWN:
476 : 0 : break;
477 : : }
478 : :
479 : : // prepare progress bars
480 [ + - ]: 60 : if( mxProgressBar.get() )
481 : : {
482 [ + - ][ + - ]: 60 : mxRowProgress = mxProgressBar->createSegment( 0.5 );
[ + - ]
483 [ + - ][ + - ]: 60 : mxFinalProgress = mxProgressBar->createSegment( 0.5 );
[ + - ]
484 : : }
485 : 60 : }
486 : :
487 : 42 : Reference< XCell > WorksheetGlobals::getCell( const CellAddress& rAddress ) const
488 : : {
489 : 42 : Reference< XCell > xCell;
490 [ + - ]: 42 : if( mxSheet.is() ) try
491 : : {
492 [ + - ][ + - ]: 42 : xCell = mxSheet->getCellByPosition( rAddress.Column, rAddress.Row );
[ + - ][ # # ]
493 : : }
494 [ # # ]: 0 : catch( Exception& )
495 : : {
496 : : }
497 : 42 : return xCell;
498 : : }
499 : :
500 : 387 : Reference< XCellRange > WorksheetGlobals::getCellRange( const CellRangeAddress& rRange ) const
501 : : {
502 : 387 : Reference< XCellRange > xRange;
503 [ + - ]: 387 : if( mxSheet.is() ) try
504 : : {
505 [ + - ][ + - ]: 387 : xRange = mxSheet->getCellRangeByPosition( rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow );
[ + - ][ # # ]
506 : : }
507 [ # # ]: 0 : catch( Exception& )
508 : : {
509 : : }
510 : 387 : return xRange;
511 : : }
512 : :
513 : 0 : Reference< XSheetCellRanges > WorksheetGlobals::getCellRangeList( const ApiCellRangeList& rRanges ) const
514 : : {
515 : 0 : Reference< XSheetCellRanges > xRanges;
516 [ # # ][ # # ]: 0 : if( mxSheet.is() && !rRanges.empty() ) try
[ # # ]
517 : : {
518 [ # # ][ # # ]: 0 : xRanges.set( getBaseFilter().getModelFactory()->createInstance( maSheetCellRanges ), UNO_QUERY_THROW );
[ # # ][ # # ]
[ # # ]
519 [ # # ]: 0 : Reference< XSheetCellRangeContainer > xRangeCont( xRanges, UNO_QUERY_THROW );
520 [ # # ][ # # ]: 0 : xRangeCont->addRangeAddresses( ContainerHelper::vectorToSequence( rRanges ), sal_False );
[ # # ][ # # ]
[ # # ]
521 : : }
522 [ # # ]: 0 : catch( Exception& )
523 : : {
524 : : }
525 : 0 : return xRanges;
526 : : }
527 : :
528 : 0 : Reference< XCellRange > WorksheetGlobals::getColumn( sal_Int32 nCol ) const
529 : : {
530 : 0 : Reference< XCellRange > xColumn;
531 : : try
532 : : {
533 [ # # ]: 0 : Reference< XColumnRowRange > xColRowRange( mxSheet, UNO_QUERY_THROW );
534 [ # # ][ # # ]: 0 : Reference< XTableColumns > xColumns( xColRowRange->getColumns(), UNO_SET_THROW );
[ # # ]
535 [ # # ][ # # ]: 0 : xColumn.set( xColumns->getByIndex( nCol ), UNO_QUERY );
[ # # ][ # # ]
536 : : }
537 [ # # ]: 0 : catch( Exception& )
538 : : {
539 : : }
540 : 0 : return xColumn;
541 : : }
542 : :
543 : 0 : Reference< XCellRange > WorksheetGlobals::getRow( sal_Int32 nRow ) const
544 : : {
545 : 0 : Reference< XCellRange > xRow;
546 : : try
547 : : {
548 [ # # ]: 0 : Reference< XColumnRowRange > xColRowRange( mxSheet, UNO_QUERY_THROW );
549 [ # # ][ # # ]: 0 : Reference< XTableRows > xRows( xColRowRange->getRows(), UNO_SET_THROW );
[ # # ]
550 [ # # ][ # # ]: 0 : xRow.set( xRows->getByIndex( nRow ), UNO_QUERY );
[ # # ][ # # ]
551 : : }
552 [ # # ]: 0 : catch( Exception& )
553 : : {
554 : : }
555 : 0 : return xRow;
556 : : }
557 : :
558 : 129 : Reference< XTableColumns > WorksheetGlobals::getColumns( const ValueRange& rColRange ) const
559 : : {
560 : 129 : Reference< XTableColumns > xColumns;
561 [ + - ]: 129 : sal_Int32 nLastCol = ::std::min( rColRange.mnLast, mrMaxApiPos.Column );
562 [ + - ][ + + ]: 129 : if( (0 <= rColRange.mnFirst) && (rColRange.mnFirst <= nLastCol) )
563 : : {
564 [ + - ][ + - ]: 87 : Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), rColRange.mnFirst, 0, nLastCol, 0 ) ), UNO_QUERY );
565 [ + - ]: 87 : if( xRange.is() )
566 [ + - ][ + - ]: 129 : xColumns = xRange->getColumns();
[ + - ]
567 : : }
568 : 129 : return xColumns;
569 : : }
570 : :
571 : 171 : Reference< XTableRows > WorksheetGlobals::getRows( const ValueRange& rRowRange ) const
572 : : {
573 : 171 : Reference< XTableRows > xRows;
574 [ + - ]: 171 : sal_Int32 nLastRow = ::std::min( rRowRange.mnLast, mrMaxApiPos.Row );
575 [ + - ][ + - ]: 171 : if( (0 <= rRowRange.mnFirst) && (rRowRange.mnFirst <= nLastRow) )
576 : : {
577 [ + - ][ + - ]: 171 : Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), 0, rRowRange.mnFirst, 0, nLastRow ) ), UNO_QUERY );
578 [ + - ]: 171 : if( xRange.is() )
579 [ + - ][ + - ]: 171 : xRows = xRange->getRows();
[ + - ]
580 : : }
581 : 171 : return xRows;
582 : : }
583 : :
584 : 66 : Reference< XDrawPage > WorksheetGlobals::getDrawPage() const
585 : : {
586 : 66 : Reference< XDrawPage > xDrawPage;
587 : : try
588 : : {
589 [ + - ][ + - ]: 66 : xDrawPage = Reference< XDrawPageSupplier >( mxSheet, UNO_QUERY_THROW )->getDrawPage();
[ + - ][ # # ]
[ + - ]
590 : : }
591 [ # # ]: 0 : catch( Exception& )
592 : : {
593 : : }
594 : 66 : return xDrawPage;
595 : : }
596 : :
597 : 6 : const awt::Size& WorksheetGlobals::getDrawPageSize() const
598 : : {
599 : : OSL_ENSURE( (maDrawPageSize.Width > 0) && (maDrawPageSize.Height > 0), "WorksheetGlobals::getDrawPageSize - called too early, size invalid" );
600 : 6 : return maDrawPageSize;
601 : : }
602 : :
603 : 39 : awt::Point WorksheetGlobals::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const
604 : : {
605 : 39 : awt::Point aPoint;
606 [ + - ][ + - ]: 39 : PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) );
607 [ + - ]: 39 : aCellProp.getProperty( aPoint, PROP_Position );
608 [ + - ]: 39 : return aPoint;
609 : : }
610 : :
611 : 0 : awt::Size WorksheetGlobals::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const
612 : : {
613 : 0 : awt::Size aSize;
614 [ # # ][ # # ]: 0 : PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) );
615 [ # # ]: 0 : aCellProp.getProperty( aSize, PROP_Size );
616 [ # # ]: 0 : return aSize;
617 : : }
618 : :
619 : : namespace {
620 : :
621 : 36 : inline sal_Int32 lclGetMidAddr( sal_Int32 nBegAddr, sal_Int32 nEndAddr, sal_Int32 nBegPos, sal_Int32 nEndPos, sal_Int32 nSearchPos )
622 : : {
623 : : // use sal_Int64 to prevent integer overflow
624 : 36 : return nBegAddr + 1 + static_cast< sal_Int32 >( static_cast< sal_Int64 >( nEndAddr - nBegAddr - 2 ) * (nSearchPos - nBegPos) / (nEndPos - nBegPos) );
625 : : }
626 : :
627 : 12 : bool lclPrepareInterval( sal_Int32 nBegAddr, sal_Int32& rnMidAddr, sal_Int32 nEndAddr,
628 : : sal_Int32 nBegPos, sal_Int32 nEndPos, sal_Int32 nSearchPos )
629 : : {
630 : : // searched position before nBegPos -> use nBegAddr
631 [ - + ]: 12 : if( nSearchPos <= nBegPos )
632 : : {
633 : 0 : rnMidAddr = nBegAddr;
634 : 0 : return false;
635 : : }
636 : :
637 : : // searched position after nEndPos, or begin next to end -> use nEndAddr
638 [ + - ][ - + ]: 12 : if( (nSearchPos >= nEndPos) || (nBegAddr + 1 >= nEndAddr) )
639 : : {
640 : 0 : rnMidAddr = nEndAddr;
641 : 0 : return false;
642 : : }
643 : :
644 : : /* Otherwise find mid address according to position. lclGetMidAddr() will
645 : : return an address between nBegAddr and nEndAddr. */
646 : 12 : rnMidAddr = lclGetMidAddr( nBegAddr, nEndAddr, nBegPos, nEndPos, nSearchPos );
647 : 12 : return true;
648 : : }
649 : :
650 : 36 : bool lclUpdateInterval( sal_Int32& rnBegAddr, sal_Int32& rnMidAddr, sal_Int32& rnEndAddr,
651 : : sal_Int32& rnBegPos, sal_Int32 nMidPos, sal_Int32& rnEndPos, sal_Int32 nSearchPos )
652 : : {
653 : : // nSearchPos < nMidPos: use the interval [begin,mid] in the next iteration
654 [ + + ]: 36 : if( nSearchPos < nMidPos )
655 : : {
656 : : // if rnBegAddr is next to rnMidAddr, the latter is the column/row in question
657 [ - + ]: 12 : if( rnBegAddr + 1 >= rnMidAddr )
658 : 0 : return false;
659 : : // otherwise, set interval end to mid
660 : 12 : rnEndPos = nMidPos;
661 : 12 : rnEndAddr = rnMidAddr;
662 : 12 : rnMidAddr = lclGetMidAddr( rnBegAddr, rnEndAddr, rnBegPos, rnEndPos, nSearchPos );
663 : 12 : return true;
664 : : }
665 : :
666 : : // nSearchPos > nMidPos: use the interval [mid,end] in the next iteration
667 [ + - ]: 24 : if( nSearchPos > nMidPos )
668 : : {
669 : : // if rnMidAddr is next to rnEndAddr, the latter is the column/row in question
670 [ + + ]: 24 : if( rnMidAddr + 1 >= rnEndAddr )
671 : : {
672 : 12 : rnMidAddr = rnEndAddr;
673 : 12 : return false;
674 : : }
675 : : // otherwise, set interval start to mid
676 : 12 : rnBegPos = nMidPos;
677 : 12 : rnBegAddr = rnMidAddr;
678 : 12 : rnMidAddr = lclGetMidAddr( rnBegAddr, rnEndAddr, rnBegPos, rnEndPos, nSearchPos );
679 : 12 : return true;
680 : : }
681 : :
682 : : // nSearchPos == nMidPos: rnMidAddr is the column/row in question, do not loop anymore
683 : 36 : return false;
684 : : }
685 : :
686 : : } // namespace
687 : :
688 : 6 : CellAddress WorksheetGlobals::getCellAddressFromPosition( const awt::Point& rPosition ) const
689 : : {
690 : : // starting cell address and its position in drawing layer (top-left edge)
691 : 6 : sal_Int32 nBegCol = 0;
692 : 6 : sal_Int32 nBegRow = 0;
693 : 6 : awt::Point aBegPos( 0, 0 );
694 : :
695 : : // end cell address and its position in drawing layer (bottom-right edge)
696 : 6 : sal_Int32 nEndCol = mrMaxApiPos.Column + 1;
697 : 6 : sal_Int32 nEndRow = mrMaxApiPos.Row + 1;
698 : 6 : awt::Point aEndPos( maDrawPageSize.Width, maDrawPageSize.Height );
699 : :
700 : : // starting point for interval search
701 : : sal_Int32 nMidCol, nMidRow;
702 : 6 : bool bLoopCols = lclPrepareInterval( nBegCol, nMidCol, nEndCol, aBegPos.X, aEndPos.X, rPosition.X );
703 : 6 : bool bLoopRows = lclPrepareInterval( nBegRow, nMidRow, nEndRow, aBegPos.Y, aEndPos.Y, rPosition.Y );
704 [ + - ]: 6 : awt::Point aMidPos = getCellPosition( nMidCol, nMidRow );
705 : :
706 : : /* The loop will find the column/row index of the cell right of/below
707 : : the cell containing the passed point, unless the point is located at
708 : : the top or left border of the containing cell. */
709 [ + + ][ - + ]: 24 : while( bLoopCols || bLoopRows )
[ + + ]
710 : : {
711 [ + - ][ + + ]: 18 : bLoopCols = bLoopCols && lclUpdateInterval( nBegCol, nMidCol, nEndCol, aBegPos.X, aMidPos.X, aEndPos.X, rPosition.X );
712 [ + - ][ + + ]: 18 : bLoopRows = bLoopRows && lclUpdateInterval( nBegRow, nMidRow, nEndRow, aBegPos.Y, aMidPos.Y, aEndPos.Y, rPosition.Y );
713 [ + - ]: 18 : aMidPos = getCellPosition( nMidCol, nMidRow );
714 : : }
715 : :
716 : : /* The cell left of/above the current search position contains the passed
717 : : point, unless the point is located on the top/left border of the cell,
718 : : or the last column/row of the sheet has been reached. */
719 [ + - ]: 6 : if( aMidPos.X > rPosition.X ) --nMidCol;
720 [ + - ]: 6 : if( aMidPos.Y > rPosition.Y ) --nMidRow;
721 : 6 : return CellAddress( getSheetIndex(), nMidCol, nMidRow );
722 : : }
723 : :
724 : 3 : CellRangeAddress WorksheetGlobals::getCellRangeFromRectangle( const awt::Rectangle& rRect ) const
725 : : {
726 [ + - ]: 3 : CellAddress aStartAddr = getCellAddressFromPosition( awt::Point( rRect.X, rRect.Y ) );
727 : 3 : awt::Point aBotRight( rRect.X + rRect.Width, rRect.Y + rRect.Height );
728 [ + - ]: 3 : CellAddress aEndAddr = getCellAddressFromPosition( aBotRight );
729 : 3 : bool bMultiCols = aStartAddr.Column < aEndAddr.Column;
730 : 3 : bool bMultiRows = aStartAddr.Row < aEndAddr.Row;
731 [ - + ][ # # ]: 3 : if( bMultiCols || bMultiRows )
732 : : {
733 : : /* Reduce end position of the cell range to previous column or row, if
734 : : the rectangle ends exactly between two columns or rows. */
735 [ + - ]: 3 : awt::Point aEndPos = getCellPosition( aEndAddr.Column, aEndAddr.Row );
736 [ + - ][ - + ]: 3 : if( bMultiCols && (aBotRight.X <= aEndPos.X) )
737 : 0 : --aEndAddr.Column;
738 [ - + ][ # # ]: 3 : if( bMultiRows && (aBotRight.Y <= aEndPos.Y) )
739 : 3 : --aEndAddr.Row;
740 : : }
741 : 3 : return CellRangeAddress( getSheetIndex(), aStartAddr.Column, aStartAddr.Row, aEndAddr.Column, aEndAddr.Row );
742 : : }
743 : :
744 : 0 : void WorksheetGlobals::setPageBreak( const PageBreakModel& rModel, bool bRowBreak )
745 : : {
746 [ # # ][ # # ]: 0 : if( rModel.mbManual && (rModel.mnColRow > 0) )
747 : : {
748 [ # # ][ # # ]: 0 : PropertySet aPropSet( bRowBreak ? getRow( rModel.mnColRow ) : getColumn( rModel.mnColRow ) );
[ # # ][ # # ]
749 [ # # ][ # # ]: 0 : aPropSet.setProperty( PROP_IsStartOfNewPage, true );
750 : : }
751 : 0 : }
752 : :
753 : 0 : void WorksheetGlobals::setHyperlink( const HyperlinkModel& rModel )
754 : : {
755 : 0 : maHyperlinks.push_back( rModel );
756 : 0 : }
757 : :
758 : 0 : void WorksheetGlobals::setValidation( const ValidationModel& rModel )
759 : : {
760 : 0 : maValidations.push_back( rModel );
761 : 0 : }
762 : :
763 : 6 : void WorksheetGlobals::setDrawingPath( const OUString& rDrawingPath )
764 : : {
765 : 6 : maDrawingPath = rDrawingPath;
766 : 6 : }
767 : :
768 : 6 : void WorksheetGlobals::setVmlDrawingPath( const OUString& rVmlDrawingPath )
769 : : {
770 : 6 : maVmlDrawingPath = rVmlDrawingPath;
771 : 6 : }
772 : :
773 : 534 : void WorksheetGlobals::extendUsedArea( const CellAddress& rAddress )
774 : : {
775 : 534 : maUsedArea.StartColumn = ::std::min( maUsedArea.StartColumn, rAddress.Column );
776 : 534 : maUsedArea.StartRow = ::std::min( maUsedArea.StartRow, rAddress.Row );
777 : 534 : maUsedArea.EndColumn = ::std::max( maUsedArea.EndColumn, rAddress.Column );
778 : 534 : maUsedArea.EndRow = ::std::max( maUsedArea.EndRow, rAddress.Row );
779 : 534 : }
780 : :
781 : 45 : void WorksheetGlobals::extendUsedArea( const CellRangeAddress& rRange )
782 : : {
783 [ + - ]: 45 : extendUsedArea( CellAddress( rRange.Sheet, rRange.StartColumn, rRange.StartRow ) );
784 [ + - ]: 45 : extendUsedArea( CellAddress( rRange.Sheet, rRange.EndColumn, rRange.EndRow ) );
785 : 45 : }
786 : :
787 : 3 : void WorksheetGlobals::extendShapeBoundingBox( const awt::Rectangle& rShapeRect )
788 : : {
789 [ + - ][ + - ]: 3 : if( (maShapeBoundingBox.Width == 0) && (maShapeBoundingBox.Height == 0) )
790 : : {
791 : : // width and height of maShapeBoundingBox are assumed to be zero on first cell
792 : 3 : maShapeBoundingBox = rShapeRect;
793 : : }
794 : : else
795 : : {
796 [ # # ]: 0 : sal_Int32 nEndX = ::std::max( maShapeBoundingBox.X + maShapeBoundingBox.Width, rShapeRect.X + rShapeRect.Width );
797 [ # # ]: 0 : sal_Int32 nEndY = ::std::max( maShapeBoundingBox.Y + maShapeBoundingBox.Height, rShapeRect.Y + rShapeRect.Height );
798 : 0 : maShapeBoundingBox.X = ::std::min( maShapeBoundingBox.X, rShapeRect.X );
799 : 0 : maShapeBoundingBox.Y = ::std::min( maShapeBoundingBox.Y, rShapeRect.Y );
800 : 0 : maShapeBoundingBox.Width = nEndX - maShapeBoundingBox.X;
801 : 0 : maShapeBoundingBox.Height = nEndY - maShapeBoundingBox.Y;
802 : : }
803 : 3 : }
804 : :
805 : 18 : void WorksheetGlobals::setBaseColumnWidth( sal_Int32 nWidth )
806 : : {
807 : : // do not modify width, if setDefaultColumnWidth() has been used
808 [ + - ][ + - ]: 18 : if( !mbHasDefWidth && (nWidth > 0) )
809 : : {
810 : : // #i3006# add 5 pixels padding to the width
811 : 18 : const UnitConverter& rUnitConv = getUnitConverter();
812 : : maDefColModel.mfWidth = rUnitConv.scaleFromMm100(
813 : 18 : rUnitConv.scaleToMm100( nWidth, UNIT_DIGIT ) + rUnitConv.scaleToMm100( 5, UNIT_SCREENX ), UNIT_DIGIT );
814 : : }
815 : 18 : }
816 : :
817 : 18 : void WorksheetGlobals::setDefaultColumnWidth( double fWidth )
818 : : {
819 : : // overrides a width set with setBaseColumnWidth()
820 [ - + ]: 18 : if( fWidth > 0.0 )
821 : : {
822 : 0 : maDefColModel.mfWidth = fWidth;
823 : 0 : mbHasDefWidth = true;
824 : : }
825 : 18 : }
826 : :
827 : 69 : void WorksheetGlobals::setColumnModel( const ColumnModel& rModel )
828 : : {
829 : : // convert 1-based OOXML column indexes to 0-based API column indexes
830 : 69 : sal_Int32 nFirstCol = rModel.maRange.mnFirst - 1;
831 : 69 : sal_Int32 nLastCol = rModel.maRange.mnLast - 1;
832 [ + - ][ + - ]: 69 : if( getAddressConverter().checkCol( nFirstCol, true ) && (nFirstCol <= nLastCol) )
[ + - ][ + - ]
[ + - ]
833 : : {
834 : : // validate last column index
835 [ + - ][ + - ]: 69 : if( !getAddressConverter().checkCol( nLastCol, true ) )
[ + + ]
836 : 42 : nLastCol = mrMaxApiPos.Column;
837 : : // try to find entry in column model map that is able to merge with the passed model
838 : 69 : bool bInsertModel = true;
839 [ + + ]: 69 : if( !maColModels.empty() )
840 : : {
841 : : // find first column model range following nFirstCol (nFirstCol < aIt->first), or end of map
842 [ + - ]: 18 : ColumnModelRangeMap::iterator aIt = maColModels.upper_bound( nFirstCol );
843 : : OSL_ENSURE( aIt == maColModels.end(), "WorksheetGlobals::setColModel - columns are unsorted" );
844 : : // if inserting before another column model, get last free column
845 : : OSL_ENSURE( (aIt == maColModels.end()) || (nLastCol < aIt->first), "WorksheetGlobals::setColModel - multiple models of the same column" );
846 [ - + ]: 18 : if( aIt != maColModels.end() )
847 [ # # ]: 0 : nLastCol = ::std::min( nLastCol, aIt->first - 1 );
848 [ + - ]: 18 : if( aIt != maColModels.begin() )
849 : : {
850 : : // go to previous map element (which may be able to merge with the passed model)
851 : 18 : --aIt;
852 : : // the usage of upper_bound() above ensures that aIt->first is less than or equal to nFirstCol now
853 : 18 : sal_Int32& rnLastMapCol = aIt->second.second;
854 : : OSL_ENSURE( rnLastMapCol < nFirstCol, "WorksheetGlobals::setColModel - multiple models of the same column" );
855 [ + - ]: 18 : nFirstCol = ::std::max( rnLastMapCol + 1, nFirstCol );
856 [ + - ][ + - ]: 18 : if( (rnLastMapCol + 1 == nFirstCol) && (nFirstCol <= nLastCol) && aIt->second.first.isMergeable( rModel ) )
[ - + ][ - + ]
857 : : {
858 : : // can merge with existing model, update last column index
859 : 0 : rnLastMapCol = nLastCol;
860 : 18 : bInsertModel = false;
861 : : }
862 : : }
863 : : }
864 [ + - ]: 69 : if( nFirstCol <= nLastCol )
865 : : {
866 : : // insert the column model, if it has not been merged with another
867 [ + - ]: 69 : if( bInsertModel )
868 [ + - ][ + - ]: 69 : maColModels[ nFirstCol ] = ColumnModelRange( rModel, nLastCol );
869 : : // set column formatting directly
870 [ + - ]: 69 : convertColumnFormat( nFirstCol, nLastCol, rModel.mnXfId );
871 : : }
872 : : }
873 : 69 : }
874 : :
875 : 69 : void WorksheetGlobals::convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const
876 : : {
877 : 69 : CellRangeAddress aRange( getSheetIndex(), nFirstCol, 0, nLastCol, mrMaxApiPos.Row );
878 [ + - ][ + - ]: 69 : if( getAddressConverter().validateCellRange( aRange, true, false ) )
[ + - ]
879 : : {
880 [ + - ][ + - ]: 69 : PropertySet aPropSet( getCellRange( aRange ) );
881 [ + - ][ + - ]: 69 : getStyles().writeCellXfToPropertySet( aPropSet, nXfId );
[ + - ]
882 : : }
883 : 69 : }
884 : :
885 : 18 : void WorksheetGlobals::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom )
886 : : {
887 : 18 : maDefRowModel.mfHeight = fHeight;
888 : 18 : maDefRowModel.mbCustomHeight = bCustomHeight;
889 : 18 : maDefRowModel.mbHidden = bHidden;
890 : 18 : maDefRowModel.mbThickTop = bThickTop;
891 : 18 : maDefRowModel.mbThickBottom = bThickBottom;
892 : 18 : }
893 : :
894 : 243 : void WorksheetGlobals::setRowModel( const RowModel& rModel )
895 : : {
896 : : // convert 1-based OOXML row index to 0-based API row index
897 : 243 : sal_Int32 nRow = rModel.mnRow - 1;
898 [ + - ][ + - ]: 243 : if( getAddressConverter().checkRow( nRow, true ) )
[ + - ]
899 : : {
900 : : // try to find entry in row model map that is able to merge with the passed model
901 : 243 : bool bInsertModel = true;
902 : 243 : bool bUnusedRow = true;
903 [ + + ]: 243 : if( !maRowModels.empty() )
904 : : {
905 : : // find first row model range following nRow (nRow < aIt->first), or end of map
906 [ + - ]: 201 : RowModelRangeMap::iterator aIt = maRowModels.upper_bound( nRow );
907 : : OSL_ENSURE( aIt == maRowModels.end(), "WorksheetGlobals::setRowModel - rows are unsorted" );
908 [ + - ]: 201 : if( aIt != maRowModels.begin() )
909 : : {
910 : : // go to previous map element (which may be able to merge with the passed model)
911 : 201 : --aIt;
912 : : // the usage of upper_bound() above ensures that aIt->first is less than or equal to nRow now
913 : 201 : sal_Int32& rnLastMapRow = aIt->second.second;
914 : 201 : bUnusedRow = rnLastMapRow < nRow;
915 : : OSL_ENSURE( bUnusedRow, "WorksheetGlobals::setRowModel - multiple models of the same row" );
916 [ + + ][ + + ]: 201 : if( (rnLastMapRow + 1 == nRow) && aIt->second.first.isMergeable( rModel ) )
[ + + ]
917 : : {
918 : : // can merge with existing model, update last row index
919 : 129 : ++rnLastMapRow;
920 : 201 : bInsertModel = false;
921 : : }
922 : : }
923 : : }
924 [ + - ]: 243 : if( bUnusedRow )
925 : : {
926 : : // insert the row model, if it has not been merged with another
927 [ + + ]: 243 : if( bInsertModel )
928 [ + - ][ + - ]: 114 : maRowModels[ nRow ] = RowModelRange( rModel, nRow );
929 : : // set row formatting
930 [ + - ]: 243 : maSheetData.setRowFormat( nRow, rModel.mnXfId, rModel.mbCustomFormat );
931 : : // set column spans
932 [ + - ]: 243 : maSheetData.setColSpans( nRow, rModel.maColSpans );
933 : : }
934 : : }
935 [ + - ]: 243 : lclUpdateProgressBar( mxRowProgress, maUsedArea, nRow );
936 : 243 : }
937 : :
938 : 60 : void WorksheetGlobals::initializeWorksheetImport()
939 : : {
940 : : // set default cell style for unused cells
941 [ + - ]: 60 : PropertySet aPropSet( mxSheet );
942 [ + - ][ + - ]: 60 : aPropSet.setProperty( PROP_CellStyle, getStyles().getDefaultStyleName() );
[ + - ]
943 : :
944 : : /* Remember the current sheet index in global data, needed by global
945 : : objects, e.g. the chart converter. */
946 [ + - ][ + - ]: 60 : setCurrentSheetIndex( getSheetIndex() );
947 : 60 : }
948 : :
949 : 60 : void WorksheetGlobals::finalizeWorksheetImport()
950 : : {
951 : 60 : lclUpdateProgressBar( mxRowProgress, 1.0 );
952 : 60 : maSheetData.finalizeImport();
953 : 60 : lclUpdateProgressBar( mxFinalProgress, 0.25 );
954 : 60 : finalizeHyperlinkRanges();
955 : 60 : finalizeValidationRanges();
956 : 60 : maAutoFilters.finalizeImport( getSheetIndex() );
957 : 60 : maQueryTables.finalizeImport();
958 : 60 : maSheetSett.finalizeImport();
959 : 60 : maPageSett.finalizeImport();
960 : 60 : maSheetViewSett.finalizeImport();
961 : :
962 : 60 : lclUpdateProgressBar( mxFinalProgress, 0.5 );
963 : 60 : convertColumns();
964 : 60 : convertRows();
965 : 60 : lclUpdateProgressBar( mxFinalProgress, 0.75 );
966 : 60 : finalizeDrawings();
967 : 60 : lclUpdateProgressBar( mxFinalProgress, 1.0 );
968 : :
969 : : // forget current sheet index in global data
970 : 60 : setCurrentSheetIndex( -1 );
971 : 60 : }
972 : :
973 : : // private --------------------------------------------------------------------
974 : :
975 : 60 : void WorksheetGlobals::finalizeHyperlinkRanges() const
976 : : {
977 [ - + ]: 60 : for( HyperlinkModelList::const_iterator aIt = maHyperlinks.begin(), aEnd = maHyperlinks.end(); aIt != aEnd; ++aIt )
978 : : {
979 [ # # ]: 0 : OUString aUrl = getHyperlinkUrl( *aIt );
980 : : // try to insert URL into each cell of the range
981 [ # # ]: 0 : if( !aUrl.isEmpty() )
982 [ # # ]: 0 : for( CellAddress aAddress( getSheetIndex(), aIt->maRange.StartColumn, aIt->maRange.StartRow ); aAddress.Row <= aIt->maRange.EndRow; ++aAddress.Row )
983 [ # # ]: 0 : for( aAddress.Column = aIt->maRange.StartColumn; aAddress.Column <= aIt->maRange.EndColumn; ++aAddress.Column )
984 [ # # ]: 0 : insertHyperlink( aAddress, aUrl );
985 : 0 : }
986 : 60 : }
987 : :
988 : 0 : OUString WorksheetGlobals::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const
989 : : {
990 : 0 : OUStringBuffer aUrlBuffer;
991 [ # # ]: 0 : if( !rHyperlink.maTarget.isEmpty() )
992 [ # # ][ # # ]: 0 : aUrlBuffer.append( getBaseFilter().getAbsoluteUrl( rHyperlink.maTarget ) );
[ # # ]
993 [ # # ]: 0 : if( !rHyperlink.maLocation.isEmpty() )
994 [ # # ][ # # ]: 0 : aUrlBuffer.append( sal_Unicode( '#' ) ).append( rHyperlink.maLocation );
995 [ # # ]: 0 : OUString aUrl = aUrlBuffer.makeStringAndClear();
996 : :
997 : : // convert '#SheetName!A1' to '#SheetName.A1'
998 [ # # ][ # # ]: 0 : if( !aUrl.isEmpty() && (aUrl[ 0 ] == '#') )
[ # # ]
999 : : {
1000 : 0 : sal_Int32 nSepPos = aUrl.lastIndexOf( '!' );
1001 [ # # ]: 0 : if( nSepPos > 0 )
1002 : : {
1003 : : // replace the exclamation mark with a period
1004 : 0 : aUrl = aUrl.replaceAt( nSepPos, 1, OUString( sal_Unicode( '.' ) ) );
1005 : : // #i66592# convert sheet names that have been renamed on import
1006 : 0 : OUString aSheetName = aUrl.copy( 1, nSepPos - 1 );
1007 [ # # ][ # # ]: 0 : OUString aCalcName = getWorksheets().getCalcSheetName( aSheetName );
1008 [ # # ]: 0 : if( !aCalcName.isEmpty() )
1009 : 0 : aUrl = aUrl.replaceAt( 1, nSepPos - 1, aCalcName );
1010 : : }
1011 : : }
1012 : :
1013 : 0 : return aUrl;
1014 : : }
1015 : :
1016 : 0 : void WorksheetGlobals::insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const
1017 : : {
1018 [ # # ]: 0 : Reference< XCell > xCell = getCell( rAddress );
1019 [ # # ][ # # ]: 0 : if( xCell.is() ) switch( xCell->getType() )
[ # # ][ # # ]
1020 : : {
1021 : : // #i54261# restrict creation of URL field to text cells
1022 : : case CellContentType_TEXT:
1023 : : {
1024 [ # # ]: 0 : Reference< XText > xText( xCell, UNO_QUERY );
1025 [ # # ]: 0 : if( xText.is() )
1026 : : {
1027 : : // create a URL field object and set its properties
1028 [ # # ][ # # ]: 0 : Reference< XTextContent > xUrlField( getBaseFilter().getModelFactory()->createInstance( maUrlTextField ), UNO_QUERY );
[ # # ][ # # ]
[ # # ]
1029 : : OSL_ENSURE( xUrlField.is(), "WorksheetGlobals::insertHyperlink - cannot create text field" );
1030 [ # # ]: 0 : if( xUrlField.is() )
1031 : : {
1032 : : // properties of the URL field
1033 [ # # ]: 0 : PropertySet aPropSet( xUrlField );
1034 [ # # ]: 0 : aPropSet.setProperty( PROP_URL, rUrl );
1035 [ # # ][ # # ]: 0 : aPropSet.setProperty( PROP_Representation, xText->getString() );
[ # # ]
1036 : : try
1037 : : {
1038 : : // insert the field into the cell
1039 [ # # ][ # # ]: 0 : xText->setString( OUString() );
1040 [ # # ][ # # ]: 0 : Reference< XTextRange > xRange( xText->createTextCursor(), UNO_QUERY_THROW );
[ # # ]
1041 [ # # ][ # # ]: 0 : xText->insertTextContent( xRange, xUrlField, sal_False );
[ # # ]
1042 : : }
1043 [ # # ]: 0 : catch( const Exception& )
1044 : : {
1045 : : OSL_FAIL( "WorksheetData::insertHyperlink - cannot insert text field" );
1046 [ # # ]: 0 : }
1047 : 0 : }
1048 : 0 : }
1049 : : }
1050 : 0 : break;
1051 : :
1052 : : // fix for #i31050# disabled, HYPERLINK is not able to return numeric value (#i91351#)
1053 : : #if 0
1054 : : // #i31050# replace number with HYPERLINK function
1055 : : case CellContentType_VALUE:
1056 : : {
1057 : : Reference< XFormulaTokens > xTokens( xCell, UNO_QUERY );
1058 : : ApiTokenSequence aTokens = getFormulaParser().convertNumberToHyperlink( rUrl, xCell->getValue() );
1059 : : OSL_ENSURE( xTokens.is(), "WorksheetHelper::insertHyperlink - missing formula token interface" );
1060 : : if( xTokens.is() && aTokens.hasElements() )
1061 : : xTokens->setTokens( aTokens );
1062 : : }
1063 : : break;
1064 : : #endif
1065 : :
1066 : : default:;
1067 : 0 : }
1068 : 0 : }
1069 : :
1070 : 60 : void WorksheetGlobals::finalizeValidationRanges() const
1071 : : {
1072 [ - + ]: 60 : for( ValidationModelList::const_iterator aIt = maValidations.begin(), aEnd = maValidations.end(); aIt != aEnd; ++aIt )
1073 : : {
1074 [ # # ][ # # ]: 0 : PropertySet aPropSet( getCellRangeList( aIt->maRanges ) );
1075 : :
1076 [ # # ][ # # ]: 0 : Reference< XPropertySet > xValidation( aPropSet.getAnyProperty( PROP_Validation ), UNO_QUERY );
1077 [ # # ]: 0 : if( xValidation.is() )
1078 : : {
1079 [ # # ]: 0 : PropertySet aValProps( xValidation );
1080 : :
1081 : : // convert validation type to API enum
1082 : 0 : ValidationType eType = ValidationType_ANY;
1083 [ # # # # : 0 : switch( aIt->mnType )
# # # #
# ]
1084 : : {
1085 : 0 : case XML_custom: eType = ValidationType_CUSTOM; break;
1086 : 0 : case XML_date: eType = ValidationType_DATE; break;
1087 : 0 : case XML_decimal: eType = ValidationType_DECIMAL; break;
1088 : 0 : case XML_list: eType = ValidationType_LIST; break;
1089 : 0 : case XML_none: eType = ValidationType_ANY; break;
1090 : 0 : case XML_textLength: eType = ValidationType_TEXT_LEN; break;
1091 : 0 : case XML_time: eType = ValidationType_TIME; break;
1092 : 0 : case XML_whole: eType = ValidationType_WHOLE; break;
1093 : : default: OSL_FAIL( "WorksheetData::finalizeValidationRanges - unknown validation type" );
1094 : : }
1095 [ # # ]: 0 : aValProps.setProperty( PROP_Type, eType );
1096 : :
1097 : : // convert error alert style to API enum
1098 : 0 : ValidationAlertStyle eAlertStyle = ValidationAlertStyle_STOP;
1099 [ # # # # ]: 0 : switch( aIt->mnErrorStyle )
1100 : : {
1101 : 0 : case XML_information: eAlertStyle = ValidationAlertStyle_INFO; break;
1102 : 0 : case XML_stop: eAlertStyle = ValidationAlertStyle_STOP; break;
1103 : 0 : case XML_warning: eAlertStyle = ValidationAlertStyle_WARNING; break;
1104 : : default: OSL_FAIL( "WorksheetData::finalizeValidationRanges - unknown error style" );
1105 : : }
1106 [ # # ]: 0 : aValProps.setProperty( PROP_ErrorAlertStyle, eAlertStyle );
1107 : :
1108 : : // convert dropdown style to API visibility constants
1109 [ # # ]: 0 : sal_Int16 nVisibility = aIt->mbNoDropDown ? TableValidationVisibility::INVISIBLE : TableValidationVisibility::UNSORTED;
1110 [ # # ]: 0 : aValProps.setProperty( PROP_ShowList, nVisibility );
1111 : :
1112 : : // messages
1113 [ # # ]: 0 : aValProps.setProperty( PROP_ShowInputMessage, aIt->mbShowInputMsg );
1114 [ # # ]: 0 : aValProps.setProperty( PROP_InputTitle, aIt->maInputTitle );
1115 [ # # ]: 0 : aValProps.setProperty( PROP_InputMessage, aIt->maInputMessage );
1116 [ # # ]: 0 : aValProps.setProperty( PROP_ShowErrorMessage, aIt->mbShowErrorMsg );
1117 [ # # ]: 0 : aValProps.setProperty( PROP_ErrorTitle, aIt->maErrorTitle );
1118 [ # # ]: 0 : aValProps.setProperty( PROP_ErrorMessage, aIt->maErrorMessage );
1119 : :
1120 : : // allow blank cells
1121 [ # # ]: 0 : aValProps.setProperty( PROP_IgnoreBlankCells, aIt->mbAllowBlank );
1122 : :
1123 : : try
1124 : : {
1125 : : // condition operator
1126 [ # # ]: 0 : Reference< XSheetCondition2 > xSheetCond( xValidation, UNO_QUERY_THROW );
1127 [ # # ][ # # ]: 0 : xSheetCond->setConditionOperator( CondFormatBuffer::convertToApiOperator( aIt->mnOperator ) );
[ # # ]
1128 : :
1129 : : // condition formulas
1130 [ # # ]: 0 : Reference< XMultiFormulaTokens > xTokens( xValidation, UNO_QUERY_THROW );
1131 [ # # ][ # # ]: 0 : xTokens->setTokens( 0, aIt->maTokens1 );
1132 [ # # ][ # # ]: 0 : xTokens->setTokens( 1, aIt->maTokens2 );
[ # # ]
1133 : : }
1134 [ # # ]: 0 : catch( Exception& )
1135 : : {
1136 : : }
1137 : :
1138 : : // write back validation settings to cell range(s)
1139 [ # # ][ # # ]: 0 : aPropSet.setProperty( PROP_Validation, xValidation );
1140 : : }
1141 [ # # ]: 0 : }
1142 : 60 : }
1143 : :
1144 : 60 : void WorksheetGlobals::convertColumns()
1145 : : {
1146 : 60 : sal_Int32 nNextCol = 0;
1147 : 60 : sal_Int32 nMaxCol = mrMaxApiPos.Column;
1148 : : // stores first grouped column index for each level
1149 [ + - ]: 60 : OutlineLevelVec aColLevels;
1150 : :
1151 [ + + ]: 129 : for( ColumnModelRangeMap::iterator aIt = maColModels.begin(), aEnd = maColModels.end(); aIt != aEnd; ++aIt )
1152 : : {
1153 : : // column indexes are stored 0-based in maColModels
1154 [ + - ][ + - ]: 69 : ValueRange aColRange( ::std::max( aIt->first, nNextCol ), ::std::min( aIt->second.second, nMaxCol ) );
1155 : : // process gap between two column models, use default column model
1156 [ - + ]: 69 : if( nNextCol < aColRange.mnFirst )
1157 [ # # ]: 0 : convertColumns( aColLevels, ValueRange( nNextCol, aColRange.mnFirst - 1 ), maDefColModel );
1158 : : // process the column model
1159 [ + - ]: 69 : convertColumns( aColLevels, aColRange, aIt->second.first );
1160 : : // cache next column to be processed
1161 : 69 : nNextCol = aColRange.mnLast + 1;
1162 : : }
1163 : :
1164 : : // remaining default columns to end of sheet
1165 [ + - ]: 60 : convertColumns( aColLevels, ValueRange( nNextCol, nMaxCol ), maDefColModel );
1166 : : // close remaining column outlines spanning to end of sheet
1167 [ + - ]: 60 : convertOutlines( aColLevels, nMaxCol + 1, 0, false, false );
1168 : 60 : }
1169 : :
1170 : 129 : void WorksheetGlobals::convertColumns( OutlineLevelVec& orColLevels,
1171 : : const ValueRange& rColRange, const ColumnModel& rModel )
1172 : : {
1173 [ + - ][ + - ]: 129 : PropertySet aPropSet( getColumns( rColRange ) );
1174 : :
1175 : : // column width: convert 'number of characters' to column width in 1/100 mm
1176 [ + - ][ + - ]: 129 : sal_Int32 nWidth = getUnitConverter().scaleToMm100( rModel.mfWidth, UNIT_DIGIT );
1177 : : // macro sheets have double width
1178 [ - + ]: 129 : if( meSheetType == SHEETTYPE_MACROSHEET )
1179 : 0 : nWidth *= 2;
1180 [ + - ]: 129 : if( nWidth > 0 )
1181 [ + - ]: 129 : aPropSet.setProperty( PROP_Width, nWidth );
1182 : :
1183 : : // hidden columns: TODO: #108683# hide columns later?
1184 [ - + ]: 129 : if( rModel.mbHidden )
1185 [ # # ]: 0 : aPropSet.setProperty( PROP_IsVisible, false );
1186 : :
1187 : : // outline settings for this column range
1188 [ + - ][ + - ]: 129 : convertOutlines( orColLevels, rColRange.mnFirst, rModel.mnLevel, rModel.mbCollapsed, false );
1189 : 129 : }
1190 : :
1191 : 60 : void WorksheetGlobals::convertRows()
1192 : : {
1193 : 60 : sal_Int32 nNextRow = 0;
1194 : 60 : sal_Int32 nMaxRow = mrMaxApiPos.Row;
1195 : : // stores first grouped row index for each level
1196 [ + - ]: 60 : OutlineLevelVec aRowLevels;
1197 : :
1198 [ + + ]: 174 : for( RowModelRangeMap::iterator aIt = maRowModels.begin(), aEnd = maRowModels.end(); aIt != aEnd; ++aIt )
1199 : : {
1200 : : // row indexes are stored 0-based in maRowModels
1201 [ + - ][ + - ]: 114 : ValueRange aRowRange( ::std::max( aIt->first, nNextRow ), ::std::min( aIt->second.second, nMaxRow ) );
1202 : : // process gap between two row models, use default row model
1203 [ + + ]: 114 : if( nNextRow < aRowRange.mnFirst )
1204 [ + - ]: 45 : convertRows( aRowLevels, ValueRange( nNextRow, aRowRange.mnFirst - 1 ), maDefRowModel );
1205 : : // process the row model
1206 [ + - ]: 114 : convertRows( aRowLevels, aRowRange, aIt->second.first, maDefRowModel.mfHeight );
1207 : : // cache next row to be processed
1208 : 114 : nNextRow = aRowRange.mnLast + 1;
1209 : : }
1210 : :
1211 : : // remaining default rows to end of sheet
1212 [ + - ]: 60 : convertRows( aRowLevels, ValueRange( nNextRow, nMaxRow ), maDefRowModel );
1213 : : // close remaining row outlines spanning to end of sheet
1214 [ + - ]: 60 : convertOutlines( aRowLevels, nMaxRow + 1, 0, false, true );
1215 : 60 : }
1216 : :
1217 : 219 : void WorksheetGlobals::convertRows( OutlineLevelVec& orRowLevels,
1218 : : const ValueRange& rRowRange, const RowModel& rModel, double fDefHeight )
1219 : : {
1220 : : // row height: convert points to row height in 1/100 mm
1221 [ + + ]: 219 : double fHeight = (rModel.mfHeight >= 0.0) ? rModel.mfHeight : fDefHeight;
1222 [ + - ][ + - ]: 219 : sal_Int32 nHeight = getUnitConverter().scaleToMm100( fHeight, UNIT_POINT );
1223 [ + + ]: 219 : if( nHeight > 0 )
1224 : : {
1225 : : /* always import the row height, ensures better layout */
1226 [ + - ][ + - ]: 165 : PropertySet aPropSet( getRows( rRowRange ) );
1227 [ + - ][ + - ]: 165 : aPropSet.setProperty( PROP_Height, nHeight );
1228 : : }
1229 : :
1230 : : // hidden rows: TODO: #108683# hide rows later?
1231 [ + + ]: 219 : if( rModel.mbHidden )
1232 : : {
1233 [ + - ][ + - ]: 6 : PropertySet aPropSet( getRows( rRowRange ) );
1234 : : // #i116460# Use VisibleFlag instead of IsVisible: directly set the flag,
1235 : : // without drawing layer update etc. (only possible before shapes are inserted)
1236 [ + - ][ + - ]: 6 : aPropSet.setProperty( PROP_VisibleFlag, false );
1237 : : }
1238 : :
1239 : : // outline settings for this row range
1240 [ + - ]: 219 : convertOutlines( orRowLevels, rRowRange.mnFirst, rModel.mnLevel, rModel.mbCollapsed, true );
1241 : 219 : }
1242 : :
1243 : 468 : void WorksheetGlobals::convertOutlines( OutlineLevelVec& orLevels,
1244 : : sal_Int32 nColRow, sal_Int32 nLevel, bool bCollapsed, bool bRows )
1245 : : {
1246 : : /* It is ensured from caller functions, that this function is called
1247 : : without any gaps between the processed column or row ranges. */
1248 : :
1249 : : OSL_ENSURE( nLevel >= 0, "WorksheetGlobals::convertOutlines - negative outline level" );
1250 [ + - ]: 468 : nLevel = ::std::max< sal_Int32 >( nLevel, 0 );
1251 : :
1252 : 468 : sal_Int32 nSize = orLevels.size();
1253 [ - + ]: 468 : if( nSize < nLevel )
1254 : : {
1255 : : // Outline level increased. Push the begin column position.
1256 [ # # ]: 0 : for( sal_Int32 nIndex = nSize; nIndex < nLevel; ++nIndex )
1257 : 0 : orLevels.push_back( nColRow );
1258 : : }
1259 [ - + ]: 468 : else if( nLevel < nSize )
1260 : : {
1261 : : // Outline level decreased. Pop them all out.
1262 [ # # ]: 0 : for( sal_Int32 nIndex = nLevel; nIndex < nSize; ++nIndex )
1263 : : {
1264 : 0 : sal_Int32 nFirstInLevel = orLevels.back();
1265 : 0 : orLevels.pop_back();
1266 : 0 : groupColumnsOrRows( nFirstInLevel, nColRow - 1, bCollapsed, bRows );
1267 : 0 : bCollapsed = false; // collapse only once
1268 : : }
1269 : : }
1270 : 468 : }
1271 : :
1272 : 0 : void WorksheetGlobals::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapse, bool bRows )
1273 : : {
1274 : : try
1275 : : {
1276 [ # # ]: 0 : Reference< XSheetOutline > xOutline( mxSheet, UNO_QUERY_THROW );
1277 [ # # ]: 0 : if( bRows )
1278 : : {
1279 : 0 : CellRangeAddress aRange( getSheetIndex(), 0, nFirstColRow, 0, nLastColRow );
1280 [ # # ][ # # ]: 0 : xOutline->group( aRange, TableOrientation_ROWS );
1281 [ # # ]: 0 : if( bCollapse )
1282 [ # # ][ # # ]: 0 : xOutline->hideDetail( aRange );
1283 : : }
1284 : : else
1285 : : {
1286 : 0 : CellRangeAddress aRange( getSheetIndex(), nFirstColRow, 0, nLastColRow, 0 );
1287 [ # # ][ # # ]: 0 : xOutline->group( aRange, TableOrientation_COLUMNS );
1288 [ # # ]: 0 : if( bCollapse )
1289 [ # # ][ # # ]: 0 : xOutline->hideDetail( aRange );
1290 [ # # ]: 0 : }
1291 : : }
1292 : 0 : catch( Exception& )
1293 : : {
1294 : : }
1295 : 0 : }
1296 : :
1297 : 60 : void WorksheetGlobals::finalizeDrawings()
1298 : : {
1299 : : // calculate the current drawing page size (after rows/columns are imported)
1300 [ + - ][ + - ]: 60 : PropertySet aRangeProp( getCellRange( CellRangeAddress( getSheetIndex(), 0, 0, mrMaxApiPos.Column, mrMaxApiPos.Row ) ) );
1301 [ + - ]: 60 : aRangeProp.getProperty( maDrawPageSize, PROP_Size );
1302 : :
1303 [ + - ]: 60 : switch( getFilterType() )
[ + - - - ]
1304 : : {
1305 : : case FILTER_OOXML:
1306 : : // import DML and VML
1307 [ + + ]: 60 : if( !maDrawingPath.isEmpty() )
1308 [ + - ][ + - ]: 6 : importOoxFragment( new DrawingFragment( *this, maDrawingPath ) );
[ + - ][ + - ]
1309 [ + + ]: 60 : if( !maVmlDrawingPath.isEmpty() )
1310 [ + - ][ + - ]: 6 : importOoxFragment( new VmlDrawingFragment( *this, maVmlDrawingPath ) );
[ + - ][ + - ]
1311 : 60 : break;
1312 : :
1313 : : case FILTER_BIFF:
1314 : : // convert BIFF3-BIFF5 drawing objects, or import and convert DFF stream
1315 [ # # ]: 0 : getBiffDrawing().finalizeImport();
1316 : 0 : break;
1317 : :
1318 : : case FILTER_UNKNOWN:
1319 : 0 : break;
1320 : : }
1321 : :
1322 : : // comments (after callout shapes have been imported from VML/DFF)
1323 [ + - ]: 60 : maComments.finalizeImport();
1324 : :
1325 : : /* Extend used area of the sheet by cells covered with drawing objects.
1326 : : Needed if the imported document is inserted as "OLE object from file"
1327 : : and thus does not provide an OLE size property by itself. */
1328 [ + + ][ - + ]: 60 : if( (maShapeBoundingBox.Width > 0) || (maShapeBoundingBox.Height > 0) )
1329 [ + - ][ + - ]: 3 : extendUsedArea( getCellRangeFromRectangle( maShapeBoundingBox ) );
1330 : :
1331 : : // if no used area is set, default to A1
1332 [ + + ]: 60 : if( maUsedArea.StartColumn > maUsedArea.EndColumn )
1333 : 18 : maUsedArea.StartColumn = maUsedArea.EndColumn = 0;
1334 [ + + ]: 60 : if( maUsedArea.StartRow > maUsedArea.EndRow )
1335 : 18 : maUsedArea.StartRow = maUsedArea.EndRow = 0;
1336 : :
1337 : : /* Register the used area of this sheet in global view settings. The
1338 : : global view settings will set the visible area if this document is an
1339 : : embedded OLE object. */
1340 [ + - ][ + - ]: 60 : getViewSettings().setSheetUsedArea( maUsedArea );
1341 : :
1342 : : /* #i103686# Set right-to-left sheet layout. Must be done after all
1343 : : drawing shapes to simplify calculation of shape coordinates. */
1344 [ + - ][ - + ]: 60 : if( maSheetViewSett.isSheetRightToLeft() )
1345 : : {
1346 [ # # ]: 0 : PropertySet aPropSet( mxSheet );
1347 [ # # ][ # # ]: 0 : aPropSet.setProperty( PROP_TableLayout, WritingMode2::RL_TB );
1348 [ + - ]: 60 : }
1349 : 60 : }
1350 : :
1351 : : // ============================================================================
1352 : : // ============================================================================
1353 : :
1354 : 552 : WorksheetHelper::WorksheetHelper( WorksheetGlobals& rSheetGlob ) :
1355 : : WorkbookHelper( rSheetGlob ),
1356 : 552 : mrSheetGlob( rSheetGlob )
1357 : : {
1358 : 552 : }
1359 : :
1360 : 60 : /*static*/ WorksheetGlobalsRef WorksheetHelper::constructGlobals( const WorkbookHelper& rHelper,
1361 : : const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet )
1362 : : {
1363 [ + - ][ + - ]: 60 : WorksheetGlobalsRef xSheetGlob( new WorksheetGlobals( rHelper, rxProgressBar, eSheetType, nSheet ) );
1364 [ - + ]: 60 : if( !xSheetGlob->isValidSheet() )
1365 [ # # ]: 0 : xSheetGlob.reset();
1366 : 60 : return xSheetGlob;
1367 : : }
1368 : :
1369 : 180 : WorksheetType WorksheetHelper::getSheetType() const
1370 : : {
1371 : 180 : return mrSheetGlob.getSheetType();
1372 : : }
1373 : :
1374 : 456 : sal_Int16 WorksheetHelper::getSheetIndex() const
1375 : : {
1376 : 456 : return mrSheetGlob.getSheetIndex();
1377 : : }
1378 : :
1379 : 207 : const Reference< XSpreadsheet >& WorksheetHelper::getSheet() const
1380 : : {
1381 : 207 : return mrSheetGlob.getSheet();
1382 : : }
1383 : :
1384 : 3 : Reference< XCell > WorksheetHelper::getCell( const CellAddress& rAddress ) const
1385 : : {
1386 : 3 : return mrSheetGlob.getCell( rAddress );
1387 : : }
1388 : :
1389 : 0 : Reference< XCellRange > WorksheetHelper::getCellRange( const CellRangeAddress& rRange ) const
1390 : : {
1391 : 0 : return mrSheetGlob.getCellRange( rRange );
1392 : : }
1393 : :
1394 : 66 : Reference< XDrawPage > WorksheetHelper::getDrawPage() const
1395 : : {
1396 : 66 : return mrSheetGlob.getDrawPage();
1397 : : }
1398 : :
1399 : 12 : awt::Point WorksheetHelper::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const
1400 : : {
1401 : 12 : return mrSheetGlob.getCellPosition( nCol, nRow );
1402 : : }
1403 : :
1404 : 0 : awt::Size WorksheetHelper::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const
1405 : : {
1406 : 0 : return mrSheetGlob.getCellSize( nCol, nRow );
1407 : : }
1408 : :
1409 : 6 : awt::Size WorksheetHelper::getDrawPageSize() const
1410 : : {
1411 : 6 : return mrSheetGlob.getDrawPageSize();
1412 : : }
1413 : :
1414 : 63 : SheetDataBuffer& WorksheetHelper::getSheetData() const
1415 : : {
1416 : 63 : return mrSheetGlob.getSheetData();
1417 : : }
1418 : :
1419 : 0 : CondFormatBuffer& WorksheetHelper::getCondFormats() const
1420 : : {
1421 : 0 : return mrSheetGlob.getCondFormats();
1422 : : }
1423 : :
1424 : 3 : CommentsBuffer& WorksheetHelper::getComments() const
1425 : : {
1426 : 3 : return mrSheetGlob.getComments();
1427 : : }
1428 : :
1429 : 3 : AutoFilterBuffer& WorksheetHelper::getAutoFilters() const
1430 : : {
1431 : 3 : return mrSheetGlob.getAutoFilters();
1432 : : }
1433 : :
1434 : 0 : QueryTableBuffer& WorksheetHelper::getQueryTables() const
1435 : : {
1436 : 0 : return mrSheetGlob.getQueryTables();
1437 : : }
1438 : :
1439 : 51 : WorksheetSettings& WorksheetHelper::getWorksheetSettings() const
1440 : : {
1441 : 51 : return mrSheetGlob.getWorksheetSettings();
1442 : : }
1443 : :
1444 : 342 : PageSettings& WorksheetHelper::getPageSettings() const
1445 : : {
1446 : 342 : return mrSheetGlob.getPageSettings();
1447 : : }
1448 : :
1449 : 108 : SheetViewSettings& WorksheetHelper::getSheetViewSettings() const
1450 : : {
1451 : 108 : return mrSheetGlob.getSheetViewSettings();
1452 : : }
1453 : :
1454 : 15 : VmlDrawing& WorksheetHelper::getVmlDrawing() const
1455 : : {
1456 : 15 : return mrSheetGlob.getVmlDrawing();
1457 : : }
1458 : :
1459 : 0 : ExtLst& WorksheetHelper::getExtLst() const
1460 : : {
1461 : 0 : return mrSheetGlob.getExtLst();
1462 : : }
1463 : :
1464 : 0 : void WorksheetHelper::setPageBreak( const PageBreakModel& rModel, bool bRowBreak )
1465 : : {
1466 : 0 : mrSheetGlob.setPageBreak( rModel, bRowBreak );
1467 : 0 : }
1468 : :
1469 : 0 : void WorksheetHelper::setHyperlink( const HyperlinkModel& rModel )
1470 : : {
1471 : 0 : mrSheetGlob.setHyperlink( rModel );
1472 : 0 : }
1473 : :
1474 : 0 : void WorksheetHelper::setValidation( const ValidationModel& rModel )
1475 : : {
1476 : 0 : mrSheetGlob.setValidation( rModel );
1477 : 0 : }
1478 : :
1479 : 6 : void WorksheetHelper::setDrawingPath( const OUString& rDrawingPath )
1480 : : {
1481 : 6 : mrSheetGlob.setDrawingPath( rDrawingPath );
1482 : 6 : }
1483 : :
1484 : 6 : void WorksheetHelper::setVmlDrawingPath( const OUString& rVmlDrawingPath )
1485 : : {
1486 : 6 : mrSheetGlob.setVmlDrawingPath( rVmlDrawingPath );
1487 : 6 : }
1488 : :
1489 : 444 : void WorksheetHelper::extendUsedArea( const CellAddress& rAddress )
1490 : : {
1491 : 444 : mrSheetGlob.extendUsedArea( rAddress );
1492 : 444 : }
1493 : :
1494 : 42 : void WorksheetHelper::extendUsedArea( const CellRangeAddress& rRange )
1495 : : {
1496 : 42 : mrSheetGlob.extendUsedArea( rRange );
1497 : 42 : }
1498 : :
1499 : 3 : void WorksheetHelper::extendShapeBoundingBox( const awt::Rectangle& rShapeRect )
1500 : : {
1501 : 3 : mrSheetGlob.extendShapeBoundingBox( rShapeRect );
1502 : 3 : }
1503 : :
1504 : 18 : void WorksheetHelper::setBaseColumnWidth( sal_Int32 nWidth )
1505 : : {
1506 : 18 : mrSheetGlob.setBaseColumnWidth( nWidth );
1507 : 18 : }
1508 : :
1509 : 18 : void WorksheetHelper::setDefaultColumnWidth( double fWidth )
1510 : : {
1511 : 18 : mrSheetGlob.setDefaultColumnWidth( fWidth );
1512 : 18 : }
1513 : :
1514 : 69 : void WorksheetHelper::setColumnModel( const ColumnModel& rModel )
1515 : : {
1516 : 69 : mrSheetGlob.setColumnModel( rModel );
1517 : 69 : }
1518 : :
1519 : 18 : void WorksheetHelper::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom )
1520 : : {
1521 : 18 : mrSheetGlob.setDefaultRowSettings( fHeight, bCustomHeight, bHidden, bThickTop, bThickBottom );
1522 : 18 : }
1523 : :
1524 : 243 : void WorksheetHelper::setRowModel( const RowModel& rModel )
1525 : : {
1526 : 243 : mrSheetGlob.setRowModel( rModel );
1527 : 243 : }
1528 : :
1529 : 195 : void WorksheetHelper::putValue( const CellAddress& rAddress, double fValue ) const
1530 : : {
1531 : 195 : ScAddress aAddress;
1532 : 195 : ScUnoConversion::FillScAddress( aAddress, rAddress );
1533 [ + - ][ + - ]: 195 : getScDocument().SetValue( aAddress.Col(), aAddress.Row(), aAddress.Tab(), fValue );
1534 : 195 : }
1535 : :
1536 : 93 : void WorksheetHelper::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress,
1537 : : double fValue )
1538 : : {
1539 : 93 : getFormulaBuffer().setCellFormulaValue( rAddress, fValue );
1540 : 93 : }
1541 : :
1542 : 147 : void WorksheetHelper::putString( const CellAddress& rAddress, const OUString& rText ) const
1543 : : {
1544 : 147 : ScAddress aAddress;
1545 : 147 : ScUnoConversion::FillScAddress( aAddress, rAddress );
1546 [ + - ][ + - ]: 147 : getScDocument().SetString( aAddress.Col(), aAddress.Row(), aAddress.Tab(), rText );
1547 : 147 : }
1548 : :
1549 : 0 : void WorksheetHelper::putRichString( const CellAddress& rAddress, const RichString& rString, const Font* pFirstPortionFont ) const
1550 : : {
1551 [ # # ][ # # ]: 0 : Reference< XText > xText( getCell( rAddress ), UNO_QUERY );
1552 : : OSL_ENSURE( xText.is(), "WorksheetHelper::putRichString - missing text interface" );
1553 : : /* Passing false will always append the portions to the XText. This is
1554 : : essential for special rich formatting attributes at the leading text
1555 : : portion supported by edit cells only, e.g. font escapement. */
1556 [ # # ]: 0 : rString.convert( xText, false, pFirstPortionFont );
1557 : 0 : }
1558 : :
1559 : 0 : void WorksheetHelper::putFormulaTokens( const CellAddress& rAddress, const ApiTokenSequence& rTokens ) const
1560 : : {
1561 [ # # ]: 0 : ScDocument& rDoc = getScDocument();
1562 [ # # ]: 0 : ScTokenArray aTokenArray;
1563 : 0 : ScAddress aCellPos;
1564 : 0 : ScUnoConversion::FillScAddress( aCellPos, rAddress );
1565 [ # # ]: 0 : ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
1566 [ # # ][ # # ]: 0 : ScBaseCell* pNewCell = new ScFormulaCell( &rDoc, aCellPos, &aTokenArray );
[ # # ]
1567 [ # # ][ # # ]: 0 : rDoc.PutCell( aCellPos, pNewCell, sal_True );
1568 : 0 : }
1569 : :
1570 : 60 : void WorksheetHelper::initializeWorksheetImport()
1571 : : {
1572 : 60 : mrSheetGlob.initializeWorksheetImport();
1573 : 60 : }
1574 : :
1575 : 60 : void WorksheetHelper::finalizeWorksheetImport()
1576 : : {
1577 : 60 : mrSheetGlob.finalizeWorksheetImport();
1578 : 60 : }
1579 : :
1580 : 81 : void WorksheetHelper::setCellFormula( const ::com::sun::star::table::CellAddress& rTokenAddress, const rtl::OUString& rTokenStr )
1581 : : {
1582 : 81 : getFormulaBuffer().setCellFormula( rTokenAddress, rTokenStr );
1583 : 81 : }
1584 : :
1585 : 21 : void WorksheetHelper::setCellFormula( const ::com::sun::star::table::CellAddress& rTokenAddress, sal_Int32 nSharedId )
1586 : : {
1587 : 21 : getFormulaBuffer().setCellFormula( rTokenAddress, nSharedId );
1588 : 21 : }
1589 : :
1590 : 0 : void WorksheetHelper::setCellArrayFormula( const ::com::sun::star::table::CellRangeAddress& rRangeAddress, const ::com::sun::star::table::CellAddress& rTokenAddress, const rtl::OUString& rTokenStr )
1591 : : {
1592 : 0 : getFormulaBuffer().setCellArrayFormula( rRangeAddress, rTokenAddress, rTokenStr );
1593 : 0 : }
1594 : :
1595 : 3 : void WorksheetHelper::createSharedFormulaMapEntry( const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId, const rtl::OUString& rTokens )
1596 : : {
1597 : 3 : getFormulaBuffer().createSharedFormulaMapEntry( rAddress, nSharedId, rTokens );
1598 : 3 : }
1599 : :
1600 : : // ============================================================================
1601 : : // ============================================================================
1602 : :
1603 : : } // namespace xls
1604 [ + - ][ + - ]: 24 : } // namespace oox
1605 : :
1606 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|