1*ca5ec200SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*ca5ec200SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*ca5ec200SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*ca5ec200SAndrew Rist * distributed with this work for additional information 6*ca5ec200SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*ca5ec200SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*ca5ec200SAndrew Rist * "License"); you may not use this file except in compliance 9*ca5ec200SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*ca5ec200SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*ca5ec200SAndrew Rist * software distributed under the License is distributed on an 15*ca5ec200SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*ca5ec200SAndrew Rist * KIND, either express or implied. See the License for the 17*ca5ec200SAndrew Rist * specific language governing permissions and limitations 18*ca5ec200SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*ca5ec200SAndrew Rist *************************************************************/ 21*ca5ec200SAndrew Rist 22*ca5ec200SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "oox/xls/condformatbuffer.hxx" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp> 27cdf0e10cSrcweir #include <com/sun/star/container/XIndexAccess.hpp> 28cdf0e10cSrcweir #include <com/sun/star/container/XNameContainer.hpp> 29cdf0e10cSrcweir #include <com/sun/star/sheet/ConditionOperator.hpp> 30cdf0e10cSrcweir #include <com/sun/star/sheet/XSheetCellRanges.hpp> 31cdf0e10cSrcweir #include <com/sun/star/sheet/XSheetConditionalEntries.hpp> 32cdf0e10cSrcweir #include <com/sun/star/sheet/XSpreadsheet.hpp> 33cdf0e10cSrcweir #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> 34cdf0e10cSrcweir #include <com/sun/star/sheet/XSpreadsheets.hpp> 35cdf0e10cSrcweir #include <com/sun/star/style/XStyle.hpp> 36cdf0e10cSrcweir #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> 37cdf0e10cSrcweir #include <com/sun/star/table/CellAddress.hpp> 38cdf0e10cSrcweir #include <com/sun/star/table/CellRangeAddress.hpp> 39cdf0e10cSrcweir #include <com/sun/star/table/XCellRange.hpp> 40cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 41cdf0e10cSrcweir #include "oox/helper/attributelist.hxx" 42cdf0e10cSrcweir #include "oox/helper/containerhelper.hxx" 43cdf0e10cSrcweir #include "oox/helper/propertyset.hxx" 44cdf0e10cSrcweir #include "oox/xls/addressconverter.hxx" 45cdf0e10cSrcweir #include "oox/xls/biffinputstream.hxx" 46cdf0e10cSrcweir #include "oox/xls/stylesbuffer.hxx" 47cdf0e10cSrcweir 48cdf0e10cSrcweir namespace oox { 49cdf0e10cSrcweir namespace xls { 50cdf0e10cSrcweir 51cdf0e10cSrcweir // ============================================================================ 52cdf0e10cSrcweir 53cdf0e10cSrcweir using namespace ::com::sun::star::beans; 54cdf0e10cSrcweir using namespace ::com::sun::star::container; 55cdf0e10cSrcweir using namespace ::com::sun::star::sheet; 56cdf0e10cSrcweir using namespace ::com::sun::star::style; 57cdf0e10cSrcweir using namespace ::com::sun::star::table; 58cdf0e10cSrcweir using namespace ::com::sun::star::uno; 59cdf0e10cSrcweir 60cdf0e10cSrcweir using ::rtl::OUString; 61cdf0e10cSrcweir using ::rtl::OUStringBuffer; 62cdf0e10cSrcweir 63cdf0e10cSrcweir // ============================================================================ 64cdf0e10cSrcweir 65cdf0e10cSrcweir namespace { 66cdf0e10cSrcweir 67cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TYPE_CELLIS = 1; 68cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TYPE_EXPRESSION = 2; 69cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TYPE_COLORSCALE = 3; 70cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TYPE_DATABAR = 4; 71cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TYPE_TOPTEN = 5; 72cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TYPE_ICONSET = 6; 73cdf0e10cSrcweir 74cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_CELLIS = 0; 75cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_EXPRESSION = 1; 76cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_COLORSCALE = 2; 77cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_DATABAR = 3; 78cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_ICONSET = 4; 79cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_TOPTEN = 5; 80cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_UNIQUE = 7; 81cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_TEXT = 8; 82cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_BLANK = 9; 83cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_NOTBLANK = 10; 84cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_ERROR = 11; 85cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_NOTERROR = 12; 86cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_TODAY = 15; 87cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_TOMORROW = 16; 88cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_YESTERDAY = 17; 89cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_LAST7DAYS = 18; 90cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_LASTMONTH = 19; 91cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_NEXTMONTH = 20; 92cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_THISWEEK = 21; 93cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_NEXTWEEK = 22; 94cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_LASTWEEK = 23; 95cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_THISMONTH = 24; 96cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_ABOVEAVERAGE = 25; 97cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_BELOWAVERAGE = 26; 98cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_DUPLICATE = 27; 99cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_EQABOVEAVERAGE = 29; 100cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_SUB_EQBELOWAVERAGE = 30; 101cdf0e10cSrcweir 102cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TIMEOP_TODAY = 0; 103cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TIMEOP_YESTERDAY = 1; 104cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TIMEOP_LAST7DAYS = 2; 105cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TIMEOP_THISWEEK = 3; 106cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TIMEOP_LASTWEEK = 4; 107cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TIMEOP_LASTMONTH = 5; 108cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TIMEOP_TOMORROW = 6; 109cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TIMEOP_NEXTWEEK = 7; 110cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TIMEOP_NEXTMONTH = 8; 111cdf0e10cSrcweir const sal_Int32 BIFF12_CFRULE_TIMEOP_THISMONTH = 9; 112cdf0e10cSrcweir 113cdf0e10cSrcweir const sal_uInt16 BIFF12_CFRULE_STOPIFTRUE = 0x0002; 114cdf0e10cSrcweir const sal_uInt16 BIFF12_CFRULE_ABOVEAVERAGE = 0x0004; 115cdf0e10cSrcweir const sal_uInt16 BIFF12_CFRULE_BOTTOM = 0x0008; 116cdf0e10cSrcweir const sal_uInt16 BIFF12_CFRULE_PERCENT = 0x0010; 117cdf0e10cSrcweir 118cdf0e10cSrcweir // ---------------------------------------------------------------------------- 119cdf0e10cSrcweir 120cdf0e10cSrcweir template< typename Type > 121cdf0e10cSrcweir void lclAppendProperty( ::std::vector< PropertyValue >& orProps, const OUString& rPropName, const Type& rValue ) 122cdf0e10cSrcweir { 123cdf0e10cSrcweir orProps.push_back( PropertyValue() ); 124cdf0e10cSrcweir orProps.back().Name = rPropName; 125cdf0e10cSrcweir orProps.back().Value <<= rValue; 126cdf0e10cSrcweir } 127cdf0e10cSrcweir 128cdf0e10cSrcweir } // namespace 129cdf0e10cSrcweir 130cdf0e10cSrcweir // ============================================================================ 131cdf0e10cSrcweir 132cdf0e10cSrcweir CondFormatRuleModel::CondFormatRuleModel() : 133cdf0e10cSrcweir mnPriority( -1 ), 134cdf0e10cSrcweir mnType( XML_TOKEN_INVALID ), 135cdf0e10cSrcweir mnOperator( XML_TOKEN_INVALID ), 136cdf0e10cSrcweir mnTimePeriod( XML_TOKEN_INVALID ), 137cdf0e10cSrcweir mnRank( 0 ), 138cdf0e10cSrcweir mnStdDev( 0 ), 139cdf0e10cSrcweir mnDxfId( -1 ), 140cdf0e10cSrcweir mbStopIfTrue( false ), 141cdf0e10cSrcweir mbBottom( false ), 142cdf0e10cSrcweir mbPercent( false ), 143cdf0e10cSrcweir mbAboveAverage( true ), 144cdf0e10cSrcweir mbEqualAverage( false ) 145cdf0e10cSrcweir { 146cdf0e10cSrcweir } 147cdf0e10cSrcweir 148cdf0e10cSrcweir void CondFormatRuleModel::setBiffOperator( sal_Int32 nOperator ) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir static const sal_Int32 spnOperators[] = { 151cdf0e10cSrcweir XML_TOKEN_INVALID, XML_between, XML_notBetween, XML_equal, XML_notEqual, 152cdf0e10cSrcweir XML_greaterThan, XML_lessThan, XML_greaterThanOrEqual, XML_lessThanOrEqual }; 153cdf0e10cSrcweir mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID ); 154cdf0e10cSrcweir } 155cdf0e10cSrcweir 156cdf0e10cSrcweir void CondFormatRuleModel::setBiff12TextType( sal_Int32 nOperator ) 157cdf0e10cSrcweir { 158cdf0e10cSrcweir // note: type XML_notContainsText vs. operator XML_notContains 159cdf0e10cSrcweir static const sal_Int32 spnTypes[] = { XML_containsText, XML_notContainsText, XML_beginsWith, XML_endsWith }; 160cdf0e10cSrcweir mnType = STATIC_ARRAY_SELECT( spnTypes, nOperator, XML_TOKEN_INVALID ); 161cdf0e10cSrcweir static const sal_Int32 spnOperators[] = { XML_containsText, XML_notContains, XML_beginsWith, XML_endsWith }; 162cdf0e10cSrcweir mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID ); 163cdf0e10cSrcweir } 164cdf0e10cSrcweir 165cdf0e10cSrcweir // ============================================================================ 166cdf0e10cSrcweir 167cdf0e10cSrcweir CondFormatRule::CondFormatRule( const CondFormat& rCondFormat ) : 168cdf0e10cSrcweir WorksheetHelper( rCondFormat ), 169cdf0e10cSrcweir mrCondFormat( rCondFormat ) 170cdf0e10cSrcweir { 171cdf0e10cSrcweir } 172cdf0e10cSrcweir 173cdf0e10cSrcweir void CondFormatRule::importCfRule( const AttributeList& rAttribs ) 174cdf0e10cSrcweir { 175cdf0e10cSrcweir maModel.maText = rAttribs.getString( XML_text, OUString() ); 176cdf0e10cSrcweir maModel.mnPriority = rAttribs.getInteger( XML_priority, -1 ); 177cdf0e10cSrcweir maModel.mnType = rAttribs.getToken( XML_type, XML_TOKEN_INVALID ); 178cdf0e10cSrcweir maModel.mnOperator = rAttribs.getToken( XML_operator, XML_TOKEN_INVALID ); 179cdf0e10cSrcweir maModel.mnTimePeriod = rAttribs.getToken( XML_timePeriod, XML_TOKEN_INVALID ); 180cdf0e10cSrcweir maModel.mnRank = rAttribs.getInteger( XML_rank, 0 ); 181cdf0e10cSrcweir maModel.mnStdDev = rAttribs.getInteger( XML_stdDev, 0 ); 182cdf0e10cSrcweir maModel.mnDxfId = rAttribs.getInteger( XML_dxfId, -1 ); 183cdf0e10cSrcweir maModel.mbStopIfTrue = rAttribs.getBool( XML_stopIfTrue, false ); 184cdf0e10cSrcweir maModel.mbBottom = rAttribs.getBool( XML_bottom, false ); 185cdf0e10cSrcweir maModel.mbPercent = rAttribs.getBool( XML_percent, false ); 186cdf0e10cSrcweir maModel.mbAboveAverage = rAttribs.getBool( XML_aboveAverage, true ); 187cdf0e10cSrcweir maModel.mbEqualAverage = rAttribs.getBool( XML_equalAverage, false ); 188cdf0e10cSrcweir } 189cdf0e10cSrcweir 190cdf0e10cSrcweir void CondFormatRule::appendFormula( const OUString& rFormula ) 191cdf0e10cSrcweir { 192cdf0e10cSrcweir CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress(); 193cdf0e10cSrcweir ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, rFormula ); 194cdf0e10cSrcweir maModel.maFormulas.push_back( aTokens ); 195cdf0e10cSrcweir } 196cdf0e10cSrcweir 197cdf0e10cSrcweir void CondFormatRule::importCfRule( SequenceInputStream& rStrm ) 198cdf0e10cSrcweir { 199cdf0e10cSrcweir sal_Int32 nType, nSubType, nOperator, nFmla1Size, nFmla2Size, nFmla3Size; 200cdf0e10cSrcweir sal_uInt16 nFlags; 201cdf0e10cSrcweir rStrm >> nType >> nSubType >> maModel.mnDxfId >> maModel.mnPriority >> nOperator; 202cdf0e10cSrcweir rStrm.skip( 8 ); 203cdf0e10cSrcweir rStrm >> nFlags >> nFmla1Size >> nFmla2Size >> nFmla3Size >> maModel.maText; 204cdf0e10cSrcweir 205cdf0e10cSrcweir /* Import the formulas. For no obvious reason, the sizes of the formulas 206cdf0e10cSrcweir are already stored before. Nevertheless the following formulas contain 207cdf0e10cSrcweir their own sizes. */ 208cdf0e10cSrcweir 209cdf0e10cSrcweir // first formula 210cdf0e10cSrcweir OSL_ENSURE( (nFmla1Size >= 0) || ((nFmla2Size == 0) && (nFmla3Size == 0)), "CondFormatRule::importCfRule - missing first formula" ); 211cdf0e10cSrcweir OSL_ENSURE( (nFmla1Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" ); 212cdf0e10cSrcweir if( rStrm.getRemaining() >= 8 ) 213cdf0e10cSrcweir { 214cdf0e10cSrcweir CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress(); 215cdf0e10cSrcweir ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm ); 216cdf0e10cSrcweir maModel.maFormulas.push_back( aTokens ); 217cdf0e10cSrcweir 218cdf0e10cSrcweir // second formula 219cdf0e10cSrcweir OSL_ENSURE( (nFmla2Size >= 0) || (nFmla3Size == 0), "CondFormatRule::importCfRule - missing second formula" ); 220cdf0e10cSrcweir OSL_ENSURE( (nFmla2Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" ); 221cdf0e10cSrcweir if( rStrm.getRemaining() >= 8 ) 222cdf0e10cSrcweir { 223cdf0e10cSrcweir aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm ); 224cdf0e10cSrcweir maModel.maFormulas.push_back( aTokens ); 225cdf0e10cSrcweir 226cdf0e10cSrcweir // third formula 227cdf0e10cSrcweir OSL_ENSURE( (nFmla3Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" ); 228cdf0e10cSrcweir if( rStrm.getRemaining() >= 8 ) 229cdf0e10cSrcweir { 230cdf0e10cSrcweir aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm ); 231cdf0e10cSrcweir maModel.maFormulas.push_back( aTokens ); 232cdf0e10cSrcweir } 233cdf0e10cSrcweir } 234cdf0e10cSrcweir } 235cdf0e10cSrcweir 236cdf0e10cSrcweir // flags 237cdf0e10cSrcweir maModel.mbStopIfTrue = getFlag( nFlags, BIFF12_CFRULE_STOPIFTRUE ); 238cdf0e10cSrcweir maModel.mbBottom = getFlag( nFlags, BIFF12_CFRULE_BOTTOM ); 239cdf0e10cSrcweir maModel.mbPercent = getFlag( nFlags, BIFF12_CFRULE_PERCENT ); 240cdf0e10cSrcweir maModel.mbAboveAverage = getFlag( nFlags, BIFF12_CFRULE_ABOVEAVERAGE ); 241cdf0e10cSrcweir // no flag for equalAverage, must be determined from subtype below... 242cdf0e10cSrcweir 243cdf0e10cSrcweir // Convert the type/operator settings. This is a real mess... 244cdf0e10cSrcweir switch( nType ) 245cdf0e10cSrcweir { 246cdf0e10cSrcweir case BIFF12_CFRULE_TYPE_CELLIS: 247cdf0e10cSrcweir OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_CELLIS, "CondFormatRule::importCfRule - rule type/subtype mismatch" ); 248cdf0e10cSrcweir maModel.mnType = XML_cellIs; 249cdf0e10cSrcweir maModel.setBiffOperator( nOperator ); 250cdf0e10cSrcweir OSL_ENSURE( maModel.mnOperator != XML_TOKEN_INVALID, "CondFormatRule::importCfRule - unknown operator" ); 251cdf0e10cSrcweir break; 252cdf0e10cSrcweir case BIFF12_CFRULE_TYPE_EXPRESSION: 253cdf0e10cSrcweir // here we have to look at the subtype to find the real type... 254cdf0e10cSrcweir switch( nSubType ) 255cdf0e10cSrcweir { 256cdf0e10cSrcweir case BIFF12_CFRULE_SUB_EXPRESSION: 257cdf0e10cSrcweir OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" ); 258cdf0e10cSrcweir maModel.mnType = XML_expression; 259cdf0e10cSrcweir break; 260cdf0e10cSrcweir case BIFF12_CFRULE_SUB_UNIQUE: 261cdf0e10cSrcweir OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" ); 262cdf0e10cSrcweir maModel.mnType = XML_uniqueValues; 263cdf0e10cSrcweir break; 264cdf0e10cSrcweir case BIFF12_CFRULE_SUB_TEXT: 265cdf0e10cSrcweir maModel.setBiff12TextType( nOperator ); 266cdf0e10cSrcweir OSL_ENSURE( maModel.mnType != XML_TOKEN_INVALID, "CondFormatRule::importCfRule - unexpected operator value" ); 267cdf0e10cSrcweir break; 268cdf0e10cSrcweir case BIFF12_CFRULE_SUB_BLANK: 269cdf0e10cSrcweir OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" ); 270cdf0e10cSrcweir maModel.mnType = XML_containsBlanks; 271cdf0e10cSrcweir break; 272cdf0e10cSrcweir case BIFF12_CFRULE_SUB_NOTBLANK: 273cdf0e10cSrcweir OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" ); 274cdf0e10cSrcweir maModel.mnType = XML_notContainsBlanks; 275cdf0e10cSrcweir break; 276cdf0e10cSrcweir case BIFF12_CFRULE_SUB_ERROR: 277cdf0e10cSrcweir OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" ); 278cdf0e10cSrcweir maModel.mnType = XML_containsErrors; 279cdf0e10cSrcweir break; 280cdf0e10cSrcweir case BIFF12_CFRULE_SUB_NOTERROR: 281cdf0e10cSrcweir OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" ); 282cdf0e10cSrcweir maModel.mnType = XML_notContainsErrors; 283cdf0e10cSrcweir break; 284cdf0e10cSrcweir case BIFF12_CFRULE_SUB_TODAY: 285cdf0e10cSrcweir OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_TODAY, "CondFormatRule::importCfRule - unexpected time operator value" ); 286cdf0e10cSrcweir maModel.mnType = XML_timePeriod; 287cdf0e10cSrcweir maModel.mnTimePeriod = XML_today; 288cdf0e10cSrcweir break; 289cdf0e10cSrcweir case BIFF12_CFRULE_SUB_TOMORROW: 290cdf0e10cSrcweir OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_TOMORROW, "CondFormatRule::importCfRule - unexpected time operator value" ); 291cdf0e10cSrcweir maModel.mnType = XML_timePeriod; 292cdf0e10cSrcweir maModel.mnTimePeriod = XML_tomorrow; 293cdf0e10cSrcweir break; 294cdf0e10cSrcweir case BIFF12_CFRULE_SUB_YESTERDAY: 295cdf0e10cSrcweir OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_YESTERDAY, "CondFormatRule::importCfRule - unexpected time operator value" ); 296cdf0e10cSrcweir maModel.mnType = XML_timePeriod; 297cdf0e10cSrcweir maModel.mnTimePeriod = XML_yesterday; 298cdf0e10cSrcweir break; 299cdf0e10cSrcweir case BIFF12_CFRULE_SUB_LAST7DAYS: 300cdf0e10cSrcweir OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_LAST7DAYS, "CondFormatRule::importCfRule - unexpected time operator value" ); 301cdf0e10cSrcweir maModel.mnType = XML_timePeriod; 302cdf0e10cSrcweir maModel.mnTimePeriod = XML_last7Days; 303cdf0e10cSrcweir break; 304cdf0e10cSrcweir case BIFF12_CFRULE_SUB_LASTMONTH: 305cdf0e10cSrcweir OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_LASTMONTH, "CondFormatRule::importCfRule - unexpected time operator value" ); 306cdf0e10cSrcweir maModel.mnType = XML_timePeriod; 307cdf0e10cSrcweir maModel.mnTimePeriod = XML_lastMonth; 308cdf0e10cSrcweir break; 309cdf0e10cSrcweir case BIFF12_CFRULE_SUB_NEXTMONTH: 310cdf0e10cSrcweir OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_NEXTMONTH, "CondFormatRule::importCfRule - unexpected time operator value" ); 311cdf0e10cSrcweir maModel.mnType = XML_timePeriod; 312cdf0e10cSrcweir maModel.mnTimePeriod = XML_nextMonth; 313cdf0e10cSrcweir break; 314cdf0e10cSrcweir case BIFF12_CFRULE_SUB_THISWEEK: 315cdf0e10cSrcweir OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_THISWEEK, "CondFormatRule::importCfRule - unexpected time operator value" ); 316cdf0e10cSrcweir maModel.mnType = XML_timePeriod; 317cdf0e10cSrcweir maModel.mnTimePeriod = XML_thisWeek; 318cdf0e10cSrcweir break; 319cdf0e10cSrcweir case BIFF12_CFRULE_SUB_NEXTWEEK: 320cdf0e10cSrcweir OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_NEXTWEEK, "CondFormatRule::importCfRule - unexpected time operator value" ); 321cdf0e10cSrcweir maModel.mnType = XML_timePeriod; 322cdf0e10cSrcweir maModel.mnTimePeriod = XML_nextWeek; 323cdf0e10cSrcweir break; 324cdf0e10cSrcweir case BIFF12_CFRULE_SUB_LASTWEEK: 325cdf0e10cSrcweir OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_LASTWEEK, "CondFormatRule::importCfRule - unexpected time operator value" ); 326cdf0e10cSrcweir maModel.mnType = XML_timePeriod; 327cdf0e10cSrcweir maModel.mnTimePeriod = XML_lastWeek; 328cdf0e10cSrcweir break; 329cdf0e10cSrcweir case BIFF12_CFRULE_SUB_THISMONTH: 330cdf0e10cSrcweir OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_THISMONTH, "CondFormatRule::importCfRule - unexpected time operator value" ); 331cdf0e10cSrcweir maModel.mnType = XML_timePeriod; 332cdf0e10cSrcweir maModel.mnTimePeriod = XML_thisMonth; 333cdf0e10cSrcweir break; 334cdf0e10cSrcweir case BIFF12_CFRULE_SUB_ABOVEAVERAGE: 335cdf0e10cSrcweir OSL_ENSURE( maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" ); 336cdf0e10cSrcweir maModel.mnType = XML_aboveAverage; 337cdf0e10cSrcweir maModel.mnStdDev = nOperator; // operator field used for standard deviation 338cdf0e10cSrcweir maModel.mbAboveAverage = true; 339cdf0e10cSrcweir maModel.mbEqualAverage = false; // does not exist as real flag... 340cdf0e10cSrcweir break; 341cdf0e10cSrcweir case BIFF12_CFRULE_SUB_BELOWAVERAGE: 342cdf0e10cSrcweir OSL_ENSURE( !maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" ); 343cdf0e10cSrcweir maModel.mnType = XML_aboveAverage; 344cdf0e10cSrcweir maModel.mnStdDev = nOperator; // operator field used for standard deviation 345cdf0e10cSrcweir maModel.mbAboveAverage = false; 346cdf0e10cSrcweir maModel.mbEqualAverage = false; // does not exist as real flag... 347cdf0e10cSrcweir break; 348cdf0e10cSrcweir case BIFF12_CFRULE_SUB_DUPLICATE: 349cdf0e10cSrcweir OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" ); 350cdf0e10cSrcweir maModel.mnType = XML_duplicateValues; 351cdf0e10cSrcweir break; 352cdf0e10cSrcweir case BIFF12_CFRULE_SUB_EQABOVEAVERAGE: 353cdf0e10cSrcweir OSL_ENSURE( maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" ); 354cdf0e10cSrcweir maModel.mnType = XML_aboveAverage; 355cdf0e10cSrcweir maModel.mnStdDev = nOperator; // operator field used for standard deviation 356cdf0e10cSrcweir maModel.mbAboveAverage = true; 357cdf0e10cSrcweir maModel.mbEqualAverage = true; // does not exist as real flag... 358cdf0e10cSrcweir break; 359cdf0e10cSrcweir case BIFF12_CFRULE_SUB_EQBELOWAVERAGE: 360cdf0e10cSrcweir OSL_ENSURE( !maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" ); 361cdf0e10cSrcweir maModel.mnType = XML_aboveAverage; 362cdf0e10cSrcweir maModel.mnStdDev = nOperator; // operator field used for standard deviation 363cdf0e10cSrcweir maModel.mbAboveAverage = false; 364cdf0e10cSrcweir maModel.mbEqualAverage = true; // does not exist as real flag... 365cdf0e10cSrcweir break; 366cdf0e10cSrcweir } 367cdf0e10cSrcweir break; 368cdf0e10cSrcweir case BIFF12_CFRULE_TYPE_COLORSCALE: 369cdf0e10cSrcweir OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_COLORSCALE, "CondFormatRule::importCfRule - rule type/subtype mismatch" ); 370cdf0e10cSrcweir OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" ); 371cdf0e10cSrcweir maModel.mnType = XML_colorScale; 372cdf0e10cSrcweir break; 373cdf0e10cSrcweir case BIFF12_CFRULE_TYPE_DATABAR: 374cdf0e10cSrcweir OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_DATABAR, "CondFormatRule::importCfRule - rule type/subtype mismatch" ); 375cdf0e10cSrcweir OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" ); 376cdf0e10cSrcweir maModel.mnType = XML_dataBar; 377cdf0e10cSrcweir break; 378cdf0e10cSrcweir case BIFF12_CFRULE_TYPE_TOPTEN: 379cdf0e10cSrcweir OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_TOPTEN, "CondFormatRule::importCfRule - rule type/subtype mismatch" ); 380cdf0e10cSrcweir maModel.mnType = XML_top10; 381cdf0e10cSrcweir maModel.mnRank = nOperator; // operator field used for rank value 382cdf0e10cSrcweir break; 383cdf0e10cSrcweir case BIFF12_CFRULE_TYPE_ICONSET: 384cdf0e10cSrcweir OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_ICONSET, "CondFormatRule::importCfRule - rule type/subtype mismatch" ); 385cdf0e10cSrcweir OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" ); 386cdf0e10cSrcweir maModel.mnType = XML_iconSet; 387cdf0e10cSrcweir break; 388cdf0e10cSrcweir default: 389cdf0e10cSrcweir OSL_ENSURE( false, "CondFormatRule::importCfRule - unknown rule type" ); 390cdf0e10cSrcweir } 391cdf0e10cSrcweir } 392cdf0e10cSrcweir 393cdf0e10cSrcweir void CondFormatRule::importCfRule( BiffInputStream& rStrm, sal_Int32 nPriority ) 394cdf0e10cSrcweir { 395cdf0e10cSrcweir sal_uInt8 nType, nOperator; 396cdf0e10cSrcweir sal_uInt16 nFmla1Size, nFmla2Size; 397cdf0e10cSrcweir sal_uInt32 nFlags; 398cdf0e10cSrcweir rStrm >> nType >> nOperator >> nFmla1Size >> nFmla2Size >> nFlags; 399cdf0e10cSrcweir rStrm.skip( 2 ); 400cdf0e10cSrcweir 401cdf0e10cSrcweir static const sal_Int32 spnTypeIds[] = { XML_TOKEN_INVALID, XML_cellIs, XML_expression }; 402cdf0e10cSrcweir maModel.mnType = STATIC_ARRAY_SELECT( spnTypeIds, nType, XML_TOKEN_INVALID ); 403cdf0e10cSrcweir 404cdf0e10cSrcweir maModel.setBiffOperator( nOperator ); 405cdf0e10cSrcweir maModel.mnPriority = nPriority; 406cdf0e10cSrcweir maModel.mbStopIfTrue = true; 407cdf0e10cSrcweir 408cdf0e10cSrcweir DxfRef xDxf = getStyles().createDxf( &maModel.mnDxfId ); 409cdf0e10cSrcweir xDxf->importCfRule( rStrm, nFlags ); 410cdf0e10cSrcweir xDxf->finalizeImport(); 411cdf0e10cSrcweir 412cdf0e10cSrcweir // import the formulas 413cdf0e10cSrcweir OSL_ENSURE( (nFmla1Size > 0) || (nFmla2Size == 0), "CondFormatRule::importCfRule - missing first formula" ); 414cdf0e10cSrcweir if( nFmla1Size > 0 ) 415cdf0e10cSrcweir { 416cdf0e10cSrcweir CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress(); 417cdf0e10cSrcweir ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm, &nFmla1Size ); 418cdf0e10cSrcweir maModel.maFormulas.push_back( aTokens ); 419cdf0e10cSrcweir if( nFmla2Size > 0 ) 420cdf0e10cSrcweir { 421cdf0e10cSrcweir aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm, &nFmla2Size ); 422cdf0e10cSrcweir maModel.maFormulas.push_back( aTokens ); 423cdf0e10cSrcweir } 424cdf0e10cSrcweir } 425cdf0e10cSrcweir } 426cdf0e10cSrcweir 427cdf0e10cSrcweir void CondFormatRule::finalizeImport( const Reference< XSheetConditionalEntries >& rxEntries ) 428cdf0e10cSrcweir { 429cdf0e10cSrcweir ConditionOperator eOperator = ConditionOperator_NONE; 430cdf0e10cSrcweir 431cdf0e10cSrcweir /* Replacement formula for unsupported rule types (text comparison rules, 432cdf0e10cSrcweir time period rules, cell type rules). The replacement formulas below may 433cdf0e10cSrcweir contain several placeholders: 434cdf0e10cSrcweir - '#B' will be replaced by the current relative base address (may occur 435cdf0e10cSrcweir several times). 436cdf0e10cSrcweir - '#R' will be replaced by the entire range list of the conditional 437cdf0e10cSrcweir formatting (absolute addresses). 438cdf0e10cSrcweir - '#T' will be replaced by the quoted comparison text. 439cdf0e10cSrcweir - '#L' will be replaced by the length of the comparison text (from 440cdf0e10cSrcweir the 'text' attribute) used in text comparison rules. 441cdf0e10cSrcweir - '#K' will be replaced by the rank (from the 'rank' attribute) used in 442cdf0e10cSrcweir top-10 rules. 443cdf0e10cSrcweir - '#M' will be replaced by the top/bottom flag (from the 'bottom' 444cdf0e10cSrcweir attribute) used in the RANK function in top-10 rules. 445cdf0e10cSrcweir - '#C' will be replaced by one of the comparison operators <, >, <=, or 446cdf0e10cSrcweir >=, according to the 'aboveAverage' and 'equalAverage' flags. 447cdf0e10cSrcweir */ 448cdf0e10cSrcweir OUString aReplaceFormula; 449cdf0e10cSrcweir 450cdf0e10cSrcweir switch( maModel.mnType ) 451cdf0e10cSrcweir { 452cdf0e10cSrcweir case XML_cellIs: 453cdf0e10cSrcweir eOperator = CondFormatBuffer::convertToApiOperator( maModel.mnOperator ); 454cdf0e10cSrcweir break; 455cdf0e10cSrcweir case XML_expression: 456cdf0e10cSrcweir eOperator = ConditionOperator_FORMULA; 457cdf0e10cSrcweir break; 458cdf0e10cSrcweir case XML_containsText: 459cdf0e10cSrcweir OSL_ENSURE( maModel.mnOperator == XML_containsText, "CondFormatRule::finalizeImport - unexpected operator" ); 460cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "NOT(ISERROR(SEARCH(#T,#B)))" ); 461cdf0e10cSrcweir break; 462cdf0e10cSrcweir case XML_notContainsText: 463cdf0e10cSrcweir // note: type XML_notContainsText vs. operator XML_notContains 464cdf0e10cSrcweir OSL_ENSURE( maModel.mnOperator == XML_notContains, "CondFormatRule::finalizeImport - unexpected operator" ); 465cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "ISERROR(SEARCH(#T,#B))" ); 466cdf0e10cSrcweir break; 467cdf0e10cSrcweir case XML_beginsWith: 468cdf0e10cSrcweir OSL_ENSURE( maModel.mnOperator == XML_beginsWith, "CondFormatRule::finalizeImport - unexpected operator" ); 469cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "LEFT(#B,#L)=#T" ); 470cdf0e10cSrcweir break; 471cdf0e10cSrcweir case XML_endsWith: 472cdf0e10cSrcweir OSL_ENSURE( maModel.mnOperator == XML_endsWith, "CondFormatRule::finalizeImport - unexpected operator" ); 473cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "RIGHT(#B,#L)=#T" ); 474cdf0e10cSrcweir break; 475cdf0e10cSrcweir case XML_timePeriod: 476cdf0e10cSrcweir switch( maModel.mnTimePeriod ) 477cdf0e10cSrcweir { 478cdf0e10cSrcweir case XML_yesterday: 479cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "FLOOR(#B,1)=TODAY()-1" ); 480cdf0e10cSrcweir break; 481cdf0e10cSrcweir case XML_today: 482cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "FLOOR(#B,1)=TODAY()" ); 483cdf0e10cSrcweir break; 484cdf0e10cSrcweir case XML_tomorrow: 485cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "FLOOR(#B,1)=TODAY()+1" ); 486cdf0e10cSrcweir break; 487cdf0e10cSrcweir case XML_last7Days: 488cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-7<FLOOR(#B,1),FLOOR(#B,1)<=TODAY())" ); 489cdf0e10cSrcweir break; 490cdf0e10cSrcweir case XML_lastWeek: 491cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-WEEKDAY(TODAY())-7<FLOOR(#B,1),FLOOR(#B,1)<=TODAY()-WEEKDAY(TODAY()))" ); 492cdf0e10cSrcweir break; 493cdf0e10cSrcweir case XML_thisWeek: 494cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-WEEKDAY(TODAY())<FLOOR(#B,1),FLOOR(#B,1)<=TODAY()-WEEKDAY(TODAY())+7)" ); 495cdf0e10cSrcweir break; 496cdf0e10cSrcweir case XML_nextWeek: 497cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-WEEKDAY(TODAY())+7<FLOOR(#B,1),FLOOR(#B,1)<=TODAY()-WEEKDAY(TODAY())+14)" ); 498cdf0e10cSrcweir break; 499cdf0e10cSrcweir case XML_lastMonth: 500cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "OR(AND(MONTH(#B)=MONTH(TODAY())-1,YEAR(#B)=YEAR(TODAY())),AND(MONTH(#B)=12,MONTH(TODAY())=1,YEAR(#B)=YEAR(TODAY())-1))" ); 501cdf0e10cSrcweir break; 502cdf0e10cSrcweir case XML_thisMonth: 503cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "AND(MONTH(#B)=MONTH(TODAY()),YEAR(#B)=YEAR(TODAY()))" ); 504cdf0e10cSrcweir break; 505cdf0e10cSrcweir case XML_nextMonth: 506cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "OR(AND(MONTH(#B)=MONTH(TODAY())+1,YEAR(#B)=YEAR(TODAY())),AND(MONTH(#B)=1,MONTH(TODAY())=12,YEAR(#B)=YEAR(TODAY())+1))" ); 507cdf0e10cSrcweir break; 508cdf0e10cSrcweir default: 509cdf0e10cSrcweir OSL_ENSURE( false, "CondFormatRule::finalizeImport - unknown time period type" ); 510cdf0e10cSrcweir } 511cdf0e10cSrcweir break; 512cdf0e10cSrcweir case XML_containsBlanks: 513cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "LEN(TRIM(#B))=0" ); 514cdf0e10cSrcweir break; 515cdf0e10cSrcweir case XML_notContainsBlanks: 516cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "LEN(TRIM(#B))>0" ); 517cdf0e10cSrcweir break; 518cdf0e10cSrcweir case XML_containsErrors: 519cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "ISERROR(#B)" ); 520cdf0e10cSrcweir break; 521cdf0e10cSrcweir case XML_notContainsErrors: 522cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "NOT(ISERROR(#B))" ); 523cdf0e10cSrcweir break; 524cdf0e10cSrcweir case XML_top10: 525cdf0e10cSrcweir if( maModel.mbPercent ) 526cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "RANK(#B,#R,#M)/COUNT(#R)<=#K%" ); 527cdf0e10cSrcweir else 528cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "RANK(#B,#R,#M)<=#K" ); 529cdf0e10cSrcweir break; 530cdf0e10cSrcweir case XML_aboveAverage: 531cdf0e10cSrcweir if( maModel.mnStdDev == 0 ) 532cdf0e10cSrcweir aReplaceFormula = CREATE_OUSTRING( "#B#CAVERAGE(#R)" ); 533cdf0e10cSrcweir break; 534cdf0e10cSrcweir } 535cdf0e10cSrcweir 536cdf0e10cSrcweir if( aReplaceFormula.getLength() > 0 ) 537cdf0e10cSrcweir { 538cdf0e10cSrcweir OUString aAddress, aRanges, aText, aComp; 539cdf0e10cSrcweir sal_Int32 nStrPos = aReplaceFormula.getLength(); 540cdf0e10cSrcweir while( (nStrPos = aReplaceFormula.lastIndexOf( '#', nStrPos )) >= 0 ) 541cdf0e10cSrcweir { 542cdf0e10cSrcweir switch( aReplaceFormula[ nStrPos + 1 ] ) 543cdf0e10cSrcweir { 544cdf0e10cSrcweir case 'B': // current base address 545cdf0e10cSrcweir if( aAddress.getLength() == 0 ) 546cdf0e10cSrcweir aAddress = FormulaProcessorBase::generateAddress2dString( mrCondFormat.getRanges().getBaseAddress(), false ); 547cdf0e10cSrcweir aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aAddress ); 548cdf0e10cSrcweir break; 549cdf0e10cSrcweir case 'R': // range list of conditional formatting 550cdf0e10cSrcweir if( aRanges.getLength() == 0 ) 551cdf0e10cSrcweir aRanges = FormulaProcessorBase::generateRangeList2dString( mrCondFormat.getRanges(), true, ',', true ); 552cdf0e10cSrcweir aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aRanges ); 553cdf0e10cSrcweir break; 554cdf0e10cSrcweir case 'T': // comparison text 555cdf0e10cSrcweir if( aText.getLength() == 0 ) 556cdf0e10cSrcweir // quote the comparison text, and handle embedded quote characters 557cdf0e10cSrcweir aText = FormulaProcessorBase::generateApiString( maModel.maText ); 558cdf0e10cSrcweir aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aText ); 559cdf0e10cSrcweir break; 560cdf0e10cSrcweir case 'L': // length of comparison text 561cdf0e10cSrcweir aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, 562cdf0e10cSrcweir OUString::valueOf( maModel.maText.getLength() ) ); 563cdf0e10cSrcweir break; 564cdf0e10cSrcweir case 'K': // top-10 rank 565cdf0e10cSrcweir aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, 566cdf0e10cSrcweir OUString::valueOf( maModel.mnRank ) ); 567cdf0e10cSrcweir break; 568cdf0e10cSrcweir case 'M': // top-10 top/bottom flag 569cdf0e10cSrcweir aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, 570cdf0e10cSrcweir OUString::valueOf( static_cast< sal_Int32 >( maModel.mbBottom ? 1 : 0 ) ) ); 571cdf0e10cSrcweir break; 572cdf0e10cSrcweir case 'C': // average comparison operator 573cdf0e10cSrcweir if( aComp.getLength() == 0 ) 574cdf0e10cSrcweir aComp = maModel.mbAboveAverage ? 575cdf0e10cSrcweir (maModel.mbEqualAverage ? CREATE_OUSTRING( ">=" ) : CREATE_OUSTRING( ">" )) : 576cdf0e10cSrcweir (maModel.mbEqualAverage ? CREATE_OUSTRING( "<=" ) : CREATE_OUSTRING( "<" )); 577cdf0e10cSrcweir aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aComp ); 578cdf0e10cSrcweir break; 579cdf0e10cSrcweir default: 580cdf0e10cSrcweir OSL_ENSURE( false, "CondFormatRule::finalizeImport - unknown placeholder" ); 581cdf0e10cSrcweir } 582cdf0e10cSrcweir } 583cdf0e10cSrcweir 584cdf0e10cSrcweir // set the replacement formula 585cdf0e10cSrcweir maModel.maFormulas.clear(); 586cdf0e10cSrcweir appendFormula( aReplaceFormula ); 587cdf0e10cSrcweir eOperator = ConditionOperator_FORMULA; 588cdf0e10cSrcweir } 589cdf0e10cSrcweir 590cdf0e10cSrcweir if( rxEntries.is() && (eOperator != ConditionOperator_NONE) && !maModel.maFormulas.empty() ) 591cdf0e10cSrcweir { 592cdf0e10cSrcweir ::std::vector< PropertyValue > aProps; 593cdf0e10cSrcweir // create condition properties 594cdf0e10cSrcweir lclAppendProperty( aProps, CREATE_OUSTRING( "Operator" ), eOperator ); 595cdf0e10cSrcweir lclAppendProperty( aProps, CREATE_OUSTRING( "Formula1" ), maModel.maFormulas[ 0 ] ); 596cdf0e10cSrcweir if( maModel.maFormulas.size() >= 2 ) 597cdf0e10cSrcweir lclAppendProperty( aProps, CREATE_OUSTRING( "Formula2" ), maModel.maFormulas[ 1 ] ); 598cdf0e10cSrcweir 599cdf0e10cSrcweir // style name for the formatting attributes 600cdf0e10cSrcweir OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId ); 601cdf0e10cSrcweir if( aStyleName.getLength() > 0 ) 602cdf0e10cSrcweir lclAppendProperty( aProps, CREATE_OUSTRING( "StyleName" ), aStyleName ); 603cdf0e10cSrcweir 604cdf0e10cSrcweir // append the new rule 605cdf0e10cSrcweir try 606cdf0e10cSrcweir { 607cdf0e10cSrcweir rxEntries->addNew( ContainerHelper::vectorToSequence( aProps ) ); 608cdf0e10cSrcweir } 609cdf0e10cSrcweir catch( Exception& ) 610cdf0e10cSrcweir { 611cdf0e10cSrcweir } 612cdf0e10cSrcweir } 613cdf0e10cSrcweir } 614cdf0e10cSrcweir 615cdf0e10cSrcweir // ============================================================================ 616cdf0e10cSrcweir 617cdf0e10cSrcweir CondFormatModel::CondFormatModel() : 618cdf0e10cSrcweir mbPivot( false ) 619cdf0e10cSrcweir { 620cdf0e10cSrcweir } 621cdf0e10cSrcweir 622cdf0e10cSrcweir // ============================================================================ 623cdf0e10cSrcweir 624cdf0e10cSrcweir CondFormat::CondFormat( const WorksheetHelper& rHelper ) : 625cdf0e10cSrcweir WorksheetHelper( rHelper ) 626cdf0e10cSrcweir { 627cdf0e10cSrcweir } 628cdf0e10cSrcweir 629cdf0e10cSrcweir void CondFormat::importConditionalFormatting( const AttributeList& rAttribs ) 630cdf0e10cSrcweir { 631cdf0e10cSrcweir getAddressConverter().convertToCellRangeList( maModel.maRanges, rAttribs.getString( XML_sqref, OUString() ), getSheetIndex(), true ); 632cdf0e10cSrcweir maModel.mbPivot = rAttribs.getBool( XML_pivot, false ); 633cdf0e10cSrcweir } 634cdf0e10cSrcweir 635cdf0e10cSrcweir CondFormatRuleRef CondFormat::importCfRule( const AttributeList& rAttribs ) 636cdf0e10cSrcweir { 637cdf0e10cSrcweir CondFormatRuleRef xRule = createRule(); 638cdf0e10cSrcweir xRule->importCfRule( rAttribs ); 639cdf0e10cSrcweir insertRule( xRule ); 640cdf0e10cSrcweir return xRule; 641cdf0e10cSrcweir } 642cdf0e10cSrcweir 643cdf0e10cSrcweir void CondFormat::importCondFormatting( SequenceInputStream& rStrm ) 644cdf0e10cSrcweir { 645cdf0e10cSrcweir BinRangeList aRanges; 646cdf0e10cSrcweir rStrm.skip( 8 ); 647cdf0e10cSrcweir rStrm >> aRanges; 648cdf0e10cSrcweir getAddressConverter().convertToCellRangeList( maModel.maRanges, aRanges, getSheetIndex(), true ); 649cdf0e10cSrcweir } 650cdf0e10cSrcweir 651cdf0e10cSrcweir void CondFormat::importCfRule( SequenceInputStream& rStrm ) 652cdf0e10cSrcweir { 653cdf0e10cSrcweir CondFormatRuleRef xRule = createRule(); 654cdf0e10cSrcweir xRule->importCfRule( rStrm ); 655cdf0e10cSrcweir insertRule( xRule ); 656cdf0e10cSrcweir } 657cdf0e10cSrcweir 658cdf0e10cSrcweir void CondFormat::importCfHeader( BiffInputStream& rStrm ) 659cdf0e10cSrcweir { 660cdf0e10cSrcweir // import the CFHEADER record 661cdf0e10cSrcweir sal_uInt16 nRuleCount; 662cdf0e10cSrcweir BinRangeList aRanges; 663cdf0e10cSrcweir rStrm >> nRuleCount; 664cdf0e10cSrcweir rStrm.skip( 10 ); 665cdf0e10cSrcweir rStrm >> aRanges; 666cdf0e10cSrcweir getAddressConverter().convertToCellRangeList( maModel.maRanges, aRanges, getSheetIndex(), true ); 667cdf0e10cSrcweir 668cdf0e10cSrcweir // import following list of CFRULE records 669cdf0e10cSrcweir for( sal_uInt16 nRule = 0; (nRule < nRuleCount) && (rStrm.getNextRecId() == BIFF_ID_CFRULE) && rStrm.startNextRecord(); ++nRule ) 670cdf0e10cSrcweir { 671cdf0e10cSrcweir CondFormatRuleRef xRule = createRule(); 672cdf0e10cSrcweir xRule->importCfRule( rStrm, nRule + 1 ); 673cdf0e10cSrcweir insertRule( xRule ); 674cdf0e10cSrcweir } 675cdf0e10cSrcweir } 676cdf0e10cSrcweir 677cdf0e10cSrcweir void CondFormat::finalizeImport() 678cdf0e10cSrcweir { 679cdf0e10cSrcweir try 680cdf0e10cSrcweir { 681cdf0e10cSrcweir Reference< XSheetCellRanges > xRanges( getCellRangeList( maModel.maRanges ), UNO_SET_THROW ); 682cdf0e10cSrcweir PropertySet aPropSet( xRanges ); 683cdf0e10cSrcweir Reference< XSheetConditionalEntries > xEntries( aPropSet.getAnyProperty( PROP_ConditionalFormat ), UNO_QUERY_THROW ); 684cdf0e10cSrcweir // maRules is sorted by rule priority 685cdf0e10cSrcweir maRules.forEachMem( &CondFormatRule::finalizeImport, ::boost::cref( xEntries ) ); 686cdf0e10cSrcweir aPropSet.setProperty( PROP_ConditionalFormat, xEntries ); 687cdf0e10cSrcweir } 688cdf0e10cSrcweir catch( Exception& ) 689cdf0e10cSrcweir { 690cdf0e10cSrcweir } 691cdf0e10cSrcweir } 692cdf0e10cSrcweir 693cdf0e10cSrcweir CondFormatRuleRef CondFormat::createRule() 694cdf0e10cSrcweir { 695cdf0e10cSrcweir return CondFormatRuleRef( new CondFormatRule( *this ) ); 696cdf0e10cSrcweir } 697cdf0e10cSrcweir 698cdf0e10cSrcweir void CondFormat::insertRule( CondFormatRuleRef xRule ) 699cdf0e10cSrcweir { 700cdf0e10cSrcweir if( xRule.get() && (xRule->getPriority() > 0) ) 701cdf0e10cSrcweir { 702cdf0e10cSrcweir OSL_ENSURE( maRules.find( xRule->getPriority() ) == maRules.end(), "CondFormat::insertRule - multiple rules with equal priority" ); 703cdf0e10cSrcweir maRules[ xRule->getPriority() ] = xRule; 704cdf0e10cSrcweir } 705cdf0e10cSrcweir } 706cdf0e10cSrcweir 707cdf0e10cSrcweir // ============================================================================ 708cdf0e10cSrcweir 709cdf0e10cSrcweir CondFormatBuffer::CondFormatBuffer( const WorksheetHelper& rHelper ) : 710cdf0e10cSrcweir WorksheetHelper( rHelper ) 711cdf0e10cSrcweir { 712cdf0e10cSrcweir } 713cdf0e10cSrcweir 714cdf0e10cSrcweir CondFormatRef CondFormatBuffer::importConditionalFormatting( const AttributeList& rAttribs ) 715cdf0e10cSrcweir { 716cdf0e10cSrcweir CondFormatRef xCondFmt = createCondFormat(); 717cdf0e10cSrcweir xCondFmt->importConditionalFormatting( rAttribs ); 718cdf0e10cSrcweir return xCondFmt; 719cdf0e10cSrcweir } 720cdf0e10cSrcweir 721cdf0e10cSrcweir CondFormatRef CondFormatBuffer::importCondFormatting( SequenceInputStream& rStrm ) 722cdf0e10cSrcweir { 723cdf0e10cSrcweir CondFormatRef xCondFmt = createCondFormat(); 724cdf0e10cSrcweir xCondFmt->importCondFormatting( rStrm ); 725cdf0e10cSrcweir return xCondFmt; 726cdf0e10cSrcweir } 727cdf0e10cSrcweir 728cdf0e10cSrcweir void CondFormatBuffer::importCfHeader( BiffInputStream& rStrm ) 729cdf0e10cSrcweir { 730cdf0e10cSrcweir createCondFormat()->importCfHeader( rStrm ); 731cdf0e10cSrcweir } 732cdf0e10cSrcweir 733cdf0e10cSrcweir void CondFormatBuffer::finalizeImport() 734cdf0e10cSrcweir { 735cdf0e10cSrcweir maCondFormats.forEachMem( &CondFormat::finalizeImport ); 736cdf0e10cSrcweir } 737cdf0e10cSrcweir 738cdf0e10cSrcweir ConditionOperator CondFormatBuffer::convertToApiOperator( sal_Int32 nToken ) 739cdf0e10cSrcweir { 740cdf0e10cSrcweir switch( nToken ) 741cdf0e10cSrcweir { 742cdf0e10cSrcweir case XML_between: return ConditionOperator_BETWEEN; 743cdf0e10cSrcweir case XML_equal: return ConditionOperator_EQUAL; 744cdf0e10cSrcweir case XML_greaterThan: return ConditionOperator_GREATER; 745cdf0e10cSrcweir case XML_greaterThanOrEqual: return ConditionOperator_GREATER_EQUAL; 746cdf0e10cSrcweir case XML_lessThan: return ConditionOperator_LESS; 747cdf0e10cSrcweir case XML_lessThanOrEqual: return ConditionOperator_LESS_EQUAL; 748cdf0e10cSrcweir case XML_notBetween: return ConditionOperator_NOT_BETWEEN; 749cdf0e10cSrcweir case XML_notEqual: return ConditionOperator_NOT_EQUAL; 750cdf0e10cSrcweir } 751cdf0e10cSrcweir return ConditionOperator_NONE; 752cdf0e10cSrcweir } 753cdf0e10cSrcweir 754cdf0e10cSrcweir // private -------------------------------------------------------------------- 755cdf0e10cSrcweir 756cdf0e10cSrcweir CondFormatRef CondFormatBuffer::createCondFormat() 757cdf0e10cSrcweir { 758cdf0e10cSrcweir CondFormatRef xCondFmt( new CondFormat( *this ) ); 759cdf0e10cSrcweir maCondFormats.push_back( xCondFmt ); 760cdf0e10cSrcweir return xCondFmt; 761cdf0e10cSrcweir } 762cdf0e10cSrcweir 763cdf0e10cSrcweir // ============================================================================ 764cdf0e10cSrcweir 765cdf0e10cSrcweir } // namespace xls 766cdf0e10cSrcweir } // namespace oox 767