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