1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef OOX_XLS_SHEETDATABUFFER_HXX 25 #define OOX_XLS_SHEETDATABUFFER_HXX 26 27 #include <list> 28 #include <map> 29 #include "oox/xls/richstring.hxx" 30 #include "oox/xls/worksheethelper.hxx" 31 32 namespace com { namespace sun { namespace star { 33 namespace sheet { class XNamedRange; } 34 namespace util { struct DateTime; } 35 } } } 36 37 namespace oox { 38 namespace xls { 39 40 // ============================================================================ 41 42 /** Stores basic data about cell values and formatting. */ 43 struct CellModel 44 { 45 ::com::sun::star::table::CellAddress 46 maCellAddr; /// The address of the current cell. 47 sal_Int32 mnCellType; /// Data type of the cell value. 48 sal_Int32 mnXfId; /// XF (cell formatting) identifier. 49 bool mbShowPhonetic; /// True = show phonetic text. 50 51 explicit CellModel(); 52 }; 53 54 // ---------------------------------------------------------------------------- 55 56 /** Stores data about cell formulas. */ 57 struct CellFormulaModel 58 { 59 ::com::sun::star::table::CellRangeAddress 60 maFormulaRef; /// Formula range for array/shared formulas and data tables. 61 sal_Int32 mnFormulaType; /// Type of the formula (regular, array, shared, table). 62 sal_Int32 mnSharedId; /// Identifier of a shared formula (OOXML only). 63 64 explicit CellFormulaModel(); 65 66 /** Returns true, if the passed cell address is valid for an array formula. */ 67 bool isValidArrayRef( const ::com::sun::star::table::CellAddress& rCellAddr ); 68 /** Returns true, if the passed cell address is valid for a shared formula. */ 69 bool isValidSharedRef( const ::com::sun::star::table::CellAddress& rCellAddr ); 70 }; 71 72 // ---------------------------------------------------------------------------- 73 74 /** Stores data about table operations. */ 75 struct DataTableModel 76 { 77 ::rtl::OUString maRef1; /// First reference cell for table operations. 78 ::rtl::OUString maRef2; /// Second reference cell for table operations. 79 bool mb2dTable; /// True = 2-dimensional data table. 80 bool mbRowTable; /// True = row oriented data table. 81 bool mbRef1Deleted; /// True = first reference cell deleted. 82 bool mbRef2Deleted; /// True = second reference cell deleted. 83 84 explicit DataTableModel(); 85 }; 86 87 // ============================================================================ 88 89 /** Stores position and contents of a range of cells for optimized import. */ 90 class CellBlock : public WorksheetHelper 91 { 92 public: 93 explicit CellBlock( const WorksheetHelper& rHelper, const ValueRange& rColSpan, sal_Int32 nRow ); 94 95 /** Returns true, if the end index of the passed colspan is greater than 96 the own column end index, or if the passed range has the same end index 97 but the start indexes do not match. */ 98 bool isBefore( const ValueRange& rColSpan ) const; 99 /** Returns true, if the cell block can be expanded with the passed colspan. */ 100 bool isExpandable( const ValueRange& rColSpan ) const; 101 /** Returns true, if the own colspan contains the passed column. */ 102 bool contains( sal_Int32 nCol ) const; 103 104 /** Returns the specified cell from the last row in the cell buffer array. */ 105 ::com::sun::star::uno::Any& getCellAny( sal_Int32 nCol ); 106 /** Inserts a rich-string into the cell block. */ 107 void insertRichString( 108 const ::com::sun::star::table::CellAddress& rAddress, 109 const RichStringRef& rxString, 110 const Font* pFirstPortionFont ); 111 112 /** Appends a new row to the cell buffer array. */ 113 void startNextRow(); 114 /** Writes all buffered cells into the Calc sheet. */ 115 void finalizeImport(); 116 117 private: 118 /** Fills unused cells before passed index with empty strings. */ 119 void fillUnusedCells( sal_Int32 nIndex ); 120 121 private: 122 /** Stores position and string data of a rich-string cell. */ 123 struct RichStringCell 124 { 125 ::com::sun::star::table::CellAddress 126 maCellAddr; /// The address of the rich-string cell. 127 RichStringRef mxString; /// The string with rich formatting. 128 const Font* mpFirstPortionFont; /// Font information from cell for first text portion. 129 130 explicit RichStringCell( 131 const ::com::sun::star::table::CellAddress& rCellAddr, 132 const RichStringRef& rxString, 133 const Font* pFirstPortionFont ); 134 }; 135 typedef ::std::list< RichStringCell > RichStringCellList; 136 137 ::com::sun::star::table::CellRangeAddress 138 maRange; /// Cell range covered by this cell block. 139 RichStringCellList maRichStrings; /// Cached rich-string cells. 140 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > > 141 maCellArray; /// The array of cells of this cell block. 142 ::com::sun::star::uno::Any* 143 mpCurrCellRow; /// Pointer to first cell of current row (last row in maCellArray). 144 const sal_Int32 mnRowLength; /// Number of cells covered by row of this cell block. 145 sal_Int32 mnFirstFreeIndex; /// Relative index of first unused cell in current row. 146 }; 147 148 // ============================================================================ 149 150 /** Manages all cell blocks currently in use. */ 151 class CellBlockBuffer : public WorksheetHelper 152 { 153 public: 154 explicit CellBlockBuffer( const WorksheetHelper& rHelper ); 155 156 /** Sets column span information for a row. */ 157 void setColSpans( sal_Int32 nRow, const ValueRangeSet& rColSpans ); 158 159 /** Tries to find a cell block. Recalculates the map of cell blocks, if the 160 passed cell address is located in another row than the last cell. */ 161 CellBlock* getCellBlock( const ::com::sun::star::table::CellAddress& rCellAddr ); 162 163 /** Inserts all cells of all open cell blocks into the Calc document. */ 164 void finalizeImport(); 165 166 private: 167 typedef ::std::map< sal_Int32, ValueRangeVector > ColSpanVectorMap; 168 typedef RefMap< sal_Int32, CellBlock > CellBlockMap; 169 170 ColSpanVectorMap maColSpans; /// Buffereed column spans, mapped by row index. 171 CellBlockMap maCellBlocks; /// All open cell blocks, mapped by last (!) column of the block span. 172 CellBlockMap::iterator maCellBlockIt; /// Pointer to cell block currently in use. 173 sal_Int32 mnCurrRow; /// Current row index used for buffered cell import. 174 }; 175 176 // ============================================================================ 177 178 /** Manages the cell contents and cell formatting of a sheet. 179 */ 180 class SheetDataBuffer : public WorksheetHelper 181 { 182 public: 183 explicit SheetDataBuffer( const WorksheetHelper& rHelper ); 184 185 /** Sets column span information for a row. */ 186 void setColSpans( sal_Int32 nRow, const ValueRangeSet& rColSpans ); 187 188 /** Inserts a blank cell (with formatting) into the sheet. */ 189 void setBlankCell( const CellModel& rModel ); 190 /** Inserts a value cell into the sheet. */ 191 void setValueCell( const CellModel& rModel, double fValue ); 192 /** Inserts a simple string cell into the sheet. */ 193 void setStringCell( const CellModel& rModel, const ::rtl::OUString& rText ); 194 /** Inserts a rich-string cell into the sheet. */ 195 void setStringCell( const CellModel& rModel, const RichStringRef& rxString ); 196 /** Inserts a shared string cell into the sheet. */ 197 void setStringCell( const CellModel& rModel, sal_Int32 nStringId ); 198 /** Inserts a date/time cell into the sheet and adjusts number format. */ 199 void setDateTimeCell( const CellModel& rModel, const ::com::sun::star::util::DateTime& rDateTime ); 200 /** Inserts a boolean cell into the sheet and adjusts number format. */ 201 void setBooleanCell( const CellModel& rModel, bool bValue ); 202 /** Inserts an error cell from the passed error code into the sheet. */ 203 void setErrorCell( const CellModel& rModel, const ::rtl::OUString& rErrorCode ); 204 /** Inserts an error cell from the passed BIFF error code into the sheet. */ 205 void setErrorCell( const CellModel& rModel, sal_uInt8 nErrorCode ); 206 /** Inserts a formula cell into the sheet. */ 207 void setFormulaCell( const CellModel& rModel, const ApiTokenSequence& rTokens ); 208 /** Inserts a shared formula cell into the sheet (OOXML only). */ 209 void setFormulaCell( const CellModel& rModel, sal_Int32 nSharedId ); 210 211 /** Inserts the passed token array as array formula. */ 212 void createArrayFormula( 213 const ::com::sun::star::table::CellRangeAddress& rRange, 214 const ApiTokenSequence& rTokens ); 215 /** Sets a multiple table operation to the passed range. */ 216 void createTableOperation( 217 const ::com::sun::star::table::CellRangeAddress& rRange, 218 const DataTableModel& rModel ); 219 /** Creates a named range with a special name for a shared formula with the 220 specified identifier and formula definition (OOXML only). */ 221 void createSharedFormula( 222 sal_Int32 nSharedId, 223 const ApiTokenSequence& rTokens ); 224 /** Creates a named range with a special name for a shared formula with the 225 specified base address and formula definition (BIFF only). */ 226 void createSharedFormula( 227 const ::com::sun::star::table::CellAddress& rCellAddr, 228 const ApiTokenSequence& rTokens ); 229 230 /** Sets default cell formatting for the specified range of rows. */ 231 void setRowFormat( sal_Int32 nRow, sal_Int32 nXfId, bool bCustomFormat ); 232 /** Merges the cells in the passed cell range. */ 233 void setMergedRange( const ::com::sun::star::table::CellRangeAddress& rRange ); 234 /** Sets a standard number format (constant from com.sun.star.util.NumberFormat) to the specified cell. */ 235 void setStandardNumFmt( 236 const ::com::sun::star::table::CellAddress& rCellAddr, 237 sal_Int16 nStdNumFmt ); 238 239 /** Final processing after the sheet has been imported. */ 240 void finalizeImport(); 241 242 private: 243 struct XfIdRowRange; 244 struct XfIdRange; 245 246 /** Sets the passed formula token array into a cell. */ 247 void setCellFormula( 248 const ::com::sun::star::table::CellAddress& rCellAddr, 249 const ApiTokenSequence& rTokens ); 250 251 /** Creates a named range with a special name for a shared formula with the 252 specified base address and formula definition. */ 253 void createSharedFormula( const BinAddress& rMapKey, const ApiTokenSequence& rTokens ); 254 /** Creates a formula token array representing the shared formula with the 255 passed identifier. */ 256 ApiTokenSequence resolveSharedFormula( const BinAddress& rMapKey ) const; 257 258 /** Inserts the passed array formula into the sheet. */ 259 void finalizeArrayFormula( 260 const ::com::sun::star::table::CellRangeAddress& rRange, 261 const ApiTokenSequence& rTokens ) const; 262 /** Inserts the passed table operation into the sheet. */ 263 void finalizeTableOperation( 264 const ::com::sun::star::table::CellRangeAddress& rRange, 265 const DataTableModel& rModel ) const; 266 267 /** Processes the cell formatting data of the passed cell. 268 @param nNumFmtId If set, overrides number format of the cell XF. */ 269 void setCellFormat( const CellModel& rModel, sal_Int32 nNumFmtId = -1 ); 270 271 /** Writes all cell formatting attributes to the passed row range. */ 272 void writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const; 273 /** Writes all cell formatting attributes to the passed cell range. */ 274 void writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const; 275 /** Tries to merge the ranges last inserted in maXfIdRanges with existing ranges. */ 276 void mergeXfIdRanges(); 277 278 /** Merges the passed merged range and updates right/bottom cell borders. */ 279 void finalizeMergedRange( const ::com::sun::star::table::CellRangeAddress& rRange ); 280 281 private: 282 /** Stores cell range address and formula token array of an array formula. */ 283 typedef ::std::pair< ::com::sun::star::table::CellRangeAddress, ApiTokenSequence > ArrayFormula; 284 typedef ::std::list< ArrayFormula > ArrayFormulaList; 285 286 /** Stores cell range address and settings of a table operation. */ 287 typedef ::std::pair< ::com::sun::star::table::CellRangeAddress, DataTableModel > TableOperation; 288 typedef ::std::list< TableOperation > TableOperationList; 289 290 typedef ::std::map< BinAddress, sal_Int32 > SharedFormulaMap; 291 292 /** Stores information about a range of rows with equal cell formatting. */ 293 struct XfIdRowRange 294 { 295 ValueRange maRowRange; /// Indexes of first and last row. 296 sal_Int32 mnXfId; /// XF identifier for the row range. 297 298 explicit XfIdRowRange(); 299 bool intersects( const ::com::sun::star::table::CellRangeAddress& rRange ) const; 300 void set( sal_Int32 nRow, sal_Int32 nXfId ); 301 bool tryExpand( sal_Int32 nRow, sal_Int32 nXfId ); 302 }; 303 304 /** Stores information about a range of cells with equal formatting. */ 305 struct XfIdRange 306 { 307 ::com::sun::star::table::CellRangeAddress 308 maRange; /// The formatted cell range. 309 sal_Int32 mnXfId; /// XF identifier for the range. 310 sal_Int32 mnNumFmtId; /// Number format overriding the XF. 311 312 void set( const ::com::sun::star::table::CellAddress& rCellAddr, sal_Int32 nXfId, sal_Int32 nNumFmtId ); 313 bool tryExpand( const ::com::sun::star::table::CellAddress& rCellAddr, sal_Int32 nXfId, sal_Int32 nNumFmtId ); 314 bool tryMerge( const XfIdRange& rXfIdRange ); 315 }; 316 typedef ::std::map< BinAddress, XfIdRange > XfIdRangeMap; 317 318 /** Stores information about a merged cell range. */ 319 struct MergedRange 320 { 321 ::com::sun::star::table::CellRangeAddress 322 maRange; /// The formatted cell range. 323 sal_Int32 mnHorAlign; /// Horizontal alignment in the range. 324 325 explicit MergedRange( const ::com::sun::star::table::CellRangeAddress& rRange ); 326 explicit MergedRange( const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nHorAlign ); 327 bool tryExpand( const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nHorAlign ); 328 }; 329 typedef ::std::list< MergedRange > MergedRangeList; 330 331 CellBlockBuffer maCellBlocks; /// Manages all open cell blocks. 332 ArrayFormulaList maArrayFormulas; /// All array formulas in the sheet. 333 TableOperationList maTableOperations; /// All table operations in the sheet. 334 SharedFormulaMap maSharedFormulas; /// Maps shared formula base address to defined name token index. 335 ::com::sun::star::table::CellAddress 336 maSharedFmlaAddr; /// Address of a cell containing a pending shared formula. 337 BinAddress maSharedBaseAddr; /// Base address of the pending shared formula. 338 XfIdRowRange maXfIdRowRange; /// Cached XF identifier for a range of rows. 339 XfIdRangeMap maXfIdRanges; /// Collected XF identifiers for cell ranges. 340 MergedRangeList maMergedRanges; /// Merged cell ranges. 341 MergedRangeList maCenterFillRanges; /// Merged cell ranges from 'center across' or 'fill' alignment. 342 bool mbPendingSharedFmla; /// True = maSharedFmlaAddr and maSharedBaseAddr are valid. 343 }; 344 345 // ============================================================================ 346 347 } // namespace xls 348 } // namespace oox 349 350 #endif 351