1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "oox/xls/pivottablebuffer.hxx" 29 30 #include <set> 31 #include <com/sun/star/container/XIndexAccess.hpp> 32 #include <com/sun/star/container/XNameAccess.hpp> 33 #include <com/sun/star/sheet/CellFlags.hpp> 34 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp> 35 #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp> 36 #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp> 37 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> 38 #include <com/sun/star/sheet/DataPilotFieldReference.hpp> 39 #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp> 40 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp> 41 #include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp> 42 #include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp> 43 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp> 44 #include <com/sun/star/sheet/GeneralFunction.hpp> 45 #include <com/sun/star/sheet/XDataPilotDataLayoutFieldSupplier.hpp> 46 #include <com/sun/star/sheet/XDataPilotField.hpp> 47 #include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp> 48 #include <com/sun/star/sheet/XSheetOperation.hpp> 49 #include "oox/helper/attributelist.hxx" 50 #include "oox/helper/containerhelper.hxx" 51 #include "oox/helper/propertyset.hxx" 52 #include "oox/xls/addressconverter.hxx" 53 #include "oox/xls/biffinputstream.hxx" 54 55 namespace oox { 56 namespace xls { 57 58 // ============================================================================ 59 60 using namespace ::com::sun::star::container; 61 using namespace ::com::sun::star::sheet; 62 using namespace ::com::sun::star::table; 63 using namespace ::com::sun::star::uno; 64 65 using ::rtl::OUString; 66 67 // ============================================================================ 68 69 namespace { 70 71 const sal_Int32 OOX_PT_DATALAYOUTFIELD = -2; /// Placeholder index of data layout field. 72 73 const sal_Int32 OOX_PT_PREVIOUS_ITEM = 0x001000FC; /// Calculation of data item result is based on previous item. 74 const sal_Int32 OOX_PT_NEXT_ITEM = 0x001000FD; /// Calculation of data item result is based on next item. 75 76 // ---------------------------------------------------------------------------- 77 78 const sal_uInt32 BIFF12_PTFIELD_DATAFIELD = 0x00000008; 79 const sal_uInt32 BIFF12_PTFIELD_DEFAULT = 0x00000100; 80 const sal_uInt32 BIFF12_PTFIELD_SUM = 0x00000200; 81 const sal_uInt32 BIFF12_PTFIELD_COUNTA = 0x00000400; 82 const sal_uInt32 BIFF12_PTFIELD_AVERAGE = 0x00000800; 83 const sal_uInt32 BIFF12_PTFIELD_MAX = 0x00001000; 84 const sal_uInt32 BIFF12_PTFIELD_MIN = 0x00002000; 85 const sal_uInt32 BIFF12_PTFIELD_PRODUCT = 0x00004000; 86 const sal_uInt32 BIFF12_PTFIELD_COUNT = 0x00008000; 87 const sal_uInt32 BIFF12_PTFIELD_STDDEV = 0x00010000; 88 const sal_uInt32 BIFF12_PTFIELD_STDDEVP = 0x00020000; 89 const sal_uInt32 BIFF12_PTFIELD_VAR = 0x00040000; 90 const sal_uInt32 BIFF12_PTFIELD_VARP = 0x00080000; 91 92 const sal_uInt32 BIFF12_PTFIELD_SHOWALL = 0x00000020; 93 const sal_uInt32 BIFF12_PTFIELD_OUTLINE = 0x00000040; 94 const sal_uInt32 BIFF12_PTFIELD_INSERTBLANKROW = 0x00000080; 95 const sal_uInt32 BIFF12_PTFIELD_SUBTOTALTOP = 0x00000100; 96 const sal_uInt32 BIFF12_PTFIELD_INSERTPAGEBREAK = 0x00000800; 97 const sal_uInt32 BIFF12_PTFIELD_AUTOSORT = 0x00001000; 98 const sal_uInt32 BIFF12_PTFIELD_SORTASCENDING = 0x00002000; 99 const sal_uInt32 BIFF12_PTFIELD_AUTOSHOW = 0x00004000; 100 const sal_uInt32 BIFF12_PTFIELD_AUTOSHOWTOP = 0x00008000; 101 const sal_uInt32 BIFF12_PTFIELD_MULTIPAGEITEMS = 0x00080000; 102 103 const sal_uInt16 BIFF12_PTFITEM_HIDDEN = 0x0001; 104 const sal_uInt16 BIFF12_PTFITEM_HIDEDETAILS = 0x0002; 105 106 const sal_uInt8 BIFF12_PTPAGEFIELD_HASNAME = 0x01; 107 const sal_uInt8 BIFF12_PTPAGEFIELD_HASOLAPCAPTION = 0x02; 108 const sal_Int32 BIFF12_PTPAGEFIELD_MULTIITEMS = 0x001000FE; 109 110 const sal_uInt16 BIFF12_PTFILTER_HASNAME = 0x0001; 111 const sal_uInt16 BIFF12_PTFILTER_HASDESCRIPTION = 0x0002; 112 const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE1 = 0x0004; 113 const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE2 = 0x0008; 114 115 const sal_uInt8 BIFF12_TOP10FILTER_TOP = 0x01; 116 const sal_uInt8 BIFF12_TOP10FILTER_PERCENT = 0x02; 117 118 const sal_uInt32 BIFF12_PTDEF_SHOWITEMS = 0x00000100; 119 const sal_uInt32 BIFF12_PTDEF_DISABLEFIELDLIST = 0x00000400; 120 const sal_uInt32 BIFF12_PTDEF_HIDECALCMEMBERS = 0x00001000; 121 const sal_uInt32 BIFF12_PTDEF_WITHHIDDENTOTALS = 0x00002000; 122 const sal_uInt32 BIFF12_PTDEF_HIDEDRILL = 0x00100000; 123 const sal_uInt32 BIFF12_PTDEF_PRINTDRILL = 0x00200000; 124 const sal_uInt32 BIFF12_PTDEF_HIDEHEADERS = 0x80000000; 125 126 const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYROW = 0x00000004; 127 const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYCOL = 0x00000008; 128 const sal_uInt32 BIFF12_PTDEF_ENABLEDRILL = 0x00000020; 129 const sal_uInt32 BIFF12_PTDEF_PRESERVEFORMATTING = 0x00000080; 130 const sal_uInt32 BIFF12_PTDEF_USEAUTOFORMAT = 0x00000100; 131 const sal_uInt32 BIFF12_PTDEF_SHOWERROR = 0x00000200; 132 const sal_uInt32 BIFF12_PTDEF_SHOWMISSING = 0x00000400; 133 const sal_uInt32 BIFF12_PTDEF_PAGEOVERTHENDOWN = 0x00000800; 134 const sal_uInt32 BIFF12_PTDEF_SUBTOTALHIDDENITEMS = 0x00001000; 135 const sal_uInt32 BIFF12_PTDEF_ROWGRANDTOTALS = 0x00002000; 136 const sal_uInt32 BIFF12_PTDEF_COLGRANDTOTALS = 0x00004000; 137 const sal_uInt32 BIFF12_PTDEF_FIELDPRINTTITLES = 0x00008000; 138 const sal_uInt32 BIFF12_PTDEF_ITEMPRINTTITLES = 0x00020000; 139 const sal_uInt32 BIFF12_PTDEF_MERGEITEM = 0x00040000; 140 const sal_uInt32 BIFF12_PTDEF_HASDATACAPTION = 0x00080000; 141 const sal_uInt32 BIFF12_PTDEF_HASGRANDTOTALCAPTION = 0x00100000; 142 const sal_uInt32 BIFF12_PTDEF_HASPAGESTYLE = 0x00200000; 143 const sal_uInt32 BIFF12_PTDEF_HASPIVOTTABLESTYLE = 0x00400000; 144 const sal_uInt32 BIFF12_PTDEF_HASVACATEDSTYLE = 0x00800000; 145 const sal_uInt32 BIFF12_PTDEF_APPLYNUMFMT = 0x01000000; 146 const sal_uInt32 BIFF12_PTDEF_APPLYFONT = 0x02000000; 147 const sal_uInt32 BIFF12_PTDEF_APPLYALIGNMENT = 0x04000000; 148 const sal_uInt32 BIFF12_PTDEF_APPLYBORDER = 0x08000000; 149 const sal_uInt32 BIFF12_PTDEF_APPLYFILL = 0x10000000; 150 const sal_uInt32 BIFF12_PTDEF_APPLYPROTECTION = 0x20000000; 151 const sal_uInt32 BIFF12_PTDEF_HASTAG = 0x40000000; 152 153 const sal_uInt32 BIFF12_PTDEF_NOERRORCAPTION = 0x00000040; 154 const sal_uInt32 BIFF12_PTDEF_NOMISSINGCAPTION = 0x00000080; 155 const sal_uInt32 BIFF12_PTDEF_HASROWHEADERCAPTION = 0x00000400; 156 const sal_uInt32 BIFF12_PTDEF_HASCOLHEADERCAPTION = 0x00000800; 157 const sal_uInt32 BIFF12_PTDEF_FIELDLISTSORTASC = 0x00001000; 158 const sal_uInt32 BIFF12_PTDEF_NOCUSTOMLISTSORT = 0x00004000; 159 160 const sal_uInt8 BIFF12_PTDEF_ROWAXIS = 1; 161 const sal_uInt8 BIFF12_PTDEF_COLAXIS = 2; 162 163 // ---------------------------------------------------------------------------- 164 165 const sal_uInt16 BIFF_PT_NOSTRING = 0xFFFF; 166 167 const sal_uInt16 BIFF_PTFIELD_DATAFIELD = 0x0008; 168 const sal_uInt16 BIFF_PTFIELD_DEFAULT = 0x0001; 169 const sal_uInt16 BIFF_PTFIELD_SUM = 0x0002; 170 const sal_uInt16 BIFF_PTFIELD_COUNTA = 0x0004; 171 const sal_uInt16 BIFF_PTFIELD_AVERAGE = 0x0008; 172 const sal_uInt16 BIFF_PTFIELD_MAX = 0x0010; 173 const sal_uInt16 BIFF_PTFIELD_MIN = 0x0020; 174 const sal_uInt16 BIFF_PTFIELD_PRODUCT = 0x0040; 175 const sal_uInt16 BIFF_PTFIELD_COUNT = 0x0080; 176 const sal_uInt16 BIFF_PTFIELD_STDDEV = 0x0100; 177 const sal_uInt16 BIFF_PTFIELD_STDDEVP = 0x0200; 178 const sal_uInt16 BIFF_PTFIELD_VAR = 0x0400; 179 const sal_uInt16 BIFF_PTFIELD_VARP = 0x0800; 180 181 const sal_uInt32 BIFF_PTFIELD2_SHOWALL = 0x00000001; 182 const sal_uInt32 BIFF_PTFIELD2_AUTOSORT = 0x00000200; 183 const sal_uInt32 BIFF_PTFIELD2_SORTASCENDING = 0x00000400; 184 const sal_uInt32 BIFF_PTFIELD2_AUTOSHOW = 0x00000800; 185 const sal_uInt32 BIFF_PTFIELD2_AUTOSHOWTOP = 0x00001000; 186 const sal_uInt32 BIFF_PTFIELD2_OUTLINE = 0x00200000; 187 const sal_uInt32 BIFF_PTFIELD2_INSERTBLANKROW = 0x00400000; 188 const sal_uInt32 BIFF_PTFIELD2_SUBTOTALTOP = 0x00800000; 189 190 const sal_uInt16 BIFF_PTFITEM_HIDDEN = 0x0001; 191 const sal_uInt16 BIFF_PTFITEM_HIDEDETAILS = 0x0002; 192 193 const sal_uInt16 BIFF_PTDEF_ROWGRANDTOTALS = 0x0001; 194 const sal_uInt16 BIFF_PTDEF_COLGRANDTOTALS = 0x0002; 195 196 const sal_uInt8 BIFF_PTDEF_ROWAXIS = 1; 197 const sal_uInt8 BIFF_PTDEF_COLAXIS = 2; 198 199 const sal_uInt32 BIFF_PTDEF2_PAGEOVERTHENDOWN = 0x00000001; 200 const sal_uInt32 BIFF_PTDE2F_ENABLEDRILL = 0x00020000; 201 const sal_uInt32 BIFF_PTDEF2_PRESERVEFORMATTING = 0x00080000; 202 const sal_uInt32 BIFF_PTDEF2_MERGEITEM = 0x00100000; 203 const sal_uInt32 BIFF_PTDEF2_SHOWERROR = 0x00200000; 204 const sal_uInt32 BIFF_PTDEF2_SHOWMISSING = 0x00400000; 205 const sal_uInt32 BIFF_PTDEF2_SUBTOTALHIDDENITEMS = 0x00800000; 206 207 const sal_Int16 BIFF_PTPAGEFIELDS_ALLITEMS = 0x7FFD; 208 209 const sal_Int16 BIFF_PTDATAFIELD_PREVIOUS = 0x7FFB; 210 const sal_Int16 BIFF_PTDATAFIELD_NEXT = 0x7FFC; 211 212 // ---------------------------------------------------------------------------- 213 214 OUString lclReadPivotString( const WorkbookHelper& rHelper, BiffInputStream& rStrm, sal_uInt16 nLen ) 215 { 216 if( nLen == BIFF_PT_NOSTRING ) 217 return OUString(); 218 return (rHelper.getBiff() == BIFF8) ? rStrm.readUniStringBody( nLen ) : rStrm.readCharArrayUC( nLen, rHelper.getTextEncoding() ); 219 } 220 221 } // namespace 222 223 // ============================================================================ 224 225 PTFieldItemModel::PTFieldItemModel() : 226 mnCacheItem( -1 ), 227 mnType( XML_data ), 228 mbShowDetails( true ), 229 mbHidden( false ) 230 { 231 } 232 233 void PTFieldItemModel::setBiffType( sal_uInt16 nType ) 234 { 235 static const sal_Int32 spnTypes[] = { XML_data, XML_default, 236 XML_sum, XML_countA, XML_avg, XML_max, XML_min, XML_product, XML_count, 237 XML_stdDev, XML_stdDevP, XML_var, XML_varP, XML_grand, XML_blank }; 238 mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_data ); 239 } 240 241 // ---------------------------------------------------------------------------- 242 243 PTFieldModel::PTFieldModel() : 244 mnAxis( XML_TOKEN_INVALID ), 245 mnNumFmtId( 0 ), 246 mnAutoShowItems( 10 ), 247 mnAutoShowRankBy( -1 ), 248 mnSortType( XML_manual ), 249 mnSortRefField( -1 ), 250 mnSortRefItem( -1 ), 251 mbDataField( false ), 252 mbDefaultSubtotal( true ), 253 mbSumSubtotal( false ), 254 mbCountASubtotal( false ), 255 mbAverageSubtotal( false ), 256 mbMaxSubtotal( false ), 257 mbMinSubtotal( false ), 258 mbProductSubtotal( false ), 259 mbCountSubtotal( false ), 260 mbStdDevSubtotal( false ), 261 mbStdDevPSubtotal( false ), 262 mbVarSubtotal( false ), 263 mbVarPSubtotal( false ), 264 mbShowAll( true ), 265 mbOutline( true ), 266 mbSubtotalTop( true ), 267 mbInsertBlankRow( false ), 268 mbInsertPageBreak( false ), 269 mbAutoShow( false ), 270 mbTopAutoShow( true ), 271 mbMultiPageItems( false ) 272 { 273 } 274 275 void PTFieldModel::setBiffAxis( sal_uInt8 nAxis ) 276 { 277 /* Weird. The axis field is organized as bit field, but only one of the 278 row/col/page flags are allowed at the same time and refer to the values 279 'axisRow', 'axisCol', and 'axisPage' of the XML attribute 280 'pivotField@axis'. Additionally, the fourth bit determines if the field 281 is a data field, which may appear combined with the row/col/page flags. 282 Therefore, this bit is unrelated to the 'axisValues' value of the 283 'pivotField@axis' attribute, but refers to the 'pivotField@dataField' 284 boolean attribute. */ 285 static const sal_Int32 spnAxisIds[] = { XML_TOKEN_INVALID, XML_axisRow, XML_axisCol, XML_TOKEN_INVALID, XML_axisPage }; 286 mnAxis = STATIC_ARRAY_SELECT( spnAxisIds, nAxis, XML_TOKEN_INVALID ); 287 } 288 289 // ---------------------------------------------------------------------------- 290 291 PTPageFieldModel::PTPageFieldModel() : 292 mnField( -1 ), 293 mnItem( BIFF12_PTPAGEFIELD_MULTIITEMS ) 294 { 295 } 296 297 // ---------------------------------------------------------------------------- 298 299 PTDataFieldModel::PTDataFieldModel() : 300 mnField( -1 ), 301 mnSubtotal( XML_sum ), 302 mnShowDataAs( XML_normal ), 303 mnBaseField( -1 ), 304 mnBaseItem( -1 ), 305 mnNumFmtId( 0 ) 306 { 307 } 308 309 void PTDataFieldModel::setBiffSubtotal( sal_Int32 nSubtotal ) 310 { 311 static sal_Int32 spnSubtotals[] = { XML_sum, XML_count, XML_average, XML_max, XML_min, XML_product, XML_countNums, XML_stdDev, XML_stdDevp, XML_var, XML_varp }; 312 mnSubtotal = STATIC_ARRAY_SELECT( spnSubtotals, nSubtotal, XML_TOKEN_INVALID ); 313 } 314 315 void PTDataFieldModel::setBiffShowDataAs( sal_Int32 nShowDataAs ) 316 { 317 static sal_Int32 spnShowDataAs[] = { XML_normal, XML_difference, XML_percent, XML_percentDiff, XML_runTotal, XML_percentOfRow, XML_percentOfCol, XML_percentOfTotal, XML_index }; 318 mnShowDataAs = STATIC_ARRAY_SELECT( spnShowDataAs, nShowDataAs, XML_TOKEN_INVALID ); 319 } 320 321 // ---------------------------------------------------------------------------- 322 323 PivotTableField::PivotTableField( PivotTable& rPivotTable, sal_Int32 nFieldIndex ) : 324 WorkbookHelper( rPivotTable ), 325 mrPivotTable( rPivotTable ), 326 mnFieldIndex( nFieldIndex ) 327 { 328 } 329 330 void PivotTableField::importPivotField( const AttributeList& rAttribs ) 331 { 332 /* The documentation mentions a value 'axisValues' for the attribute 333 'pivotField@axis'. But this value is not used to mark a data field, as 334 data fields may be inserted in one of the row/column/page dimensions at 335 the same time. Therefore, the boolean attribute 'pivotField@dataField' 336 is really used to mark data fields. */ 337 maModel.mnAxis = rAttribs.getToken( XML_axis, XML_TOKEN_INVALID ); 338 maModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 ); 339 maModel.mnAutoShowItems = rAttribs.getInteger( XML_itemPageCount, 10 ); 340 maModel.mnAutoShowRankBy = rAttribs.getInteger( XML_rankBy, -1 ); 341 maModel.mnSortType = rAttribs.getToken( XML_sortType, XML_manual ); 342 maModel.mbDataField = rAttribs.getBool( XML_dataField, false ); 343 maModel.mbDefaultSubtotal = rAttribs.getBool( XML_defaultSubtotal, true ); 344 maModel.mbSumSubtotal = rAttribs.getBool( XML_sumSubtotal, false ); 345 maModel.mbCountASubtotal = rAttribs.getBool( XML_countASubtotal, false ); 346 maModel.mbAverageSubtotal = rAttribs.getBool( XML_avgSubtotal, false ); 347 maModel.mbMaxSubtotal = rAttribs.getBool( XML_maxSubtotal, false ); 348 maModel.mbMinSubtotal = rAttribs.getBool( XML_minSubtotal, false ); 349 maModel.mbProductSubtotal = rAttribs.getBool( XML_productSubtotal, false ); 350 maModel.mbCountSubtotal = rAttribs.getBool( XML_countSubtotal, false ); 351 maModel.mbStdDevSubtotal = rAttribs.getBool( XML_stdDevSubtotal, false ); 352 maModel.mbStdDevPSubtotal = rAttribs.getBool( XML_stdDevPSubtotal, false ); 353 maModel.mbVarSubtotal = rAttribs.getBool( XML_varSubtotal, false ); 354 maModel.mbVarPSubtotal = rAttribs.getBool( XML_varPSubtotal, false ); 355 maModel.mbShowAll = rAttribs.getBool( XML_showAll, true ); 356 maModel.mbOutline = rAttribs.getBool( XML_outline, true ); 357 maModel.mbSubtotalTop = rAttribs.getBool( XML_subtotalTop, true ); 358 maModel.mbInsertBlankRow = rAttribs.getBool( XML_insertBlankRow, false ); 359 maModel.mbInsertPageBreak = rAttribs.getBool( XML_insertPageBreak, false ); 360 maModel.mbAutoShow = rAttribs.getBool( XML_autoShow, false ); 361 maModel.mbTopAutoShow = rAttribs.getBool( XML_topAutoShow, true ); 362 maModel.mbMultiPageItems = rAttribs.getBool( XML_multipleItemSelectionAllowed, false ); 363 } 364 365 void PivotTableField::importItem( const AttributeList& rAttribs ) 366 { 367 PTFieldItemModel aModel; 368 aModel.mnCacheItem = rAttribs.getInteger( XML_x, -1 ); 369 aModel.mnType = rAttribs.getToken( XML_t, XML_data ); 370 aModel.mbShowDetails = rAttribs.getBool( XML_sd, true ); 371 aModel.mbHidden = rAttribs.getBool( XML_h, false ); 372 maItems.push_back( aModel ); 373 } 374 375 void PivotTableField::importReference( const AttributeList& rAttribs ) 376 { 377 // field index is stored as unsigned integer 378 maModel.mnSortRefField = static_cast< sal_Int32 >( rAttribs.getUnsigned( XML_field, SAL_MAX_UINT32 ) ); 379 } 380 381 void PivotTableField::importReferenceItem( const AttributeList& rAttribs ) 382 { 383 maModel.mnSortRefItem = rAttribs.getInteger( XML_v, -1 ); 384 } 385 386 void PivotTableField::importPTField( SequenceInputStream& rStrm ) 387 { 388 sal_uInt32 nFlags1, nFlags2; 389 rStrm >> nFlags1 >> maModel.mnNumFmtId >> nFlags2 >> maModel.mnAutoShowItems >> maModel.mnAutoShowRankBy; 390 391 maModel.setBiffAxis( extractValue< sal_uInt8 >( nFlags1, 0, 3 ) ); 392 maModel.mbDataField = getFlag( nFlags1, BIFF12_PTFIELD_DATAFIELD ); 393 maModel.mbDefaultSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_DEFAULT ); 394 maModel.mbSumSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_SUM ); 395 maModel.mbCountASubtotal = getFlag( nFlags1, BIFF12_PTFIELD_COUNTA ); 396 maModel.mbAverageSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_AVERAGE ); 397 maModel.mbMaxSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_MAX ); 398 maModel.mbMinSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_MIN ); 399 maModel.mbProductSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_PRODUCT ); 400 maModel.mbCountSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_COUNT ); 401 maModel.mbStdDevSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_STDDEV ); 402 maModel.mbStdDevPSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_STDDEVP ); 403 maModel.mbVarSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_VAR ); 404 maModel.mbVarPSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_VARP ); 405 406 maModel.mbShowAll = getFlag( nFlags2, BIFF12_PTFIELD_SHOWALL ); 407 maModel.mbOutline = getFlag( nFlags2, BIFF12_PTFIELD_OUTLINE ); 408 maModel.mbSubtotalTop = getFlag( nFlags2, BIFF12_PTFIELD_SUBTOTALTOP ); 409 maModel.mbInsertBlankRow = getFlag( nFlags2, BIFF12_PTFIELD_INSERTBLANKROW ); 410 maModel.mbInsertPageBreak = getFlag( nFlags2, BIFF12_PTFIELD_INSERTPAGEBREAK ); 411 maModel.mbAutoShow = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOW ); 412 maModel.mbTopAutoShow = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOWTOP ); 413 maModel.mbMultiPageItems = getFlag( nFlags2, BIFF12_PTFIELD_MULTIPAGEITEMS ); 414 415 bool bAutoSort = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSORT ); 416 bool bAscending = getFlag( nFlags2, BIFF12_PTFIELD_SORTASCENDING ); 417 maModel.mnSortType = bAutoSort ? (bAscending ? XML_ascending : XML_descending) : XML_manual; 418 } 419 420 void PivotTableField::importPTFItem( SequenceInputStream& rStrm ) 421 { 422 PTFieldItemModel aModel; 423 sal_uInt8 nType; 424 sal_uInt16 nFlags; 425 rStrm >> nType >> nFlags >> aModel.mnCacheItem; 426 427 aModel.setBiffType( nType ); 428 aModel.mbShowDetails = !getFlag( nFlags, BIFF12_PTFITEM_HIDEDETAILS ); 429 aModel.mbHidden = getFlag( nFlags, BIFF12_PTFITEM_HIDDEN ); 430 431 maItems.push_back( aModel ); 432 } 433 434 void PivotTableField::importPTReference( SequenceInputStream& rStrm ) 435 { 436 rStrm >> maModel.mnSortRefField; 437 } 438 439 void PivotTableField::importPTReferenceItem( SequenceInputStream& rStrm ) 440 { 441 rStrm >> maModel.mnSortRefItem; 442 } 443 444 void PivotTableField::importPTField( BiffInputStream& rStrm ) 445 { 446 sal_uInt16 nAxis, nSubtCount, nSubtotals; 447 rStrm >> nAxis >> nSubtCount >> nSubtotals; 448 rStrm.skip( 2 ); // item count 449 450 maModel.setBiffAxis( extractValue< sal_uInt8 >( nAxis, 0, 3 ) ); 451 maModel.mbDataField = getFlag( nAxis, BIFF_PTFIELD_DATAFIELD ); 452 453 maModel.mbDefaultSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_DEFAULT ); 454 maModel.mbSumSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_SUM ); 455 maModel.mbCountASubtotal = getFlag( nSubtotals, BIFF_PTFIELD_COUNTA ); 456 maModel.mbAverageSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_AVERAGE ); 457 maModel.mbMaxSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_MAX ); 458 maModel.mbMinSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_MIN ); 459 maModel.mbProductSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_PRODUCT ); 460 maModel.mbCountSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_COUNT ); 461 maModel.mbStdDevSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_STDDEV ); 462 maModel.mbStdDevPSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_STDDEVP ); 463 maModel.mbVarSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_VAR ); 464 maModel.mbVarPSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_VARP ); 465 466 // set different defaults for BIFF 467 maModel.mbShowAll = maModel.mbOutline = maModel.mbSubtotalTop = false; 468 469 // read following items 470 while( (rStrm.getNextRecId() == BIFF_ID_PTFITEM) && rStrm.startNextRecord() ) 471 importPTFItem( rStrm ); 472 473 // read following PTFIELD2 record with additional field settings 474 if( (getBiff() == BIFF8) && (rStrm.getNextRecId() == BIFF_ID_PTFIELD2) && rStrm.startNextRecord() ) 475 importPTField2( rStrm ); 476 } 477 478 void PivotTableField::importPTField2( BiffInputStream& rStrm ) 479 { 480 sal_uInt32 nFlags; 481 rStrm >> nFlags; 482 maModel.mnSortRefItem = rStrm.readInt16(); 483 maModel.mnAutoShowRankBy = rStrm.readInt16(); 484 maModel.mnNumFmtId = rStrm.readuInt16(); 485 486 maModel.mnAutoShowItems = extractValue< sal_Int32 >( nFlags, 24, 8 ); 487 maModel.mbShowAll = getFlag( nFlags, BIFF_PTFIELD2_SHOWALL ); 488 maModel.mbOutline = getFlag( nFlags, BIFF_PTFIELD2_OUTLINE ); 489 maModel.mbSubtotalTop = getFlag( nFlags, BIFF_PTFIELD2_SUBTOTALTOP ); 490 maModel.mbInsertBlankRow = getFlag( nFlags, BIFF_PTFIELD2_INSERTBLANKROW ); 491 maModel.mbAutoShow = getFlag( nFlags, BIFF_PTFIELD2_AUTOSHOW ); 492 maModel.mbTopAutoShow = getFlag( nFlags, BIFF_PTFIELD2_AUTOSHOWTOP ); 493 494 bool bAutoSort = getFlag( nFlags, BIFF_PTFIELD2_AUTOSORT ); 495 bool bAscending = getFlag( nFlags, BIFF_PTFIELD2_SORTASCENDING ); 496 maModel.mnSortType = bAutoSort ? (bAscending ? XML_ascending : XML_descending) : XML_manual; 497 // mnSortRefField == OOX_PT_DATALAYOUTFIELD will indicate sorting by data field 498 if( maModel.mnSortRefItem >= 0 ) 499 maModel.mnSortRefField = OOX_PT_DATALAYOUTFIELD; 500 } 501 502 void PivotTableField::importPTFItem( BiffInputStream& rStrm ) 503 { 504 PTFieldItemModel aModel; 505 sal_uInt16 nType, nFlags; 506 sal_Int16 nCacheItem; 507 rStrm >> nType >> nFlags >> nCacheItem; 508 509 aModel.setBiffType( nType ); 510 aModel.mnCacheItem = nCacheItem; 511 aModel.mbShowDetails = !getFlag( nFlags, BIFF_PTFITEM_HIDEDETAILS ); 512 aModel.mbHidden = getFlag( nFlags, BIFF_PTFITEM_HIDDEN ); 513 514 maItems.push_back( aModel ); 515 } 516 517 void PivotTableField::finalizeImport( const Reference< XDataPilotDescriptor >& rxDPDesc ) 518 { 519 /* Process all fields based on source data, other fields (e.g. group 520 fields) are processed from here. PivotCacahe::getDatabaseIndex() 521 returns -1 for all fields not based on source data. */ 522 Reference< XDataPilotField > xDPField; 523 sal_Int32 nDatabaseIdx = mrPivotTable.getCacheDatabaseIndex( mnFieldIndex ); 524 if( (nDatabaseIdx >= 0) && rxDPDesc.is() ) try 525 { 526 // try to get the source field and its name from passed DataPilot descriptor 527 Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(), UNO_SET_THROW ); 528 xDPField.set( xDPFieldsIA->getByIndex( nDatabaseIdx ), UNO_QUERY_THROW ); 529 Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW ); 530 maDPFieldName = xDPFieldName->getName(); 531 OSL_ENSURE( maDPFieldName.getLength() > 0, "PivotTableField::finalizeImport - no field name in source data found" ); 532 533 // try to convert grouping settings 534 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) ) 535 { 536 // numeric grouping is done inplace, no nested group fields will appear 537 if( pCacheField->hasNumericGrouping() ) 538 { 539 pCacheField->convertNumericGrouping( xDPField ); 540 } 541 else if( pCacheField->hasDateGrouping() ) 542 { 543 // first date group settings are inplace 544 pCacheField->createDateGroupField( xDPField ); 545 // create all nested group fields (if any) 546 mrPivotTable.finalizeDateGroupingImport( xDPField, mnFieldIndex ); 547 } 548 else if( pCacheField->hasParentGrouping() ) 549 { 550 // create a list of all item names, needed to map between original and group items 551 ::std::vector< OUString > aItems; 552 pCacheField->getCacheItemNames( aItems ); 553 PivotCacheGroupItemVector aItemNames; 554 for( ::std::vector< OUString >::iterator aIt = aItems.begin(), aEnd = aItems.end(); aIt != aEnd; ++aIt ) 555 aItemNames.push_back( PivotCacheGroupItem( *aIt ) ); 556 // create all nested group fields (if any) 557 mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, aItemNames ); 558 } 559 } 560 } 561 catch( Exception& ) 562 { 563 } 564 } 565 566 void PivotTableField::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx ) 567 { 568 if( maDPFieldName.getLength() == 0 ) // prevent endless loops if file format is broken 569 { 570 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) ) 571 { 572 if( !pCacheField->isDatabaseField() && pCacheField->hasDateGrouping() && (pCacheField->getGroupBaseField() == nBaseFieldIdx) ) 573 { 574 maDPFieldName = pCacheField->createDateGroupField( rxBaseDPField ); 575 OSL_ENSURE( maDPFieldName.getLength() > 0, "PivotTableField::finalizeDateGroupingImport - cannot create date group field" ); 576 } 577 } 578 } 579 } 580 581 void PivotTableField::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, PivotCacheGroupItemVector& orItemNames ) 582 { 583 if( maDPFieldName.getLength() == 0 ) // prevent endless loops if file format is broken 584 { 585 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) ) 586 { 587 maDPFieldName = pCacheField->createParentGroupField( rxBaseDPField, orItemNames ); 588 // on success, try to create nested group fields 589 Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName ); 590 if( xDPField.is() ) 591 mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, orItemNames ); 592 } 593 } 594 } 595 596 void PivotTableField::convertRowField() 597 { 598 convertRowColPageField( XML_axisRow ); 599 } 600 601 void PivotTableField::convertColField() 602 { 603 convertRowColPageField( XML_axisCol ); 604 } 605 606 void PivotTableField::convertHiddenField() 607 { 608 convertRowColPageField( XML_TOKEN_INVALID ); 609 } 610 611 void PivotTableField::convertPageField( const PTPageFieldModel& rPageField ) 612 { 613 OSL_ENSURE( rPageField.mnField == mnFieldIndex, "PivotTableField::convertPageField - wrong field index" ); 614 // convert all settings common for row/column/page fields 615 Reference< XDataPilotField > xDPField = convertRowColPageField( XML_axisPage ); 616 617 if( xDPField.is() ) 618 { 619 PropertySet aPropSet( xDPField ); 620 using namespace ::com::sun::star::sheet; 621 622 // find cache item used as 'selected page' 623 sal_Int32 nCacheItem = -1; 624 if( maModel.mbMultiPageItems ) 625 { 626 // multiple items may be selected 627 OSL_ENSURE( rPageField.mnItem == BIFF12_PTPAGEFIELD_MULTIITEMS, "PivotTableField::convertPageField - unexpected cache item index" ); 628 // try to find a single visible item 629 bool bHasMultiItems = false; 630 for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); (aIt != aEnd) && !bHasMultiItems; ++aIt ) 631 { 632 if( (aIt->mnType == XML_data) && !aIt->mbHidden ) 633 { 634 bHasMultiItems = nCacheItem >= 0; 635 nCacheItem = bHasMultiItems ? -1 : aIt->mnCacheItem; 636 } 637 } 638 } 639 else 640 { 641 // single item may be selected 642 if( (0 <= rPageField.mnItem) && (rPageField.mnItem < static_cast< sal_Int32 >( maItems.size() )) ) 643 nCacheItem = maItems[ rPageField.mnItem ].mnCacheItem; 644 } 645 646 if( nCacheItem >= 0 ) 647 { 648 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) ) 649 { 650 if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( nCacheItem ) ) 651 { 652 OUString aSelectedPage = pSharedItem->getName(); 653 if( aSelectedPage.getLength() > 0 ) 654 aPropSet.setProperty( PROP_SelectedPage, aSelectedPage ); 655 } 656 } 657 } 658 } 659 } 660 661 void PivotTableField::convertDataField( const PTDataFieldModel& rDataField ) 662 { 663 OSL_ENSURE( rDataField.mnField == mnFieldIndex, "PivotTableField::convertDataField - wrong field index" ); 664 OSL_ENSURE( maModel.mbDataField, "PivotTableField::convertDataField - not a data field" ); 665 Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName ); 666 if( xDPField.is() ) 667 { 668 PropertySet aPropSet( xDPField ); 669 using namespace ::com::sun::star::sheet; 670 671 // field orientation 672 aPropSet.setProperty( PROP_Orientation, DataPilotFieldOrientation_DATA ); 673 674 /* Field aggregation function. Documentation is a little bit confused 675 about which names to use for the count functions. The name 'count' 676 means 'count all', and 'countNum' means 'count numbers'. On the 677 other hand, for subtotals, 'countA' means 'count all', and 'count' 678 means 'count numbers' (see above). */ 679 GeneralFunction eAggFunc = GeneralFunction_SUM; 680 switch( rDataField.mnSubtotal ) 681 { 682 case XML_sum: eAggFunc = GeneralFunction_SUM; break; 683 case XML_count: eAggFunc = GeneralFunction_COUNT; break; 684 case XML_average: eAggFunc = GeneralFunction_AVERAGE; break; 685 case XML_max: eAggFunc = GeneralFunction_MAX; break; 686 case XML_min: eAggFunc = GeneralFunction_MIN; break; 687 case XML_product: eAggFunc = GeneralFunction_PRODUCT; break; 688 case XML_countNums: eAggFunc = GeneralFunction_COUNTNUMS; break; 689 case XML_stdDev: eAggFunc = GeneralFunction_STDEV; break; 690 case XML_stdDevp: eAggFunc = GeneralFunction_STDEVP; break; 691 case XML_var: eAggFunc = GeneralFunction_VAR; break; 692 case XML_varp: eAggFunc = GeneralFunction_VARP; break; 693 default: OSL_ENSURE( false, "PivotTableField::convertDataField - unknown aggregation function" ); 694 } 695 aPropSet.setProperty( PROP_Function, eAggFunc ); 696 697 // field reference ('show data as') 698 DataPilotFieldReference aReference; 699 aReference.ReferenceType = DataPilotFieldReferenceType::NONE; 700 switch( rDataField.mnShowDataAs ) 701 { 702 case XML_difference: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_DIFFERENCE; break; 703 case XML_percent: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE; break; 704 case XML_percentDiff: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE; break; 705 case XML_runTotal: aReference.ReferenceType = DataPilotFieldReferenceType::RUNNING_TOTAL; break; 706 case XML_percentOfRow: aReference.ReferenceType = DataPilotFieldReferenceType::ROW_PERCENTAGE; break; 707 case XML_percentOfCol: aReference.ReferenceType = DataPilotFieldReferenceType::COLUMN_PERCENTAGE; break; 708 case XML_percentOfTotal: aReference.ReferenceType = DataPilotFieldReferenceType::TOTAL_PERCENTAGE; break; 709 case XML_index: aReference.ReferenceType = DataPilotFieldReferenceType::INDEX; break; 710 } 711 if( aReference.ReferenceType != DataPilotFieldReferenceType::NONE ) 712 { 713 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( rDataField.mnBaseField ) ) 714 { 715 aReference.ReferenceField = pCacheField->getName(); 716 switch( rDataField.mnBaseItem ) 717 { 718 case OOX_PT_PREVIOUS_ITEM: 719 aReference.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS; 720 break; 721 case OOX_PT_NEXT_ITEM: 722 aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT; 723 break; 724 default: 725 aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED; 726 if( const PivotCacheItem* pCacheItem = pCacheField->getCacheItem( rDataField.mnBaseItem ) ) 727 aReference.ReferenceItemName = pCacheItem->getName(); 728 } 729 aPropSet.setProperty( PROP_Reference, aReference ); 730 } 731 } 732 } 733 } 734 735 // private -------------------------------------------------------------------- 736 737 Reference< XDataPilotField > PivotTableField::convertRowColPageField( sal_Int32 nAxis ) 738 { 739 bool bDataLayout = mnFieldIndex == OOX_PT_DATALAYOUTFIELD; 740 Reference< XDataPilotField > xDPField = bDataLayout ? mrPivotTable.getDataLayoutField() : mrPivotTable.getDataPilotField( maDPFieldName ); 741 OSL_ENSURE( bDataLayout || (nAxis == maModel.mnAxis), "PivotTableField::convertRowColPageField - field axis mismatch" ); 742 743 if( xDPField.is() ) 744 { 745 PropertySet aPropSet( xDPField ); 746 using namespace ::com::sun::star::sheet; 747 748 // field orientation 749 DataPilotFieldOrientation eFieldOrient = DataPilotFieldOrientation_HIDDEN; 750 switch( nAxis ) 751 { 752 case XML_axisRow: eFieldOrient = DataPilotFieldOrientation_ROW; break; 753 case XML_axisCol: eFieldOrient = DataPilotFieldOrientation_COLUMN; break; 754 case XML_axisPage: eFieldOrient = DataPilotFieldOrientation_PAGE; break; 755 } 756 if( eFieldOrient != DataPilotFieldOrientation_HIDDEN ) 757 aPropSet.setProperty( PROP_Orientation, eFieldOrient ); 758 759 // all other settings not for the data layout field 760 if( !bDataLayout ) 761 { 762 /* Field subtotal functions. Ignore the 'defaultSubtotal' flag, if 763 explicit functions are set. This is different behaviour between 764 XML (where 'defaultSubtotal' is set regardless of other 765 functions) and binary formats (where 'defaultSubtotal' is not 766 set if other functions are set). */ 767 ::std::vector< GeneralFunction > aSubtotals; 768 /* Order of subtotals is fixed in Excel. Documentation is a little 769 bit confused about which names to use for the count functions. 770 For subtotals, 'countA' means 'count all', and 'count' means 771 'count numbers'. On the other hand, for the data field 772 aggregation function, 'count' means 'count all', and 'countNum' 773 means 'count numbers' (see below). */ 774 if( maModel.mbSumSubtotal ) aSubtotals.push_back( GeneralFunction_SUM ); 775 if( maModel.mbCountASubtotal ) aSubtotals.push_back( GeneralFunction_COUNT ); 776 if( maModel.mbAverageSubtotal ) aSubtotals.push_back( GeneralFunction_AVERAGE ); 777 if( maModel.mbMaxSubtotal ) aSubtotals.push_back( GeneralFunction_MAX ); 778 if( maModel.mbMinSubtotal ) aSubtotals.push_back( GeneralFunction_MIN ); 779 if( maModel.mbProductSubtotal ) aSubtotals.push_back( GeneralFunction_PRODUCT ); 780 if( maModel.mbCountSubtotal ) aSubtotals.push_back( GeneralFunction_COUNTNUMS ); 781 if( maModel.mbStdDevSubtotal ) aSubtotals.push_back( GeneralFunction_STDEV ); 782 if( maModel.mbStdDevPSubtotal ) aSubtotals.push_back( GeneralFunction_STDEVP ); 783 if( maModel.mbVarSubtotal ) aSubtotals.push_back( GeneralFunction_VAR ); 784 if( maModel.mbVarPSubtotal ) aSubtotals.push_back( GeneralFunction_VARP ); 785 // if no function is set manually, check the 'defaultSubtotal' flag 786 if( aSubtotals.empty() && maModel.mbDefaultSubtotal ) 787 aSubtotals.push_back( GeneralFunction_AUTO ); 788 aPropSet.setProperty( PROP_Subtotals, ContainerHelper::vectorToSequence( aSubtotals ) ); 789 790 // layout settings 791 DataPilotFieldLayoutInfo aLayoutInfo; 792 aLayoutInfo.LayoutMode = maModel.mbOutline ? 793 (maModel.mbSubtotalTop ? DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP : DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM) : 794 DataPilotFieldLayoutMode::TABULAR_LAYOUT; 795 aLayoutInfo.AddEmptyLines = maModel.mbInsertBlankRow; 796 aPropSet.setProperty( PROP_LayoutInfo, aLayoutInfo ); 797 aPropSet.setProperty( PROP_ShowEmpty, maModel.mbShowAll ); 798 799 // auto show (OOXML/BIFF12 only) 800 if( maModel.mbAutoShow ) 801 { 802 DataPilotFieldAutoShowInfo aAutoShowInfo; 803 aAutoShowInfo.IsEnabled = sal_True; 804 aAutoShowInfo.ShowItemsMode = maModel.mbTopAutoShow ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM; 805 aAutoShowInfo.ItemCount = maModel.mnAutoShowItems; 806 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnAutoShowRankBy ) ) 807 aAutoShowInfo.DataField = pCacheField->getName(); 808 aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo ); 809 } 810 811 // auto sort 812 DataPilotFieldSortInfo aSortInfo; 813 aSortInfo.IsAscending = maModel.mnSortType == XML_ascending; 814 if( (maModel.mnSortType != XML_ascending) && (maModel.mnSortType != XML_descending) ) 815 { 816 aSortInfo.Mode = DataPilotFieldSortMode::MANUAL; 817 } 818 else 819 { 820 const PivotCacheField* pCacheField = (maModel.mnSortRefField == OOX_PT_DATALAYOUTFIELD) ? 821 mrPivotTable.getCacheFieldOfDataField( maModel.mnSortRefItem ) : 0; 822 if( pCacheField ) 823 { 824 aSortInfo.Mode = DataPilotFieldSortMode::DATA; 825 aSortInfo.Field = pCacheField->getName(); 826 } 827 else 828 { 829 aSortInfo.Mode = DataPilotFieldSortMode::NAME; 830 } 831 } 832 aPropSet.setProperty( PROP_SortInfo, aSortInfo ); 833 834 // item settings 835 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) ) try 836 { 837 Reference< XNameAccess > xDPItemsNA( xDPField->getItems(), UNO_QUERY_THROW ); 838 for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt ) 839 { 840 if( aIt->mnType == XML_data ) 841 { 842 if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( aIt->mnCacheItem ) ) try 843 { 844 PropertySet aItemProp( xDPItemsNA->getByName( pSharedItem->getName() ) ); 845 aItemProp.setProperty( PROP_ShowDetail, aIt->mbShowDetails ); 846 aItemProp.setProperty( PROP_IsHidden, aIt->mbHidden ); 847 } 848 catch( Exception& ) 849 { 850 // catch every failed container access to be able to process following items 851 } 852 } 853 } 854 } 855 catch( Exception& ) 856 { 857 } 858 } 859 } 860 return xDPField; 861 } 862 863 // ============================================================================ 864 865 PTFilterModel::PTFilterModel() : 866 mfValue( 0.0 ), 867 mnField( -1 ), 868 mnMemPropField( -1 ), 869 mnType( XML_TOKEN_INVALID ), 870 mnEvalOrder( 0 ), 871 mnId( -1 ), 872 mnMeasureField( -1 ), 873 mnMeasureHier( -1 ), 874 mbTopFilter( true ) 875 { 876 } 877 878 // ---------------------------------------------------------------------------- 879 880 PivotTableFilter::PivotTableFilter( const PivotTable& rPivotTable ) : 881 WorkbookHelper( rPivotTable ), 882 mrPivotTable( rPivotTable ) 883 { 884 } 885 886 void PivotTableFilter::importFilter( const AttributeList& rAttribs ) 887 { 888 maModel.maName = rAttribs.getXString( XML_name, OUString() ); 889 maModel.maDescription = rAttribs.getXString( XML_description, OUString() ); 890 maModel.maStrValue1 = rAttribs.getXString( XML_stringValue1, OUString() ); 891 maModel.maStrValue2 = rAttribs.getXString( XML_stringValue2, OUString() ); 892 maModel.mnField = rAttribs.getInteger( XML_fld, -1 ); 893 maModel.mnMemPropField = rAttribs.getInteger( XML_mpFld, -1 ); 894 maModel.mnType = rAttribs.getToken( XML_type, XML_TOKEN_INVALID ); 895 maModel.mnEvalOrder = rAttribs.getInteger( XML_evalOrder, 0 ); 896 maModel.mnId = rAttribs.getInteger( XML_id, -1 ); 897 maModel.mnMeasureField = rAttribs.getInteger( XML_iMeasureFld, -1 ); 898 maModel.mnMeasureHier = rAttribs.getInteger( XML_iMeasureHier, -1 ); 899 } 900 901 void PivotTableFilter::importTop10( const AttributeList& rAttribs ) 902 { 903 OSL_ENSURE( rAttribs.getBool( XML_percent, false ) == (maModel.mnType == XML_percent), 904 "PivotTableFilter::importTop10 - unexpected value of percent attribute" ); 905 maModel.mfValue = rAttribs.getDouble( XML_val, 0.0 ); 906 maModel.mbTopFilter = rAttribs.getBool( XML_top, true ); 907 } 908 909 void PivotTableFilter::importPTFilter( SequenceInputStream& rStrm ) 910 { 911 sal_Int32 nType; 912 sal_uInt16 nFlags; 913 rStrm >> maModel.mnField >> maModel.mnMemPropField >> nType; 914 rStrm.skip( 4 ); // unused 915 rStrm >> maModel.mnId >> maModel.mnMeasureField >> maModel.mnMeasureHier >> nFlags; 916 if( getFlag( nFlags, BIFF12_PTFILTER_HASNAME ) ) 917 rStrm >> maModel.maName; 918 if( getFlag( nFlags, BIFF12_PTFILTER_HASDESCRIPTION ) ) 919 rStrm >> maModel.maDescription; 920 if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE1 ) ) 921 rStrm >> maModel.maStrValue1; 922 if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE2 ) ) 923 rStrm >> maModel.maStrValue2; 924 925 static sal_Int32 spnTypes[] = 926 { 927 XML_unknown, 928 // data field top10 filter (1-3) 929 XML_count, XML_percent, XML_sum, 930 // caption filter (4-17) 931 XML_captionEqual, XML_captionNotEqual, 932 XML_captionBeginsWith, XML_captionNotBeginsWith, XML_captionEndsWith, XML_captionNotEndsWith, 933 XML_captionContains, XML_captionNotContains, XML_captionGreaterThan, XML_captionGreaterThanOrEqual, 934 XML_captionLessThan, XML_captionLessThanOrEqual, XML_captionBetween, XML_captionNotBetween, 935 // value filter (18-25) 936 XML_valueEqual, XML_valueNotEqual, XML_valueGreaterThan, XML_valueGreaterThanOrEqual, 937 XML_valueLessThan, XML_valueLessThanOrEqual, XML_valueBetween, XML_valueNotBetween, 938 // date filter (26-65) 939 XML_dateEqual, XML_dateOlderThan, XML_dateNewerThan, XML_dateBetween, 940 XML_tomorrow, XML_today, XML_yesterday, XML_nextWeek, XML_thisWeek, XML_lastWeek, 941 XML_nextMonth, XML_thisMonth, XML_lastMonth, XML_nextQuarter, XML_thisQuarter, XML_lastQuarter, 942 XML_nextYear, XML_thisYear, XML_lastYear, XML_yearToDate, XML_Q1, XML_Q2, XML_Q3, XML_Q4, 943 XML_M1, XML_M2, XML_M3, XML_M4, XML_M5, XML_M6, XML_M7, XML_M8, XML_M9, XML_M10, XML_M11, XML_M12, 944 XML_dateNotEqual, XML_dateOlderThanOrEqual, XML_dateNewerThanOrEqual, XML_dateNotBetween 945 }; 946 maModel.mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID ); 947 } 948 949 void PivotTableFilter::importTop10Filter( SequenceInputStream& rStrm ) 950 { 951 sal_uInt8 nFlags; 952 rStrm >> nFlags >> maModel.mfValue; 953 954 OSL_ENSURE( getFlag( nFlags, BIFF12_TOP10FILTER_PERCENT ) == (maModel.mnType == XML_percent), 955 "PivotTableFilter::importTop10 - unexpected value of percent attribute" ); 956 maModel.mbTopFilter = getFlag( nFlags, BIFF12_TOP10FILTER_TOP ); 957 } 958 959 void PivotTableFilter::finalizeImport() 960 { 961 // only simple top10 filter supported 962 if( maModel.mnType == XML_count ) 963 { 964 PropertySet aPropSet( mrPivotTable.getDataPilotField( maModel.mnField ) ); 965 if( aPropSet.is() ) 966 { 967 using namespace ::com::sun::star::sheet; 968 DataPilotFieldAutoShowInfo aAutoShowInfo; 969 aAutoShowInfo.IsEnabled = sal_True; 970 aAutoShowInfo.ShowItemsMode = maModel.mbTopFilter ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM; 971 aAutoShowInfo.ItemCount = getLimitedValue< sal_Int32, double >( maModel.mfValue, 0, SAL_MAX_INT32 ); 972 if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnMeasureField ) ) 973 aAutoShowInfo.DataField = pCacheField->getName(); 974 aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo ); 975 } 976 } 977 } 978 979 // ============================================================================ 980 981 PTDefinitionModel::PTDefinitionModel() : 982 mnCacheId( -1 ), 983 mnDataPosition( 0 ), 984 mnPageWrap( 0 ), 985 mnIndent( 1 ), 986 mnChartFormat( 0 ), 987 mnRowFields( 0 ), 988 mnColFields( 0 ), 989 mbDataOnRows( false ), 990 mbShowError( false ), 991 mbShowMissing( true ), 992 mbShowItems( true ), 993 mbDisableFieldList( false ), 994 mbShowCalcMembers( true ), 995 mbVisualTotals( true ), 996 mbShowDrill( true ), 997 mbPrintDrill( false ), 998 mbEnableDrill( true ), 999 mbPreserveFormatting( true ), 1000 mbUseAutoFormat( false ), 1001 mbPageOverThenDown( false ), 1002 mbSubtotalHiddenItems( false ), 1003 mbRowGrandTotals( true ), 1004 mbColGrandTotals( true ), 1005 mbFieldPrintTitles( false ), 1006 mbItemPrintTitles( false ), 1007 mbMergeItem( false ), 1008 mbShowEmptyRow( false ), 1009 mbShowEmptyCol( false ), 1010 mbShowHeaders( true ), 1011 mbFieldListSortAsc( false ), 1012 mbCustomListSort( true ) 1013 { 1014 } 1015 1016 // ---------------------------------------------------------------------------- 1017 1018 PTLocationModel::PTLocationModel() : 1019 mnFirstHeaderRow( 0 ), 1020 mnFirstDataRow( 0 ), 1021 mnFirstDataCol( 0 ), 1022 mnRowPageCount( 0 ), 1023 mnColPageCount( 0 ) 1024 { 1025 } 1026 1027 // ---------------------------------------------------------------------------- 1028 1029 PivotTable::PivotTable( const WorkbookHelper& rHelper ) : 1030 WorkbookHelper( rHelper ), 1031 maDataField( *this, OOX_PT_DATALAYOUTFIELD ), 1032 mpPivotCache( 0 ) 1033 { 1034 } 1035 1036 void PivotTable::importPivotTableDefinition( const AttributeList& rAttribs ) 1037 { 1038 maDefModel.maName = rAttribs.getXString( XML_name, OUString() ); 1039 maDefModel.maDataCaption = rAttribs.getXString( XML_dataCaption , OUString() ); 1040 maDefModel.maGrandTotalCaption = rAttribs.getXString( XML_grandTotalCaption, OUString() ); 1041 maDefModel.maRowHeaderCaption = rAttribs.getXString( XML_rowHeaderCaption, OUString() ); 1042 maDefModel.maColHeaderCaption = rAttribs.getXString( XML_colHeaderCaption, OUString() ); 1043 maDefModel.maErrorCaption = rAttribs.getXString( XML_errorCaption, OUString() ); 1044 maDefModel.maMissingCaption = rAttribs.getXString( XML_missingCaption, OUString() ); 1045 maDefModel.maPageStyle = rAttribs.getXString( XML_pageStyle, OUString() ); 1046 maDefModel.maPivotTableStyle = rAttribs.getXString( XML_pivotTableStyle, OUString() ); 1047 maDefModel.maVacatedStyle = rAttribs.getXString( XML_vacatedStyle, OUString() ); 1048 maDefModel.maTag = rAttribs.getXString( XML_tag, OUString() ); 1049 maDefModel.mnCacheId = rAttribs.getInteger( XML_cacheId, -1 ); 1050 maDefModel.mnDataPosition = rAttribs.getInteger( XML_dataPosition, 0 ); 1051 maDefModel.mnPageWrap = rAttribs.getInteger( XML_pageWrap, 0 ); 1052 maDefModel.mnIndent = rAttribs.getInteger( XML_indent, 1 ); 1053 maDefModel.mnChartFormat = rAttribs.getInteger( XML_chartFormat, 0 ); 1054 maDefModel.mnAutoFormatId = rAttribs.getInteger( XML_autoFormatId, 0 ); 1055 maDefModel.mbDataOnRows = rAttribs.getBool( XML_dataOnRows, false ); 1056 maDefModel.mbShowError = rAttribs.getBool( XML_showError, false ); 1057 maDefModel.mbShowMissing = rAttribs.getBool( XML_showMissing, true ); 1058 maDefModel.mbShowItems = rAttribs.getBool( XML_showItems, true ); 1059 maDefModel.mbDisableFieldList = rAttribs.getBool( XML_disableFieldList, false ); 1060 maDefModel.mbShowCalcMembers = rAttribs.getBool( XML_showCalcMbrs, true ); 1061 maDefModel.mbVisualTotals = rAttribs.getBool( XML_visualTotals, true ); 1062 maDefModel.mbShowDrill = rAttribs.getBool( XML_showDrill, true ); 1063 maDefModel.mbPrintDrill = rAttribs.getBool( XML_printDrill, false ); 1064 maDefModel.mbEnableDrill = rAttribs.getBool( XML_enableDrill, true ); 1065 maDefModel.mbPreserveFormatting = rAttribs.getBool( XML_preserveFormatting, true ); 1066 maDefModel.mbUseAutoFormat = rAttribs.getBool( XML_useAutoFormatting, false ); 1067 maDefModel.mbPageOverThenDown = rAttribs.getBool( XML_pageOverThenDown, false ); 1068 maDefModel.mbSubtotalHiddenItems = rAttribs.getBool( XML_subtotalHiddenItems, false ); 1069 maDefModel.mbRowGrandTotals = rAttribs.getBool( XML_rowGrandTotals, true ); 1070 maDefModel.mbColGrandTotals = rAttribs.getBool( XML_colGrandTotals, true ); 1071 maDefModel.mbFieldPrintTitles = rAttribs.getBool( XML_fieldPrintTitles, false ); 1072 maDefModel.mbItemPrintTitles = rAttribs.getBool( XML_itemPrintTitles, false ); 1073 maDefModel.mbMergeItem = rAttribs.getBool( XML_mergeItem, false ); 1074 maDefModel.mbShowEmptyRow = rAttribs.getBool( XML_showEmptyRow, false ); 1075 maDefModel.mbShowEmptyCol = rAttribs.getBool( XML_showEmptyCol, false ); 1076 maDefModel.mbShowHeaders = rAttribs.getBool( XML_showHeaders, true ); 1077 maDefModel.mbFieldListSortAsc = rAttribs.getBool( XML_fieldListSortAscending, false ); 1078 maDefModel.mbCustomListSort = rAttribs.getBool( XML_customListSort, true ); 1079 maDefModel.mbApplyNumFmt = rAttribs.getBool( XML_applyNumberFormats, false ); 1080 maDefModel.mbApplyFont = rAttribs.getBool( XML_applyFontFormats, false ); 1081 maDefModel.mbApplyAlignment = rAttribs.getBool( XML_applyAlignmentFormats, false ); 1082 maDefModel.mbApplyBorder = rAttribs.getBool( XML_applyBorderFormats, false ); 1083 maDefModel.mbApplyFill = rAttribs.getBool( XML_applyPatternFormats, false ); 1084 // OOXML and BIFF12 documentation differ: OOXML mentions width/height, BIFF12 mentions protection 1085 maDefModel.mbApplyProtection = rAttribs.getBool( XML_applyWidthHeightFormats, false ); 1086 } 1087 1088 void PivotTable::importLocation( const AttributeList& rAttribs, sal_Int16 nSheet ) 1089 { 1090 getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, rAttribs.getString( XML_ref, OUString() ), nSheet ); 1091 maLocationModel.mnFirstHeaderRow = rAttribs.getInteger( XML_firstHeaderRow, 0 ); 1092 maLocationModel.mnFirstDataRow = rAttribs.getInteger( XML_firstDataRow, 0 ); 1093 maLocationModel.mnFirstDataCol = rAttribs.getInteger( XML_firstDataCol, 0 ); 1094 maLocationModel.mnRowPageCount = rAttribs.getInteger( XML_rowPageCount, 0 ); 1095 maLocationModel.mnColPageCount = rAttribs.getInteger( XML_colPageCount, 0 ); 1096 } 1097 1098 void PivotTable::importRowField( const AttributeList& rAttribs ) 1099 { 1100 importField( maRowFields, rAttribs ); 1101 } 1102 1103 void PivotTable::importColField( const AttributeList& rAttribs ) 1104 { 1105 importField( maColFields, rAttribs ); 1106 } 1107 1108 void PivotTable::importPageField( const AttributeList& rAttribs ) 1109 { 1110 PTPageFieldModel aModel; 1111 aModel.maName = rAttribs.getXString( XML_name, OUString() ); 1112 aModel.mnField = rAttribs.getInteger( XML_fld, -1 ); 1113 // specification is wrong, XML_item is not the cache item, but the field item 1114 aModel.mnItem = rAttribs.getInteger( XML_item, BIFF12_PTPAGEFIELD_MULTIITEMS ); 1115 maPageFields.push_back( aModel ); 1116 } 1117 1118 void PivotTable::importDataField( const AttributeList& rAttribs ) 1119 { 1120 PTDataFieldModel aModel; 1121 aModel.maName = rAttribs.getXString( XML_name, OUString() ); 1122 aModel.mnField = rAttribs.getInteger( XML_fld, -1 ); 1123 aModel.mnSubtotal = rAttribs.getToken( XML_subtotal, XML_sum ); 1124 aModel.mnShowDataAs = rAttribs.getToken( XML_showDataAs, XML_normal ); 1125 aModel.mnBaseField = rAttribs.getInteger( XML_baseField, -1 ); 1126 aModel.mnBaseItem = rAttribs.getInteger( XML_baseItem, -1 ); 1127 aModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 ); 1128 maDataFields.push_back( aModel ); 1129 } 1130 1131 void PivotTable::importPTDefinition( SequenceInputStream& rStrm ) 1132 { 1133 sal_uInt32 nFlags1, nFlags2, nFlags3; 1134 sal_uInt8 nDataAxis; 1135 rStrm >> nFlags1 >> nFlags2 >> nFlags3 >> nDataAxis; 1136 maDefModel.mnPageWrap = rStrm.readuInt8(); 1137 rStrm.skip( 2 ); // refresh versions 1138 rStrm >> maDefModel.mnDataPosition; 1139 maDefModel.mnAutoFormatId = rStrm.readuInt16(); 1140 rStrm.skip( 2 ); // unused 1141 rStrm >> maDefModel.mnChartFormat >> maDefModel.mnCacheId >> maDefModel.maName; 1142 if( getFlag( nFlags2, BIFF12_PTDEF_HASDATACAPTION ) ) 1143 rStrm >> maDefModel.maDataCaption; 1144 if( getFlag( nFlags2, BIFF12_PTDEF_HASGRANDTOTALCAPTION ) ) 1145 rStrm >> maDefModel.maGrandTotalCaption; 1146 if( !getFlag( nFlags3, BIFF12_PTDEF_NOERRORCAPTION ) ) // missing flag indicates existing string 1147 rStrm >> maDefModel.maErrorCaption; 1148 if( !getFlag( nFlags3, BIFF12_PTDEF_NOMISSINGCAPTION ) ) // missing flag indicates existing string 1149 rStrm >> maDefModel.maMissingCaption; 1150 if( getFlag( nFlags2, BIFF12_PTDEF_HASPAGESTYLE ) ) 1151 rStrm >> maDefModel.maPageStyle; 1152 if( getFlag( nFlags2, BIFF12_PTDEF_HASPIVOTTABLESTYLE ) ) 1153 rStrm >> maDefModel.maPivotTableStyle; 1154 if( getFlag( nFlags2, BIFF12_PTDEF_HASVACATEDSTYLE ) ) 1155 rStrm >> maDefModel.maVacatedStyle; 1156 if( getFlag( nFlags2, BIFF12_PTDEF_HASTAG ) ) 1157 rStrm >> maDefModel.maTag; 1158 if( getFlag( nFlags3, BIFF12_PTDEF_HASCOLHEADERCAPTION ) ) // TODO: right order (col/row)? spec is unclear 1159 rStrm >> maDefModel.maColHeaderCaption; 1160 if( getFlag( nFlags3, BIFF12_PTDEF_HASROWHEADERCAPTION ) ) 1161 rStrm >> maDefModel.maRowHeaderCaption; 1162 1163 OSL_ENSURE( (nDataAxis == BIFF12_PTDEF_ROWAXIS) || (nDataAxis == BIFF12_PTDEF_COLAXIS), 1164 "PivotTable::importPTDefinition - unexpected axis position for data field" ); 1165 1166 maDefModel.mnIndent = extractValue< sal_uInt8 >( nFlags1, 24, 7 ); 1167 maDefModel.mbDataOnRows = nDataAxis == BIFF12_PTDEF_ROWAXIS; 1168 maDefModel.mbShowError = getFlag( nFlags2, BIFF12_PTDEF_SHOWERROR ); 1169 maDefModel.mbShowMissing = getFlag( nFlags2, BIFF12_PTDEF_SHOWMISSING ); 1170 maDefModel.mbShowItems = getFlag( nFlags1, BIFF12_PTDEF_SHOWITEMS ); 1171 maDefModel.mbDisableFieldList = getFlag( nFlags1, BIFF12_PTDEF_DISABLEFIELDLIST ); 1172 maDefModel.mbShowCalcMembers = !getFlag( nFlags1, BIFF12_PTDEF_HIDECALCMEMBERS ); 1173 maDefModel.mbVisualTotals = !getFlag( nFlags1, BIFF12_PTDEF_WITHHIDDENTOTALS ); 1174 maDefModel.mbShowDrill = !getFlag( nFlags1, BIFF12_PTDEF_HIDEDRILL ); 1175 maDefModel.mbPrintDrill = getFlag( nFlags1, BIFF12_PTDEF_PRINTDRILL ); 1176 maDefModel.mbEnableDrill = getFlag( nFlags2, BIFF12_PTDEF_ENABLEDRILL ); 1177 maDefModel.mbPreserveFormatting = getFlag( nFlags2, BIFF12_PTDEF_PRESERVEFORMATTING ); 1178 maDefModel.mbUseAutoFormat = getFlag( nFlags2, BIFF12_PTDEF_USEAUTOFORMAT ); 1179 maDefModel.mbPageOverThenDown = getFlag( nFlags2, BIFF12_PTDEF_PAGEOVERTHENDOWN ); 1180 maDefModel.mbSubtotalHiddenItems = getFlag( nFlags2, BIFF12_PTDEF_SUBTOTALHIDDENITEMS ); 1181 maDefModel.mbRowGrandTotals = getFlag( nFlags2, BIFF12_PTDEF_ROWGRANDTOTALS ); 1182 maDefModel.mbColGrandTotals = getFlag( nFlags2, BIFF12_PTDEF_COLGRANDTOTALS ); 1183 maDefModel.mbFieldPrintTitles = getFlag( nFlags2, BIFF12_PTDEF_FIELDPRINTTITLES ); 1184 maDefModel.mbItemPrintTitles = getFlag( nFlags2, BIFF12_PTDEF_ITEMPRINTTITLES ); 1185 maDefModel.mbMergeItem = getFlag( nFlags2, BIFF12_PTDEF_MERGEITEM ); 1186 maDefModel.mbApplyNumFmt = getFlag( nFlags2, BIFF12_PTDEF_APPLYNUMFMT ); 1187 maDefModel.mbApplyFont = getFlag( nFlags2, BIFF12_PTDEF_APPLYFONT ); 1188 maDefModel.mbApplyAlignment = getFlag( nFlags2, BIFF12_PTDEF_APPLYALIGNMENT ); 1189 maDefModel.mbApplyBorder = getFlag( nFlags2, BIFF12_PTDEF_APPLYBORDER ); 1190 maDefModel.mbApplyFill = getFlag( nFlags2, BIFF12_PTDEF_APPLYFILL ); 1191 maDefModel.mbApplyProtection = getFlag( nFlags2, BIFF12_PTDEF_APPLYPROTECTION ); 1192 maDefModel.mbShowEmptyRow = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYROW ); 1193 maDefModel.mbShowEmptyCol = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYCOL ); 1194 maDefModel.mbShowHeaders = !getFlag( nFlags1, BIFF12_PTDEF_HIDEHEADERS ); 1195 maDefModel.mbFieldListSortAsc = getFlag( nFlags3, BIFF12_PTDEF_FIELDLISTSORTASC ); 1196 maDefModel.mbCustomListSort = !getFlag( nFlags3, BIFF12_PTDEF_NOCUSTOMLISTSORT ); 1197 } 1198 1199 void PivotTable::importPTLocation( SequenceInputStream& rStrm, sal_Int16 nSheet ) 1200 { 1201 BinRange aBinRange; 1202 rStrm >> aBinRange >> maLocationModel.mnFirstHeaderRow 1203 >> maLocationModel.mnFirstDataRow >> maLocationModel.mnFirstDataCol 1204 >> maLocationModel.mnRowPageCount >> maLocationModel.mnColPageCount; 1205 getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, aBinRange, nSheet ); 1206 } 1207 1208 void PivotTable::importPTRowFields( SequenceInputStream& rStrm ) 1209 { 1210 importFields( maRowFields, rStrm ); 1211 } 1212 1213 void PivotTable::importPTColFields( SequenceInputStream& rStrm ) 1214 { 1215 importFields( maColFields, rStrm ); 1216 } 1217 1218 void PivotTable::importPTPageField( SequenceInputStream& rStrm ) 1219 { 1220 PTPageFieldModel aModel; 1221 sal_uInt8 nFlags; 1222 rStrm >> aModel.mnField >> aModel.mnItem; 1223 rStrm.skip( 4 ); // hierarchy 1224 rStrm >> nFlags; 1225 if( getFlag( nFlags, BIFF12_PTPAGEFIELD_HASNAME ) ) 1226 rStrm >> aModel.maName; 1227 maPageFields.push_back( aModel ); 1228 } 1229 1230 void PivotTable::importPTDataField( SequenceInputStream& rStrm ) 1231 { 1232 PTDataFieldModel aModel; 1233 sal_Int32 nSubtotal, nShowDataAs; 1234 sal_uInt8 nHasName; 1235 rStrm >> aModel.mnField >> nSubtotal >> nShowDataAs >> aModel.mnBaseField >> aModel.mnBaseItem >> aModel.mnNumFmtId >> nHasName; 1236 if( nHasName == 1 ) 1237 rStrm >> aModel.maName; 1238 aModel.setBiffSubtotal( nSubtotal ); 1239 aModel.setBiffShowDataAs( nShowDataAs ); 1240 maDataFields.push_back( aModel ); 1241 } 1242 1243 void PivotTable::importPTDefinition( BiffInputStream& rStrm, sal_Int16 nSheet ) 1244 { 1245 BinRange aBinRange; 1246 sal_uInt16 nFlags, nTabNameLen, nDataNameLen; 1247 rStrm >> aBinRange; 1248 maLocationModel.mnFirstHeaderRow = rStrm.readuInt16(); 1249 maLocationModel.mnFirstDataRow = rStrm.readuInt16(); 1250 maLocationModel.mnFirstDataCol = rStrm.readuInt16(); 1251 maDefModel.mnCacheId = rStrm.readuInt16(); 1252 rStrm.skip( 2 ); // unused 1253 maDefModel.mbDataOnRows = rStrm.readuInt16() == BIFF_PTDEF_ROWAXIS; 1254 maDefModel.mnDataPosition = rStrm.readInt16(); 1255 rStrm.skip( 2 ); // number of fields 1256 rStrm >> maDefModel.mnRowFields >> maDefModel.mnColFields; 1257 rStrm.skip( 8 ); // number of page fields, data fields, data rows, data columns 1258 rStrm >> nFlags; 1259 maDefModel.mnChartFormat = rStrm.readuInt16(); 1260 rStrm >> nTabNameLen >> nDataNameLen; 1261 maDefModel.maName = lclReadPivotString( *this, rStrm, nTabNameLen ); 1262 maDefModel.maDataCaption = lclReadPivotString( *this, rStrm, nDataNameLen ); 1263 1264 maDefModel.mbRowGrandTotals = getFlag( nFlags, BIFF_PTDEF_ROWGRANDTOTALS ); 1265 maDefModel.mbColGrandTotals = getFlag( nFlags, BIFF_PTDEF_COLGRANDTOTALS ); 1266 1267 getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, aBinRange, nSheet ); 1268 } 1269 1270 void PivotTable::importPTDefinition2( BiffInputStream& rStrm ) 1271 { 1272 if( getBiff() == BIFF8 ) 1273 { 1274 sal_uInt16 nErrCaptLen, nMissCaptLen, nTagLen, nPageStyleLen, nTabStyleLen, nVacStyleLen; 1275 sal_uInt32 nFlags; 1276 rStrm.skip( 2 ); // number of formatting records 1277 rStrm >> nErrCaptLen >> nMissCaptLen >> nTagLen; 1278 rStrm.skip( 6 ); // number of selection records, page rows, page columns 1279 rStrm >> nFlags >> nPageStyleLen >> nTabStyleLen >> nVacStyleLen; 1280 maDefModel.maErrorCaption = lclReadPivotString( *this, rStrm, nErrCaptLen ); 1281 maDefModel.maMissingCaption = lclReadPivotString( *this, rStrm, nMissCaptLen ); 1282 maDefModel.maTag = lclReadPivotString( *this, rStrm, nTagLen ); 1283 maDefModel.maPageStyle = lclReadPivotString( *this, rStrm, nPageStyleLen ); 1284 maDefModel.maPivotTableStyle = lclReadPivotString( *this, rStrm, nTabStyleLen ); 1285 maDefModel.maVacatedStyle = lclReadPivotString( *this, rStrm, nVacStyleLen ); 1286 1287 maDefModel.mbShowError = getFlag( nFlags, BIFF_PTDEF2_SHOWERROR ); 1288 maDefModel.mbShowMissing = getFlag( nFlags, BIFF_PTDEF2_SHOWMISSING ); 1289 maDefModel.mbEnableDrill = getFlag( nFlags, BIFF_PTDE2F_ENABLEDRILL ); 1290 maDefModel.mbPreserveFormatting = getFlag( nFlags, BIFF_PTDEF2_PRESERVEFORMATTING ); 1291 maDefModel.mbPageOverThenDown = getFlag( nFlags, BIFF_PTDEF2_PAGEOVERTHENDOWN ); 1292 maDefModel.mbSubtotalHiddenItems = getFlag( nFlags, BIFF_PTDEF2_SUBTOTALHIDDENITEMS ); 1293 maDefModel.mbMergeItem = getFlag( nFlags, BIFF_PTDEF2_MERGEITEM ); 1294 } 1295 } 1296 1297 void PivotTable::importPTRowColFields( BiffInputStream& rStrm ) 1298 { 1299 // first PTROWCOLFIELDS record contains row fields unless there are no row fields 1300 if( (maDefModel.mnRowFields > 0) && maRowFields.empty() ) 1301 importFields( maRowFields, rStrm, maDefModel.mnRowFields ); 1302 else if( (maDefModel.mnColFields > 0) && maColFields.empty() ) 1303 importFields( maColFields, rStrm, maDefModel.mnColFields ); 1304 } 1305 1306 void PivotTable::importPTPageFields( BiffInputStream& rStrm ) 1307 { 1308 while( rStrm.getRemaining() >= 6 ) 1309 { 1310 PTPageFieldModel aModel; 1311 sal_Int16 nField, nItem; 1312 rStrm >> nField >> nItem; 1313 rStrm.skip( 2 ); // dropdown object ID 1314 aModel.mnField = nField; 1315 aModel.mnItem = (nItem == BIFF_PTPAGEFIELDS_ALLITEMS) ? BIFF12_PTPAGEFIELD_MULTIITEMS : nItem; 1316 maPageFields.push_back( aModel ); 1317 } 1318 } 1319 1320 void PivotTable::importPTDataField( BiffInputStream& rStrm ) 1321 { 1322 PTDataFieldModel aModel; 1323 sal_Int16 nField, nBaseField, nBaseItem; 1324 sal_uInt16 nSubtotal, nShowDataAs, nNumFmt, nNameLen; 1325 rStrm >> nField >> nSubtotal >> nShowDataAs >> nBaseField >> nBaseItem >> nNumFmt >> nNameLen; 1326 aModel.maName = lclReadPivotString( *this, rStrm, nNameLen ); 1327 1328 aModel.mnField = nField; 1329 aModel.setBiffSubtotal( nSubtotal ); 1330 aModel.setBiffShowDataAs( nShowDataAs ); 1331 aModel.mnBaseField = nBaseField; 1332 switch( nBaseItem ) 1333 { 1334 case BIFF_PTDATAFIELD_PREVIOUS: aModel.mnBaseItem = OOX_PT_PREVIOUS_ITEM; break; 1335 case BIFF_PTDATAFIELD_NEXT: aModel.mnBaseItem = OOX_PT_NEXT_ITEM; break; 1336 default: aModel.mnBaseItem = nBaseItem; 1337 } 1338 aModel.mnNumFmtId = nNumFmt; 1339 1340 maDataFields.push_back( aModel ); 1341 } 1342 1343 PivotTableField& PivotTable::createTableField() 1344 { 1345 sal_Int32 nFieldIndex = static_cast< sal_Int32 >( maFields.size() ); 1346 PivotTableFieldVector::value_type xTableField( new PivotTableField( *this, nFieldIndex ) ); 1347 maFields.push_back( xTableField ); 1348 return *xTableField; 1349 } 1350 1351 PivotTableFilter& PivotTable::createTableFilter() 1352 { 1353 PivotTableFilterVector::value_type xTableFilter( new PivotTableFilter( *this ) ); 1354 maFilters.push_back( xTableFilter ); 1355 return *xTableFilter; 1356 } 1357 1358 void PivotTable::finalizeImport() 1359 { 1360 if( getAddressConverter().validateCellRange( maLocationModel.maRange, true, true ) ) 1361 { 1362 mpPivotCache = getPivotCaches().importPivotCacheFragment( maDefModel.mnCacheId ); 1363 if( mpPivotCache && mpPivotCache->isValidDataSource() && (maDefModel.maName.getLength() > 0) ) 1364 { 1365 // clear destination area of the original pivot table 1366 try 1367 { 1368 Reference< XSheetOperation > xSheetOp( getCellRangeFromDoc( maLocationModel.maRange ), UNO_QUERY_THROW ); 1369 using namespace ::com::sun::star::sheet::CellFlags; 1370 xSheetOp->clearContents( VALUE | DATETIME | STRING | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED ); 1371 } 1372 catch( Exception& ) 1373 { 1374 } 1375 1376 try 1377 { 1378 // create a new data pilot descriptor based on the source data 1379 Reference< XDataPilotTablesSupplier > xDPTablesSupp( getSheetFromDoc( maLocationModel.maRange.Sheet ), UNO_QUERY_THROW ); 1380 Reference< XDataPilotTables > xDPTables( xDPTablesSupp->getDataPilotTables(), UNO_SET_THROW ); 1381 mxDPDescriptor.set( xDPTables->createDataPilotDescriptor(), UNO_SET_THROW ); 1382 mxDPDescriptor->setSourceRange( mpPivotCache->getSourceRange() ); 1383 mxDPDescriptor->setTag( maDefModel.maTag ); 1384 1385 // global data pilot properties 1386 PropertySet aDescProp( mxDPDescriptor ); 1387 aDescProp.setProperty( PROP_ColumnGrand, maDefModel.mbColGrandTotals ); 1388 aDescProp.setProperty( PROP_RowGrand, maDefModel.mbRowGrandTotals ); 1389 aDescProp.setProperty( PROP_ShowFilterButton, false ); 1390 aDescProp.setProperty( PROP_DrillDownOnDoubleClick, maDefModel.mbEnableDrill ); 1391 1392 // finalize all fields, this finds field names and creates grouping fields 1393 maFields.forEachMem( &PivotTableField::finalizeImport, ::boost::cref( mxDPDescriptor ) ); 1394 1395 // all row fields 1396 for( IndexVector::iterator aIt = maRowFields.begin(), aEnd = maRowFields.end(); aIt != aEnd; ++aIt ) 1397 if( PivotTableField* pField = getTableField( *aIt ) ) 1398 pField->convertRowField(); 1399 1400 // all column fields 1401 for( IndexVector::iterator aIt = maColFields.begin(), aEnd = maColFields.end(); aIt != aEnd; ++aIt ) 1402 if( PivotTableField* pField = getTableField( *aIt ) ) 1403 pField->convertColField(); 1404 1405 // all page fields 1406 for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt ) 1407 if( PivotTableField* pField = getTableField( aIt->mnField ) ) 1408 pField->convertPageField( *aIt ); 1409 1410 // all hidden fields 1411 ::std::set< sal_Int32 > aVisFields; 1412 aVisFields.insert( maRowFields.begin(), maRowFields.end() ); 1413 aVisFields.insert( maColFields.begin(), maColFields.end() ); 1414 for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt ) 1415 aVisFields.insert( aIt->mnField ); 1416 for( PivotTableFieldVector::iterator aBeg = maFields.begin(), aIt = aBeg, aEnd = maFields.end(); aIt != aEnd; ++aIt ) 1417 if( aVisFields.count( static_cast< sal_Int32 >( aIt - aBeg ) ) == 0 ) 1418 (*aIt)->convertHiddenField(); 1419 1420 // all data fields 1421 for( DataFieldVector::iterator aIt = maDataFields.begin(), aEnd = maDataFields.end(); aIt != aEnd; ++aIt ) 1422 if( PivotTableField* pField = getTableField( aIt->mnField ) ) 1423 pField->convertDataField( *aIt ); 1424 1425 // filters 1426 maFilters.forEachMem( &PivotTableFilter::finalizeImport ); 1427 1428 // calculate base position of table 1429 CellAddress aPos( maLocationModel.maRange.Sheet, maLocationModel.maRange.StartColumn, maLocationModel.maRange.StartRow ); 1430 /* If page fields exist, include them into the destination 1431 area (they are excluded in Excel). Add an extra blank row. */ 1432 if( !maPageFields.empty() ) 1433 aPos.Row = ::std::max< sal_Int32 >( static_cast< sal_Int32 >( aPos.Row - maPageFields.size() - 1 ), 0 ); 1434 1435 // insert the DataPilot table into the sheet 1436 xDPTables->insertNewByName( maDefModel.maName, aPos, mxDPDescriptor ); 1437 } 1438 catch( Exception& ) 1439 { 1440 OSL_ENSURE( false, "PivotTable::finalizeImport - exception while creating the DataPilot table" ); 1441 } 1442 } 1443 } 1444 } 1445 1446 void PivotTable::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx ) 1447 { 1448 // process all fields, there is no chaining information in the cache fields 1449 maFields.forEachMem( &PivotTableField::finalizeDateGroupingImport, ::boost::cref( rxBaseDPField ), nBaseFieldIdx ); 1450 } 1451 1452 void PivotTable::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, 1453 const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames ) 1454 { 1455 // try to create parent group fields that group the items of the passed base field 1456 if( PivotTableField* pParentTableField = maFields.get( rBaseCacheField.getParentGroupField() ).get() ) 1457 pParentTableField->finalizeParentGroupingImport( rxBaseDPField, orItemNames ); 1458 } 1459 1460 Reference< XDataPilotField > PivotTable::getDataPilotField( const OUString& rFieldName ) const 1461 { 1462 Reference< XDataPilotField > xDPField; 1463 if( (rFieldName.getLength() > 0) && mxDPDescriptor.is() ) try 1464 { 1465 Reference< XNameAccess > xDPFieldsNA( mxDPDescriptor->getDataPilotFields(), UNO_QUERY_THROW ); 1466 xDPField.set( xDPFieldsNA->getByName( rFieldName ), UNO_QUERY ); 1467 } 1468 catch( Exception& ) 1469 { 1470 } 1471 return xDPField; 1472 } 1473 1474 Reference< XDataPilotField > PivotTable::getDataPilotField( sal_Int32 nFieldIdx ) const 1475 { 1476 Reference< XDataPilotField > xDPField; 1477 if( const PivotTableField* pTableField = maFields.get( nFieldIdx ).get() ) 1478 xDPField = getDataPilotField( pTableField->getDPFieldName() ); 1479 return xDPField; 1480 } 1481 1482 Reference< XDataPilotField > PivotTable::getDataLayoutField() const 1483 { 1484 Reference< XDataPilotField > xDPField; 1485 try 1486 { 1487 Reference< XDataPilotDataLayoutFieldSupplier > xDPDataFieldSupp( mxDPDescriptor, UNO_QUERY_THROW ); 1488 xDPField = xDPDataFieldSupp->getDataLayoutField(); 1489 } 1490 catch( Exception& ) 1491 { 1492 } 1493 return xDPField; 1494 } 1495 1496 const PivotCacheField* PivotTable::getCacheField( sal_Int32 nFieldIdx ) const 1497 { 1498 return mpPivotCache ? mpPivotCache->getCacheField( nFieldIdx ) : 0; 1499 } 1500 1501 const PivotCacheField* PivotTable::getCacheFieldOfDataField( sal_Int32 nDataItemIdx ) const 1502 { 1503 const PTDataFieldModel* pDataField = ContainerHelper::getVectorElement( maDataFields, nDataItemIdx ); 1504 return pDataField ? getCacheField( pDataField->mnField ) : 0; 1505 } 1506 1507 sal_Int32 PivotTable::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const 1508 { 1509 return mpPivotCache ? mpPivotCache->getCacheDatabaseIndex( nFieldIdx ) : -1; 1510 } 1511 1512 // private -------------------------------------------------------------------- 1513 1514 PivotTableField* PivotTable::getTableField( sal_Int32 nFieldIdx ) 1515 { 1516 return (nFieldIdx == OOX_PT_DATALAYOUTFIELD) ? &maDataField : maFields.get( nFieldIdx ).get(); 1517 } 1518 1519 void PivotTable::importField( IndexVector& orFields, const AttributeList& rAttribs ) 1520 { 1521 orFields.push_back( rAttribs.getInteger( XML_x, -1 ) ); 1522 } 1523 1524 void PivotTable::importFields( IndexVector& orFields, SequenceInputStream& rStrm ) 1525 { 1526 OSL_ENSURE( orFields.empty(), "PivotTable::importFields - multiple record instances" ); 1527 orFields.clear(); 1528 sal_Int32 nCount = rStrm.readInt32(); 1529 OSL_ENSURE( 4 * nCount == rStrm.getRemaining(), "PivotTable::importFields - invalid field count" ); 1530 nCount = static_cast< sal_Int32 >( rStrm.getRemaining() / 4 ); 1531 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx ) 1532 orFields.push_back( rStrm.readInt32() ); 1533 } 1534 1535 void PivotTable::importFields( IndexVector& orFields, BiffInputStream& rStrm, sal_Int32 nCount ) 1536 { 1537 OSL_ENSURE( orFields.empty(), "PivotTable::importFields - multiple record instances" ); 1538 orFields.clear(); 1539 OSL_ENSURE( 2 * nCount == rStrm.getRemaining(), "PivotTable::importFields - invalid field count" ); 1540 nCount = static_cast< sal_Int32 >( rStrm.getRemaining() / 2 ); 1541 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx ) 1542 orFields.push_back( rStrm.readInt16() ); 1543 } 1544 1545 // ============================================================================ 1546 1547 PivotTableBuffer::PivotTableBuffer( const WorkbookHelper& rHelper ) : 1548 WorkbookHelper( rHelper ) 1549 { 1550 } 1551 1552 PivotTable& PivotTableBuffer::createPivotTable() 1553 { 1554 PivotTableVector::value_type xTable( new PivotTable( *this ) ); 1555 maTables.push_back( xTable ); 1556 return *xTable; 1557 } 1558 1559 void PivotTableBuffer::finalizeImport() 1560 { 1561 maTables.forEachMem( &PivotTable::finalizeImport ); 1562 } 1563 1564 // ============================================================================ 1565 1566 } // namespace xls 1567 } // namespace oox 1568