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/pivottablefragment.hxx"
25 
26 #include "oox/xls/biffinputstream.hxx"
27 #include "oox/xls/pivottablebuffer.hxx"
28 
29 namespace oox {
30 namespace xls {
31 
32 // ============================================================================
33 
34 using namespace ::oox::core;
35 
36 using ::rtl::OUString;
37 
38 // ============================================================================
39 
PivotTableFieldContext(WorksheetFragmentBase & rFragment,PivotTableField & rTableField)40 PivotTableFieldContext::PivotTableFieldContext( WorksheetFragmentBase& rFragment, PivotTableField& rTableField ) :
41     WorksheetContextBase( rFragment ),
42     mrTableField( rTableField )
43 {
44 }
45 
onCreateContext(sal_Int32 nElement,const AttributeList & rAttribs)46 ContextHandlerRef PivotTableFieldContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
47 {
48     switch( getCurrentElement() )
49     {
50         case XLS_TOKEN( pivotField ):
51             switch( nElement )
52             {
53                 case XLS_TOKEN( items ):            return this;
54                 case XLS_TOKEN( autoSortScope ):    return this;
55             }
56         break;
57         case XLS_TOKEN( items ):
58             if( nElement == XLS_TOKEN( item ) ) mrTableField.importItem( rAttribs );
59         break;
60         case XLS_TOKEN( autoSortScope ):
61             if( nElement == XLS_TOKEN( pivotArea ) ) return this;
62         break;
63         case XLS_TOKEN( pivotArea ):
64             if( nElement == XLS_TOKEN( references ) ) return this;
65         break;
66         case XLS_TOKEN( references ):
67             if( nElement == XLS_TOKEN( reference ) ) { mrTableField.importReference( rAttribs ); return this; }
68         break;
69         case XLS_TOKEN( reference ):
70             if( nElement == XLS_TOKEN( x ) ) mrTableField.importReferenceItem( rAttribs );
71         break;
72     }
73     return 0;
74 }
75 
onStartElement(const AttributeList & rAttribs)76 void PivotTableFieldContext::onStartElement( const AttributeList& rAttribs )
77 {
78     if( isRootElement() )
79         mrTableField.importPivotField( rAttribs );
80 }
81 
onCreateRecordContext(sal_Int32 nRecId,SequenceInputStream & rStrm)82 ContextHandlerRef PivotTableFieldContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
83 {
84     switch( getCurrentElement() )
85     {
86         case BIFF12_ID_PTFIELD:
87             switch( nRecId )
88             {
89                 case BIFF12_ID_PTFITEMS:        return this;
90                 case BIFF12_ID_AUTOSORTSCOPE:   return this;
91             }
92         break;
93         case BIFF12_ID_PTFITEMS:
94             if( nRecId == BIFF12_ID_PTFITEM ) mrTableField.importPTFItem( rStrm );
95         break;
96         case BIFF12_ID_AUTOSORTSCOPE:
97             if( nRecId == BIFF12_ID_PIVOTAREA ) return this;
98         break;
99         case BIFF12_ID_PIVOTAREA:
100             if( nRecId == BIFF12_ID_PTREFERENCES ) return this;
101         break;
102         case BIFF12_ID_PTREFERENCES:
103             if( nRecId == BIFF12_ID_PTREFERENCE ) { mrTableField.importPTReference( rStrm ); return this; }
104         break;
105         case BIFF12_ID_PTREFERENCE:
106             if( nRecId == BIFF12_ID_PTREFERENCEITEM ) mrTableField.importPTReferenceItem( rStrm );
107         break;
108     }
109     return 0;
110 }
111 
onStartRecord(SequenceInputStream & rStrm)112 void PivotTableFieldContext::onStartRecord( SequenceInputStream& rStrm )
113 {
114     if( isRootElement() )
115         mrTableField.importPTField( rStrm );
116 }
117 
118 // ============================================================================
119 
PivotTableFilterContext(WorksheetFragmentBase & rFragment,PivotTableFilter & rTableFilter)120 PivotTableFilterContext::PivotTableFilterContext( WorksheetFragmentBase& rFragment, PivotTableFilter& rTableFilter ) :
121     WorksheetContextBase( rFragment ),
122     mrTableFilter( rTableFilter )
123 {
124 }
125 
onCreateContext(sal_Int32 nElement,const AttributeList & rAttribs)126 ContextHandlerRef PivotTableFilterContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
127 {
128     switch( getCurrentElement() )
129     {
130         case XLS_TOKEN( filter ):
131             if( nElement == XLS_TOKEN( autoFilter ) ) return this;
132         break;
133         case XLS_TOKEN( autoFilter ):
134             if( nElement == XLS_TOKEN( filterColumn ) ) return this;
135         break;
136         case XLS_TOKEN( filterColumn ):
137             if( nElement == XLS_TOKEN( top10 ) ) mrTableFilter.importTop10( rAttribs );
138         break;
139     }
140     return 0;
141 }
142 
onStartElement(const AttributeList & rAttribs)143 void PivotTableFilterContext::onStartElement( const AttributeList& rAttribs )
144 {
145     if( isRootElement() )
146         mrTableFilter.importFilter( rAttribs );
147 }
148 
onCreateRecordContext(sal_Int32 nRecId,SequenceInputStream & rStrm)149 ContextHandlerRef PivotTableFilterContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
150 {
151     switch( getCurrentElement() )
152     {
153         case BIFF12_ID_PTFILTER:
154             if( nRecId == BIFF12_ID_AUTOFILTER ) return this;
155         break;
156         case BIFF12_ID_AUTOFILTER:
157             if( nRecId == BIFF12_ID_FILTERCOLUMN ) return this;
158         break;
159         case BIFF12_ID_FILTERCOLUMN:
160             if( nRecId == BIFF12_ID_TOP10FILTER ) mrTableFilter.importTop10Filter( rStrm );
161         break;
162     }
163     return 0;
164 }
165 
onStartRecord(SequenceInputStream & rStrm)166 void PivotTableFilterContext::onStartRecord( SequenceInputStream& rStrm )
167 {
168     if( isRootElement() )
169         mrTableFilter.importPTFilter( rStrm );
170 }
171 
172 // ============================================================================
173 
PivotTableFragment(const WorksheetHelper & rHelper,const OUString & rFragmentPath)174 PivotTableFragment::PivotTableFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
175     WorksheetFragmentBase( rHelper, rFragmentPath ),
176     mrPivotTable( getPivotTables().createPivotTable() )
177 {
178 }
179 
onCreateContext(sal_Int32 nElement,const AttributeList & rAttribs)180 ContextHandlerRef PivotTableFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
181 {
182     switch( getCurrentElement() )
183     {
184         case XML_ROOT_CONTEXT:
185             if( nElement == XLS_TOKEN( pivotTableDefinition ) ) { mrPivotTable.importPivotTableDefinition( rAttribs ); return this; }
186         break;
187 
188         case XLS_TOKEN( pivotTableDefinition ):
189             switch( nElement )
190             {
191                 case XLS_TOKEN( location ):     mrPivotTable.importLocation( rAttribs, getSheetIndex() );   break;
192                 case XLS_TOKEN( pivotFields ):  return this;
193                 case XLS_TOKEN( rowFields ):    return this;
194                 case XLS_TOKEN( colFields ):    return this;
195                 case XLS_TOKEN( pageFields ):   return this;
196                 case XLS_TOKEN( dataFields ):   return this;
197                 case XLS_TOKEN( filters ):      return this;
198             }
199         break;
200 
201         case XLS_TOKEN( pivotFields ):
202             if( nElement == XLS_TOKEN( pivotField ) ) return new PivotTableFieldContext( *this, mrPivotTable.createTableField() );
203         break;
204         case XLS_TOKEN( rowFields ):
205             if( nElement == XLS_TOKEN( field ) ) mrPivotTable.importRowField( rAttribs );
206         break;
207         case XLS_TOKEN( colFields ):
208             if( nElement == XLS_TOKEN( field ) ) mrPivotTable.importColField( rAttribs );
209         break;
210         case XLS_TOKEN( pageFields ):
211             if( nElement == XLS_TOKEN( pageField ) ) mrPivotTable.importPageField( rAttribs );
212         break;
213         case XLS_TOKEN( dataFields ):
214             if( nElement == XLS_TOKEN( dataField ) ) mrPivotTable.importDataField( rAttribs );
215         break;
216         case XLS_TOKEN( filters ):
217             if( nElement == XLS_TOKEN( filter ) ) return new PivotTableFilterContext( *this, mrPivotTable.createTableFilter() );
218         break;
219     }
220     return 0;
221 }
222 
onCreateRecordContext(sal_Int32 nRecId,SequenceInputStream & rStrm)223 ContextHandlerRef PivotTableFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
224 {
225     switch( getCurrentElement() )
226     {
227         case XML_ROOT_CONTEXT:
228             if( nRecId == BIFF12_ID_PTDEFINITION ) { mrPivotTable.importPTDefinition( rStrm ); return this; }
229         break;
230 
231         case BIFF12_ID_PTDEFINITION:
232             switch( nRecId )
233             {
234                 case BIFF12_ID_PTLOCATION:      mrPivotTable.importPTLocation( rStrm, getSheetIndex() );    break;
235                 case BIFF12_ID_PTFIELDS:        return this;
236                 case BIFF12_ID_PTROWFIELDS:     mrPivotTable.importPTRowFields( rStrm );                    break;
237                 case BIFF12_ID_PTCOLFIELDS:     mrPivotTable.importPTColFields( rStrm );                    break;
238                 case BIFF12_ID_PTPAGEFIELDS:    return this;
239                 case BIFF12_ID_PTDATAFIELDS:    return this;
240                 case BIFF12_ID_PTFILTERS:       return this;
241             }
242         break;
243 
244         case BIFF12_ID_PTFIELDS:
245             if( nRecId == BIFF12_ID_PTFIELD ) return new PivotTableFieldContext( *this, mrPivotTable.createTableField() );
246         break;
247         case BIFF12_ID_PTPAGEFIELDS:
248             if( nRecId == BIFF12_ID_PTPAGEFIELD ) mrPivotTable.importPTPageField( rStrm );
249         break;
250         case BIFF12_ID_PTDATAFIELDS:
251             if( nRecId == BIFF12_ID_PTDATAFIELD ) mrPivotTable.importPTDataField( rStrm );
252         break;
253         case BIFF12_ID_PTFILTERS:
254             if( nRecId == BIFF12_ID_PTFILTER ) return new PivotTableFilterContext( *this, mrPivotTable.createTableFilter() );
255         break;
256     }
257     return 0;
258 }
259 
getRecordInfos() const260 const RecordInfo* PivotTableFragment::getRecordInfos() const
261 {
262     static const RecordInfo spRecInfos[] =
263     {
264         { BIFF12_ID_AUTOFILTER,         BIFF12_ID_AUTOFILTER + 1        },
265         { BIFF12_ID_AUTOSORTSCOPE,      BIFF12_ID_AUTOSORTSCOPE + 1     },
266         { BIFF12_ID_FILTERCOLUMN,       BIFF12_ID_FILTERCOLUMN + 1      },
267         { BIFF12_ID_PIVOTAREA,          BIFF12_ID_PIVOTAREA + 1         },
268         { BIFF12_ID_PTCOLFIELDS,        BIFF12_ID_PTCOLFIELDS + 1       },
269         { BIFF12_ID_PTDATAFIELD,        BIFF12_ID_PTDATAFIELD + 1       },
270         { BIFF12_ID_PTDATAFIELDS,       BIFF12_ID_PTDATAFIELDS + 1      },
271         { BIFF12_ID_PTDEFINITION,       BIFF12_ID_PTDEFINITION + 35     },
272         { BIFF12_ID_PTFIELD,            BIFF12_ID_PTFIELD + 1           },
273         { BIFF12_ID_PTFIELDS,           BIFF12_ID_PTFIELDS + 1          },
274         { BIFF12_ID_PTFILTER,           BIFF12_ID_PTFILTER + 1          },
275         { BIFF12_ID_PTFILTERS,          BIFF12_ID_PTFILTERS + 1         },
276         { BIFF12_ID_PTFITEM,            BIFF12_ID_PTFITEM - 1           },
277         { BIFF12_ID_PTFITEMS,           BIFF12_ID_PTFITEMS + 1          },
278         { BIFF12_ID_PTLOCATION,         BIFF12_ID_PTLOCATION - 1        },
279         { BIFF12_ID_PTPAGEFIELD,        BIFF12_ID_PTPAGEFIELD + 1       },
280         { BIFF12_ID_PTPAGEFIELDS,       BIFF12_ID_PTPAGEFIELDS + 1      },
281         { BIFF12_ID_PTREFERENCE,        BIFF12_ID_PTREFERENCE + 1       },
282         { BIFF12_ID_PTREFERENCEITEM,    BIFF12_ID_PTREFERENCEITEM + 1   },
283         { BIFF12_ID_PTREFERENCES,       BIFF12_ID_PTREFERENCES + 1      },
284         { BIFF12_ID_PTROWFIELDS,        BIFF12_ID_PTROWFIELDS + 1       },
285         { -1,                           -1                              }
286     };
287     return spRecInfos;
288 }
289 
290 // ============================================================================
291 // ============================================================================
292 
BiffPivotTableContext(const WorksheetHelper & rHelper)293 BiffPivotTableContext::BiffPivotTableContext( const WorksheetHelper& rHelper ) :
294     BiffWorksheetContextBase( rHelper ),
295     mrPivotTable( getPivotTables().createPivotTable() )
296 {
297 }
298 
importRecord(BiffInputStream & rStrm)299 void BiffPivotTableContext::importRecord( BiffInputStream& rStrm )
300 {
301     switch( rStrm.getRecId() )
302     {
303         case BIFF_ID_PTDEFINITION:      mrPivotTable.importPTDefinition( rStrm, getSheetIndex() );  break;
304         case BIFF_ID_PTDEFINITION2:     mrPivotTable.importPTDefinition2( rStrm );                  break;
305         case BIFF_ID_PTFIELD:           mrPivotTable.createTableField().importPTField( rStrm );     break;
306         case BIFF_ID_PTROWCOLFIELDS:    mrPivotTable.importPTRowColFields( rStrm );                 break;
307         case BIFF_ID_PTPAGEFIELDS:      mrPivotTable.importPTPageFields( rStrm );                   break;
308         case BIFF_ID_PTDATAFIELD:       mrPivotTable.importPTDataField( rStrm );                    break;
309     }
310 }
311 
312 // ============================================================================
313 
314 } // namespace xls
315 } // namespace oox
316