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