merge the formfield patch from ooo-build
[ooovba.git] / oox / source / xls / scenariobuffer.cxx
blob2d11f55d538a9d546182be047ba5add437dac9fd
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: scenariobuffer.cxx,v $
10 * $Revision: 1.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "oox/xls/scenariobuffer.hxx"
32 #include <com/sun/star/container/XIndexAccess.hpp>
33 #include <com/sun/star/sheet/XScenario.hpp>
34 #include <com/sun/star/sheet/XScenarios.hpp>
35 #include <com/sun/star/sheet/XScenariosSupplier.hpp>
36 #include <com/sun/star/sheet/XSpreadsheet.hpp>
37 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
38 #include "properties.hxx"
39 #include "oox/helper/attributelist.hxx"
40 #include "oox/helper/propertyset.hxx"
41 #include "oox/helper/recordinputstream.hxx"
42 #include "oox/xls/addressconverter.hxx"
43 #include "oox/xls/biffinputstream.hxx"
45 using ::rtl::OUString;
46 using ::com::sun::star::uno::Exception;
47 using ::com::sun::star::uno::Reference;
48 using ::com::sun::star::uno::UNO_QUERY_THROW;
49 using ::com::sun::star::uno::UNO_SET_THROW;
50 using ::com::sun::star::container::XIndexAccess;
51 using ::com::sun::star::container::XNameAccess;
52 using ::com::sun::star::table::CellAddress;
53 using ::com::sun::star::table::CellRangeAddress;
54 using ::com::sun::star::table::XCell;
55 using ::com::sun::star::sheet::XScenario;
56 using ::com::sun::star::sheet::XScenarios;
57 using ::com::sun::star::sheet::XScenariosSupplier;
58 using ::com::sun::star::sheet::XSpreadsheet;
60 namespace oox {
61 namespace xls {
63 // ============================================================================
65 namespace {
67 const sal_Int32 BIFF_SCENARIO_DELETED = 0x4000;
69 } // namespace
71 // ============================================================================
73 ScenarioCellModel::ScenarioCellModel() :
74 mnNumFmtId( 0 ),
75 mbDeleted( false )
79 // ----------------------------------------------------------------------------
81 ScenarioModel::ScenarioModel() :
82 mbLocked( false ),
83 mbHidden( false )
87 // ----------------------------------------------------------------------------
89 Scenario::Scenario( const WorkbookHelper& rHelper, sal_Int16 nSheet ) :
90 WorkbookHelper( rHelper ),
91 mnSheet( nSheet )
95 void Scenario::importScenario( const AttributeList& rAttribs )
97 maModel.maName = rAttribs.getXString( XML_name, OUString() );
98 maModel.maComment = rAttribs.getXString( XML_comment, OUString() );
99 maModel.maUser = rAttribs.getXString( XML_user, OUString() );
100 maModel.mbLocked = rAttribs.getBool( XML_locked, false );
101 maModel.mbHidden = rAttribs.getBool( XML_hidden, false );
104 void Scenario::importInputCells( const AttributeList& rAttribs )
106 ScenarioCellModel aModel;
107 getAddressConverter().convertToCellAddressUnchecked( aModel.maPos, rAttribs.getString( XML_r, OUString() ), mnSheet );
108 aModel.maValue = rAttribs.getXString( XML_val, OUString() );
109 aModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
110 aModel.mbDeleted = rAttribs.getBool( XML_deleted, false );
111 maCells.push_back( aModel );
114 void Scenario::importScenario( RecordInputStream& rStrm )
116 rStrm.skip( 2 ); // cell count
117 // two longs instead of flag field
118 maModel.mbLocked = rStrm.readInt32() != 0;
119 maModel.mbHidden = rStrm.readInt32() != 0;
120 rStrm >> maModel.maName >> maModel.maComment >> maModel.maUser;
123 void Scenario::importInputCells( RecordInputStream& rStrm )
125 // TODO: where is the deleted flag?
126 ScenarioCellModel aModel;
127 BinAddress aPos;
128 rStrm >> aPos;
129 rStrm.skip( 8 );
130 aModel.mnNumFmtId = rStrm.readuInt16();
131 rStrm >> aModel.maValue;
132 getAddressConverter().convertToCellAddressUnchecked( aModel.maPos, aPos, mnSheet );
133 maCells.push_back( aModel );
136 void Scenario::importScenario( BiffInputStream& rStrm )
138 sal_uInt16 nCellCount;
139 sal_uInt8 nNameLen, nCommentLen, nUserLen;
140 rStrm >> nCellCount;
141 // two bytes instead of flag field
142 maModel.mbLocked = rStrm.readuInt8() != 0;
143 maModel.mbHidden = rStrm.readuInt8() != 0;
144 rStrm >> nNameLen >> nCommentLen >> nUserLen;
145 maModel.maName = rStrm.readUniStringBody( nNameLen );
146 // user name: before comment (in difference to leading length field), repeated length
147 if( nUserLen > 0 )
148 maModel.maUser = rStrm.readUniString();
149 // comment: repeated length
150 if( nCommentLen > 0 )
151 maModel.maComment = rStrm.readUniString();
153 // list of cell addresses
154 for( sal_uInt16 nCell = 0; !rStrm.isEof() && (nCell < nCellCount); ++nCell )
156 ScenarioCellModel aModel;
157 BinAddress aPos;
158 rStrm >> aPos;
159 // deleted flag is encoded in column index
160 aModel.mbDeleted = getFlag( aPos.mnCol, BIFF_SCENARIO_DELETED );
161 setFlag( aPos.mnCol, BIFF_SCENARIO_DELETED, false );
162 getAddressConverter().convertToCellAddressUnchecked( aModel.maPos, aPos, mnSheet );
163 maCells.push_back( aModel );
166 // list of cell values
167 for( ScenarioCellVector::iterator aIt = maCells.begin(), aEnd = maCells.end(); !rStrm.isEof() && (aIt != aEnd); ++aIt )
168 aIt->maValue = rStrm.readUniString();
171 void Scenario::finalizeImport()
173 AddressConverter& rAddrConv = getAddressConverter();
174 ::std::vector< CellRangeAddress > aRanges;
175 for( ScenarioCellVector::iterator aIt = maCells.begin(), aEnd = maCells.end(); aIt != aEnd; ++aIt )
176 if( !aIt->mbDeleted && rAddrConv.checkCellAddress( aIt->maPos, true ) )
177 aRanges.push_back( CellRangeAddress( aIt->maPos.Sheet, aIt->maPos.Column, aIt->maPos.Row, aIt->maPos.Column, aIt->maPos.Row ) );
179 if( !aRanges.empty() && (maModel.maName.getLength() > 0) ) try
181 /* Find an unused name for the scenario (Calc stores scenario data in
182 hidden sheets named after the scenario following the base sheet). */
183 Reference< XNameAccess > xSheetsNA( getDocument()->getSheets(), UNO_QUERY_THROW );
184 OUString aScenName = ContainerHelper::getUnusedName( xSheetsNA, maModel.maName, '_' );
186 // create the new scenario sheet
187 Reference< XScenariosSupplier > xScenariosSupp( getSheetFromDoc( mnSheet ), UNO_QUERY_THROW );
188 Reference< XScenarios > xScenarios( xScenariosSupp->getScenarios(), UNO_SET_THROW );
189 xScenarios->addNewByName( aScenName, ContainerHelper::vectorToSequence( aRanges ), maModel.maComment );
191 // write scenario cell values
192 Reference< XSpreadsheet > xSheet( getSheetFromDoc( aScenName ), UNO_SET_THROW );
193 for( ScenarioCellVector::iterator aIt = maCells.begin(), aEnd = maCells.end(); aIt != aEnd; ++aIt )
195 if( !aIt->mbDeleted ) try
197 // use XCell::setFormula to auto-detect values and strings
198 Reference< XCell > xCell( xSheet->getCellByPosition( aIt->maPos.Column, aIt->maPos.Row ), UNO_SET_THROW );
199 xCell->setFormula( aIt->maValue );
201 catch( Exception& )
206 // scenario properties
207 PropertySet aPropSet( xScenarios->getByName( aScenName ) );
208 aPropSet.setProperty( PROP_IsActive, false );
209 aPropSet.setProperty( PROP_CopyBack, false );
210 aPropSet.setProperty( PROP_CopyStyles, false );
211 aPropSet.setProperty( PROP_CopyFormulas, false );
212 aPropSet.setProperty( PROP_Protected, maModel.mbLocked );
213 // #112621# do not show/print scenario border
214 aPropSet.setProperty( PROP_ShowBorder, false );
215 aPropSet.setProperty( PROP_PrintBorder, false );
217 catch( Exception& )
222 // ============================================================================
224 SheetScenariosModel::SheetScenariosModel() :
225 mnCurrent( 0 ),
226 mnShown( 0 )
230 // ----------------------------------------------------------------------------
232 SheetScenarios::SheetScenarios( const WorkbookHelper& rHelper, sal_Int16 nSheet ) :
233 WorkbookHelper( rHelper ),
234 mnSheet( nSheet )
238 void SheetScenarios::importScenarios( const AttributeList& rAttribs )
240 maModel.mnCurrent = rAttribs.getInteger( XML_current, 0 );
241 maModel.mnShown = rAttribs.getInteger( XML_show, 0 );
244 void SheetScenarios::importScenarios( RecordInputStream& rStrm )
246 maModel.mnCurrent = rStrm.readuInt16();
247 maModel.mnShown = rStrm.readuInt16();
250 void SheetScenarios::importScenarios( BiffInputStream& rStrm )
252 rStrm.skip( 2 ); // scenario count
253 maModel.mnCurrent = rStrm.readuInt16();
254 maModel.mnShown = rStrm.readuInt16();
256 // read following SCENARIO records
257 while( (rStrm.getNextRecId() == BIFF_ID_SCENARIO) && rStrm.startNextRecord() )
258 createScenario().importScenario( rStrm );
261 Scenario& SheetScenarios::createScenario()
263 ScenarioVector::value_type xScenario( new Scenario( *this, mnSheet ) );
264 maScenarios.push_back( xScenario );
265 return *xScenario;
268 void SheetScenarios::finalizeImport()
270 maScenarios.forEachMem( &Scenario::finalizeImport );
272 // activate a scenario
275 Reference< XScenariosSupplier > xScenariosSupp( getSheetFromDoc( mnSheet ), UNO_QUERY_THROW );
276 Reference< XIndexAccess > xScenariosIA( xScenariosSupp->getScenarios(), UNO_QUERY_THROW );
277 Reference< XScenario > xScenario( xScenariosIA->getByIndex( maModel.mnShown ), UNO_QUERY_THROW );
278 xScenario->apply();
280 catch( Exception& )
285 // ============================================================================
287 ScenarioBuffer::ScenarioBuffer( const WorkbookHelper& rHelper ) :
288 WorkbookHelper( rHelper )
292 SheetScenarios& ScenarioBuffer::createSheetScenarios( sal_Int16 nSheet )
294 SheetScenariosMap::mapped_type& rxSheetScens = maSheetScenarios[ nSheet ];
295 if( !rxSheetScens )
296 rxSheetScens.reset( new SheetScenarios( *this, nSheet ) );
297 return *rxSheetScens;
300 void ScenarioBuffer::finalizeImport()
302 maSheetScenarios.forEachMem( &SheetScenarios::finalizeImport );
305 // ============================================================================
307 } // namespace xls
308 } // namespace oox