import org.apache.poi.hssf.record.aggregates.ChartSubstreamRecordAggregate;
import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;
+import org.apache.poi.hssf.record.aggregates.CustomViewSettingsRecordAggregate;
import org.apache.poi.hssf.record.aggregates.DataValidityTable;
import org.apache.poi.hssf.record.aggregates.MergedCellsTable;
import org.apache.poi.hssf.record.aggregates.PageSettingsBlock;
records.add(rra); //only add the aggregate once
continue;
}
+
+ if (CustomViewSettingsRecordAggregate.isBeginRecord(recSid)) {
+ // This happens three times in test sample file "29982.xls"
+ // Also several times in bugzilla samples 46840-23373 and 46840-23374
+ records.add(new CustomViewSettingsRecordAggregate(rs));
+ continue;
+ }
if (PageSettingsBlock.isComponentRecord(recSid)) {
- PageSettingsBlock psb;
if (_psBlock == null) {
- psb = new PageSettingsBlock(rs);
- _psBlock = psb;
- records.add(psb);
+ // typical case - just one PSB (so far)
+ _psBlock = new PageSettingsBlock(rs);
+ records.add(_psBlock);
continue;
}
- if (windowTwo != null) {
- // probably 'Custom View Settings' sub-stream which is found between
- // USERSVIEWBEGIN(01AA) and USERSVIEWEND(01AB)
- // TODO - create UsersViewAggregate to hold these sub-streams, and simplify this code a bit
- // This happens three times in test sample file "29982.xls"
- // Also several times in bugzilla samples 46840-23373 and 46840-23374
- if (recSid == UnknownRecord.HEADER_FOOTER_089C) {
- _psBlock.addLateHeaderFooter(rs.getNext());
- continue;
- }
- psb = new PageSettingsBlock(rs);
- if (rs.peekNextSid() != UnknownRecord.USERSVIEWEND_01AB) {
- // not quite the expected situation
- throw new RuntimeException("two Page Settings Blocks found in the same sheet");
- }
- } else {
- psb = new PageSettingsBlock(rs);
- // Some apps write PLS, WSBOOL, <psb> but PLS is part of <psb>
- // This happens in the test sample file "NoGutsRecords.xls" and "WORKBOOK_in_capitals.xls"
- // In this case the first PSB is two records back
- int prevPsbIx = records.size()-2;
- if (_psBlock != records.get(prevPsbIx) || !(records.get(prevPsbIx+1) instanceof WSBoolRecord)) {
- // not quite the expected situation
- throw new RuntimeException("two Page Settings Blocks found in the same sheet");
- }
- records.remove(prevPsbIx); // WSBOOL will drop down one position.
- psb = mergePSBs(_psBlock, psb);
- _psBlock = psb;
+ if (recSid == UnknownRecord.HEADER_FOOTER_089C) {
+ // test samples: SharedFormulaTest.xls, ex44921-21902.xls, ex42570-20305.xls
+ _psBlock.addLateHeaderFooter(rs.getNext());
+ continue;
+ }
+ // Some apps write PLS, WSBOOL, <psb> but PLS is part of <psb>
+ // This happens in the test sample file "NoGutsRecords.xls" and "WORKBOOK_in_capitals.xls"
+ // In this case the first PSB is two records back
+ int prevPsbIx = records.size()-2;
+ if (_psBlock != records.get(prevPsbIx) || !(records.get(prevPsbIx+1) instanceof WSBoolRecord)) {
+ // not quite the expected situation
+ throw new RuntimeException("two Page Settings Blocks found in the same sheet");
}
- records.add(psb);
+ records.remove(prevPsbIx); // WSBOOL will drop down one position.
+ PageSettingsBlock latePsb = new PageSettingsBlock(rs);
+ _psBlock = mergePSBs(_psBlock, latePsb);
+ records.add(_psBlock);
continue;
}
import org.apache.poi.hssf.model.ConvertAnchor;
import org.apache.poi.hssf.model.DrawingManager2;
import org.apache.poi.hssf.model.TextboxShape;
-import org.apache.poi.hssf.record.aggregates.RecordAggregate;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFShape;
private static short sid( List records, int loc )
{
- Object obj = records.get( loc );
- if (obj instanceof RecordAggregate) {
- return -1;
- }
- return ( (Record) obj ).getSid();
+ return ( (Record) records.get( loc ) ).getSid();
}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.aggregates;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordBase;
+import org.apache.poi.hssf.record.UnknownRecord;
+
+/**
+ * Manages the all the records associated with a 'Custom View Settings' sub-stream.<br/>
+ * Includes the initial USERSVIEWBEGIN(0x01AA) and final USERSVIEWEND(0x01AB).
+ *
+ * @author Josh Micich
+ */
+public final class CustomViewSettingsRecordAggregate extends RecordAggregate {
+
+ private final Record _begin;
+ private final Record _end;
+ /**
+ * All the records between BOF and EOF
+ */
+ private final List<RecordBase> _recs;
+ private PageSettingsBlock _psBlock;
+
+ public CustomViewSettingsRecordAggregate(RecordStream rs) {
+ _begin = rs.getNext();
+ if (_begin.getSid() != UnknownRecord.USERSVIEWBEGIN_01AA) {
+ throw new IllegalStateException("Bad begin record");
+ }
+ List<RecordBase> temp = new ArrayList<RecordBase>();
+ while (rs.peekNextSid() != UnknownRecord.USERSVIEWEND_01AB) {
+ if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) {
+ if (_psBlock != null) {
+ throw new IllegalStateException(
+ "Found more than one PageSettingsBlock in custom view settings sub-stream");
+ }
+ _psBlock = new PageSettingsBlock(rs);
+ temp.add(_psBlock);
+ continue;
+ }
+ temp.add(rs.getNext());
+ }
+ _recs = temp;
+ _end = rs.getNext(); // no need to save EOF in field
+ if (_end.getSid() != UnknownRecord.USERSVIEWEND_01AB) {
+ throw new IllegalStateException("Bad custom view settings end record");
+ }
+ }
+
+ public void visitContainedRecords(RecordVisitor rv) {
+ if (_recs.isEmpty()) {
+ return;
+ }
+ rv.visitRecord(_begin);
+ for (int i = 0; i < _recs.size(); i++) {
+ RecordBase rb = _recs.get(i);
+ if (rb instanceof RecordAggregate) {
+ ((RecordAggregate) rb).visitContainedRecords(rv);
+ } else {
+ rv.visitRecord((Record) rb);
+ }
+ }
+ rv.visitRecord(_end);
+ }
+
+ public static boolean isBeginRecord(int sid) {
+ return sid == UnknownRecord.USERSVIEWBEGIN_01AA;
+ }
+}