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