From 518771d95e7dec96e7636719c5da8a74b692cddd Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Wed, 8 Dec 2010 15:41:52 +0100 Subject: dr78: #i111413# export secant functions to BIFF --- oox/source/dump/biffdumper.ini | 2 +- oox/source/xls/formulabase.cxx | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'oox/source') diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini index d4b862825b3c..97685c850515 100644 --- a/oox/source/dump/biffdumper.ini +++ b/oox/source/dump/biffdumper.ini @@ -358,7 +358,7 @@ multilist=RECORD-NAMES-BIFF5 # chart records exclude=0x1004,0x102D,0x102F,0x1036,0x1037,0x1038,0x103B 0x1040=CHRADARAREA,CHAXESSET,,CHLEGENDENTRY,CHPROPERTIES,CHSERGROUP,CHUSEDAXESSETS, - 0x1048=CHPIVOTREF,,CHSERPARENT,CHSERTRENDLINE,,,CHFORMAT,CHFRAMEPOS + 0x1048=CHPIVOTRANGE,,CHSERPARENT,CHSERTRENDLINE,,,CHFORMAT,CHFRAMEPOS 0x1050=CHFORMATRUNS,CHSOURCELINK,,,,,, 0x1058=,,,CHSERERRORBAR,,CHSERIESFORMAT,, end diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx index ea353bb48558..5e1ed6b35141 100644 --- a/oox/source/xls/formulabase.cxx +++ b/oox/source/xls/formulabase.cxx @@ -308,7 +308,9 @@ static const FunctionData saFuncTableBiff2[] = { "DOLLAR", "DOLLAR", 13, 13, 1, 2, V, { VR }, 0 }, { "FIXED", "FIXED", 14, 14, 1, 2, V, { VR, VR, C }, 0 }, { "SIN", "SIN", 15, 15, 1, 1, V, { VR }, 0 }, + { "CSC", "SIN", 15, 15, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, { "COS", "COS", 16, 16, 1, 1, V, { VR }, 0 }, + { "SEC", "COS", 16, 16, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, { "TAN", "TAN", 17, 17, 1, 1, V, { VR }, 0 }, { "COT", "TAN", 17, 17, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, { "ATAN", "ATAN", 18, 18, 1, 1, V, { VR }, 0 }, @@ -468,7 +470,9 @@ static const FunctionData saFuncTableBiff3[] = { "MEDIAN", "MEDIAN", 227, 227, 1, MX, V, { RX }, 0 }, { "SUMPRODUCT", "SUMPRODUCT", 228, 228, 1, MX, V, { VA }, 0 }, { "SINH", "SINH", 229, 229, 1, 1, V, { VR }, 0 }, + { "CSCH", "SINH", 229, 229, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, { "COSH", "COSH", 230, 230, 1, 1, V, { VR }, 0 }, + { "SECH", "COSH", 230, 230, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, { "TANH", "TANH", 231, 231, 1, 1, V, { VR }, 0 }, { "COTH", "TANH", 231, 231, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, { "ASINH", "ASINH", 232, 232, 1, 1, V, { VR }, 0 }, -- cgit From 4e7a88638a1293491fb06f3d1d4c0e22cd4c7631 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Tue, 14 Dec 2010 14:40:00 +0100 Subject: dr78: simplified handling of external add-in functions, changed handling of empty function parameters --- oox/source/xls/formulabase.cxx | 15 ++++++-------- oox/source/xls/formulaparser.cxx | 42 ++++++++++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 15 deletions(-) (limited to 'oox/source') diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx index 5e1ed6b35141..c7a11c7c1cdd 100644 --- a/oox/source/xls/formulabase.cxx +++ b/oox/source/xls/formulabase.cxx @@ -237,8 +237,10 @@ const sal_uInt16 FUNCFLAG_MACROCMD = 0x0080; /// Function is a macro- const sal_uInt16 FUNCFLAG_ALWAYSVAR = 0x0100; /// Function is always represented by a tFuncVar token. const sal_uInt16 FUNCFLAG_PARAMPAIRS = 0x0200; /// Optional parameters are expected to appear in pairs. -const sal_uInt16 FUNCFLAG_FUNCLIBMASK = 0xF000; /// Mask for function library bits. -const sal_uInt16 FUNCFLAG_EUROTOOL = 0x1000; /// Function is part of the EuroTool add-in. +/// Converts a function library index (value of enum FunctionLibraryType) to function flags. +#define FUNCLIB_TO_FUNCFLAGS( funclib_index ) static_cast< sal_uInt16 >( static_cast< sal_uInt8 >( funclib_index ) << 12 ) +/// Extracts a function library index (value of enum FunctionLibraryType) from function flags. +#define FUNCFLAGS_TO_FUNCLIB( func_flags ) extractValue< FunctionLibraryType >( func_flags, 12, 4 ) typedef ::boost::shared_ptr< FunctionInfo > FunctionInfoRef; @@ -688,7 +690,7 @@ static const FunctionData saFuncTableBiff5[] = // *** EuroTool add-in *** - { "EUROCONVERT", "EUROCONVERT", NOID, NOID, 3, 5, V, { VR }, FUNCFLAG_EUROTOOL }, + { "EUROCONVERT", "EUROCONVERT", NOID, NOID, 3, 5, V, { VR }, FUNCLIB_TO_FUNCFLAGS( FUNCLIB_EUROTOOL ) }, // *** macro sheet commands *** @@ -925,12 +927,7 @@ void FunctionProviderImpl::initFunc( const FunctionData& rFuncData, sal_uInt8 nM xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfnodf." ) + xFuncInfo->maOdfFuncName; } - switch( rFuncData.mnFlags & FUNCFLAG_FUNCLIBMASK ) - { - case FUNCFLAG_EUROTOOL: xFuncInfo->meFuncLibType = FUNCLIB_EUROTOOL; break; - default: xFuncInfo->meFuncLibType = FUNCLIB_UNKNOWN; - } - + xFuncInfo->meFuncLibType = FUNCFLAGS_TO_FUNCLIB( rFuncData.mnFlags ); xFuncInfo->mnApiOpCode = -1; xFuncInfo->mnOobFuncId = rFuncData.mnOobFuncId; xFuncInfo->mnBiffFuncId = rFuncData.mnBiffFuncId; diff --git a/oox/source/xls/formulaparser.cxx b/oox/source/xls/formulaparser.cxx index 12deadecd695..bc5d30bc98c4 100644 --- a/oox/source/xls/formulaparser.cxx +++ b/oox/source/xls/formulaparser.cxx @@ -126,7 +126,6 @@ const FunctionInfo* FormulaFinalizer::getFunctionInfo( ApiToken& orFuncToken ) // no success - return null return 0; - } const FunctionInfo* FormulaFinalizer::getExternCallInfo( ApiToken& orFuncToken, const ApiToken& rECToken ) @@ -248,17 +247,29 @@ const ApiToken* FormulaFinalizer::processParameters( if( !aParamInfoIt.isExcelOnlyParam() ) { - // replace empty second and third parameter in IF function with zeros - if( (pRealFuncInfo->mnOobFuncId == OOBIN_FUNC_IF) && ((nParam == 1) || (nParam == 2)) && bIsEmpty ) + // handle empty parameters + if( bIsEmpty ) { - maTokens.append< double >( OPCODE_PUSH, 0.0 ); - bIsEmpty = false; + // append leading space tokens from original token array + while( (pParamBegin < pParamEnd) && (pParamBegin->OpCode == OPCODE_SPACES) ) + maTokens.push_back( *pParamBegin++ ); + // add default values for some empty parameters, or the OPCODE_MISSING token + appendEmptyParameter( *pRealFuncInfo, nParam ); + // reset bIsEmpty flag, if something has been appended in appendEmptyParameter() + bIsEmpty = maTokens.back().OpCode == OPCODE_MISSING; + // skip OPCODE_MISSING token in the original token array + OSL_ENSURE( (pParamBegin == pParamEnd) || (pParamBegin->OpCode == OPCODE_MISSING), "FormulaFinalizer::processParameters - OPCODE_MISSING expected" ); + if( pParamBegin < pParamEnd ) ++pParamBegin; + // append trailing space tokens from original token array + while( (pParamBegin < pParamEnd) && (pParamBegin->OpCode == OPCODE_SPACES) ) + maTokens.push_back( *pParamBegin++ ); } else { - // process all tokens of the parameter + // if parameter is not empty, process all tokens of the parameter processTokens( pParamBegin, pParamEnd ); } + // append parameter separator token maTokens.append( OPCODE_SEP ); } @@ -365,6 +376,25 @@ const ApiToken* FormulaFinalizer::findParameters( ParameterPosVector& rParams, return (pToken < pTokenEnd) ? (pToken + 1) : pTokenEnd; } +void FormulaFinalizer::appendEmptyParameter( const FunctionInfo& rFuncInfo, size_t nParam ) +{ + // remeber old size of the token array + size_t nTokenArraySize = maTokens.size(); + + switch( rFuncInfo.mnOobFuncId ) + { + case OOBIN_FUNC_IF: + if( (nParam == 1) || (nParam == 2) ) + maTokens.append< double >( OPCODE_PUSH, 0.0 ); + break; + default:; + } + + // if no token has been added, append a OPCODE_MISSING token + if( nTokenArraySize == maTokens.size() ) + maTokens.append( OPCODE_MISSING ); +} + void FormulaFinalizer::appendCalcOnlyParameter( const FunctionInfo& rFuncInfo, size_t nParam ) { (void)nParam; // prevent 'unused' warning -- cgit From b60db466ef41f4414ef80563dc3b97428336acf5 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Wed, 15 Dec 2010 17:43:27 +0100 Subject: dr78: #i71810# rework import of fill bitmap mode: ignore CHPICFORMAT record except for bar chart series/points and for 3D walls/floor --- oox/source/dump/biffdumper.cxx | 2 +- oox/source/dump/biffdumper.ini | 10 -------- oox/source/dump/dffdumper.ini | 53 ++++++++++++++++++++++++------------------ 3 files changed, 32 insertions(+), 33 deletions(-) (limited to 'oox/source') diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index 30938f9ebbe6..3d6f20ed62ba 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -1909,7 +1909,7 @@ void WorkbookStreamObject::implDumpRecordBody() case BIFF_ID_CHPICFORMAT: dumpDec< sal_uInt16 >( "bitmap-mode", "CHPICFORMAT-BITMAP-MODE" ); - dumpDec< sal_uInt16 >( "image-format", "CHPICFORMAT-IMAGE-FORMAT" ); + dumpUnused( 2 ); dumpHex< sal_uInt16 >( "flags", "CHPICFORMAT-FLAGS" ); dumpDec< double >( "scaling-factor" ); break; diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini index 97685c850515..8e1626f82659 100644 --- a/oox/source/dump/biffdumper.ini +++ b/oox/source/dump/biffdumper.ini @@ -1045,17 +1045,7 @@ end shortlist=CHPICFORMAT-BITMAP-MODE,1,stretched,stacked,stacked-scaled -constlist=CHPICFORMAT-IMAGE-FORMAT - 2=wmf - 9=bmp - 19=?emf -end - -shortlist=CHPICFORMAT-ENV,1,windows,apple - combilist=CHPICFORMAT-FLAGS - 0x00FF=uint16,dec,environment,CHPICFORMAT-ENV - 0x0100=format-only 0x0200=top-bottom 0x0400=front-back 0x0800=left-right diff --git a/oox/source/dump/dffdumper.ini b/oox/source/dump/dffdumper.ini index c33d733c6bd8..ebdf652afcfa 100644 --- a/oox/source/dump/dffdumper.ini +++ b/oox/source/dump/dffdumper.ini @@ -79,6 +79,9 @@ end shortlist=DFF-COLORMOD-TYPE,0,none,shade,tint +unitconverter=DFF-OPACITY,/655.36,% +unitconverter=DFF-DEGREES,/65536,° + # DFFBSE --------------------------------------------------------------------- combilist=DFFBSE-RECORD-INST @@ -136,8 +139,8 @@ multilist=DFFOPT-PROPERTY-NAMES # 0x0100-0x013F: picture (BLIP) 0x0100=blip-crop-top,blip-crop-bottom,blip-crop-left,blip-crop-right,blip-id,blip-name,blip-opt,blip-transparency-color 0x0108=blip-contrast,blip-brightness,blip-gamma,blip-ole-id,blip-double-cr-mod,blip-fill-cr-mod,blip-line-cr-mod,blip-print-id - 0x0110=blip-print-name,blip-print-opt,blip-movie,,,blip-transparency-color-ext,,blip-transparency-color-ext-mod - 0x0118,,blip-recolor,blip-recolor,blip-recolor-ext,,blip-recolor-ext-mod + 0x0110=blip-print-name,blip-print-opt,blip-movie,,,blip-transparency-color-ext,reserved,blip-transparency-color-ext-mod + 0x0118=reserved,reserved,blip-recolor,blip-recolor-ext,reserved,blip-recolor-ext-mod,reserved,reserved 0x013F=blip-flags # 0x0140-0x017F: shape geometry 0x0140=geo-left,geo-top,geo-right,geo-bottom,geo-shape-path,geo-vertices,geo-segment-info,geo-adjust-1 @@ -149,20 +152,21 @@ multilist=DFFOPT-PROPERTY-NAMES 0x0180=fill-type,fill-color,fill-opacity,fill-back-color,fill-back-opacity,fill-cr-mod,fill-blip,fill-blip-name 0x0188=fill-blip-opt,fill-width,fill-height,fill-angle,fill-focus,fill-to-left,fill-to-top,fill-to-right 0x0190=fill-to-bottom,fill-rect-left,fill-rect-top,fill-rect-right,fill-rect-bottom,fill-dz-type,fill-shade-preset,fill-shade-colors - 0x0198=fill-origin-x,fill-origin-y,fill-shape-origin-x,fill-shape-origin-y,fill-shade-type,,fill-color-ext, - 0x01A0=fill-color-ext-mod,,fill-back-color-ext,,fill-back-color-ext-mod + 0x0198=fill-origin-x,fill-origin-y,fill-shape-origin-x,fill-shape-origin-y,fill-shade-type,,fill-color-ext,reserved + 0x01A0=fill-color-ext-mod,reserved,fill-back-color-ext,reserved,fill-back-color-ext-mod,reserved,reserved,reserved 0x01BF=fill-flags # 0x01C0-0x01FF: line style 0x01C0=line-color,line-opacity,line-back-color,line-cr-mod,line-type,line-fill-blip,line-fill-blip-name,line-fill-blip-opt 0x01C8=line-fill-width,line-fill-height,line-fill-dz-type,line-width,line-miter-limit,line-style,line-dash,line-dash-style 0x01D0=line-start-arrow-head,line-end-arrow-head,line-start-arrow-width,line-start-arrow-length,line-end-arrow-width,line-end-arrow-length,line-join-style,line-end-cap-style - 0x01D8=,line-color-ext,,line-color-ext-mod,,line-back-color-ext,,line-back-color-ext-mod + 0x01D8=,line-color-ext,reserved,line-color-ext-mod,reserved,line-back-color-ext,reserved,line-back-color-ext-mod + 0x01E0=reserved,reserved,reserved 0x01FF=line-flags # 0x0200-0x023F: shadow style 0x0200=shadow-type,shadow-color,shadow-highlight,shadow-cr-mod,shadow-opacity,shadow-offset-x,shadow-offset-y,shadow-2nd-offset-x 0x0208=shadow-2nd-offset-y,,,,,,, - 0x0210=shadow-origin-x,shadow-origin-y,shadow-color-ext,,shadow-color-ext-mod,,shadow-highlight-ext, - 0x0218=shadow-highlight-ext-mod + 0x0210=shadow-origin-x,shadow-origin-y,shadow-color-ext,reserved,shadow-color-ext-mod,reserved,shadow-highlight-ext,reserved + 0x0218=shadow-highlight-ext-mod,reserved,reserved,reserved 0x023F=shadow-flags # 0x0240-0x027F: perspective 0x0240=persp-type,persp-offset-x,persp-offsety,persp-scale-x-to-x,persp-scale-y-to-x,persp-scale-x-to-y,persp-scale-y-to-y,persp-persp-x @@ -170,7 +174,7 @@ multilist=DFFOPT-PROPERTY-NAMES 0x027F=persp-flags # 0x0280-0x02BF: 3d object 0x0280=3dobj-specular-amt,3dobj-diffuse-amt,3dobj-shininess,3dobj-edge-thickness,3dobj-extrude-forward,3dobj-extrude-backward,3dobj-extrude-plane,3dobj-extrusion-color - 0x0288=3dobj-cr-mod,3dobj-extrusion-color-ext,,3dobj-extrusion-color-ext-mod + 0x0288=3dobj-cr-mod,3dobj-extrusion-color-ext,reserved,3dobj-extrusion-color-ext-mod,reserved,reserved 0x02BF=3dobj-flags # 0x02C0-0x02FF: 3d style 0x02C0=3dstyle-y-rotation,3dstyle-x-rotation,3dstyle-rotation-axis-x,3dstyle-rotation-axis-y,3dstyle-rotation-axis-z,3dstyle-rotation,3dstyle-rotation-center-x,3dstyle-rotation-center-y @@ -208,25 +212,29 @@ multilist=DFFOPT-PROPERTY-NAMES 0x0540=lline-color,lline-opacity,lline-back-color,lline-cr-mod,lline-type,lline-fill-blip,lline-fill-blip-name,lline-fill-blip-opt 0x0548=lline-fill-width,lline-fill-height,lline-fill-dz-type,lline-width,lline-miter-limit,lline-style,lline-dash,lline-dash-style 0x0550=lline-start-arrow-head,lline-end-arrow-head,lline-start-arrow-width,lline-start-arrow-length,lline-end-arrow-width,lline-end-arrow-length,lline-join-style,lline-end-cap-style - 0x0558=,lline-color-ext,,lline-color-ext-mod,,lline-back-color-ext,,lline-back-color-ext-mod + 0x0558=,lline-color-ext,reserved,lline-color-ext-mod,reserved,lline-back-color-ext,reserved,lline-back-color-ext-mod + 0x0560=reserved,reserved,reserved 0x057F=lline-flags # 0x0580-0x05BF: top line style 0x0580=tline-color,tline-opacity,tline-back-color,tline-cr-mod,tline-type,tline-fill-blip,tline-fill-blip-name,tline-fill-blip-opt 0x0588=tline-fill-width,tline-fill-height,tline-fill-dz-type,tline-width,tline-miter-limit,tline-style,tline-dash,tline-dash-style 0x0590=tline-start-arrow-head,tline-end-arrow-head,tline-start-arrow-width,tline-start-arrow-length,tline-end-arrow-width,tline-end-arrow-length,tline-join-style,tline-end-cap-style - 0x0598=,tline-color-ext,,tline-color-ext-mod,,tline-back-color-ext,,tline-back-color-ext-mod + 0x0598=,tline-color-ext,reserved,tline-color-ext-mod,reserved,tline-back-color-ext,reserved,tline-back-color-ext-mod + 0x05A0=reserved,reserved,reserved 0x05BF=tline-flags # 0x05C0-0x05FF: right line style 0x05C0=rline-color,rline-opacity,rline-back-color,rline-cr-mod,rline-type,rline-fill-blip,rline-fill-blip-name,rline-fill-blip-opt 0x05C8=rline-fill-width,rline-fill-height,rline-fill-dz-type,rline-width,rline-miter-limit,rline-style,rline-dash,rline-dash-style 0x05D0=rline-start-arrow-head,rline-end-arrow-head,rline-start-arrow-width,rline-start-arrow-length,rline-end-arrow-width,rline-end-arrow-length,rline-join-style,rline-end-cap-style - 0x05D8=,rline-color-ext,,rline-color-ext-mod,,rline-back-color-ext,,rline-back-color-ext-mod + 0x05D8=,rline-color-ext,reserved,rline-color-ext-mod,reserved,rline-back-color-ext,reserved,rline-back-color-ext-mod + 0x05E0=reserved,reserved,reserved 0x05FF=rline-flags # 0x0600-0x063F: bottom line style 0x0600=bline-color,bline-opacity,bline-back-color,bline-cr-mod,bline-type,bline-fill-blip,bline-fill-blip-name,bline-fill-blip-opt 0x0608=bline-fill-width,bline-fill-height,bline-fill-dz-type,bline-width,bline-miter-limit,bline-style,bline-dash,bline-dash-style 0x0610=bline-start-arrow-head,bline-end-arrow-head,bline-start-arrow-width,bline-start-arrow-length,bline-end-arrow-width,bline-end-arrow-length,bline-join-style,bline-end-cap-style - 0x0618=,bline-color-ext,,bline-color-ext-mod,,bline-back-color-ext,,bline-back-color-ext-mod + 0x0618=,bline-color-ext,reserved,bline-color-ext-mod,reserved,bline-back-color-ext,reserved,bline-back-color-ext-mod + 0x0620=reserved,reserved,reserved 0x063F=bline-flags # 0x0680-0x06BF: web component 0x0680=webcomp-html,webcomp-name,webcomp-url @@ -258,7 +266,7 @@ constlist=DFFOPT-SIMPLE-PROPERTIES # fill style 0x0180=uint32,dec,type,DFFOPT-FILL-TYPE 0x0181=uint32,hex,color,DFF-COLOR - 0x0182=int32,fix,opacity,CONV-FLOAT-TO-PERC + 0x0182=int32,fix,opacity,DFF-OPACITY 0x0183=uint32,hex,color,DFF-COLOR 0x0184=int32,fix,opacity,DFF-OPACITY 0x0185=uint32,hex,color,DFF-COLOR @@ -266,22 +274,22 @@ constlist=DFFOPT-SIMPLE-PROPERTIES 0x0188=uint32,dec,blip-opt,DFFOPT-BLIPOPT 0x0189=int32,dec,width 0x018A=int32,dec,height - 0x018B=int32,fix,angle,CONV-DEG + 0x018B=int32,fix,angle,DFF-DEGREES 0x018C=int32,dec,focus,CONV-PERCENT - 0x018D=int32,fix,size,CONV-FLOAT-TO-PERC - 0x018E=int32,fix,size,CONV-FLOAT-TO-PERC - 0x018F=int32,fix,size,CONV-FLOAT-TO-PERC - 0x0190=int32,fix,size,CONV-FLOAT-TO-PERC + 0x018D=int32,fix,size,DFF-OPACITY + 0x018E=int32,fix,size,DFF-OPACITY + 0x018F=int32,fix,size,DFF-OPACITY + 0x0190=int32,fix,size,DFF-OPACITY 0x0191=int32,fix,size,CONV-EMU-TO-CM 0x0192=int32,fix,size,CONV-EMU-TO-CM 0x0193=int32,fix,size,CONV-EMU-TO-CM 0x0194=int32,fix,size,CONV-EMU-TO-CM 0x0195=uint32,dec,type,DFFOPT-FILL-DZTYPE 0x0196=int32,dec,preset - 0x0198=int32,fix,pos,CONV-FLOAT-TO-PERC - 0x0199=int32,fix,pos,CONV-FLOAT-TO-PERC - 0x019A=int32,fix,pos,CONV-FLOAT-TO-PERC - 0x019B=int32,fix,pos,CONV-FLOAT-TO-PERC + 0x0198=int32,fix,pos,DFF-OPACITY + 0x0199=int32,fix,pos,DFF-OPACITY + 0x019A=int32,fix,pos,DFF-OPACITY + 0x019B=int32,fix,pos,DFF-OPACITY 0x019C=uint32,hex,type,DFFOPT-FILL-SHADETYPE 0x019E=uint32,hex,color,DFF-COLOR 0x01A0=uint32,hex,color-mod,DFF-COLORMOD @@ -443,6 +451,7 @@ shortlist=DFFOPT-FILL-DZTYPE-UNIT,0,unused,emu,pixel,shape-size-rel shortlist=DFFOPT-FILL-DZTYPE-ASPECT,0,none,fixed,prefer-largest flagslist=DFFOPT-FILL-SHADETYPE + ignore=0x40000000 0x00000001=none 0x00000002=gamma 0x00000004=sigma-transfer -- cgit From 2b7da24f60f3cf7feafa17562c47760b8f1f44d0 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Thu, 16 Dec 2010 19:00:18 +0100 Subject: dr78: #i109800# SHEET record may not point to BOF but to any record in the sheet substream --- oox/source/dump/biffdumper.cxx | 16 ++++++++++++++++ oox/source/dump/dumperbase.ini | 2 +- oox/source/xls/excelhandlers.cxx | 28 +++++++++------------------- oox/source/xls/workbookfragment.cxx | 19 +++++++++++++++++-- 4 files changed, 43 insertions(+), 22 deletions(-) (limited to 'oox/source') diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index 3d6f20ed62ba..709fa22b41e0 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -2461,6 +2461,12 @@ void WorkbookStreamObject::implDumpRecordBody() dumpDec< sal_Int32 >( "sst-idx" ); break; + case BIFF_ID_MERGEDCELLS: + mxOut->resetItemIndex(); + for( sal_uInt16 nIdx = 0, nCount = dumpDec< sal_uInt16 >( "count" ); !rStrm.isEof() && (nIdx < nCount); ++nIdx ) + dumpRange( "#range" ); + break; + case BIFF_ID_MSODRAWING: case BIFF_ID_MSODRAWINGGROUP: case BIFF_ID_MSODRAWINGSEL: @@ -2560,6 +2566,16 @@ void WorkbookStreamObject::implDumpRecordBody() } break; + case BIFF_ID_PALETTE: + mxOut->resetItemIndex(); + for( sal_uInt16 nIdx = 0, nCount = dumpDec< sal_uInt16 >( "count" ); !rStrm.isEof() && (nIdx < nCount); ++nIdx ) + { + OUStringBuffer aColorName; + StringHelper::appendHex( aColorName, dumpColorABGR( "#color" ) ); + mxColors->setName( nIdx, aColorName.makeStringAndClear() ); + } + break; + case BIFF_ID_PANE: dumpDec< sal_uInt16 >( "x-pos", "CONV-TWIP-TO-CM" ); dumpDec< sal_uInt16 >( "y-pos", "CONV-TWIP-TO-CM" ); diff --git a/oox/source/dump/dumperbase.ini b/oox/source/dump/dumperbase.ini index 34ef302c784c..f9b776c9d99a 100644 --- a/oox/source/dump/dumperbase.ini +++ b/oox/source/dump/dumperbase.ini @@ -35,7 +35,7 @@ show-trailing-unknown=1 # Shows the absolute stream position of records in the record header field # (default=on). # 0=off, 1=on -show-record-position=0 +show-record-position=1 # name lists ================================================================= # diff --git a/oox/source/xls/excelhandlers.cxx b/oox/source/xls/excelhandlers.cxx index aaf551424483..a02009ec1898 100644 --- a/oox/source/xls/excelhandlers.cxx +++ b/oox/source/xls/excelhandlers.cxx @@ -139,29 +139,11 @@ BiffFragmentHandler::BiffFragmentHandler( const BiffFragmentHandler& rHandler ) } BiffFragmentType BiffFragmentHandler::startFragment( BiffType eBiff ) -{ - return mrStrm.startNextRecord() ? implStartFragment( eBiff ) : BIFF_FRAGMENT_UNKNOWN; -} - -BiffFragmentType BiffFragmentHandler::startFragment( BiffType eBiff, sal_Int64 nRecHandle ) -{ - return mrStrm.startRecordByHandle( nRecHandle ) ? implStartFragment( eBiff ) : BIFF_FRAGMENT_UNKNOWN; -} - -bool BiffFragmentHandler::skipFragment() -{ - while( mrStrm.startNextRecord() && (mrStrm.getRecId() != BIFF_ID_EOF) ) - if( isBofRecord() ) - skipFragment(); - return !mrStrm.isEof() && (mrStrm.getRecId() == BIFF_ID_EOF); -} - -BiffFragmentType BiffFragmentHandler::implStartFragment( BiffType eBiff ) { BiffFragmentType eFragment = BIFF_FRAGMENT_UNKNOWN; /* #i23425# Don't rely on BOF record ID to read BOF contents, but on the detected BIFF version. */ - if( isBofRecord() ) + if( mrStrm.startNextRecord() && isBofRecord() ) { // BOF is always written unencrypted mrStrm.enableDecoder( false ); @@ -219,6 +201,14 @@ BiffFragmentType BiffFragmentHandler::implStartFragment( BiffType eBiff ) return eFragment; } +bool BiffFragmentHandler::skipFragment() +{ + while( mrStrm.startNextRecord() && (mrStrm.getRecId() != BIFF_ID_EOF) ) + if( isBofRecord() ) + skipFragment(); + return !mrStrm.isEof() && (mrStrm.getRecId() == BIFF_ID_EOF); +} + // ============================================================================ BiffWorkbookFragmentBase::BiffWorkbookFragmentBase( const WorkbookHelper& rHelper, const OUString& rStrmName, bool bCloneDecoder ) : diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx index 6e43a32495be..fcc9f4972b7d 100644 --- a/oox/source/xls/workbookfragment.cxx +++ b/oox/source/xls/workbookfragment.cxx @@ -379,10 +379,25 @@ bool BiffWorkbookFragment::importFragment() bool bNextSheet = bRet; for( sal_Int32 nWorksheet = 0, nWorksheetCount = rWorksheets.getWorksheetCount(); bNextSheet && (nWorksheet < nWorksheetCount); ++nWorksheet ) { - // try to start a new sheet fragment + // calculate progress size for the sheet double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength ); - BiffFragmentType eSheetFragment = startFragment( getBiff(), rWorksheets.getBiffRecordHandle( nWorksheet ) ); + /* Try to start a new sheet fragment. The SHEET records point to the + first record of the sheet fragment which is usually a BOF record. */ + BiffFragmentType eSheetFragment = BIFF_FRAGMENT_UNKNOWN; + sal_Int64 nRecHandle = rWorksheets.getBiffRecordHandle( nWorksheet ); + if( mrStrm.startRecordByHandle( nRecHandle ) ) + { + /* #i109800# Stream may point to any record of the sheet fragment. + Check the record identifier before calling startFragment(). */ + bool bIsBofRec = isBofRecord(); + /* Rewind the record. If it is the BOF record, it will be read in + startFragment(). In every case, stream will point before the + first available non-BOF record. */ + mrStrm.rewindRecord(); + // if the BOF record is missing, a regular worksheet will be assumed + eSheetFragment = bIsBofRec ? startFragment( getBiff() ) : BIFF_FRAGMENT_WORKSHEET; + } sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet ); bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCalcSheet ); } -- cgit From 70ec19ae3cbf881388c0011e0c4aa132bece311c Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Thu, 16 Dec 2010 19:07:41 +0100 Subject: dr78: corrected color indexes when dumping PALETTE --- oox/source/dump/biffdumper.cxx | 4 ++-- oox/source/dump/dumperbase.ini | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'oox/source') diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index 709fa22b41e0..0cc07eb23d2d 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -2567,12 +2567,12 @@ void WorkbookStreamObject::implDumpRecordBody() break; case BIFF_ID_PALETTE: - mxOut->resetItemIndex(); + mxOut->resetItemIndex( 8 ); for( sal_uInt16 nIdx = 0, nCount = dumpDec< sal_uInt16 >( "count" ); !rStrm.isEof() && (nIdx < nCount); ++nIdx ) { OUStringBuffer aColorName; StringHelper::appendHex( aColorName, dumpColorABGR( "#color" ) ); - mxColors->setName( nIdx, aColorName.makeStringAndClear() ); + mxColors->setName( nIdx + 8, aColorName.makeStringAndClear() ); } break; diff --git a/oox/source/dump/dumperbase.ini b/oox/source/dump/dumperbase.ini index f9b776c9d99a..34ef302c784c 100644 --- a/oox/source/dump/dumperbase.ini +++ b/oox/source/dump/dumperbase.ini @@ -35,7 +35,7 @@ show-trailing-unknown=1 # Shows the absolute stream position of records in the record header field # (default=on). # 0=off, 1=on -show-record-position=1 +show-record-position=0 # name lists ================================================================= # -- cgit From a25f4715687671a2cdeb1c7e07df02e21bd46758 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Fri, 17 Dec 2010 12:09:17 +0100 Subject: dr78: #i71453# BIFF2: use formatting information from cell records if XF records are missing --- oox/source/dump/biffdumper.ini | 2 +- oox/source/xls/sheetdatacontext.cxx | 39 ++++++++++++++++++++++++++++--------- oox/source/xls/stylesbuffer.cxx | 35 +++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 10 deletions(-) (limited to 'oox/source') diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini index 8e1626f82659..18e8cd87e551 100644 --- a/oox/source/dump/biffdumper.ini +++ b/oox/source/dump/biffdumper.ini @@ -2193,7 +2193,7 @@ combilist=XF-FILLCOLOR-BIFF8 0x3F80=uint8,dec,bg-color-idx,COLORS end -# BIFF2 XF index field ------------------------------------------------------- +# BIFF2 cell records ---------------------------------------------------------- constlist=XFINDEX-BIFF2 default= diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx index 05e4c5bfe767..8ce601b0aa8c 100644 --- a/oox/source/xls/sheetdatacontext.cxx +++ b/oox/source/xls/sheetdatacontext.cxx @@ -106,8 +106,9 @@ const sal_uInt32 BIFF_ROW_THICKTOP = 0x10000000; const sal_uInt32 BIFF_ROW_THICKBOTTOM = 0x20000000; const sal_uInt32 BIFF_ROW_SHOWPHONETIC = 0x40000000; -const sal_Int32 BIFF2_XF_EXTENDED_IDS = 63; -const sal_uInt8 BIFF2_XF_MASK = 0x3F; +const sal_uInt8 BIFF2_CELL_LOCKED = 0x40; +const sal_uInt8 BIFF2_CELL_HIDDEN = 0x80; +const sal_Int32 BIFF2_CELL_USEIXFE = 63; // ---------------------------------------------------------------------------- @@ -600,7 +601,6 @@ BiffSheetDataContext::BiffSheetDataContext( const BiffWorksheetFragmentBase& rPa BiffWorksheetContextBase( rParent ), mnBiff2XfId( 0 ) { - mnArrayIgnoreSize = (getBiff() == BIFF2) ? 1 : ((getBiff() <= BIFF4) ? 2 : 6); switch( getBiff() ) { case BIFF2: @@ -718,12 +718,33 @@ void BiffSheetDataContext::importXfId( bool bBiff2 ) { if( bBiff2 ) { - sal_uInt8 nBiff2XfId; - mrStrm >> nBiff2XfId; - mrStrm.skip( 2 ); - maCurrCell.mnXfId = nBiff2XfId & BIFF2_XF_MASK; - if( maCurrCell.mnXfId == BIFF2_XF_EXTENDED_IDS ) - maCurrCell.mnXfId = mnBiff2XfId; + /* #i71453# On first call, check if the file contains XF records (by + trying to access the first XF with index 0). If there are no XFs, + the explicit formatting information contained in each cell record + will be used instead. */ + if( !mobBiff2HasXfs ) + mobBiff2HasXfs = getStyles().getCellXf( 0 ).get() != 0; + // read formatting information (includes the XF identifier) + sal_uInt8 nFlags1, nFlags2, nFlags3; + mrStrm >> nFlags1 >> nFlags2 >> nFlags3; + /* If the file contains XFs, extract and set the XF identifier, + otherwise get the explicit formatting. */ + if( mobBiff2HasXfs.get() ) + { + maCurrCell.mnXfId = extractValue< sal_Int32 >( nFlags1, 0, 6 ); + /* If the identifier is equal to 63, then the real identifier is + contained in the preceding IXFE record (stored in mnBiff2XfId). */ + if( maCurrCell.mnXfId == BIFF2_CELL_USEIXFE ) + maCurrCell.mnXfId = mnBiff2XfId; + } + else + { + /* Let the Xf class do the API conversion. Keeping the member + maCurrCell.mnXfId untouched will prevent to trigger the usual + XF formatting conversion later on. */ + PropertySet aPropSet( maCurrCell.mxCell ); + Xf::writeBiff2CellFormatToPropertySet( *this, aPropSet, nFlags1, nFlags2, nFlags3 ); + } } else { diff --git a/oox/source/xls/stylesbuffer.cxx b/oox/source/xls/stylesbuffer.cxx index 5a149961c0e2..b95ca8984ded 100644 --- a/oox/source/xls/stylesbuffer.cxx +++ b/oox/source/xls/stylesbuffer.cxx @@ -2477,6 +2477,41 @@ void Xf::writeToPropertySet( PropertySet& rPropSet ) const rPropSet.setProperties( aPropMap ); } +/*static*/ void Xf::writeBiff2CellFormatToPropertySet( const WorkbookHelper& rHelper, + PropertySet& rPropSet, sal_uInt8 nFlags1, sal_uInt8 nFlags2, sal_uInt8 nFlags3 ) +{ + /* Create an XF object and let it do the work. We will have access to its + private members here. Also, create temporary border and fill objects, + this prevents polluting the border and fill buffers with new temporary + objects per imported cell. */ + Xf aXf( rHelper ); + Border aBorder( rHelper, false ); + Fill aFill( rHelper, false ); + + // no used flags available in BIFF2 (always true) + aXf.setAllUsedFlags( true ); + + // set the attributes + aXf.maModel.mnFontId = extractValue< sal_Int32 >( nFlags2, 6, 2 ); + aXf.maModel.mnNumFmtId = extractValue< sal_Int32 >( nFlags2, 0, 6 ); + aXf.maAlignment.setBiff2Data( nFlags3 ); + aXf.maProtection.setBiff2Data( nFlags1 ); + aBorder.setBiff2Data( nFlags3 ); + aFill.setBiff2Data( nFlags3 ); + + // finalize the objects (convert model to API attributes) + aXf.finalizeImport(); + aBorder.finalizeImport(); + aFill.finalizeImport(); + + // write the properties to the property set + PropertyMap aPropMap; + aXf.writeToPropertyMap( aPropMap ); + aBorder.writeToPropertyMap( aPropMap ); + aFill.writeToPropertyMap( aPropMap ); + rPropSet.setProperties( aPropMap ); +} + void Xf::setBiffUsedFlags( sal_uInt8 nUsedFlags ) { /* Notes about finding the used flags: -- cgit From e3c7c4fc089ad365b7d9b2d66addc85255df1eeb Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Fri, 17 Dec 2010 12:17:41 +0100 Subject: dr78: #i71453# remove unused flags --- oox/source/xls/sheetdatacontext.cxx | 2 -- 1 file changed, 2 deletions(-) (limited to 'oox/source') diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx index 8ce601b0aa8c..ab041846cd18 100644 --- a/oox/source/xls/sheetdatacontext.cxx +++ b/oox/source/xls/sheetdatacontext.cxx @@ -106,8 +106,6 @@ const sal_uInt32 BIFF_ROW_THICKTOP = 0x10000000; const sal_uInt32 BIFF_ROW_THICKBOTTOM = 0x20000000; const sal_uInt32 BIFF_ROW_SHOWPHONETIC = 0x40000000; -const sal_uInt8 BIFF2_CELL_LOCKED = 0x40; -const sal_uInt8 BIFF2_CELL_HIDDEN = 0x80; const sal_Int32 BIFF2_CELL_USEIXFE = 63; // ---------------------------------------------------------------------------- -- cgit From c15fb91736dfb70247d864267290d0053a05267c Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Tue, 4 Jan 2011 18:51:14 +0100 Subject: dr78: oox - import of BIFF3-BIFF5 drawing objects - first bits --- .../drawingml/chart/chartdrawingfragment.cxx | 55 +- oox/source/drawingml/shape.cxx | 5 +- oox/source/vml/vmlformatting.cxx | 19 +- oox/source/xls/drawingbase.cxx | 327 +++++++ oox/source/xls/drawingfragment.cxx | 362 +------- oox/source/xls/drawingmanager.cxx | 979 +++++++++++++++++++++ oox/source/xls/makefile.mk | 2 + oox/source/xls/worksheetfragment.cxx | 6 + oox/source/xls/worksheethelper.cxx | 146 +-- 9 files changed, 1457 insertions(+), 444 deletions(-) create mode 100755 oox/source/xls/drawingbase.cxx create mode 100755 oox/source/xls/drawingmanager.cxx (limited to 'oox/source') diff --git a/oox/source/drawingml/chart/chartdrawingfragment.cxx b/oox/source/drawingml/chart/chartdrawingfragment.cxx index fcc350b583c3..f4d4ab8daf59 100644 --- a/oox/source/drawingml/chart/chartdrawingfragment.cxx +++ b/oox/source/drawingml/chart/chartdrawingfragment.cxx @@ -83,42 +83,41 @@ void ShapeAnchor::setPos( sal_Int32 nElement, sal_Int32 nParentContext, const OU } } -Rectangle ShapeAnchor::calcEmuLocation( const EmuRectangle& rEmuChartRect ) const +EmuRectangle ShapeAnchor::calcAnchorRectEmu( const EmuRectangle& rChartRect ) const { - Rectangle aLoc( -1, -1, -1, -1 ); + EmuRectangle aAnchorRect( -1, -1, -1, -1 ); - OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcEmuLocation - invalid from position" ); - OSL_ENSURE( mbRelSize ? maTo.isValid() : maSize.isValid(), "ShapeAnchor::calcEmuLocation - invalid to/size" ); + OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid from position" ); + OSL_ENSURE( mbRelSize ? maTo.isValid() : maSize.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid to/size" ); if( maFrom.isValid() && (mbRelSize ? maTo.isValid() : maSize.isValid()) ) { // calculate shape position - aLoc.X = getLimitedValue< sal_Int32, double >( maFrom.mfX * rEmuChartRect.Width, 0, SAL_MAX_INT32 ); - aLoc.Y = getLimitedValue< sal_Int32, double >( maFrom.mfY * rEmuChartRect.Height, 0, SAL_MAX_INT32 ); + aAnchorRect.X = static_cast< sal_Int64 >( maFrom.mfX * rChartRect.Width + 0.5 ); + aAnchorRect.Y = static_cast< sal_Int64 >( maFrom.mfY * rChartRect.Height + 0.5 ); // calculate shape size if( mbRelSize ) { - aLoc.Width = getLimitedValue< sal_Int32, double >( maTo.mfX * rEmuChartRect.Width, 0, SAL_MAX_INT32 ) - aLoc.X; - if( aLoc.Width < 0 ) + aAnchorRect.Width = static_cast< sal_Int64 >( maTo.mfX * rChartRect.Width + 0.5 ) - aAnchorRect.X; + if( aAnchorRect.Width < 0 ) { - aLoc.X += aLoc.Width; - aLoc.Width *= -1; + aAnchorRect.X += aAnchorRect.Width; + aAnchorRect.Width *= -1; } - aLoc.Height = getLimitedValue< sal_Int32, double >( maTo.mfY * rEmuChartRect.Height, 0, SAL_MAX_INT32 ) - aLoc.Y; - if( aLoc.Height < 0 ) + aAnchorRect.Height = static_cast< sal_Int64 >( maTo.mfY * rChartRect.Height + 0.5 ) - aAnchorRect.Y; + if( aAnchorRect.Height < 0 ) { - aLoc.Y += aLoc.Height; - aLoc.Height *= -1; + aAnchorRect.Y += aAnchorRect.Height; + aAnchorRect.Height *= -1; } } else { - aLoc.Width = getLimitedValue< sal_Int32, sal_Int64 >( maSize.Width, 0, SAL_MAX_INT32 ); - aLoc.Height = getLimitedValue< sal_Int32, sal_Int64 >( maSize.Height, 0, SAL_MAX_INT32 ); + aAnchorRect.setSize( maSize ); } } - return aLoc; + return aAnchorRect; } // ============================================================================ @@ -129,10 +128,10 @@ ChartDrawingFragment::ChartDrawingFragment( XmlFilterBase& rFilter, mxDrawPage( rxDrawPage ), mbOleSupport( bOleSupport ) { - maEmuChartRect.X = static_cast< sal_Int64 >( rShapesOffset.X ) * 360; - maEmuChartRect.Y = static_cast< sal_Int64 >( rShapesOffset.Y ) * 360; - maEmuChartRect.Width = static_cast< sal_Int64 >( rChartSize.Width ) * 360; - maEmuChartRect.Height = static_cast< sal_Int64 >( rChartSize.Height ) * 360; + maChartRectEmu.X = convertHmmToEmu( rShapesOffset.X ); + maChartRectEmu.Y = convertHmmToEmu( rShapesOffset.Y ); + maChartRectEmu.Width = convertHmmToEmu( rChartSize.Width ); + maChartRectEmu.Height = convertHmmToEmu( rChartSize.Height ); } ChartDrawingFragment::~ChartDrawingFragment() @@ -217,9 +216,17 @@ void ChartDrawingFragment::onEndElement( const OUString& rChars ) case CDR_TOKEN( relSizeAnchor ): if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() ) { - Rectangle aLoc = mxAnchor->calcEmuLocation( maEmuChartRect ); - if( (aLoc.X >= 0) && (aLoc.Y >= 0) && (aLoc.Width >= 0) && (aLoc.Height >= 0) ) - mxShape->addShape( getFilter(), getFilter().getCurrentTheme(), mxDrawPage, &aLoc ); + EmuRectangle aShapeRectEmu = mxAnchor->calcAnchorRectEmu( maChartRectEmu ); + if( (aShapeRectEmu.X >= 0) && (aShapeRectEmu.Y >= 0) && (aShapeRectEmu.Width >= 0) && (aShapeRectEmu.Height >= 0) ) + { + // TODO: DrawingML implementation expects 32-bit coordinates for EMU rectangles (change that to EmuRectangle) + Rectangle aShapeRectEmu32( + getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.X, 0, SAL_MAX_INT32 ), + getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Y, 0, SAL_MAX_INT32 ), + getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Width, 0, SAL_MAX_INT32 ), + getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Height, 0, SAL_MAX_INT32 ) ); + mxShape->addShape( getFilter(), getFilter().getCurrentTheme(), mxDrawPage, &aShapeRectEmu32 ); + } } mxShape.reset(); mxAnchor.reset(); diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index f0ae2ec2a7a3..4d15886a641a 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -259,7 +259,10 @@ Reference< XShape > Shape::createAndInsert( OUString aServiceName = rServiceName; if( mxCreateCallback.get() ) - aServiceName = mxCreateCallback->onCreateXShape( aServiceName, awt::Rectangle( aPosition.X / 360, aPosition.Y / 360, aSize.Width / 360, aSize.Height / 360 ) ); + { + awt::Rectangle aShapeRectHmm( convertEmuToHmm( aPosition.X ), convertEmuToHmm( aPosition.Y ), convertEmuToHmm( aSize.Width ), convertEmuToHmm( aSize.Height ) ); + aServiceName = mxCreateCallback->onCreateXShape( aServiceName, aShapeRectHmm ); + } sal_Bool bIsCustomShape = aServiceName == OUString::createFromAscii( "com.sun.star.drawing.CustomShape" ); basegfx::B2DHomMatrix aTransformation; diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx index 827930c22496..9ee8a4ec3215 100644 --- a/oox/source/vml/vmlformatting.cxx +++ b/oox/source/vml/vmlformatting.cxx @@ -105,7 +105,7 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r return fDefValue; } -/*static*/ sal_Int32 ConversionHelper::decodeMeasureToEmu( const GraphicHelper& rGraphicHelper, +/*static*/ sal_Int64 ConversionHelper::decodeMeasureToEmu( const GraphicHelper& rGraphicHelper, const OUString& rValue, sal_Int32 nRefValue, bool bPixelX, bool bDefaultAsPixel ) { // default for missing values is 0 @@ -148,10 +148,11 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r fValue *= 12700.0; else if( (cChar1 == 'p') && (cChar2 == 'c') ) // 1 pica = 1/6 inch = 152,400 EMU fValue *= 152400.0; - else if( (cChar1 == 'p') && (cChar2 == 'x') ) // 1 pixel, dependent on output device, factor 360 to convert 1/100mm to EMU - fValue = bPixelX ? - rGraphicHelper.convertScreenPixelXToHmm( 360.0 * fValue ) : - rGraphicHelper.convertScreenPixelYToHmm( 360.0 * fValue ); + else if( (cChar1 == 'p') && (cChar2 == 'x') ) // 1 pixel, dependent on output device + fValue = static_cast< double >( ::oox::drawingml::convertHmmToEmu( + bPixelX ? + rGraphicHelper.convertScreenPixelXToHmm( fValue ) : + rGraphicHelper.convertScreenPixelYToHmm( fValue ) ) ); } else if( (aUnit.getLength() == 1) && (aUnit[ 0 ] == '%') ) { @@ -162,13 +163,13 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r OSL_ENSURE( false, "ConversionHelper::decodeMeasureToEmu - unknown measure unit" ); fValue = nRefValue; } - return static_cast< sal_Int32 >( fValue + 0.5 ); + return static_cast< sal_Int64 >( fValue + 0.5 ); } /*static*/ sal_Int32 ConversionHelper::decodeMeasureToHmm( const GraphicHelper& rGraphicHelper, const OUString& rValue, sal_Int32 nRefValue, bool bPixelX, bool bDefaultAsPixel ) { - return (decodeMeasureToEmu( rGraphicHelper, rValue, nRefValue, bPixelX, bDefaultAsPixel ) + 180) / 360; + return ::oox::drawingml::convertEmuToHmm( decodeMeasureToEmu( rGraphicHelper, rValue, nRefValue, bPixelX, bDefaultAsPixel ) ); } // ============================================================================ @@ -285,7 +286,7 @@ void lclGetColor( Color& orDmlColor, const GraphicHelper& rGraphicHelper, orDmlColor.setSrgbClr( nDefaultRgb ); } -sal_Int32 lclGetEmu( const GraphicHelper& rGraphicHelper, const OptValue< OUString >& roValue, sal_Int32 nDefValue ) +sal_Int64 lclGetEmu( const GraphicHelper& rGraphicHelper, const OptValue< OUString >& roValue, sal_Int64 nDefValue ) { return roValue.has() ? ConversionHelper::decodeMeasureToEmu( rGraphicHelper, roValue.get(), 0, false, false ) : nDefValue; } @@ -442,7 +443,7 @@ void StrokeModel::pushToPropMap( PropertyMap& rPropMap, lclConvertArrow( aLineProps.maStartArrow, maStartArrow ); lclConvertArrow( aLineProps.maEndArrow, maEndArrow ); lclGetColor( aLineProps.maLineFill.maFillColor, rGraphicHelper, moColor, moOpacity, API_RGB_BLACK ); - aLineProps.moLineWidth = lclGetEmu( rGraphicHelper, moWeight, 1 ); + aLineProps.moLineWidth = getLimitedValue< sal_Int32, sal_Int64 >( lclGetEmu( rGraphicHelper, moWeight, 1 ), 0, SAL_MAX_INT32 ); lclGetDmlLineDash( aLineProps.moPresetDash, aLineProps.maCustomDash, moDashStyle ); aLineProps.moLineCompound = lclGetDmlLineCompound( moLineStyle ); aLineProps.moLineCap = lclGetDmlLineCap( moEndCap ); diff --git a/oox/source/xls/drawingbase.cxx b/oox/source/xls/drawingbase.cxx new file mode 100755 index 000000000000..c7a901ead30a --- /dev/null +++ b/oox/source/xls/drawingbase.cxx @@ -0,0 +1,327 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/xls/drawingbase.hxx" + +#include +#include "oox/core/namespaces.hxx" +#include "oox/helper/attributelist.hxx" +#include "oox/helper/binaryinputstream.hxx" +#include "oox/xls/unitconverter.hxx" + +namespace oox { +namespace xls { + +// ============================================================================ + +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::table; +using namespace ::oox::drawingml; + +using ::rtl::OUString; + +// ============================================================================ + +namespace { + +/** Converts the passed 32-bit integer value from 1/100 mm to EMUs. */ +inline sal_Int64 lclHmmToEmu( sal_Int32 nValue ) +{ + return (nValue < 0) ? -1 : convertHmmToEmu( nValue ); +} + +/** Converts the passed 64-bit integer value from EMUs to 1/100 mm. */ +inline sal_Int32 lclEmuToHmm( sal_Int64 nValue ) +{ + return (nValue < 0) ? -1 : convertEmuToHmm( nValue ); +} + +/** Reads the cell anchor model from a BIFF or DFF stream. */ +BinaryInputStream& operator>>( BinaryInputStream& rStrm, CellAnchorModel& rModel ) +{ + // all members are given as 16-bit unsigned values + rModel.mnCol = rStrm.readuInt16(); + rModel.mnColOffset = rStrm.readuInt16(); + rModel.mnRow = rStrm.readuInt16(); + rModel.mnRowOffset = rStrm.readuInt16(); + return rStrm; +} + +} // namespace + +// ============================================================================ + +CellAnchorModel::CellAnchorModel() : + mnCol( -1 ), + mnRow( -1 ), + mnColOffset( 0 ), + mnRowOffset( 0 ) +{ +} + +// ---------------------------------------------------------------------------- + +AnchorClientDataModel::AnchorClientDataModel() : + mbLocksWithSheet( true ), + mbPrintsWithSheet( true ) +{ +} + +// ============================================================================ + +ShapeAnchor::ShapeAnchor( const WorksheetHelper& rHelper ) : + WorksheetHelper( rHelper ), + meAnchorType( ANCHOR_INVALID ), + meCellAnchorType( CELLANCHOR_EMU ), + mnEditAs( XML_twoCell ) +{ +} + +void ShapeAnchor::importAnchor( sal_Int32 nElement, const AttributeList& rAttribs ) +{ + switch( nElement ) + { + case XDR_TOKEN( absoluteAnchor ): + meAnchorType = ANCHOR_ABSOLUTE; + break; + case XDR_TOKEN( oneCellAnchor ): + meAnchorType = ANCHOR_ONECELL; + break; + case XDR_TOKEN( twoCellAnchor ): + meAnchorType = ANCHOR_TWOCELL; + mnEditAs = rAttribs.getToken( XML_editAs, XML_twoCell ); + break; + default: + OSL_ENSURE( false, "ShapeAnchor::importAnchor - unexpected element" ); + } + meCellAnchorType = CELLANCHOR_EMU; +} + +void ShapeAnchor::importPos( const AttributeList& rAttribs ) +{ + OSL_ENSURE( meAnchorType == ANCHOR_ABSOLUTE, "ShapeAnchor::importPos - unexpected 'xdr:pos' element" ); + maPos.X = rAttribs.getHyper( XML_x, 0 ); + maPos.Y = rAttribs.getHyper( XML_y, 0 ); +} + +void ShapeAnchor::importExt( const AttributeList& rAttribs ) +{ + OSL_ENSURE( (meAnchorType == ANCHOR_ABSOLUTE) || (meAnchorType == ANCHOR_ONECELL), "ShapeAnchor::importExt - unexpected 'xdr:ext' element" ); + maSize.Width = rAttribs.getHyper( XML_cx, 0 ); + maSize.Height = rAttribs.getHyper( XML_cy, 0 ); +} + +void ShapeAnchor::importClientData( const AttributeList& rAttribs ) +{ + maClientData.mbLocksWithSheet = rAttribs.getBool( XML_fLocksWithSheet, true ); + maClientData.mbPrintsWithSheet = rAttribs.getBool( XML_fPrintsWithSheet, true ); +} + +void ShapeAnchor::setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue ) +{ + CellAnchorModel* pCellAnchor = 0; + switch( nParentContext ) + { + case XDR_TOKEN( from ): + OSL_ENSURE( (meAnchorType == ANCHOR_ONECELL) || (meAnchorType == ANCHOR_TWOCELL), "ShapeAnchor::setCellPos - unexpected 'xdr:from' element" ); + pCellAnchor = &maFrom; + break; + case XDR_TOKEN( to ): + OSL_ENSURE( meAnchorType == ANCHOR_TWOCELL, "ShapeAnchor::setCellPos - unexpected 'xdr:to' element" ); + pCellAnchor = &maTo; + break; + default: + OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected parent element" ); + } + if( pCellAnchor ) switch( nElement ) + { + case XDR_TOKEN( col ): pCellAnchor->mnCol = rValue.toInt32(); break; + case XDR_TOKEN( row ): pCellAnchor->mnRow = rValue.toInt32(); break; + case XDR_TOKEN( colOff ): pCellAnchor->mnColOffset = rValue.toInt64(); break; + case XDR_TOKEN( rowOff ): pCellAnchor->mnRowOffset = rValue.toInt64(); break; + default: OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected element" ); + } +} + +void ShapeAnchor::importVmlAnchor( const OUString& rAnchor ) +{ + meAnchorType = ANCHOR_TWOCELL; /// VML uses two-cell anchors only + meCellAnchorType = CELLANCHOR_PIXEL; /// VML uses screen pixels for offset values + + ::std::vector< OUString > aTokens; + sal_Int32 nIndex = 0; + while( nIndex >= 0 ) + aTokens.push_back( rAnchor.getToken( 0, ',', nIndex ).trim() ); + + OSL_ENSURE( aTokens.size() >= 8, "ShapeAnchor::importVmlAnchor - missing anchor tokens" ); + if( aTokens.size() >= 8 ) + { + maFrom.mnCol = aTokens[ 0 ].toInt32(); + maFrom.mnColOffset = aTokens[ 1 ].toInt32(); + maFrom.mnRow = aTokens[ 2 ].toInt32(); + maFrom.mnRowOffset = aTokens[ 3 ].toInt32(); + maTo.mnCol = aTokens[ 4 ].toInt32(); + maTo.mnColOffset = aTokens[ 5 ].toInt32(); + maTo.mnRow = aTokens[ 6 ].toInt32(); + maTo.mnRowOffset = aTokens[ 7 ].toInt32(); + } +} + +void ShapeAnchor::importBiffAnchor( BinaryInputStream& rStrm ) +{ + meAnchorType = ANCHOR_TWOCELL; /// BIFF/DFF use two-cell anchors only + meCellAnchorType = CELLANCHOR_COLROW; /// BIFF/DFF use fraction of column/row for offset values + rStrm >> maFrom >> maTo; +} + +EmuRectangle ShapeAnchor::calcAnchorRectEmu( const Size& rPageSizeHmm ) const +{ + AddressConverter& rAddrConv = getAddressConverter(); + const UnitConverter& rUnitConv = getUnitConverter(); + + EmuSize aPageSize( lclHmmToEmu( rPageSizeHmm.Width ), lclHmmToEmu( rPageSizeHmm.Height ) ); + EmuRectangle aAnchorRect( -1, -1, -1, -1 ); + + // calculate shape position + switch( meAnchorType ) + { + case ANCHOR_ABSOLUTE: + OSL_ENSURE( maPos.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid position" ); + if( maPos.isValid() && (maPos.X < aPageSize.Width) && (maPos.Y < aPageSize.Height) ) + aAnchorRect.setPos( maPos ); + break; + case ANCHOR_ONECELL: + case ANCHOR_TWOCELL: + OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid position" ); + if( maFrom.isValid() && rAddrConv.checkCol( maFrom.mnCol, true ) && rAddrConv.checkRow( maFrom.mnRow, true ) ) + { + EmuPoint aPoint = calcCellAnchorEmu( maFrom ); + if( (aPoint.X < aPageSize.Width) && (aPoint.Y < aPageSize.Height) ) + aAnchorRect.setPos( aPoint ); + } + break; + case ANCHOR_INVALID: + OSL_ENSURE( false, "ShapeAnchor::calcAnchorRectEmu - invalid anchor" ); + break; + } + + // calculate shape size + if( (aAnchorRect.X >= 0) && (aAnchorRect.Y >= 0) ) switch( meAnchorType ) + { + case ANCHOR_ABSOLUTE: + case ANCHOR_ONECELL: + OSL_ENSURE( maSize.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid size" ); + if( maSize.isValid() ) + { + aAnchorRect.Width = ::std::min< sal_Int64 >( maSize.Width, aPageSize.Width - aAnchorRect.X ); + aAnchorRect.Height = ::std::min< sal_Int64 >( maSize.Height, aPageSize.Height - aAnchorRect.Y ); + } + break; + case ANCHOR_TWOCELL: + OSL_ENSURE( maTo.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid position" ); + if( maTo.isValid() ) + { + /* Pass a valid cell address to calcCellAnchorEmu(), otherwise + nothing useful is returned, even if either row or column is valid. */ + CellAddress aToCell = rAddrConv.createValidCellAddress( BinAddress( maTo.mnCol, maTo.mnRow ), getSheetIndex(), true ); + CellAnchorModel aValidTo = maTo; + aValidTo.mnCol = aToCell.Column; + aValidTo.mnRow = aToCell.Row; + EmuPoint aPoint = calcCellAnchorEmu( aValidTo ); + // width (if column index is valid, use the calculated offset, otherwise stretch to maximum available X position) + aAnchorRect.Width = aPageSize.Width - aAnchorRect.X; + if( aToCell.Column == maTo.mnCol ) + aAnchorRect.Width = ::std::min< sal_Int64 >( aPoint.X - aAnchorRect.X + 1, aAnchorRect.Width ); + // height (if row index is valid, use the calculated offset, otherwise stretch to maximum available Y position) + aAnchorRect.Height = aPageSize.Height - aAnchorRect.Y; + if( aToCell.Row == maTo.mnRow ) + aAnchorRect.Height = ::std::min< sal_Int64 >( aPoint.Y - aAnchorRect.Y + 1, aAnchorRect.Height ); + } + break; + case ANCHOR_INVALID: + break; + } + + // add 0.75 mm (27,000 EMUs) in X direction to correct display error + if( aAnchorRect.X >= 0 ) + aAnchorRect.X += 27000; + // remove 0.25 mm (9,000 EMUs) in Y direction to correct display error + if( aAnchorRect.Y >= 9000 ) + aAnchorRect.Y -= 9000; + + return aAnchorRect; +} + +Rectangle ShapeAnchor::calcAnchorRectHmm( const Size& rPageSizeHmm ) const +{ + EmuRectangle aAnchorRect = calcAnchorRectEmu( rPageSizeHmm ); + return Rectangle( lclEmuToHmm( aAnchorRect.X ), lclEmuToHmm( aAnchorRect.Y ), lclEmuToHmm( aAnchorRect.Width ), lclEmuToHmm( aAnchorRect.Height ) ); +} + +// private -------------------------------------------------------------------- + +EmuPoint ShapeAnchor::calcCellAnchorEmu( const CellAnchorModel& rModel ) const +{ + // calculate position of top-left edge of the cell + Point aPoint = getCellPosition( rModel.mnCol, rModel.mnRow ); + EmuPoint aEmuPoint( lclHmmToEmu( aPoint.X ), lclHmmToEmu( aPoint.Y ) ); + + // add the offset inside the cell + switch( meCellAnchorType ) + { + case CELLANCHOR_EMU: + aEmuPoint.X += rModel.mnColOffset; + aEmuPoint.Y += rModel.mnRowOffset; + break; + + case CELLANCHOR_PIXEL: + { + const UnitConverter& rUnitConv = getUnitConverter(); + aEmuPoint.X += static_cast< sal_Int64 >( rUnitConv.scaleValue( static_cast< double >( rModel.mnColOffset ), UNIT_SCREENX, UNIT_EMU ) ); + aEmuPoint.Y += static_cast< sal_Int64 >( rUnitConv.scaleValue( static_cast< double >( rModel.mnRowOffset ), UNIT_SCREENY, UNIT_EMU ) ); + } + break; + + case CELLANCHOR_COLROW: + { + Size aCellSize = getCellSize( rModel.mnCol, rModel.mnRow ); + EmuSize aEmuSize( lclHmmToEmu( aCellSize.Width ), lclHmmToEmu( aCellSize.Height ) ); + // X offset is given in 1/1024 of column width + aEmuPoint.X += static_cast< sal_Int64 >( aEmuSize.Width * getLimitedValue< double >( static_cast< double >( rModel.mnColOffset ) / 1024.0, 0.0, 1.0 ) + 0.5 ); + // Y offset is given in 1/256 of row height + aEmuPoint.Y += static_cast< sal_Int64 >( aEmuSize.Height * getLimitedValue< double >( static_cast< double >( rModel.mnRowOffset ) / 256.0, 0.0, 1.0 ) + 0.5 ); + } + break; + } + + return aEmuPoint; +} + +// ============================================================================ + +} // namespace xls +} // namespace oox diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx index 172530692923..45e311aea4a2 100644 --- a/oox/source/xls/drawingfragment.cxx +++ b/oox/source/xls/drawingfragment.cxx @@ -67,6 +67,9 @@ using ::com::sun::star::table::CellAddress; using ::com::sun::star::table::CellRangeAddress; using ::oox::core::ContextHandlerRef; using ::oox::drawingml::ConnectorShapeContext; +using ::oox::drawingml::EmuPoint; +using ::oox::drawingml::EmuRectangle; +using ::oox::drawingml::EmuSize; using ::oox::drawingml::GraphicalObjectFrameContext; using ::oox::drawingml::GraphicShapeContext; using ::oox::drawingml::Shape; @@ -80,352 +83,11 @@ namespace xls { // ============================================================================ -namespace { - -/** Converts the passed 64-bit integer value from the passed unit to EMUs. */ -sal_Int64 lclCalcEmu( const UnitConverter& rUnitConv, sal_Int64 nValue, Unit eFromUnit ) -{ - return (eFromUnit == UNIT_EMU) ? nValue : - static_cast< sal_Int64 >( rUnitConv.scaleValue( static_cast< double >( nValue ), eFromUnit, UNIT_EMU ) + 0.5 ); -} - -} // namespace - -// ============================================================================ - -AnchorCellModel::AnchorCellModel() : - mnCol( -1 ), - mnRow( -1 ), - mnColOffset( 0 ), - mnRowOffset( 0 ) -{ -} - -// ---------------------------------------------------------------------------- - -AnchorClientDataModel::AnchorClientDataModel() : - mbLocksWithSheet( true ), - mbPrintsWithSheet( true ) -{ -} - -// ============================================================================ - -ShapeAnchor::ShapeAnchor( const WorksheetHelper& rHelper ) : - WorksheetHelper( rHelper ), - meType( ANCHOR_INVALID ), - mnEditAs( XML_twoCell ) -{ -} - -void ShapeAnchor::importAnchor( sal_Int32 nElement, const AttributeList& rAttribs ) -{ - switch( nElement ) - { - case XDR_TOKEN( absoluteAnchor ): - meType = ANCHOR_ABSOLUTE; - break; - case XDR_TOKEN( oneCellAnchor ): - meType = ANCHOR_ONECELL; - break; - case XDR_TOKEN( twoCellAnchor ): - meType = ANCHOR_TWOCELL; - mnEditAs = rAttribs.getToken( XML_editAs, XML_twoCell ); - break; - default: - OSL_ENSURE( false, "ShapeAnchor::importAnchor - unexpected element" ); - } -} - -void ShapeAnchor::importPos( const AttributeList& rAttribs ) -{ - OSL_ENSURE( meType == ANCHOR_ABSOLUTE, "ShapeAnchor::importPos - unexpected 'xdr:pos' element" ); - maPos.X = rAttribs.getHyper( XML_x, 0 ); - maPos.Y = rAttribs.getHyper( XML_y, 0 ); -} - -void ShapeAnchor::importExt( const AttributeList& rAttribs ) -{ - OSL_ENSURE( (meType == ANCHOR_ABSOLUTE) || (meType == ANCHOR_ONECELL), "ShapeAnchor::importExt - unexpected 'xdr:ext' element" ); - maSize.Width = rAttribs.getHyper( XML_cx, 0 ); - maSize.Height = rAttribs.getHyper( XML_cy, 0 ); -} - -void ShapeAnchor::importClientData( const AttributeList& rAttribs ) -{ - maClientData.mbLocksWithSheet = rAttribs.getBool( XML_fLocksWithSheet, true ); - maClientData.mbPrintsWithSheet = rAttribs.getBool( XML_fPrintsWithSheet, true ); -} - -void ShapeAnchor::setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue ) -{ - AnchorCellModel* pAnchorCell = 0; - switch( nParentContext ) - { - case XDR_TOKEN( from ): - OSL_ENSURE( (meType == ANCHOR_ONECELL) || (meType == ANCHOR_TWOCELL), "ShapeAnchor::setCellPos - unexpected 'xdr:from' element" ); - pAnchorCell = &maFrom; - break; - case XDR_TOKEN( to ): - OSL_ENSURE( meType == ANCHOR_TWOCELL, "ShapeAnchor::setCellPos - unexpected 'xdr:to' element" ); - pAnchorCell = &maTo; - break; - default: - OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected parent element" ); - } - if( pAnchorCell ) switch( nElement ) - { - case XDR_TOKEN( col ): pAnchorCell->mnCol = rValue.toInt32(); break; - case XDR_TOKEN( row ): pAnchorCell->mnRow = rValue.toInt32(); break; - case XDR_TOKEN( colOff ): pAnchorCell->mnColOffset = rValue.toInt64(); break; - case XDR_TOKEN( rowOff ): pAnchorCell->mnRowOffset = rValue.toInt64(); break; - default: OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected element" ); - } -} - -void ShapeAnchor::importVmlAnchor( const OUString& rAnchor ) -{ - meType = ANCHOR_VML; - - ::std::vector< OUString > aTokens; - sal_Int32 nIndex = 0; - while( nIndex >= 0 ) - aTokens.push_back( rAnchor.getToken( 0, ',', nIndex ).trim() ); - - OSL_ENSURE( aTokens.size() >= 8, "ShapeAnchor::importVmlAnchor - missing anchor tokens" ); - if( aTokens.size() >= 8 ) - { - maFrom.mnCol = aTokens[ 0 ].toInt32(); - maFrom.mnColOffset = aTokens[ 1 ].toInt32(); - maFrom.mnRow = aTokens[ 2 ].toInt32(); - maFrom.mnRowOffset = aTokens[ 3 ].toInt32(); - maTo.mnCol = aTokens[ 4 ].toInt32(); - maTo.mnColOffset = aTokens[ 5 ].toInt32(); - maTo.mnRow = aTokens[ 6 ].toInt32(); - maTo.mnRowOffset = aTokens[ 7 ].toInt32(); - } -} - -bool ShapeAnchor::isValidAnchor() const -{ - bool bValid = false; - switch( meType ) - { - case ANCHOR_ABSOLUTE: - OSL_ENSURE( maPos.isValid(), "ShapeAnchor::isValidAnchor - invalid position" ); - OSL_ENSURE( maSize.isValid(), "ShapeAnchor::isValidAnchor - invalid size" ); - bValid = maPos.isValid() && maSize.isValid() && (maSize.Width > 0) && (maSize.Height > 0); - break; - case ANCHOR_ONECELL: - OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::isValidAnchor - invalid from position" ); - OSL_ENSURE( maSize.isValid(), "ShapeAnchor::isValidAnchor - invalid size" ); - bValid = maFrom.isValid() && maSize.isValid() && (maSize.Width > 0) && (maSize.Height > 0); - break; - case ANCHOR_TWOCELL: - case ANCHOR_VML: - OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::isValidAnchor - invalid from position" ); - OSL_ENSURE( maTo.isValid(), "ShapeAnchor::isValidAnchor - invalid to position" ); - bValid = maFrom.isValid() && maTo.isValid() && - ((maFrom.mnCol < maTo.mnCol) || ((maFrom.mnCol == maTo.mnCol) && (maFrom.mnColOffset < maTo.mnColOffset))) && - ((maFrom.mnRow < maTo.mnRow) || ((maFrom.mnRow == maTo.mnRow) && (maFrom.mnRowOffset < maTo.mnRowOffset))); - break; - case ANCHOR_INVALID: - OSL_ENSURE( false, "ShapeAnchor::isValidAnchor - invalid anchor" ); - break; - } - return bValid; -} - -Rectangle ShapeAnchor::calcApiLocation( const Size& rApiSheetSize, const AnchorSizeModel& rEmuSheetSize ) const -{ - AddressConverter& rAddrConv = getAddressConverter(); - UnitConverter& rUnitConv = getUnitConverter(); - Rectangle aApiLoc( -1, -1, -1, -1 ); - Unit eUnitX = (meType == ANCHOR_VML) ? UNIT_SCREENX : UNIT_EMU; - Unit eUnitY = (meType == ANCHOR_VML) ? UNIT_SCREENY : UNIT_EMU; - - // calculate shape position - switch( meType ) - { - case ANCHOR_ABSOLUTE: - OSL_ENSURE( maPos.isValid(), "ShapeAnchor::calcApiLocation - invalid position" ); - if( maPos.isValid() && (maPos.X < rEmuSheetSize.Width) && (maPos.Y < rEmuSheetSize.Height) ) - { - aApiLoc.X = rUnitConv.scaleToMm100( static_cast< double >( maPos.X ), UNIT_EMU ); - aApiLoc.Y = rUnitConv.scaleToMm100( static_cast< double >( maPos.Y ), UNIT_EMU ); - } - break; - case ANCHOR_ONECELL: - case ANCHOR_TWOCELL: - case ANCHOR_VML: - OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcApiLocation - invalid position" ); - if( maFrom.isValid() && rAddrConv.checkCol( maFrom.mnCol, true ) && rAddrConv.checkRow( maFrom.mnRow, true ) ) - { - Point aPoint = getCellPosition( maFrom.mnCol, maFrom.mnRow ); - aApiLoc.X = aPoint.X + rUnitConv.scaleToMm100( static_cast< double >( maFrom.mnColOffset ), eUnitX ); - aApiLoc.Y = aPoint.Y + rUnitConv.scaleToMm100( static_cast< double >( maFrom.mnRowOffset ), eUnitY ); - } - break; - case ANCHOR_INVALID: - OSL_ENSURE( false, "ShapeAnchor::calcApiLocation - invalid anchor" ); - break; - } - - // calculate shape size - if( (aApiLoc.X >= 0) && (aApiLoc.Y >= 0) ) switch( meType ) - { - case ANCHOR_ABSOLUTE: - case ANCHOR_ONECELL: - OSL_ENSURE( maSize.isValid(), "ShapeAnchor::calcApiLocation - invalid size" ); - if( maSize.isValid() ) - { - aApiLoc.Width = ::std::min< sal_Int32 >( - rUnitConv.scaleToMm100( static_cast< double >( maSize.Width ), UNIT_EMU ), - rApiSheetSize.Width - aApiLoc.X ); - aApiLoc.Height = ::std::min< sal_Int32 >( - rUnitConv.scaleToMm100( static_cast< double >( maSize.Height ), UNIT_EMU ), - rApiSheetSize.Height - aApiLoc.Y ); - } - break; - case ANCHOR_TWOCELL: - case ANCHOR_VML: - OSL_ENSURE( maTo.isValid(), "ShapeAnchor::calcApiLocation - invalid position" ); - if( maTo.isValid() ) - { - /* Pass a valid cell address to getCellPosition(), otherwise - nothing is returned, even if either row or column is valid. */ - CellAddress aToCell = rAddrConv.createValidCellAddress( BinAddress( maTo.mnCol, maTo.mnRow ), getSheetIndex(), true ); - Point aPoint = getCellPosition( aToCell.Column, aToCell.Row ); - // width - aApiLoc.Width = rApiSheetSize.Width - aApiLoc.X; - if( aToCell.Column == maTo.mnCol ) - { - aPoint.X += rUnitConv.scaleToMm100( static_cast< double >( maTo.mnColOffset ), eUnitX ); - aApiLoc.Width = ::std::min< sal_Int32 >( aPoint.X - aApiLoc.X + 1, aApiLoc.Width ); - } - // height - aApiLoc.Height = rApiSheetSize.Height - aApiLoc.Y; - if( aToCell.Row == maTo.mnRow ) - { - aPoint.Y += rUnitConv.scaleToMm100( static_cast< double >( maTo.mnRowOffset ), eUnitY ); - aApiLoc.Height = ::std::min< sal_Int32 >( aPoint.Y - aApiLoc.Y + 1, aApiLoc.Height ); - } - } - break; - case ANCHOR_INVALID: - break; - } - - return aApiLoc; -} - -Rectangle ShapeAnchor::calcEmuLocation( const AnchorSizeModel& rEmuSheetSize ) const -{ - AddressConverter& rAddrConv = getAddressConverter(); - UnitConverter& rUnitConv = getUnitConverter(); - - Size aSheetSize( - getLimitedValue< sal_Int32, sal_Int64 >( rEmuSheetSize.Width, 0, SAL_MAX_INT32 ), - getLimitedValue< sal_Int32, sal_Int64 >( rEmuSheetSize.Height, 0, SAL_MAX_INT32 ) ); - Rectangle aLoc( -1, -1, -1, -1 ); - Unit eUnitX = (meType == ANCHOR_VML) ? UNIT_SCREENX : UNIT_EMU; - Unit eUnitY = (meType == ANCHOR_VML) ? UNIT_SCREENY : UNIT_EMU; - - // calculate shape position - switch( meType ) - { - case ANCHOR_ABSOLUTE: - OSL_ENSURE( maPos.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" ); - if( maPos.isValid() && (maPos.X < aSheetSize.Width) && (maPos.Y < aSheetSize.Height) ) - { - aLoc.X = static_cast< sal_Int32 >( maPos.X ); - aLoc.Y = static_cast< sal_Int32 >( maPos.Y ); - } - break; - case ANCHOR_ONECELL: - case ANCHOR_TWOCELL: - case ANCHOR_VML: - OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" ); - if( maFrom.isValid() && rAddrConv.checkCol( maFrom.mnCol, true ) && rAddrConv.checkRow( maFrom.mnRow, true ) ) - { - Point aPoint = getCellPosition( maFrom.mnCol, maFrom.mnRow ); - sal_Int64 nX = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.X, UNIT_EMU ) ) + lclCalcEmu( rUnitConv, maFrom.mnColOffset, eUnitX ); - sal_Int64 nY = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.Y, UNIT_EMU ) ) + lclCalcEmu( rUnitConv, maFrom.mnRowOffset, eUnitY ); - if( (nX < aSheetSize.Width) && (nY < aSheetSize.Height) ) - { - aLoc.X = static_cast< sal_Int32 >( nX ); - aLoc.Y = static_cast< sal_Int32 >( nY ); - } - } - break; - case ANCHOR_INVALID: - OSL_ENSURE( false, "ShapeAnchor::calcEmuLocation - invalid anchor" ); - break; - } - - // calculate shape size - if( (aLoc.X >= 0) && (aLoc.Y >= 0) ) switch( meType ) - { - case ANCHOR_ABSOLUTE: - case ANCHOR_ONECELL: - OSL_ENSURE( maSize.isValid(), "ShapeAnchor::calcEmuLocation - invalid size" ); - if( maSize.isValid() ) - { - aLoc.Width = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( maSize.Width, aSheetSize.Width - aLoc.X ) ); - aLoc.Height = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( maSize.Height, aSheetSize.Height - aLoc.Y ) ); - } - break; - case ANCHOR_TWOCELL: - case ANCHOR_VML: - OSL_ENSURE( maTo.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" ); - if( maTo.isValid() ) - { - /* Pass a valid cell address to getCellPosition(), otherwise - nothing is returned, even if either row or column is valid. */ - CellAddress aToCell = rAddrConv.createValidCellAddress( BinAddress( maTo.mnCol, maTo.mnRow ), getSheetIndex(), true ); - Point aPoint = getCellPosition( aToCell.Column, aToCell.Row ); - sal_Int64 nX = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.X, UNIT_EMU ) ); - sal_Int64 nY = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.Y, UNIT_EMU ) ); - // width - aLoc.Width = aSheetSize.Width - aLoc.X; - if( aToCell.Column == maTo.mnCol ) - { - nX += lclCalcEmu( rUnitConv, maTo.mnColOffset, eUnitX ); - aLoc.Width = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( nX - aLoc.X + 1, aLoc.Width ) ); - } - // height - aLoc.Height = aSheetSize.Height - aLoc.Y; - if( aToCell.Row == maTo.mnRow ) - { - nY += lclCalcEmu( rUnitConv, maTo.mnRowOffset, eUnitY ); - aLoc.Height = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( nY - aLoc.Y + 1, aLoc.Height ) ); - } - } - break; - case ANCHOR_INVALID: - break; - } - - // add 0.75 mm (27,000 EMUs) in X direction to correct display error - if( aLoc.X >= 0 ) - aLoc.X += 27000; - // remove 0.25 mm (9,000 EMUs) in Y direction to correct display error - if( aLoc.Y >= 9000 ) - aLoc.Y -= 9000; - - return aLoc; -} - -// ============================================================================ - OoxDrawingFragment::OoxDrawingFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) : OoxWorksheetFragmentBase( rHelper, rFragmentPath ), mxDrawPage( rHelper.getDrawPage(), UNO_QUERY ) { OSL_ENSURE( mxDrawPage.is(), "OoxDrawingFragment::OoxDrawingFragment - missing drawing page" ); - maApiSheetSize = getDrawPageSize(); - maEmuSheetSize.Width = static_cast< sal_Int64 >( getUnitConverter().scaleFromMm100( maApiSheetSize.Width, UNIT_EMU ) ); - maEmuSheetSize.Height = static_cast< sal_Int64 >( getUnitConverter().scaleFromMm100( maApiSheetSize.Height, UNIT_EMU ) ); } // oox.core.ContextHandler2Helper interface ----------------------------------- @@ -507,14 +169,20 @@ void OoxDrawingFragment::onEndElement( const OUString& rChars ) case XDR_TOKEN( absoluteAnchor ): case XDR_TOKEN( oneCellAnchor ): case XDR_TOKEN( twoCellAnchor ): - if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() && mxAnchor->isValidAnchor() ) + if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() ) { - Rectangle aShapeRect = mxAnchor->calcEmuLocation( maEmuSheetSize ); - if( (aShapeRect.X >= 0) && (aShapeRect.Y >= 0) && (aShapeRect.Width >= 0) && (aShapeRect.Height >= 0) ) + EmuRectangle aShapeRectEmu = mxAnchor->calcAnchorRectEmu( getDrawPageSize() ); + if( (aShapeRectEmu.X >= 0) && (aShapeRectEmu.Y >= 0) && (aShapeRectEmu.Width >= 0) && (aShapeRectEmu.Height >= 0) ) { - mxShape->addShape( getOoxFilter(), &getTheme(), mxDrawPage, &aShapeRect ); + // TODO: DrawingML implementation expects 32-bit coordinates for EMU rectangles (change that to EmuRectangle) + Rectangle aShapeRectEmu32( + getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.X, 0, SAL_MAX_INT32 ), + getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Y, 0, SAL_MAX_INT32 ), + getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Width, 0, SAL_MAX_INT32 ), + getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Height, 0, SAL_MAX_INT32 ) ); + mxShape->addShape( getOoxFilter(), &getTheme(), mxDrawPage, &aShapeRectEmu32 ); // collect all shape positions in the WorksheetHelper base class - extendShapeBoundingBox( aShapeRect ); + extendShapeBoundingBox( aShapeRectEmu32 ); } } mxShape.reset(); @@ -577,7 +245,7 @@ bool VmlDrawing::convertShapeClientAnchor( Rectangle& orShapeRect, const OUStrin return false; ShapeAnchor aAnchor( *this ); aAnchor.importVmlAnchor( rShapeAnchor ); - orShapeRect = aAnchor.calcApiLocation( getDrawPageSize(), AnchorSizeModel() ); + orShapeRect = aAnchor.calcAnchorRectHmm( getDrawPageSize() ); return (orShapeRect.Width >= 0) && (orShapeRect.Height >= 0); } diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx new file mode 100755 index 000000000000..16e5ceddd27d --- /dev/null +++ b/oox/source/xls/drawingmanager.cxx @@ -0,0 +1,979 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/xls/drawingmanager.hxx" + +#include +#include +#include "oox/xls/biffinputstream.hxx" +#include "oox/xls/unitconverter.hxx" + +namespace oox { +namespace xls { + +// ============================================================================ + +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::oox::drawingml; + +using ::rtl::OUString; + +// ============================================================================ + +namespace { + +// OBJ record ----------------------------------------------------------------- + +const sal_uInt16 BIFF_OBJ_INVALID_ID = 0; + +const sal_uInt16 BIFF_OBJTYPE_GROUP = 0; +const sal_uInt16 BIFF_OBJTYPE_LINE = 1; +const sal_uInt16 BIFF_OBJTYPE_RECTANGLE = 2; +const sal_uInt16 BIFF_OBJTYPE_OVAL = 3; +const sal_uInt16 BIFF_OBJTYPE_ARC = 4; +const sal_uInt16 BIFF_OBJTYPE_CHART = 5; +const sal_uInt16 BIFF_OBJTYPE_TEXT = 6; +const sal_uInt16 BIFF_OBJTYPE_BUTTON = 7; +const sal_uInt16 BIFF_OBJTYPE_PICTURE = 8; +const sal_uInt16 BIFF_OBJTYPE_POLYGON = 9; // new in BIFF4 +const sal_uInt16 BIFF_OBJTYPE_CHECKBOX = 11; // new in BIFF5 +const sal_uInt16 BIFF_OBJTYPE_OPTIONBUTTON = 12; +const sal_uInt16 BIFF_OBJTYPE_EDIT = 13; +const sal_uInt16 BIFF_OBJTYPE_LABEL = 14; +const sal_uInt16 BIFF_OBJTYPE_DIALOG = 15; +const sal_uInt16 BIFF_OBJTYPE_SPIN = 16; +const sal_uInt16 BIFF_OBJTYPE_SCROLLBAR = 17; +const sal_uInt16 BIFF_OBJTYPE_LISTBOX = 18; +const sal_uInt16 BIFF_OBJTYPE_GROUPBOX = 19; +const sal_uInt16 BIFF_OBJTYPE_DROPDOWN = 20; +const sal_uInt16 BIFF_OBJTYPE_NOTE = 25; // new in BIFF8 +const sal_uInt16 BIFF_OBJTYPE_DRAWING = 30; +const sal_uInt16 BIFF_OBJTYPE_UNKNOWN = 0xFFFF; // for internal use only + +const sal_uInt16 BIFF_OBJ_HIDDEN = 0x0100; +const sal_uInt16 BIFF_OBJ_VISIBLE = 0x0200; +const sal_uInt16 BIFF_OBJ_PRINTABLE = 0x0400; + +// line formatting ------------------------------------------------------------ + +const sal_uInt8 BIFF_OBJ_LINE_AUTOCOLOR = 64; + +const sal_uInt8 BIFF_OBJ_LINE_SOLID = 0; +const sal_uInt8 BIFF_OBJ_LINE_DASH = 1; +const sal_uInt8 BIFF_OBJ_LINE_DOT = 2; +const sal_uInt8 BIFF_OBJ_LINE_DASHDOT = 3; +const sal_uInt8 BIFF_OBJ_LINE_DASHDOTDOT = 4; +const sal_uInt8 BIFF_OBJ_LINE_MEDTRANS = 5; +const sal_uInt8 BIFF_OBJ_LINE_DARKTRANS = 6; +const sal_uInt8 BIFF_OBJ_LINE_LIGHTTRANS = 7; +const sal_uInt8 BIFF_OBJ_LINE_NONE = 255; + +const sal_uInt8 BIFF_OBJ_LINE_HAIR = 0; +const sal_uInt8 BIFF_OBJ_LINE_THIN = 1; +const sal_uInt8 BIFF_OBJ_LINE_MEDIUM = 2; +const sal_uInt8 BIFF_OBJ_LINE_THICK = 3; + +const sal_uInt8 BIFF_OBJ_LINE_AUTO = 0x01; + +const sal_uInt8 BIFF_OBJ_ARROW_NONE = 0; +const sal_uInt8 BIFF_OBJ_ARROW_OPEN = 1; +const sal_uInt8 BIFF_OBJ_ARROW_FILLED = 2; +const sal_uInt8 BIFF_OBJ_ARROW_OPENBOTH = 3; +const sal_uInt8 BIFF_OBJ_ARROW_FILLEDBOTH = 4; + +const sal_uInt8 BIFF_OBJ_ARROW_NARROW = 0; +const sal_uInt8 BIFF_OBJ_ARROW_MEDIUM = 1; +const sal_uInt8 BIFF_OBJ_ARROW_WIDE = 2; + +const sal_uInt8 BIFF_OBJ_LINE_TL = 0; +const sal_uInt8 BIFF_OBJ_LINE_TR = 1; +const sal_uInt8 BIFF_OBJ_LINE_BR = 2; +const sal_uInt8 BIFF_OBJ_LINE_BL = 3; + +// fill formatting ------------------------------------------------------------ + +const sal_uInt8 BIFF_OBJ_FILL_AUTOCOLOR = 65; + +const sal_uInt8 BIFF_OBJ_PATT_NONE = 0; +const sal_uInt8 BIFF_OBJ_PATT_SOLID = 1; + +const sal_uInt8 BIFF_OBJ_FILL_AUTO = 0x01; + +// text formatting ------------------------------------------------------------ + +const sal_uInt8 BIFF_OBJ_HOR_LEFT = 1; +const sal_uInt8 BIFF_OBJ_HOR_CENTER = 2; +const sal_uInt8 BIFF_OBJ_HOR_RIGHT = 3; +const sal_uInt8 BIFF_OBJ_HOR_JUSTIFY = 4; + +const sal_uInt8 BIFF_OBJ_VER_TOP = 1; +const sal_uInt8 BIFF_OBJ_VER_CENTER = 2; +const sal_uInt8 BIFF_OBJ_VER_BOTTOM = 3; +const sal_uInt8 BIFF_OBJ_VER_JUSTIFY = 4; + +const sal_uInt16 BIFF_OBJ_ORIENT_NONE = 0; +const sal_uInt16 BIFF_OBJ_ORIENT_STACKED = 1; /// Stacked top to bottom. +const sal_uInt16 BIFF_OBJ_ORIENT_90CCW = 2; /// 90 degr. counterclockwise. +const sal_uInt16 BIFF_OBJ_ORIENT_90CW = 3; /// 90 degr. clockwise. + +const sal_uInt16 BIFF_OBJ_TEXT_AUTOSIZE = 0x0080; +const sal_uInt16 BIFF_OBJ_TEXT_LOCKED = 0x0200; + +const sal_Int32 BIFF_OBJ_TEXT_MARGIN = 20000; /// Automatic text margin (EMUs). + +// BIFF8 OBJ sub records ------------------------------------------------------ + +const sal_uInt16 BIFF_OBJCMO_PRINTABLE = 0x0010; /// Object printable. +const sal_uInt16 BIFF_OBJCMO_AUTOLINE = 0x2000; /// Automatic line formatting. +const sal_uInt16 BIFF_OBJCMO_AUTOFILL = 0x4000; /// Automatic fill formatting. + +// ---------------------------------------------------------------------------- + +inline BiffInputStream& operator>>( BiffInputStream& rStrm, ShapeAnchor& rAnchor ) +{ + rAnchor.importBiffAnchor( rStrm ); + return rStrm; +} + +} // namespace + +// ============================================================================ +// Model structures for BIFF OBJ record data +// ============================================================================ + +BiffObjLineModel::BiffObjLineModel() : + mnColorIdx( BIFF_OBJ_LINE_AUTOCOLOR ), + mnStyle( BIFF_OBJ_LINE_SOLID ), + mnWidth( BIFF_OBJ_LINE_HAIR ), + mnAuto( BIFF_OBJ_LINE_AUTO ) +{ +} + +bool BiffObjLineModel::isAuto() const +{ + return getFlag( mnAuto, BIFF_OBJ_LINE_AUTO ); +} + +bool BiffObjLineModel::isVisible() const +{ + return isAuto() || (mnStyle != BIFF_OBJ_LINE_NONE); +} + +BiffInputStream& operator>>( BiffInputStream& rStrm, BiffObjLineModel& rModel ) +{ + return rStrm >> rModel.mnColorIdx >> rModel.mnStyle >> rModel.mnWidth >> rModel.mnAuto; +} + +// ============================================================================ + +BiffObjFillModel::BiffObjFillModel() : + mnBackColorIdx( BIFF_OBJ_LINE_AUTOCOLOR ), + mnPattColorIdx( BIFF_OBJ_FILL_AUTOCOLOR ), + mnPattern( BIFF_OBJ_PATT_SOLID ), + mnAuto( BIFF_OBJ_FILL_AUTO ) +{ +} + +bool BiffObjFillModel::isAuto() const +{ + return getFlag( mnAuto, BIFF_OBJ_FILL_AUTO ); +} + +bool BiffObjFillModel::isFilled() const +{ + return isAuto() || (mnPattern != BIFF_OBJ_PATT_NONE); +} + +BiffInputStream& operator>>( BiffInputStream& rStrm, BiffObjFillModel& rModel ) +{ + return rStrm >> rModel.mnBackColorIdx >> rModel.mnPattColorIdx >> rModel.mnPattern >> rModel.mnAuto; +} + +// ============================================================================ + +BiffObjTextModel::BiffObjTextModel() : + mnTextLen( 0 ), + mnFormatSize( 0 ), + mnLinkSize( 0 ), + mnDefFontId( 0 ), + mnFlags( 0 ), + mnOrientation( BIFF_OBJ_ORIENT_NONE ), + mnButtonFlags( 0 ), + mnShortcut( 0 ), + mnShortcutEA( 0 ) +{ +} + +void BiffObjTextModel::readObj3( BiffInputStream& rStrm ) +{ + rStrm >> mnTextLen; + rStrm.skip( 2 ); + rStrm >> mnFormatSize >> mnDefFontId; + rStrm.skip( 2 ); + rStrm >> mnFlags >> mnOrientation; + rStrm.skip( 8 ); +} + +void BiffObjTextModel::readObj5( BiffInputStream& rStrm ) +{ + rStrm >> mnTextLen; + rStrm.skip( 2 ); + rStrm >> mnFormatSize >> mnDefFontId; + rStrm.skip( 2 ); + rStrm >> mnFlags >> mnOrientation; + rStrm.skip( 2 ); + rStrm >> mnLinkSize; + rStrm.skip( 2 ); + rStrm >> mnButtonFlags >> mnShortcut >> mnShortcutEA; +} + +void BiffObjTextModel::readTxo8( BiffInputStream& rStrm ) +{ + rStrm >> mnFlags >> mnOrientation >> mnButtonFlags >> mnShortcut >> mnShortcutEA >> mnTextLen >> mnFormatSize; +} + +sal_uInt8 BiffObjTextModel::getHorAlign() const +{ + return extractValue< sal_uInt8 >( mnFlags, 1, 3 ); +} + +sal_uInt8 BiffObjTextModel::getVerAlign() const +{ + return extractValue< sal_uInt8 >( mnFlags, 4, 3 ); +} + +// ============================================================================ +// BIFF drawing objects +// ============================================================================ + +BiffDrawingObjectContainer::BiffDrawingObjectContainer() +{ +} + +void BiffDrawingObjectContainer::append( const BiffDrawingObjectRef& rxDrawingObj ) +{ + maObjects.push_back( rxDrawingObj ); +} + +void BiffDrawingObjectContainer::insertGrouped( const BiffDrawingObjectRef& rxDrawingObj ) +{ + if( !maObjects.empty() ) + if( BiffGroupObject* pGroupObj = dynamic_cast< BiffGroupObject* >( maObjects.back().get() ) ) + if( pGroupObj->tryInsert( rxDrawingObj ) ) + return; + maObjects.push_back( rxDrawingObj ); +} + +void BiffDrawingObjectContainer::convertAndInsert( BiffDrawingBase& rDrawing, const Reference< XShapes >& rxShapes, const Rectangle* pParentRect ) const +{ + maObjects.forEachMem( &BiffDrawingObjectBase::convertAndInsert, ::boost::ref( rDrawing ), ::boost::cref( rxShapes ), pParentRect ); +} + +// ============================================================================ + +BiffDrawingObjectBase::BiffDrawingObjectBase( const WorksheetHelper& rHelper ) : + WorksheetHelper( rHelper ), + maAnchor( rHelper ), + mnObjId( BIFF_OBJ_INVALID_ID ), + mnObjType( BIFF_OBJTYPE_UNKNOWN ), + mnDffShapeId( 0 ), + mnDffFlags( 0 ), + mbHasAnchor( false ), + mbHidden( false ), + mbVisible( true ), + mbPrintable( true ), + mbAreaObj( false ), + mbAutoMargin( true ), + mbSimpleMacro( true ), + mbProcessShape( true ), + mbInsertShape( true ), + mbCustomDff( false ) +{ +} + +BiffDrawingObjectBase::~BiffDrawingObjectBase() +{ +} + +/*static*/ BiffDrawingObjectRef BiffDrawingObjectBase::importObjBiff3( const WorksheetHelper& rHelper, BiffInputStream& rStrm ) +{ + BiffDrawingObjectRef xDrawingObj; + + if( rStrm.getRemaining() >= 30 ) + { + sal_uInt16 nObjType; + rStrm.skip( 4 ); + rStrm >> nObjType; + switch( nObjType ) + { + case BIFF_OBJTYPE_GROUP: xDrawingObj.reset( new BiffGroupObject( rHelper ) ); break; + case BIFF_OBJTYPE_LINE: xDrawingObj.reset( new BiffLineObject( rHelper ) ); break; + case BIFF_OBJTYPE_RECTANGLE: xDrawingObj.reset( new BiffRectObject( rHelper ) ); break; + case BIFF_OBJTYPE_OVAL: xDrawingObj.reset( new BiffOvalObject( rHelper ) ); break; +#if 0 + case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new XclImpArcObj( rHelper ) ); break; + case BIFF_OBJTYPE_CHART: xDrawingObj.reset( new XclImpChartObj( rHelper ) ); break; + case BIFF_OBJTYPE_TEXT: xDrawingObj.reset( new XclImpTextObj( rHelper ) ); break; + case BIFF_OBJTYPE_BUTTON: xDrawingObj.reset( new XclImpButtonObj( rHelper ) ); break; + case BIFF_OBJTYPE_PICTURE: xDrawingObj.reset( new XclImpPictureObj( rHelper ) ); break; +#endif + default: + OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff3 - unknown object type" ); + xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) ); + } + } + + xDrawingObj->importObjBiff3( rStrm ); + return xDrawingObj; +} + +/*static*/ BiffDrawingObjectRef BiffDrawingObjectBase::importObjBiff4( const WorksheetHelper& rHelper, BiffInputStream& rStrm ) +{ + BiffDrawingObjectRef xDrawingObj; + + if( rStrm.getRemaining() >= 30 ) + { + sal_uInt16 nObjType; + rStrm.skip( 4 ); + rStrm >> nObjType; + switch( nObjType ) + { + case BIFF_OBJTYPE_GROUP: xDrawingObj.reset( new BiffGroupObject( rHelper ) ); break; + case BIFF_OBJTYPE_LINE: xDrawingObj.reset( new BiffLineObject( rHelper ) ); break; + case BIFF_OBJTYPE_RECTANGLE: xDrawingObj.reset( new BiffRectObject( rHelper ) ); break; + case BIFF_OBJTYPE_OVAL: xDrawingObj.reset( new BiffOvalObject( rHelper ) ); break; +#if 0 + case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new XclImpArcObj( rHelper ) ); break; + case BIFF_OBJTYPE_CHART: xDrawingObj.reset( new XclImpChartObj( rHelper ) ); break; + case BIFF_OBJTYPE_TEXT: xDrawingObj.reset( new XclImpTextObj( rHelper ) ); break; + case BIFF_OBJTYPE_BUTTON: xDrawingObj.reset( new XclImpButtonObj( rHelper ) ); break; + case BIFF_OBJTYPE_PICTURE: xDrawingObj.reset( new XclImpPictureObj( rHelper ) ); break; + case BIFF_OBJTYPE_POLYGON: xDrawingObj.reset( new XclImpPolygonObj( rHelper ) ); break; +#endif + default: + OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff4 - unknown object type" ); + xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) ); + } + } + + xDrawingObj->importObjBiff4( rStrm ); + return xDrawingObj; +} + +/*static*/ BiffDrawingObjectRef BiffDrawingObjectBase::importObjBiff5( const WorksheetHelper& rHelper, BiffInputStream& rStrm ) +{ + BiffDrawingObjectRef xDrawingObj; + + if( rStrm.getRemaining() >= 34 ) + { + sal_uInt16 nObjType; + rStrm.skip( 4 ); + rStrm >> nObjType; + switch( nObjType ) + { + case BIFF_OBJTYPE_GROUP: xDrawingObj.reset( new BiffGroupObject( rHelper ) ); break; + case BIFF_OBJTYPE_LINE: xDrawingObj.reset( new BiffLineObject( rHelper ) ); break; + case BIFF_OBJTYPE_RECTANGLE: xDrawingObj.reset( new BiffRectObject( rHelper ) ); break; + case BIFF_OBJTYPE_OVAL: xDrawingObj.reset( new BiffOvalObject( rHelper ) ); break; +#if 0 + case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new XclImpArcObj( rHelper ) ); break; + case BIFF_OBJTYPE_CHART: xDrawingObj.reset( new XclImpChartObj( rHelper ) ); break; + case BIFF_OBJTYPE_TEXT: xDrawingObj.reset( new XclImpTextObj( rHelper ) ); break; + case BIFF_OBJTYPE_BUTTON: xDrawingObj.reset( new XclImpButtonObj( rHelper ) ); break; + case BIFF_OBJTYPE_PICTURE: xDrawingObj.reset( new XclImpPictureObj( rHelper ) ); break; + case BIFF_OBJTYPE_POLYGON: xDrawingObj.reset( new XclImpPolygonObj( rHelper ) ); break; + case BIFF_OBJTYPE_CHECKBOX: xDrawingObj.reset( new XclImpCheckBoxObj( rHelper ) ); break; + case BIFF_OBJTYPE_OPTIONBUTTON: xDrawingObj.reset( new XclImpOptionButtonObj( rHelper ) ); break; + case BIFF_OBJTYPE_EDIT: xDrawingObj.reset( new XclImpEditObj( rHelper ) ); break; + case BIFF_OBJTYPE_LABEL: xDrawingObj.reset( new XclImpLabelObj( rHelper ) ); break; + case BIFF_OBJTYPE_DIALOG: xDrawingObj.reset( new XclImpDialogObj( rHelper ) ); break; + case BIFF_OBJTYPE_SPIN: xDrawingObj.reset( new XclImpSpinButtonObj( rHelper ) ); break; + case BIFF_OBJTYPE_SCROLLBAR: xDrawingObj.reset( new XclImpScrollBarObj( rHelper ) ); break; + case BIFF_OBJTYPE_LISTBOX: xDrawingObj.reset( new XclImpListBoxObj( rHelper ) ); break; + case BIFF_OBJTYPE_GROUPBOX: xDrawingObj.reset( new XclImpGroupBoxObj( rHelper ) ); break; + case BIFF_OBJTYPE_DROPDOWN: xDrawingObj.reset( new XclImpDropDownObj( rHelper ) ); break; +#endif + default: + OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff5 - unknown object type" ); + xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) ); + } + } + + xDrawingObj->importObjBiff5( rStrm ); + return xDrawingObj; +} + +/*static*/ BiffDrawingObjectRef BiffDrawingObjectBase::importObjBiff8( const WorksheetHelper& rHelper, BiffInputStream& rStrm ) +{ + BiffDrawingObjectRef xDrawingObj; + + if( rStrm.getRemaining() >= 10 ) + { + sal_uInt16 nSubRecId, nSubRecSize, nObjType; + rStrm >> nSubRecId >> nSubRecSize >> nObjType; + OSL_ENSURE( nSubRecId == BIFF_ID_OBJCMO, "BiffDrawingObjectBase::importObjBiff8 - OBJCMO subrecord expected" ); + if( (nSubRecId == BIFF_ID_OBJCMO) && (nSubRecSize >= 6) ) + { + switch( nObjType ) + { +#if 0 + // in BIFF8, all simple objects support text + case BIFF_OBJTYPE_LINE: + case BIFF_OBJTYPE_ARC: + xDrawingObj.reset( new XclImpTextObj( rHelper ) ); + // lines and arcs may be 2-dimensional + xDrawingObj->SetAreaObj( false ); + break; + + // in BIFF8, all simple objects support text + case BIFF_OBJTYPE_RECTANGLE: + case BIFF_OBJTYPE_OVAL: + case BIFF_OBJTYPE_POLYGON: + case BIFF_OBJTYPE_DRAWING: + case BIFF_OBJTYPE_TEXT: + xDrawingObj.reset( new XclImpTextObj( rHelper ) ); + break; +#endif + + case BIFF_OBJTYPE_GROUP: xDrawingObj.reset( new BiffGroupObject( rHelper ) ); break; +#if 0 + case BIFF_OBJTYPE_CHART: xDrawingObj.reset( new XclImpChartObj( rHelper ) ); break; + case BIFF_OBJTYPE_BUTTON: xDrawingObj.reset( new XclImpButtonObj( rHelper ) ); break; + case BIFF_OBJTYPE_PICTURE: xDrawingObj.reset( new XclImpPictureObj( rHelper ) ); break; + case BIFF_OBJTYPE_CHECKBOX: xDrawingObj.reset( new XclImpCheckBoxObj( rHelper ) ); break; + case BIFF_OBJTYPE_OPTIONBUTTON: xDrawingObj.reset( new XclImpOptionButtonObj( rHelper ) ); break; + case BIFF_OBJTYPE_EDIT: xDrawingObj.reset( new XclImpEditObj( rHelper ) ); break; + case BIFF_OBJTYPE_LABEL: xDrawingObj.reset( new XclImpLabelObj( rHelper ) ); break; + case BIFF_OBJTYPE_DIALOG: xDrawingObj.reset( new XclImpDialogObj( rHelper ) ); break; + case BIFF_OBJTYPE_SPIN: xDrawingObj.reset( new XclImpSpinButtonObj( rHelper ) ); break; + case BIFF_OBJTYPE_SCROLLBAR: xDrawingObj.reset( new XclImpScrollBarObj( rHelper ) ); break; + case BIFF_OBJTYPE_LISTBOX: xDrawingObj.reset( new XclImpListBoxObj( rHelper ) ); break; + case BIFF_OBJTYPE_GROUPBOX: xDrawingObj.reset( new XclImpGroupBoxObj( rHelper ) ); break; + case BIFF_OBJTYPE_DROPDOWN: xDrawingObj.reset( new XclImpDropDownObj( rHelper ) ); break; + case BIFF_OBJTYPE_NOTE: xDrawingObj.reset( new XclImpNoteObj( rHelper ) ); break; +#endif + + default: + OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff8 - unknown object type" ); + xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) ); + } + } + } + + xDrawingObj->importObjBiff8( rStrm ); + return xDrawingObj; +} + +Reference< XShape > BiffDrawingObjectBase::convertAndInsert( BiffDrawingBase& rDrawing, + const Reference< XShapes >& rxShapes, const Rectangle* pParentRect ) const +{ + Reference< XShape > xShape; + if( rxShapes.is() && mbProcessShape && !mbHidden ) // TODO: support for hidden objects? + { + // base class 'ShapeAnchor' calculates the shape rectangle in 1/100 mm + Rectangle aShapeRect = maAnchor.calcAnchorRectHmm( getDrawPageSize() ); + + // convert the shape, if the calculated rectangle is not empty + bool bHasWidth = aShapeRect.Width > 0; + bool bHasHeight = aShapeRect.Height > 0; + if( mbAreaObj ? (bHasWidth && bHasHeight) : (bHasWidth || bHasHeight) ) + { + xShape = implConvertAndInsert( rDrawing, rxShapes, aShapeRect ); + /* Notify the drawing that a new shape has been inserted (but not + for children of group shapes). For convenience, pass the + rectangle that contains position and size of the shape. */ + if( !pParentRect && xShape.is() ) + rDrawing.notifyShapeInserted( xShape, aShapeRect ); + } + } + return xShape; +} + +// protected ------------------------------------------------------------------ + +void BiffDrawingObjectBase::readNameBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen ) +{ + maObjName = OUString(); + if( nNameLen > 0 ) + { + // name length field is repeated before the name + maObjName = rStrm.readByteStringUC( false, getTextEncoding() ); + // skip padding byte for word boundaries + rStrm.alignToBlock( 2 ); + } +} + +void BiffDrawingObjectBase::readMacroBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + maMacroName = OUString(); + rStrm.skip( nMacroSize ); + // skip padding byte for word boundaries, not contained in nMacroSize + rStrm.alignToBlock( 2 ); +} + +void BiffDrawingObjectBase::readMacroBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + maMacroName = OUString(); + rStrm.skip( nMacroSize ); +} + +void BiffDrawingObjectBase::readMacroBiff5( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + maMacroName = OUString(); + rStrm.skip( nMacroSize ); +} + +void BiffDrawingObjectBase::readMacroBiff8( BiffInputStream& rStrm ) +{ + maMacroName = OUString(); + if( rStrm.getRemaining() > 6 ) + { + // macro is stored in a tNameXR token containing a link to a defined name + sal_uInt16 nFmlaSize; + rStrm >> nFmlaSize; + rStrm.skip( 4 ); + OSL_ENSURE( nFmlaSize == 7, "BiffDrawingObjectBase::readMacroBiff8 - unexpected formula size" ); + if( nFmlaSize == 7 ) + { + sal_uInt8 nTokenId; + sal_uInt16 nExtLinkId, nExtNameId; + rStrm >> nTokenId >> nExtLinkId >> nExtNameId; +#if 0 + OSL_ENSURE( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ), + "BiffDrawingObjectBase::readMacroBiff8 - tNameXR token expected" ); + if( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) ) + maMacroName = GetLinkManager().GetMacroName( nExtLinkId, nExtNameId ); +#endif + } + } +} + +void BiffDrawingObjectBase::implReadObjBiff3( BiffInputStream& /*rStrm*/, sal_uInt16 /*nMacroSize*/ ) +{ +} + +void BiffDrawingObjectBase::implReadObjBiff4( BiffInputStream& /*rStrm*/, sal_uInt16 /*nMacroSize*/ ) +{ +} + +void BiffDrawingObjectBase::implReadObjBiff5( BiffInputStream& /*rStrm*/, sal_uInt16 /*nNameLen*/, sal_uInt16 /*nMacroSize*/ ) +{ +} + +void BiffDrawingObjectBase::implReadObjBiff8SubRec( BiffInputStream& /*rStrm*/, sal_uInt16 /*nSubRecId*/, sal_uInt16 /*nSubRecSize*/ ) +{ +} + +// private -------------------------------------------------------------------- + +void BiffDrawingObjectBase::importObjBiff3( BiffInputStream& rStrm ) +{ + // back to offset 4 (ignore object count field) + rStrm.seek( 4 ); + + sal_uInt16 nObjFlags, nMacroSize; + rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize; + rStrm.skip( 2 ); + + mbHasAnchor = true; + mbHidden = getFlag( nObjFlags, BIFF_OBJ_HIDDEN ); + mbVisible = getFlag( nObjFlags, BIFF_OBJ_VISIBLE ); + implReadObjBiff3( rStrm, nMacroSize ); +} + +void BiffDrawingObjectBase::importObjBiff4( BiffInputStream& rStrm ) +{ + // back to offset 4 (ignore object count field) + rStrm.seek( 4 ); + + sal_uInt16 nObjFlags, nMacroSize; + rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize; + rStrm.skip( 2 ); + + mbHasAnchor = true; + mbHidden = getFlag( nObjFlags, BIFF_OBJ_HIDDEN ); + mbVisible = getFlag( nObjFlags, BIFF_OBJ_VISIBLE ); + mbPrintable = getFlag( nObjFlags, BIFF_OBJ_PRINTABLE ); + implReadObjBiff4( rStrm, nMacroSize ); +} + +void BiffDrawingObjectBase::importObjBiff5( BiffInputStream& rStrm ) +{ + // back to offset 4 (ignore object count field) + rStrm.seek( 4 ); + + sal_uInt16 nObjFlags, nMacroSize, nNameLen; + rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize; + rStrm.skip( 2 ); + rStrm >> nNameLen; + rStrm.skip( 2 ); + + mbHasAnchor = true; + mbHidden = getFlag( nObjFlags, BIFF_OBJ_HIDDEN ); + mbVisible = getFlag( nObjFlags, BIFF_OBJ_VISIBLE ); + mbPrintable = getFlag( nObjFlags, BIFF_OBJ_PRINTABLE ); + implReadObjBiff5( rStrm, nNameLen, nMacroSize ); +} + +void BiffDrawingObjectBase::importObjBiff8( BiffInputStream& rStrm ) +{ + // back to beginning + rStrm.seekToStart(); + + bool bLoop = true; + while( bLoop && (rStrm.getRemaining() >= 4) ) + { + sal_uInt16 nSubRecId, nSubRecSize; + rStrm >> nSubRecId >> nSubRecSize; + sal_Int64 nStrmPos = rStrm.tell(); + // sometimes the last subrecord has an invalid length (OBJLBSDATA) -> min() + nSubRecSize = static_cast< sal_uInt16 >( ::std::min< sal_Int64 >( nSubRecSize, rStrm.getRemaining() ) ); + + switch( nSubRecId ) + { + case BIFF_ID_OBJCMO: + OSL_ENSURE( rStrm.tell() == 4, "BiffDrawingObjectBase::importObjBiff8 - unexpected OBJCMO subrecord" ); + if( (rStrm.tell() == 4) && (nSubRecSize >= 6) ) + { + sal_uInt16 nObjFlags; + rStrm >> mnObjType >> mnObjId >> nObjFlags; + mbPrintable = getFlag( nObjFlags, BIFF_OBJCMO_PRINTABLE ); + } + break; + case BIFF_ID_OBJMACRO: + readMacroBiff8( rStrm ); + break; + case BIFF_ID_OBJEND: + bLoop = false; + break; + default: + implReadObjBiff8SubRec( rStrm, nSubRecId, nSubRecSize ); + } + + // seek to end of subrecord + rStrm.seek( nStrmPos + nSubRecSize ); + } + + /* Call doReadObj8SubRec() with BIFF_ID_OBJEND for further stream + processing (e.g. charts), even if the OBJEND subrecord is missing. */ + implReadObjBiff8SubRec( rStrm, BIFF_ID_OBJEND, 0 ); + + /* Pictures that Excel reads from BIFF5 and writes to BIFF8 still have the + IMGDATA record following the OBJ record (but they use the image data + stored in DFF). The IMGDATA record may be continued by several CONTINUE + records. But the last CONTINUE record may be in fact an MSODRAWING + record that contains the DFF data of the next drawing object! So we + have to skip just enough CONTINUE records to look at the next + MSODRAWING/CONTINUE record. */ + if( (rStrm.getNextRecId() == BIFF3_ID_IMGDATA) && rStrm.startNextRecord() ) + { + rStrm.skip( 4 ); + sal_Int64 nDataSize = rStrm.readuInt32(); + nDataSize -= rStrm.getRemaining(); + // skip following CONTINUE records until IMGDATA ends + while( (nDataSize > 0) && (rStrm.getNextRecId() == BIFF_ID_CONT) && rStrm.startNextRecord() ) + { + OSL_ENSURE( nDataSize >= rStrm.getRemaining(), "BiffDrawingObjectBase::importObjBiff8 - CONTINUE too long" ); + nDataSize -= ::std::min( rStrm.getRemaining(), nDataSize ); + } + OSL_ENSURE( nDataSize == 0, "BiffDrawingObjectBase::importObjBiff8 - missing CONTINUE records" ); + // next record may be MSODRAWING or CONTINUE or anything else + } +} + +// ============================================================================ + +BiffPlaceholderObject::BiffPlaceholderObject( const WorksheetHelper& rHelper ) : + BiffDrawingObjectBase( rHelper ) +{ + setProcessShape( false ); +} + +Reference< XShape > BiffPlaceholderObject::implConvertAndInsert( BiffDrawingBase& /*rDrawing*/, + const Reference< XShapes >& /*rxShapes*/, const Rectangle& /*rShapeRect*/ ) const +{ + return Reference< XShape >(); +} + +// ============================================================================ + +BiffGroupObject::BiffGroupObject( const WorksheetHelper& rHelper ) : + BiffDrawingObjectBase( rHelper ), + mnFirstUngrouped( BIFF_OBJ_INVALID_ID ) +{ +} + +bool BiffGroupObject::tryInsert( const BiffDrawingObjectRef& rxDrawingObj ) +{ + if( rxDrawingObj->getObjId() == mnFirstUngrouped ) + return false; + // insert into own list or into nested group + maChildren.insertGrouped( rxDrawingObj ); + return true; +} + +void BiffGroupObject::implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + rStrm.skip( 4 ); + rStrm >> mnFirstUngrouped; + rStrm.skip( 16 ); + readMacroBiff3( rStrm, nMacroSize ); +} + +void BiffGroupObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + rStrm.skip( 4 ); + rStrm >> mnFirstUngrouped; + rStrm.skip( 16 ); + readMacroBiff4( rStrm, nMacroSize ); +} + +void BiffGroupObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) +{ + rStrm.skip( 4 ); + rStrm >> mnFirstUngrouped; + rStrm.skip( 16 ); + readNameBiff5( rStrm, nNameLen ); + readMacroBiff5( rStrm, nMacroSize ); +} + +Reference< XShape > BiffGroupObject::implConvertAndInsert( BiffDrawingBase& /*rDrawing*/, + const Reference< XShapes >& /*rxShapes*/, const Rectangle& /*rShapeRect*/ ) const +{ + return Reference< XShape >(); +} + +// ============================================================================ + +BiffLineObject::BiffLineObject( const WorksheetHelper& rHelper ) : + BiffDrawingObjectBase( rHelper ), + mnArrows( 0 ), + mnStartPoint( BIFF_OBJ_LINE_TL ) +{ + setAreaObj( false ); +} + +void BiffLineObject::implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + rStrm >> maLineModel >> mnArrows >> mnStartPoint; + rStrm.skip( 1 ); + readMacroBiff3( rStrm, nMacroSize ); +} + +void BiffLineObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + rStrm >> maLineModel >> mnArrows >> mnStartPoint; + rStrm.skip( 1 ); + readMacroBiff4( rStrm, nMacroSize ); +} + +void BiffLineObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) +{ + rStrm >> maLineModel >> mnArrows >> mnStartPoint; + rStrm.skip( 1 ); + readNameBiff5( rStrm, nNameLen ); + readMacroBiff5( rStrm, nMacroSize ); +} + +Reference< XShape > BiffLineObject::implConvertAndInsert( BiffDrawingBase& rDrawing, + const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +{ + return rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.LineShape" ), rxShapes, rShapeRect ); +} + +// ============================================================================ + +BiffRectObject::BiffRectObject( const WorksheetHelper& rHelper ) : + BiffDrawingObjectBase( rHelper ), + mnFrameFlags( 0 ) +{ + setAreaObj( true ); +} + +void BiffRectObject::readFrameData( BiffInputStream& rStrm ) +{ + rStrm >> maFillModel >> maLineModel >> mnFrameFlags; +} + +void BiffRectObject::implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + readFrameData( rStrm ); + readMacroBiff3( rStrm, nMacroSize ); +} + +void BiffRectObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + readFrameData( rStrm ); + readMacroBiff4( rStrm, nMacroSize ); +} + +void BiffRectObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) +{ + readFrameData( rStrm ); + readNameBiff5( rStrm, nNameLen ); + readMacroBiff5( rStrm, nMacroSize ); +} + +Reference< XShape > BiffRectObject::implConvertAndInsert( BiffDrawingBase& rDrawing, + const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +{ + return rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ), rxShapes, rShapeRect ); +} + +// ============================================================================ + +BiffOvalObject::BiffOvalObject( const WorksheetHelper& rHelper ) : + BiffRectObject( rHelper ) +{ +} + +Reference< XShape > BiffOvalObject::implConvertAndInsert( BiffDrawingBase& rDrawing, + const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +{ + return rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ), rxShapes, rShapeRect ); +} + +// ============================================================================ +// BIFF drawing page +// ============================================================================ + +BiffDrawingBase::BiffDrawingBase( const WorksheetHelper& rHelper, const Reference< XDrawPage >& rxDrawPage ) : + WorksheetHelper( rHelper ), + mxDrawPage( rxDrawPage ) +{ +} + +void BiffDrawingBase::importObj( BiffInputStream& rStrm ) +{ + BiffDrawingObjectRef xDrawingObj; + +#if 0 + /* #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING + records. In this case, the OBJ records are in BIFF5 format. Do a sanity + check here that there is no DFF data loaded before. */ + DBG_ASSERT( maDffStrm.Tell() == 0, "BiffDrawingBase::importObj - unexpected DFF stream data, OBJ will be ignored" ); + if( maDffStrm.Tell() == 0 ) switch( GetBiff() ) +#else + switch( getBiff() ) +#endif + { + case BIFF3: + xDrawingObj = BiffDrawingObjectBase::importObjBiff3( *this, rStrm ); + break; + case BIFF4: + xDrawingObj = BiffDrawingObjectBase::importObjBiff4( *this, rStrm ); + break; + case BIFF5: + case BIFF8: + xDrawingObj = BiffDrawingObjectBase::importObjBiff5( *this, rStrm ); + break; + default:; + } + + if( xDrawingObj.get() ) + { + // insert into maRawObjs or into the last open group object + maRawObjs.insertGrouped( xDrawingObj ); + // to be able to find objects by ID + maObjMapId[ xDrawingObj->getObjId() ] = xDrawingObj; + } +} + +void BiffDrawingBase::setSkipObj( sal_uInt16 nObjId ) +{ + /* Store identifiers of objects to be skipped in a separate list (the OBJ + record may not be read yet). In the finalization phase, all objects + registered here will be skipped. */ + maSkipObjs.push_back( nObjId ); +} + +void BiffDrawingBase::finalizeImport() +{ + Reference< XShapes > xShapes( mxDrawPage, UNO_QUERY ); + OSL_ENSURE( xShapes.is(), "BiffDrawingBase::finalizeImport - no shapes container" ); + if( !xShapes.is() ) + return; + + // process list of objects to be skipped + for( BiffObjIdVector::const_iterator aIt = maSkipObjs.begin(), aEnd = maSkipObjs.end(); aIt != aEnd; ++aIt ) + if( BiffDrawingObjectBase* pDrawingObj = maObjMapId.get( *aIt ).get() ) + pDrawingObj->setProcessShape( false ); + + // process drawing objects without DFF data + maRawObjs.convertAndInsert( *this, xShapes ); +} + +Reference< XShape > BiffDrawingBase::createAndInsertXShape( const OUString& rService, + const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +{ + OSL_ENSURE( rService.getLength() > 0, "BiffDrawingBase::createAndInsertXShape - missing UNO shape service name" ); + OSL_ENSURE( rxShapes.is(), "BiffDrawingBase::createAndInsertXShape - missing XShapes container" ); + Reference< XShape > xShape; + if( (rService.getLength() > 0) && rxShapes.is() ) try + { + Reference< XMultiServiceFactory > xFactory( getDocumentFactory(), UNO_SET_THROW ); + xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW ); + // insert shape into passed shape collection (maybe drawpage or group shape) + rxShapes->add( xShape ); + xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); + xShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) ); + } + catch( Exception& ) + { + } + OSL_ENSURE( xShape.is(), "BiffDrawingBase::createAndInsertXShape - cannot instanciate shape object" ); + return xShape; +} + +// protected ------------------------------------------------------------------ + +void BiffDrawingBase::appendRawObject( const BiffDrawingObjectRef& rxDrawingObj ) +{ + OSL_ENSURE( rxDrawingObj.get(), "BiffDrawingBase::appendRawObject - unexpected empty object reference" ); + maRawObjs.append( rxDrawingObj ); +} + +// ============================================================================ + +BiffSheetDrawing::BiffSheetDrawing( const WorksheetHelper& rHelper ) : + BiffDrawingBase( rHelper, rHelper.getDrawPage() ) +{ +} + +void BiffSheetDrawing::notifyShapeInserted( const Reference< XShape >& /*rxShape*/, const Rectangle& rShapeRect ) +{ + // collect all shape positions in the WorksheetHelper base class + extendShapeBoundingBox( rShapeRect ); +} + +// ============================================================================ + +} // namespace xls +} // namespace oox diff --git a/oox/source/xls/makefile.mk b/oox/source/xls/makefile.mk index b5ede953bbfe..493575a408a8 100644 --- a/oox/source/xls/makefile.mk +++ b/oox/source/xls/makefile.mk @@ -55,7 +55,9 @@ SLOFILES = \ $(SLO)$/condformatcontext.obj \ $(SLO)$/connectionsfragment.obj \ $(SLO)$/defnamesbuffer.obj \ + $(SLO)$/drawingbase.obj \ $(SLO)$/drawingfragment.obj \ + $(SLO)$/drawingmanager.obj \ $(SLO)$/excelchartconverter.obj \ $(SLO)$/excelfilter.obj \ $(SLO)$/excelhandlers.obj \ diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx index bee58fdbaff3..9a8fa57f68cb 100644 --- a/oox/source/xls/worksheetfragment.cxx +++ b/oox/source/xls/worksheetfragment.cxx @@ -36,6 +36,7 @@ #include "oox/xls/commentsfragment.hxx" #include "oox/xls/condformatcontext.hxx" #include "oox/xls/drawingfragment.hxx" +#include "oox/xls/drawingmanager.hxx" #include "oox/xls/externallinkbuffer.hxx" #include "oox/xls/pagesettings.hxx" #include "oox/xls/pivottablebuffer.hxx" @@ -772,6 +773,7 @@ bool BiffWorksheetFragment::importFragment() SheetViewSettings& rSheetViewSett = getSheetViewSettings(); CondFormatBuffer& rCondFormats = getCondFormats(); PageSettings& rPageSett = getPageSettings(); + BiffSheetDrawing& rDrawing = getBiffDrawing(); // process all record in this sheet fragment while( mrStrm.startNextRecord() && (mrStrm.getRecId() != BIFF_ID_EOF) ) @@ -831,6 +833,7 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_DEFCOLWIDTH: importDefColWidth(); break; case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break; case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break; + case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( mrStrm ); break; case BIFF_ID_SHEETPR: rWorksheetSett.importSheetPr( mrStrm ); break; @@ -846,6 +849,7 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_COLINFO: importColInfo(); break; case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break; case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break; + case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( mrStrm ); break; case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( mrStrm ); break; @@ -863,6 +867,7 @@ bool BiffWorksheetFragment::importFragment() case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break; case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break; case BIFF_ID_MERGEDCELLS: importMergedCells(); break; // #i62300# also in BIFF5 + case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( mrStrm ); break; case BIFF_ID_PTDEFINITION: importPTDefinition(); break; @@ -889,6 +894,7 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_HYPERLINK: importHyperlink(); break; case BIFF_ID_LABELRANGES: importLabelRanges(); break; case BIFF_ID_MERGEDCELLS: importMergedCells(); break; +// case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( mrStrm ); break; case BIFF_ID_PHONETICPR: rWorksheetSett.importPhoneticPr( mrStrm ); break; diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index d2d42f2be369..626d3b962ceb 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -62,6 +62,7 @@ #include "oox/xls/commentsbuffer.hxx" #include "oox/xls/condformatbuffer.hxx" #include "oox/xls/drawingfragment.hxx" +#include "oox/xls/drawingmanager.hxx" #include "oox/xls/formulaparser.hxx" #include "oox/xls/pagesettings.hxx" #include "oox/xls/sharedformulabuffer.hxx" @@ -396,7 +397,7 @@ public: /** Returns the XDrawPage interface of the draw page of the current sheet. */ Reference< XDrawPage > getDrawPage() const; /** Returns the size of the entire drawing page in 1/100 mm. */ - Size getDrawPageSize() const; + const Size& getDrawPageSize() const; /** Returns the absolute position of the top-left corner of the cell in 1/100 mm. */ Point getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const; @@ -404,7 +405,7 @@ public: Size getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const; /** Returns the address of the cell that contains the passed point in 1/100 mm. */ - CellAddress getCellAddressFromPosition( const Point& rPosition, const Size& rDrawPageSize ) const; + CellAddress getCellAddressFromPosition( const Point& rPosition ) const; /** Returns the cell range address that contains the passed rectangle in 1/100 mm. */ CellRangeAddress getCellRangeFromRectangle( const Rectangle& rRect ) const; @@ -420,8 +421,10 @@ public: inline PageSettings& getPageSettings() { return maPageSett; } /** Returns the view settings for this sheet. */ inline SheetViewSettings& getSheetViewSettings() { return maSheetViewSett; } - /** Returns the VML drawing page for this sheet (OOX only!). */ + /** Returns the VML drawing page for this sheet (OOXML/BIFF12 only). */ inline VmlDrawing& getVmlDrawing() { return *mxVmlDrawing; } + /** Returns the BIFF drawing page for this sheet (BIFF2-BIFF8 only). */ + inline BiffSheetDrawing& getBiffDrawing() const { return *mxBiffDrawing; } /** Changes the current sheet type. */ inline void setSheetType( WorksheetType eSheetType ) { meSheetType = eSheetType; } @@ -543,13 +546,6 @@ private: /** Merges the passed merged range and updates right/bottom cell borders. */ void finalizeMergedRange( const CellRangeAddress& rRange ); - /** Imports the drawing layer of the sheet (DrawingML part). */ - void finalizeDrawing(); - /** Imports the drawing layer of the sheet (VML part). */ - void finalizeVmlDrawing(); - /** Extends the used cell area with the area used by drawing objects. */ - void finalizeUsedArea(); - /** Converts column properties for all columns in the sheet. */ void convertColumns(); /** Converts column properties. */ @@ -565,8 +561,12 @@ private: /** Groups columns or rows for the given range. */ void groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapsed, bool bRows ); + /** Imports the drawings of the sheet (DML, VML, DFF) and updates the used area. */ + void finalizeDrawings(); + private: - typedef ::std::auto_ptr< VmlDrawing > VmlDrawingPtr; + typedef ::std::auto_ptr< VmlDrawing > VmlDrawingPtr; + typedef ::std::auto_ptr< BiffSheetDrawing > BiffSheetDrawingPtr; const OUString maTrueFormula; /// Replacement formula for TRUE boolean cells. const OUString maFalseFormula; /// Replacement formula for FALSE boolean cells. @@ -592,8 +592,10 @@ private: PageSettings maPageSett; /// Page/print settings for this sheet. SheetViewSettings maSheetViewSett; /// View settings for this sheet. VmlDrawingPtr mxVmlDrawing; /// Collection of all VML shapes. + BiffSheetDrawingPtr mxBiffDrawing; /// Collection of all BIFF/DFF shapes. OUString maDrawingPath; /// Path to DrawingML fragment. OUString maVmlDrawingPath; /// Path to legacy VML drawing fragment. + Size maDrawPageSize; /// Current size of the drawing page in 1/100 mm. Rectangle maShapeBoundingBox; /// Bounding box for all shapes from all drawings. ISegmentProgressBarRef mxProgressBar; /// Sheet progress bar. ISegmentProgressBarRef mxRowProgress; /// Progress bar for row/cell processing. @@ -645,8 +647,17 @@ WorksheetData::WorksheetData( const WorkbookHelper& rHelper, ISegmentProgressBar maDefRowModel.mbCollapsed = false; // buffers - if( getFilterType() == FILTER_OOX ) - mxVmlDrawing.reset( new VmlDrawing( *this ) ); + switch( getFilterType() ) + { + case FILTER_OOX: + mxVmlDrawing.reset( new VmlDrawing( *this ) ); + break; + case FILTER_BIFF: + mxBiffDrawing.reset( new BiffSheetDrawing( *this ) ); + break; + case FILTER_UNKNOWN: + break; + } // prepare progress bars if( mxProgressBar.get() ) @@ -771,12 +782,10 @@ Reference< XDrawPage > WorksheetData::getDrawPage() const return xDrawPage; } -Size WorksheetData::getDrawPageSize() const +const Size& WorksheetData::getDrawPageSize() const { - Size aSize; - PropertySet aRangeProp( getCellRange( CellRangeAddress( getSheetIndex(), 0, 0, mrMaxApiPos.Column, mrMaxApiPos.Row ) ) ); - aRangeProp.getProperty( aSize, PROP_Size ); - return aSize; + OSL_ENSURE( (maDrawPageSize.Width > 0) && (maDrawPageSize.Height > 0), "WorksheetData::getDrawPageSize - called too early, size invalid" ); + return maDrawPageSize; } Point WorksheetData::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const @@ -864,7 +873,7 @@ bool lclUpdateInterval( sal_Int32& rnBegAddr, sal_Int32& rnMidAddr, sal_Int32& r } // namespace -CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition, const Size& rDrawPageSize ) const +CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition ) const { // starting cell address and its position in drawing layer (top-left edge) sal_Int32 nBegCol = 0; @@ -874,7 +883,7 @@ CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition, c // end cell address and its position in drawing layer (bottom-right edge) sal_Int32 nEndCol = mrMaxApiPos.Column + 1; sal_Int32 nEndRow = mrMaxApiPos.Row + 1; - Point aEndPos( rDrawPageSize.Width, rDrawPageSize.Height ); + Point aEndPos( maDrawPageSize.Width, maDrawPageSize.Height ); // starting point for interval search sal_Int32 nMidCol, nMidRow; @@ -902,10 +911,9 @@ CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition, c CellRangeAddress WorksheetData::getCellRangeFromRectangle( const Rectangle& rRect ) const { - Size aPageSize = getDrawPageSize(); - CellAddress aStartAddr = getCellAddressFromPosition( Point( rRect.X, rRect.Y ), aPageSize ); + CellAddress aStartAddr = getCellAddressFromPosition( Point( rRect.X, rRect.Y ) ); Point aBotRight( rRect.X + rRect.Width, rRect.Y + rRect.Height ); - CellAddress aEndAddr = getCellAddressFromPosition( aBotRight, aPageSize ); + CellAddress aEndAddr = getCellAddressFromPosition( aBotRight ); bool bMultiCols = aStartAddr.Column < aEndAddr.Column; bool bMultiRows = aStartAddr.Row < aEndAddr.Row; if( bMultiCols || bMultiRows ) @@ -1171,10 +1179,7 @@ void WorksheetData::finalizeWorksheetImport() convertColumns(); convertRows(); lclUpdateProgressBar( mxFinalProgress, 0.75 ); - finalizeDrawing(); - finalizeVmlDrawing(); - maComments.finalizeImport(); // after VML drawing - finalizeUsedArea(); // after DML and VML drawing + finalizeDrawings(); lclUpdateProgressBar( mxFinalProgress, 1.0 ); // reset current sheet index in global data @@ -1561,42 +1566,6 @@ void WorksheetData::finalizeMergedRange( const CellRangeAddress& rRange ) } } -void WorksheetData::finalizeDrawing() -{ - OSL_ENSURE( (getFilterType() == FILTER_OOX) || (maDrawingPath.getLength() == 0), - "WorksheetData::finalizeDrawing - unexpected DrawingML path" ); - if( (getFilterType() == FILTER_OOX) && (maDrawingPath.getLength() > 0) ) - importOoxFragment( new OoxDrawingFragment( *this, maDrawingPath ) ); -} - -void WorksheetData::finalizeVmlDrawing() -{ - OSL_ENSURE( (getFilterType() == FILTER_OOX) || (maVmlDrawingPath.getLength() == 0), - "WorksheetData::finalizeVmlDrawing - unexpected VML path" ); - if( (getFilterType() == FILTER_OOX) && (maVmlDrawingPath.getLength() > 0) ) - importOoxFragment( new OoxVmlDrawingFragment( *this, maVmlDrawingPath ) ); -} - -void WorksheetData::finalizeUsedArea() -{ - /* Extend used area of the sheet by cells covered with drawing objects. - Needed if the imported document is inserted as "OLE object from file" - and thus does not provide an OLE size property by itself. */ - if( (maShapeBoundingBox.Width > 0) || (maShapeBoundingBox.Height > 0) ) - extendUsedArea( getCellRangeFromRectangle( maShapeBoundingBox ) ); - - // if no used area is set, default to A1 - if( maUsedArea.StartColumn > maUsedArea.EndColumn ) - maUsedArea.StartColumn = maUsedArea.EndColumn = 0; - if( maUsedArea.StartRow > maUsedArea.EndRow ) - maUsedArea.StartRow = maUsedArea.EndRow = 0; - - /* Register the used area of this sheet in global view settings. The - global view settings will set the visible area if this document is an - embedded OLE object. */ - getViewSettings().setSheetUsedArea( maUsedArea ); -} - void WorksheetData::convertColumns() { sal_Int32 nNextCol = 0; @@ -1761,6 +1730,52 @@ void WorksheetData::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastC } } +void WorksheetData::finalizeDrawings() +{ + // calculate the current drawing page size (after rows/columns are imported) + PropertySet aRangeProp( getCellRange( CellRangeAddress( getSheetIndex(), 0, 0, mrMaxApiPos.Column, mrMaxApiPos.Row ) ) ); + aRangeProp.getProperty( maDrawPageSize, PROP_Size ); + + switch( getFilterType() ) + { + case FILTER_OOX: + // import DML and VML + if( maDrawingPath.getLength() > 0 ) + importOoxFragment( new OoxDrawingFragment( *this, maDrawingPath ) ); + if( maVmlDrawingPath.getLength() > 0 ) + importOoxFragment( new OoxVmlDrawingFragment( *this, maVmlDrawingPath ) ); + break; + + case FILTER_BIFF: + // convert BIFF3-BIFF5 drawing objects, or import and convert DFF stream + getBiffDrawing().finalizeImport(); + break; + + case FILTER_UNKNOWN: + break; + } + + // comments (after callout shapes have been imported from VML/DFF) + maComments.finalizeImport(); + + /* Extend used area of the sheet by cells covered with drawing objects. + Needed if the imported document is inserted as "OLE object from file" + and thus does not provide an OLE size property by itself. */ + if( (maShapeBoundingBox.Width > 0) || (maShapeBoundingBox.Height > 0) ) + extendUsedArea( getCellRangeFromRectangle( maShapeBoundingBox ) ); + + // if no used area is set, default to A1 + if( maUsedArea.StartColumn > maUsedArea.EndColumn ) + maUsedArea.StartColumn = maUsedArea.EndColumn = 0; + if( maUsedArea.StartRow > maUsedArea.EndRow ) + maUsedArea.StartRow = maUsedArea.EndRow = 0; + + /* Register the used area of this sheet in global view settings. The + global view settings will set the visible area if this document is an + embedded OLE object. */ + getViewSettings().setSheetUsedArea( maUsedArea ); +} + // ============================================================================ // ============================================================================ @@ -1957,6 +1972,11 @@ VmlDrawing& WorksheetHelper::getVmlDrawing() const return mrSheetData.getVmlDrawing(); } +BiffSheetDrawing& WorksheetHelper::getBiffDrawing() const +{ + return mrSheetData.getBiffDrawing(); +} + void WorksheetHelper::setStringCell( const Reference< XCell >& rxCell, const OUString& rText ) const { OSL_ENSURE( rxCell.is(), "WorksheetHelper::setStringCell - missing cell interface" ); -- cgit From b156d957d5029e80483bfe0da9279243a6fbf439 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Wed, 5 Jan 2011 21:25:56 +0100 Subject: dr78: #i96587# import text formatting from OOXML and BIFF12 --- oox/source/xls/commentsbuffer.cxx | 44 ++++++++++++++++++------------------ oox/source/xls/richstring.cxx | 47 +++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 44 deletions(-) (limited to 'oox/source') diff --git a/oox/source/xls/commentsbuffer.cxx b/oox/source/xls/commentsbuffer.cxx index 190309649789..612568ed0b51 100644 --- a/oox/source/xls/commentsbuffer.cxx +++ b/oox/source/xls/commentsbuffer.cxx @@ -48,6 +48,7 @@ using ::com::sun::star::sheet::XSheetAnnotationAnchor; using ::com::sun::star::sheet::XSheetAnnotationShapeSupplier; using ::com::sun::star::sheet::XSheetAnnotations; using ::com::sun::star::sheet::XSheetAnnotationsSupplier; +using ::com::sun::star::text::XText; namespace oox { namespace xls { @@ -96,30 +97,29 @@ void Comment::finalizeImport() CellAddress aNotePos( maModel.maRange.Sheet, maModel.maRange.StartColumn, maModel.maRange.StartRow ); if( getAddressConverter().checkCellAddress( aNotePos, true ) && maModel.mxText.get() ) try { - maModel.mxText->finalizeImport(); - OUString aNoteText = maModel.mxText->getPlainText(); - // non-empty string required by note implementation - if( aNoteText.getLength() > 0 ) + Reference< XSheetAnnotationsSupplier > xAnnosSupp( getSheet(), UNO_QUERY_THROW ); + Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW ); + // non-empty string required by note implementation (real text will be added below) + xAnnos->insertNew( aNotePos, OUString( sal_Unicode( ' ' ) ) ); + // receive craeted note from cell (insertNew does not return the note) + Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( aNotePos ), UNO_QUERY_THROW ); + Reference< XSheetAnnotation > xAnno( xAnnoAnchor->getAnnotation(), UNO_SET_THROW ); + Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnno, UNO_QUERY_THROW ); + Reference< XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), UNO_SET_THROW ); + // convert shape formatting + if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) ) { - Reference< XSheetAnnotationsSupplier > xAnnosSupp( getSheet(), UNO_QUERY_THROW ); - Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW ); - xAnnos->insertNew( aNotePos, aNoteText ); - // receive craeted note from cell (insertNew does not return the note) - Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( aNotePos ), UNO_QUERY_THROW ); - Reference< XSheetAnnotation > xAnno( xAnnoAnchor->getAnnotation(), UNO_SET_THROW ); - Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnno, UNO_QUERY_THROW ); - Reference< XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), UNO_SET_THROW ); - // convert shape formatting - if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) ) - { - // position and formatting - pNoteShape->convertFormatting( xAnnoShape ); - // visibility - const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = pNoteShape->getShapeModel().mxClientData; - bool bVisible = rxClientData.get() && rxClientData->mbVisible; - xAnno->setIsVisible( bVisible ); - } + // position and formatting + pNoteShape->convertFormatting( xAnnoShape ); + // visibility + const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = pNoteShape->getShapeModel().mxClientData; + bool bVisible = rxClientData.get() && rxClientData->mbVisible; + xAnno->setIsVisible( bVisible ); } + // insert text and convert text formatting + maModel.mxText->finalizeImport(); + Reference< XText > xAnnoText( xAnnoShape, UNO_QUERY_THROW ); + maModel.mxText->convert( xAnnoText, -1, true ); } catch( Exception& ) { diff --git a/oox/source/xls/richstring.cxx b/oox/source/xls/richstring.cxx index 4e82b1e696f0..c967ce60fa3d 100644 --- a/oox/source/xls/richstring.cxx +++ b/oox/source/xls/richstring.cxx @@ -37,6 +37,7 @@ using ::rtl::OString; using ::rtl::OUString; using ::rtl::OUStringBuffer; using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::text::XText; using ::com::sun::star::text::XTextRange; @@ -84,21 +85,30 @@ void RichStringPortion::finalizeImport() mxFont = getStyles().getFont( mnFontId ); } -void RichStringPortion::convert( const Reference< XText >& rxText, sal_Int32 nXfId ) +void RichStringPortion::convert( const Reference< XText >& rxText, sal_Int32 nXfId, bool bReplaceOld ) { - Reference< XTextRange > xRange = rxText->getEnd(); - xRange->setString( maText ); - if( mxFont.get() ) - { - PropertySet aPropSet( xRange ); - mxFont->writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT ); - } - if( const Font* pFont = getStyles().getFontFromCellXf( nXfId ).get() ) + Reference< XTextRange > xRange; + if( bReplaceOld ) + xRange.set( rxText, UNO_QUERY ); + else + xRange = rxText->getEnd(); + OSL_ENSURE( xRange.is(), "RichStringPortion::convert - cannot get text range interface" ); + + if( xRange.is() ) { - if( pFont->needsRichTextFormat() ) + xRange->setString( maText ); + if( mxFont.get() ) { PropertySet aPropSet( xRange ); - pFont->writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT ); + mxFont->writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT ); + } + if( const Font* pFont = getStyles().getFontFromCellXf( nXfId ).get() ) + { + if( pFont->needsRichTextFormat() ) + { + PropertySet aPropSet( xRange ); + pFont->writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT ); + } } } } @@ -489,20 +499,13 @@ void RichString::finalizeImport() maFontPortions.forEachMem( &RichStringPortion::finalizeImport ); } -OUString RichString::getPlainText() const -{ - OUStringBuffer aBuffer; - for( PortionVec::const_iterator aIt = maFontPortions.begin(), aEnd = maFontPortions.end(); aIt != aEnd; ++aIt ) - aBuffer.append( (*aIt)->getText() ); - return aBuffer.makeStringAndClear(); -} - -void RichString::convert( const Reference< XText >& rxText, sal_Int32 nXfId ) const +void RichString::convert( const Reference< XText >& rxText, sal_Int32 nXfId, bool bReplaceOld ) const { for( PortionVec::const_iterator aIt = maFontPortions.begin(), aEnd = maFontPortions.end(); aIt != aEnd; ++aIt ) { - (*aIt)->convert( rxText, nXfId ); - nXfId = -1; // use passed XF identifier for first portion only + (*aIt)->convert( rxText, nXfId, bReplaceOld ); + nXfId = -1; // use passed XF identifier for first portion only + bReplaceOld = false; // do not replace first portion text with following portions } } -- cgit From 1ed3654a1c0acf899fbe93352b93979f17103528 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Thu, 6 Jan 2011 12:32:39 +0100 Subject: dr78: #i96587# oox - import BIFF2-BIFF5 cell notes --- oox/source/dump/biffdumper.cxx | 3 +- oox/source/xls/commentsbuffer.cxx | 59 +++++++++++++++++++++++++++++++----- oox/source/xls/defnamesbuffer.cxx | 4 +++ oox/source/xls/drawingmanager.cxx | 3 +- oox/source/xls/richstring.cxx | 17 +++++++---- oox/source/xls/worksheetfragment.cxx | 11 ++++++- 6 files changed, 81 insertions(+), 16 deletions(-) (limited to 'oox/source') diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index 8b3127d0b5e7..3e9e1d77d5c2 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -2523,7 +2523,8 @@ void WorkbookStreamObject::implDumpRecordBody() } else { - sal_uInt16 nTextLen = ::std::min( dumpDec< sal_uInt16 >( "text-len" ), static_cast< sal_uInt16 >( rStrm.getRemaining() ) ); + sal_uInt16 nTextLen = dumpDec< sal_uInt16 >( "text-len" ); + nTextLen = ::std::min( nTextLen, static_cast< sal_uInt16 >( rStrm.getRemaining() ) ); writeStringItem( "note-text", rStrm.readCharArrayUC( nTextLen, getBiffData().getTextEncoding(), true ) ); } break; diff --git a/oox/source/xls/commentsbuffer.cxx b/oox/source/xls/commentsbuffer.cxx index 612568ed0b51..f0d4eb63611c 100644 --- a/oox/source/xls/commentsbuffer.cxx +++ b/oox/source/xls/commentsbuffer.cxx @@ -34,6 +34,7 @@ #include "oox/helper/recordinputstream.hxx" #include "oox/vml/vmlshape.hxx" #include "oox/xls/addressconverter.hxx" +#include "oox/xls/biffinputstream.hxx" #include "oox/xls/drawingfragment.hxx" using ::rtl::OUString; @@ -82,6 +83,39 @@ void Comment::importComment( RecordInputStream& rStrm ) getAddressConverter().convertToCellRangeUnchecked( maModel.maRange, aBinRange, getSheetIndex() ); } +void Comment::importNote( BiffInputStream& rStrm ) +{ + BinAddress aBinAddr; + sal_uInt16 nTotalLen; + rStrm >> aBinAddr >> nTotalLen; + // cell range will be checked while inserting the comment into the document + getAddressConverter().convertToCellRangeUnchecked( maModel.maRange, BinRange( aBinAddr ), getSheetIndex() ); + RichStringRef xNoteText = createText(); + + sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.getRemaining() ) ); + xNoteText->importCharArray( rStrm, nPartLen, getTextEncoding() ); + + nTotalLen = nTotalLen - nPartLen; // operator-=() gives compiler warning + while( (nTotalLen > 0) && (rStrm.getNextRecId() == BIFF_ID_NOTE) && rStrm.startNextRecord() ) + { + rStrm >> aBinAddr >> nPartLen; + OSL_ENSURE( aBinAddr.mnRow == 0xFFFF, "Comment::importNote - missing continuation NOTE record" ); + if( aBinAddr.mnRow == 0xFFFF ) + { + OSL_ENSURE( nPartLen <= nTotalLen, "Comment::importNote - string too long" ); + // call to RichString::importCharArray() appends new text portion + xNoteText->importCharArray( rStrm, nPartLen, getTextEncoding() ); + nTotalLen = nTotalLen - ::std::min( nTotalLen, nPartLen ); + } + else + { + // seems to be a new note, rewind record, so worksheet fragment loop will find it + rStrm.rewindRecord(); + nTotalLen = 0; + } + } +} + RichStringRef Comment::createText() { maModel.mxText.reset( new RichString( *this ) ); @@ -107,14 +141,25 @@ void Comment::finalizeImport() Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnno, UNO_QUERY_THROW ); Reference< XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), UNO_SET_THROW ); // convert shape formatting - if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) ) + switch( getFilterType() ) { - // position and formatting - pNoteShape->convertFormatting( xAnnoShape ); - // visibility - const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = pNoteShape->getShapeModel().mxClientData; - bool bVisible = rxClientData.get() && rxClientData->mbVisible; - xAnno->setIsVisible( bVisible ); + case FILTER_OOX: + if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) ) + { + // position and formatting + pNoteShape->convertFormatting( xAnnoShape ); + // visibility + const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = pNoteShape->getShapeModel().mxClientData; + bool bVisible = rxClientData.get() && rxClientData->mbVisible; + xAnno->setIsVisible( bVisible ); + } + break; + case FILTER_BIFF: + // notes are always hidden and unformatted in BIFF3-BIFF5 + xAnno->setIsVisible( sal_False ); + break; + case FILTER_UNKNOWN: + break; } // insert text and convert text formatting maModel.mxText->finalizeImport(); diff --git a/oox/source/xls/defnamesbuffer.cxx b/oox/source/xls/defnamesbuffer.cxx index a02375e2b869..3c1a9169f004 100644 --- a/oox/source/xls/defnamesbuffer.cxx +++ b/oox/source/xls/defnamesbuffer.cxx @@ -491,6 +491,10 @@ void DefinedName::createNameObject() if( /*maModel.mbHidden ||*/ maModel.mbFunction ) return; + // skip BIFF names without stream position (e.g. BIFF3-BIFF4 internal 3D references) + if( (getFilterType() == FILTER_BIFF) && !mxBiffStrm.get() ) + return; + // convert original name to final Calc name if( maModel.mbVBName ) maCalcName = maModel.maName; diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx index 16e5ceddd27d..0ef734aa86a0 100755 --- a/oox/source/xls/drawingmanager.cxx +++ b/oox/source/xls/drawingmanager.cxx @@ -891,7 +891,8 @@ void BiffDrawingBase::importObj( BiffInputStream& rStrm ) xDrawingObj = BiffDrawingObjectBase::importObjBiff4( *this, rStrm ); break; case BIFF5: - case BIFF8: +// TODO: add BIFF8 when DFF is supported +// case BIFF8: xDrawingObj = BiffDrawingObjectBase::importObjBiff5( *this, rStrm ); break; default:; diff --git a/oox/source/xls/richstring.cxx b/oox/source/xls/richstring.cxx index c967ce60fa3d..f7aad994c3d5 100644 --- a/oox/source/xls/richstring.cxx +++ b/oox/source/xls/richstring.cxx @@ -416,7 +416,12 @@ void RichString::importString( RecordInputStream& rStrm, bool bRich ) } } -void RichString::importByteString( BiffInputStream& rStrm, rtl_TextEncoding eDefaultTextEnc, BiffStringFlags nFlags ) +void RichString::importCharArray( BiffInputStream& rStrm, sal_uInt16 nChars, rtl_TextEncoding eTextEnc ) +{ + createPortion()->setText( rStrm.readCharArrayUC( nChars, eTextEnc ) ); +} + +void RichString::importByteString( BiffInputStream& rStrm, rtl_TextEncoding eTextEnc, BiffStringFlags nFlags ) { OSL_ENSURE( !getFlag( nFlags, BIFF_STR_KEEPFONTS ), "RichString::importString - keep fonts not implemented" ); OSL_ENSURE( !getFlag( nFlags, static_cast< BiffStringFlags >( ~(BIFF_STR_8BITLENGTH | BIFF_STR_EXTRAFONTS) ) ), "RichString::importByteString - unknown flag" ); @@ -428,11 +433,11 @@ void RichString::importByteString( BiffInputStream& rStrm, rtl_TextEncoding eDef { FontPortionModelList aPortions; aPortions.importPortions( rStrm, false ); - createFontPortions( aBaseText, eDefaultTextEnc, aPortions ); + createFontPortions( aBaseText, eTextEnc, aPortions ); } else { - createPortion()->setText( OStringToOUString( aBaseText, eDefaultTextEnc ) ); + createPortion()->setText( OStringToOUString( aBaseText, eTextEnc ) ); } } @@ -525,7 +530,7 @@ RichStringPhoneticRef RichString::createPhonetic() return xPhonetic; } -void RichString::createFontPortions( const OString& rText, rtl_TextEncoding eDefaultTextEnc, FontPortionModelList& rPortions ) +void RichString::createFontPortions( const OString& rText, rtl_TextEncoding eTextEnc, FontPortionModelList& rPortions ) { maFontPortions.clear(); sal_Int32 nStrLen = rText.getLength(); @@ -545,8 +550,8 @@ void RichString::createFontPortions( const OString& rText, rtl_TextEncoding eDef { // convert byte string to unicode string, using current font encoding FontRef xFont = getStyles().getFont( aIt->mnFontId ); - rtl_TextEncoding eTextEnc = xFont.get() ? xFont->getFontEncoding() : eDefaultTextEnc; - OUString aUniStr = OStringToOUString( rText.copy( aIt->mnPos, nPortionLen ), eTextEnc ); + rtl_TextEncoding eFontEnc = xFont.get() ? xFont->getFontEncoding() : eTextEnc; + OUString aUniStr = OStringToOUString( rText.copy( aIt->mnPos, nPortionLen ), eFontEnc ); // create string portion RichStringPortionRef xPortion = createPortion(); xPortion->setText( aUniStr ); diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx index 9a8fa57f68cb..cd017cab9cf6 100644 --- a/oox/source/xls/worksheetfragment.cxx +++ b/oox/source/xls/worksheetfragment.cxx @@ -823,6 +823,7 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_COLUMNDEFAULT: importColumnDefault(); break; case BIFF_ID_COLWIDTH: importColWidth(); break; case BIFF2_ID_DEFROWHEIGHT: importDefRowHeight(); break; + case BIFF_ID_NOTE: importNote(); break; case BIFF2_ID_WINDOW2: rSheetViewSett.importWindow2( mrStrm ); break; } break; @@ -833,6 +834,7 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_DEFCOLWIDTH: importDefColWidth(); break; case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break; case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break; + case BIFF_ID_NOTE: importNote(); break; case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( mrStrm ); break; @@ -849,6 +851,7 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_COLINFO: importColInfo(); break; case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break; case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break; + case BIFF_ID_NOTE: importNote(); break; case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( mrStrm ); break; @@ -867,6 +870,7 @@ bool BiffWorksheetFragment::importFragment() case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break; case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break; case BIFF_ID_MERGEDCELLS: importMergedCells(); break; // #i62300# also in BIFF5 + case BIFF_ID_NOTE: importNote(); break; case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( mrStrm ); break; @@ -894,7 +898,7 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_HYPERLINK: importHyperlink(); break; case BIFF_ID_LABELRANGES: importLabelRanges(); break; case BIFF_ID_MERGEDCELLS: importMergedCells(); break; -// case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; + case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( mrStrm ); break; case BIFF_ID_PHONETICPR: rWorksheetSett.importPhoneticPr( mrStrm ); break; @@ -1149,6 +1153,11 @@ void BiffWorksheetFragment::importMergedCells() setMergedRange( *aIt ); } +void BiffWorksheetFragment::importNote() +{ + getComments().createComment()->importNote( mrStrm ); +} + void BiffWorksheetFragment::importPageBreaks( bool bRowBreak ) { PageBreakModel aModel; -- cgit From b03baea914ff8f45cb1f5cf9703ff316a5396135 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Thu, 6 Jan 2011 13:56:27 +0100 Subject: dr78: #i96587# oox - import BIFF8 cell notes --- oox/source/dump/biffdumper.cxx | 17 +++++ oox/source/dump/biffdumper.ini | 14 ++++- oox/source/xls/commentsbuffer.cxx | 116 ++++++++++++++++++++++++++--------- oox/source/xls/drawingmanager.cxx | 2 - oox/source/xls/worksheetfragment.cxx | 5 +- 5 files changed, 117 insertions(+), 37 deletions(-) (limited to 'oox/source') diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index 3e9e1d77d5c2..718a8897d641 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -2520,6 +2520,8 @@ void WorkbookStreamObject::implDumpRecordBody() { dumpHex< sal_uInt16 >( "flags", "NOTE-FLAGS" ); dumpDec< sal_uInt16 >( "obj-id" ); + dumpUniString( "author" ); + dumpUnused( 1 ); } else { @@ -2529,6 +2531,21 @@ void WorkbookStreamObject::implDumpRecordBody() } break; + case BIFF_ID_NOTESOUND: + dumpHex< sal_uInt32 >( "identifier" ); + dumpDec< sal_uInt32 >( "total-data-size" ); + dumpDec< sal_uInt32 >( "wave-data-size" ); + if( dumpDec< sal_uInt32 >( "fmt-size" ) >= 16 ) + { + dumpDec< sal_uInt16 >( "format", "NOTESOUND-FORMAT" ); + dumpDec< sal_uInt16 >( "channels" ); + dumpDec< sal_uInt32 >( "sampling-rate" ); + dumpDec< sal_uInt32 >( "data-rate" ); + dumpDec< sal_uInt16 >( "data-block-size" ); + dumpDec< sal_uInt16 >( "bits-per-sample" ); + } + break; + case BIFF2_ID_NUMBER: case BIFF3_ID_NUMBER: dumpCellHeader( nRecId == BIFF2_ID_NUMBER ); diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini index 18e8cd87e551..d570fcdcf515 100644 --- a/oox/source/dump/biffdumper.ini +++ b/oox/source/dump/biffdumper.ini @@ -324,7 +324,7 @@ multilist=RECORD-NAMES-BIFF4 exclude=0x0206,0x0209,0x001E,0x0243 0x0085=SHEET 0x0088=,,,,,,SHEETSOFFSET,SHEETHEADER - 0x0090=,,,,,SOUND,SYNC + 0x0090=,,,,,,NOTESOUND,SYNC 0x0098=LPR,STANDARDWIDTH,FNGROUPNAME,,FNGROUPCOUNT,,, 0x00A0=SCL,PAGESETUP,FNPROTO,PROJEXTSHEET,,,, 0x00A8=DRAGDROP,COORDLIST,,GCW,,,, @@ -1441,6 +1441,18 @@ shortlist=IMGDATA-ENV,1,windows,apple flagslist=NOTE-FLAGS-BIFF8 0x0002=visible + 0x0080=row-hidden + 0x0100=col-hidden +end + +# NOTESOUND ------------------------------------------------------------------ + +constlist=NOTESOUND-FORMAT + 1=pcm + 3=ieee-float + 6=a-law + 7=mu-law + 0xFFFE=extensible end # OBJ ------------------------------------------------------------------------ diff --git a/oox/source/xls/commentsbuffer.cxx b/oox/source/xls/commentsbuffer.cxx index f0d4eb63611c..8b03be299a50 100644 --- a/oox/source/xls/commentsbuffer.cxx +++ b/oox/source/xls/commentsbuffer.cxx @@ -36,6 +36,7 @@ #include "oox/xls/addressconverter.hxx" #include "oox/xls/biffinputstream.hxx" #include "oox/xls/drawingfragment.hxx" +#include "oox/xls/drawingmanager.hxx" using ::rtl::OUString; using ::com::sun::star::uno::Reference; @@ -56,8 +57,18 @@ namespace xls { // ============================================================================ +namespace { + +const sal_uInt16 BIFF_NOTE_VISIBLE = 0x0002; + +} // namespace + +// ============================================================================ + CommentModel::CommentModel() : - mnAuthorId( -1 ) + mnAuthorId( -1 ), + mnObjId( BIFF_OBJ_INVALID_ID ), + mbVisible( false ) { } @@ -86,33 +97,29 @@ void Comment::importComment( RecordInputStream& rStrm ) void Comment::importNote( BiffInputStream& rStrm ) { BinAddress aBinAddr; - sal_uInt16 nTotalLen; - rStrm >> aBinAddr >> nTotalLen; + rStrm >> aBinAddr; // cell range will be checked while inserting the comment into the document getAddressConverter().convertToCellRangeUnchecked( maModel.maRange, BinRange( aBinAddr ), getSheetIndex() ); - RichStringRef xNoteText = createText(); - sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.getRemaining() ) ); - xNoteText->importCharArray( rStrm, nPartLen, getTextEncoding() ); - - nTotalLen = nTotalLen - nPartLen; // operator-=() gives compiler warning - while( (nTotalLen > 0) && (rStrm.getNextRecId() == BIFF_ID_NOTE) && rStrm.startNextRecord() ) + // remaining record data is BIFF dependent + switch( getBiff() ) { - rStrm >> aBinAddr >> nPartLen; - OSL_ENSURE( aBinAddr.mnRow == 0xFFFF, "Comment::importNote - missing continuation NOTE record" ); - if( aBinAddr.mnRow == 0xFFFF ) - { - OSL_ENSURE( nPartLen <= nTotalLen, "Comment::importNote - string too long" ); - // call to RichString::importCharArray() appends new text portion - xNoteText->importCharArray( rStrm, nPartLen, getTextEncoding() ); - nTotalLen = nTotalLen - ::std::min( nTotalLen, nPartLen ); - } - else - { - // seems to be a new note, rewind record, so worksheet fragment loop will find it - rStrm.rewindRecord(); - nTotalLen = 0; - } + case BIFF2: + case BIFF3: + importNoteBiff2( rStrm ); + break; + case BIFF4: + case BIFF5: + importNoteBiff2( rStrm ); + // in BIFF4 and BIFF5, comments can have an associated sound + if( (rStrm.getNextRecId() == BIFF_ID_NOTESOUND) && rStrm.startNextRecord() ) + importNoteSound( rStrm ); + break; + case BIFF8: + importNoteBiff8( rStrm ); + break; + case BIFF_UNKNOWN: + break; } } @@ -135,12 +142,15 @@ void Comment::finalizeImport() Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW ); // non-empty string required by note implementation (real text will be added below) xAnnos->insertNew( aNotePos, OUString( sal_Unicode( ' ' ) ) ); - // receive craeted note from cell (insertNew does not return the note) + + // receive created note from cell (insertNew does not return the note) Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( aNotePos ), UNO_QUERY_THROW ); Reference< XSheetAnnotation > xAnno( xAnnoAnchor->getAnnotation(), UNO_SET_THROW ); Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnno, UNO_QUERY_THROW ); Reference< XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), UNO_SET_THROW ); - // convert shape formatting + + // convert shape formatting and visibility + sal_Bool bVisible = sal_True; switch( getFilterType() ) { case FILTER_OOX: @@ -150,17 +160,17 @@ void Comment::finalizeImport() pNoteShape->convertFormatting( xAnnoShape ); // visibility const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = pNoteShape->getShapeModel().mxClientData; - bool bVisible = rxClientData.get() && rxClientData->mbVisible; - xAnno->setIsVisible( bVisible ); + bVisible = rxClientData.get() && rxClientData->mbVisible; } break; case FILTER_BIFF: - // notes are always hidden and unformatted in BIFF3-BIFF5 - xAnno->setIsVisible( sal_False ); + bVisible = maModel.mbVisible; break; case FILTER_UNKNOWN: break; } + xAnno->setIsVisible( bVisible ); + // insert text and convert text formatting maModel.mxText->finalizeImport(); Reference< XText > xAnnoText( xAnnoShape, UNO_QUERY_THROW ); @@ -171,6 +181,52 @@ void Comment::finalizeImport() } } +// private -------------------------------------------------------------------- + +void Comment::importNoteBiff2( BiffInputStream& rStrm ) +{ + sal_uInt16 nTotalLen; + rStrm >> nTotalLen; + sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.getRemaining() ) ); + RichStringRef xNoteText = createText(); + xNoteText->importCharArray( rStrm, nPartLen, getTextEncoding() ); + + nTotalLen = nTotalLen - nPartLen; // operator-=() gives compiler warning + while( (nTotalLen > 0) && (rStrm.getNextRecId() == BIFF_ID_NOTE) && rStrm.startNextRecord() ) + { + sal_uInt16 nMarker; + rStrm >> nMarker; + rStrm.skip( 2 ); + rStrm >> nPartLen; + OSL_ENSURE( nMarker == 0xFFFF, "Comment::importNoteBiff2 - missing continuation NOTE record" ); + if( nMarker == 0xFFFF ) + { + OSL_ENSURE( nPartLen <= nTotalLen, "Comment::importNoteBiff2 - string too long" ); + // call to RichString::importCharArray() appends new text portion + xNoteText->importCharArray( rStrm, nPartLen, getTextEncoding() ); + nTotalLen = nTotalLen - ::std::min( nTotalLen, nPartLen ); + } + else + { + // seems to be a new note, rewind record, so worksheet fragment loop will find it + rStrm.rewindRecord(); + nTotalLen = 0; + } + } +} + +void Comment::importNoteBiff8( BiffInputStream& rStrm ) +{ + sal_uInt16 nFlags; + rStrm >> nFlags >> maModel.mnObjId; + maModel.maAuthor = rStrm.readUniString(); + maModel.mbVisible = getFlag( nFlags, BIFF_NOTE_VISIBLE ); +} + +void Comment::importNoteSound( BiffInputStream& /*rStrm*/ ) +{ +} + // ============================================================================ CommentsBuffer::CommentsBuffer( const WorksheetHelper& rHelper ) : diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx index 0ef734aa86a0..1016a8fa9da9 100755 --- a/oox/source/xls/drawingmanager.cxx +++ b/oox/source/xls/drawingmanager.cxx @@ -51,8 +51,6 @@ namespace { // OBJ record ----------------------------------------------------------------- -const sal_uInt16 BIFF_OBJ_INVALID_ID = 0; - const sal_uInt16 BIFF_OBJTYPE_GROUP = 0; const sal_uInt16 BIFF_OBJTYPE_LINE = 1; const sal_uInt16 BIFF_OBJTYPE_RECTANGLE = 2; diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx index cd017cab9cf6..72137a1b82d2 100644 --- a/oox/source/xls/worksheetfragment.cxx +++ b/oox/source/xls/worksheetfragment.cxx @@ -804,6 +804,7 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_HORPAGEBREAKS: importPageBreaks( true ); break; case BIFF_ID_ITERATION: rWorkbookSett.importIteration( mrStrm ); break; case BIFF_ID_LEFTMARGIN: rPageSett.importLeftMargin( mrStrm ); break; + case BIFF_ID_NOTE: importNote(); break; case BIFF_ID_PANE: rSheetViewSett.importPane( mrStrm ); break; case BIFF_ID_PASSWORD: rWorksheetSett.importPassword( mrStrm ); break; case BIFF_ID_PRINTGRIDLINES: rPageSett.importPrintGridLines( mrStrm ); break; @@ -823,7 +824,6 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_COLUMNDEFAULT: importColumnDefault(); break; case BIFF_ID_COLWIDTH: importColWidth(); break; case BIFF2_ID_DEFROWHEIGHT: importDefRowHeight(); break; - case BIFF_ID_NOTE: importNote(); break; case BIFF2_ID_WINDOW2: rSheetViewSett.importWindow2( mrStrm ); break; } break; @@ -834,7 +834,6 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_DEFCOLWIDTH: importDefColWidth(); break; case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break; case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break; - case BIFF_ID_NOTE: importNote(); break; case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( mrStrm ); break; @@ -851,7 +850,6 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_COLINFO: importColInfo(); break; case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break; case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break; - case BIFF_ID_NOTE: importNote(); break; case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( mrStrm ); break; @@ -870,7 +868,6 @@ bool BiffWorksheetFragment::importFragment() case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break; case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break; case BIFF_ID_MERGEDCELLS: importMergedCells(); break; // #i62300# also in BIFF5 - case BIFF_ID_NOTE: importNote(); break; case BIFF_ID_OBJ: rDrawing.importObj( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( mrStrm ); break; -- cgit From bb282d6533202ce6056d6aed37774c59a2deab2a Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Thu, 6 Jan 2011 15:51:51 +0100 Subject: dr78: oox - import children of BIFF3-BIFF5 group shapes --- oox/source/xls/drawingmanager.cxx | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'oox/source') diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx index 1016a8fa9da9..d9a58eafb9d8 100755 --- a/oox/source/xls/drawingmanager.cxx +++ b/oox/source/xls/drawingmanager.cxx @@ -496,6 +496,7 @@ Reference< XShape > BiffDrawingObjectBase::convertAndInsert( BiffDrawingBase& rD if( rxShapes.is() && mbProcessShape && !mbHidden ) // TODO: support for hidden objects? { // base class 'ShapeAnchor' calculates the shape rectangle in 1/100 mm + // in BIFF3-BIFF5, all shapes have absolute anchor (also children of group shapes) Rectangle aShapeRect = maAnchor.calcAnchorRectHmm( getDrawPageSize() ); // convert the shape, if the calculated rectangle is not empty @@ -762,10 +763,26 @@ void BiffGroupObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nName readMacroBiff5( rStrm, nMacroSize ); } -Reference< XShape > BiffGroupObject::implConvertAndInsert( BiffDrawingBase& /*rDrawing*/, - const Reference< XShapes >& /*rxShapes*/, const Rectangle& /*rShapeRect*/ ) const +Reference< XShape > BiffGroupObject::implConvertAndInsert( BiffDrawingBase& rDrawing, + const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - return Reference< XShape >(); + Reference< XShape > xGroupShape; + if( !maChildren.empty() ) try + { + xGroupShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rxShapes, rShapeRect ); + Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW ); + maChildren.convertAndInsert( rDrawing, xChildShapes, &rShapeRect ); + // no child shape has been created - delete the group shape + if( !xChildShapes->hasElements() ) + { + rxShapes->remove( xGroupShape ); + xGroupShape.clear(); + } + } + catch( Exception& ) + { + } + return xGroupShape; } // ============================================================================ -- cgit From f9a2b2913692fa1d65200f53c90e77b0bd134445 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Sat, 8 Jan 2011 12:55:26 +0100 Subject: dr78: oox - BIFF3-BIFF5 arcs and polygons, line and fill formatting --- oox/source/drawingml/lineproperties.cxx | 26 +- oox/source/token/properties.txt | 4 + oox/source/xls/drawingmanager.cxx | 472 ++++++++++++++++++++++++++++++-- oox/source/xls/worksheethelper.cxx | 2 - 4 files changed, 464 insertions(+), 40 deletions(-) (limited to 'oox/source') diff --git a/oox/source/drawingml/lineproperties.cxx b/oox/source/drawingml/lineproperties.cxx index 9f23cf466d30..a0836612fafb 100644 --- a/oox/source/drawingml/lineproperties.cxx +++ b/oox/source/drawingml/lineproperties.cxx @@ -251,9 +251,9 @@ void lclPushMarkerProperties( PropertyMap& rPropMap, const LineArrowProperties& case OOX_ARROWSIZE_MEDIUM: fArrowWidth = (bIsArrow ? 4.5 : 3.0); break; case OOX_ARROWSIZE_LARGE: fArrowWidth = (bIsArrow ? 6.0 : 5.0); break; } - // set arrow width relative to line width (convert line width from EMUs to 1/100 mm) - sal_Int32 nApiLineWidth = ::std::max< sal_Int32 >( GetCoordinate( nLineWidth ), 70 ); - nMarkerWidth = static_cast< sal_Int32 >( fArrowWidth * nApiLineWidth ); + // set arrow width relative to line width + sal_Int32 nBaseLineWidth = ::std::max< sal_Int32 >( nLineWidth, 70 ); + nMarkerWidth = static_cast< sal_Int32 >( fArrowWidth * nBaseLineWidth ); // test if the arrow already exists, do not create it again in this case if( !rPropIds.mbNamedLineMarker || !rModelObjHelper.hasLineMarker( aMarkerName ) ) @@ -403,6 +403,9 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM // line style (our core only supports none and solid) LineStyle eLineStyle = (maLineFill.moFillType.get() == XML_noFill) ? LineStyle_NONE : LineStyle_SOLID; + // convert line width from EMUs to 1/100mm + sal_Int32 nLineWidth = convertEmuToHmm( moLineWidth.get( 0 ) ); + // create line dash from preset dash token (not for invisible line) if( (eLineStyle != LineStyle_NONE) && (moPresetDash.differsFrom( XML_solid ) || (!moPresetDash && !maCustomDash.empty())) ) { @@ -416,10 +419,10 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM lclConvertCustomDash( aLineDash, maCustomDash ); // convert relative dash/dot length to absolute length - sal_Int32 nLineWidth = GetCoordinate( moLineWidth.get( 103500 ) ); - aLineDash.DotLen *= nLineWidth; - aLineDash.DashLen *= nLineWidth; - aLineDash.Distance *= nLineWidth; + sal_Int32 nBaseLineWidth = ::std::max< sal_Int32 >( nLineWidth, 35 ); + aLineDash.DotLen *= nBaseLineWidth; + aLineDash.DashLen *= nBaseLineWidth; + aLineDash.Distance *= nBaseLineWidth; if( rPropIds.mbNamedLineDash ) { @@ -444,9 +447,8 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM if( moLineJoint.has() ) rPropMap.setProperty( rPropIds[ LineJointId ], lclGetLineJoint( moLineJoint.get() ) ); - // convert line width from EMUs to 1/100 mm - if( moLineWidth.has() ) - rPropMap.setProperty( rPropIds[ LineWidthId ], GetCoordinate( moLineWidth.get() ) ); + // line width in 1/100mm + rPropMap.setProperty( rPropIds[ LineWidthId ], nLineWidth ); // line color and transparence Color aLineColor = maLineFill.getBestSolidColor(); @@ -458,8 +460,8 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM } // line markers - lclPushMarkerProperties( rPropMap, maStartArrow, rModelObjHelper, rPropIds, moLineWidth.get( 0 ), false ); - lclPushMarkerProperties( rPropMap, maEndArrow, rModelObjHelper, rPropIds, moLineWidth.get( 0 ), true ); + lclPushMarkerProperties( rPropMap, maStartArrow, rModelObjHelper, rPropIds, nLineWidth, false ); + lclPushMarkerProperties( rPropMap, maEndArrow, rModelObjHelper, rPropIds, nLineWidth, true ); } } diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index ba51c3577a8e..2850d422e234 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -76,6 +76,9 @@ CharUnderlineHasColor CharWeight CharWeightAsian CharWeightComplex +CircleEndAngle +CircleKind +CircleStartAngle CodeName Color ColumnGrand @@ -301,6 +304,7 @@ PercentageNumberFormat PersistName Perspective PolyPolygon +PolygonKind Position PositionBottom PositionLeft diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx index d9a58eafb9d8..e1607e99e6c6 100755 --- a/oox/source/xls/drawingmanager.cxx +++ b/oox/source/xls/drawingmanager.cxx @@ -28,9 +28,18 @@ #include "oox/xls/drawingmanager.hxx" #include +#include +#include +#include #include +#include "oox/core/filterbase.hxx" +#include "oox/drawingml/lineproperties.hxx" +#include "oox/helper/propertymap.hxx" +#include "oox/helper/propertyset.hxx" #include "oox/xls/biffinputstream.hxx" #include "oox/xls/unitconverter.hxx" +#include "properties.hxx" +#include "tokens.hxx" namespace oox { namespace xls { @@ -115,6 +124,13 @@ const sal_uInt8 BIFF_OBJ_LINE_TR = 1; const sal_uInt8 BIFF_OBJ_LINE_BR = 2; const sal_uInt8 BIFF_OBJ_LINE_BL = 3; +const sal_uInt8 BIFF_OBJ_ARC_TR = 0; +const sal_uInt8 BIFF_OBJ_ARC_TL = 1; +const sal_uInt8 BIFF_OBJ_ARC_BL = 2; +const sal_uInt8 BIFF_OBJ_ARC_BR = 3; + +const sal_uInt16 BIFF_OBJ_POLY_CLOSED = 0x0100; + // fill formatting ------------------------------------------------------------ const sal_uInt8 BIFF_OBJ_FILL_AUTOCOLOR = 65; @@ -170,23 +186,21 @@ BiffObjLineModel::BiffObjLineModel() : mnColorIdx( BIFF_OBJ_LINE_AUTOCOLOR ), mnStyle( BIFF_OBJ_LINE_SOLID ), mnWidth( BIFF_OBJ_LINE_HAIR ), - mnAuto( BIFF_OBJ_LINE_AUTO ) -{ -} - -bool BiffObjLineModel::isAuto() const + mbAuto( true ) { - return getFlag( mnAuto, BIFF_OBJ_LINE_AUTO ); } bool BiffObjLineModel::isVisible() const { - return isAuto() || (mnStyle != BIFF_OBJ_LINE_NONE); + return mbAuto || (mnStyle != BIFF_OBJ_LINE_NONE); } BiffInputStream& operator>>( BiffInputStream& rStrm, BiffObjLineModel& rModel ) { - return rStrm >> rModel.mnColorIdx >> rModel.mnStyle >> rModel.mnWidth >> rModel.mnAuto; + sal_uInt8 nFlags; + rStrm >> rModel.mnColorIdx >> rModel.mnStyle >> rModel.mnWidth >> nFlags; + rModel.mbAuto = getFlag( nFlags, BIFF_OBJ_LINE_AUTO ); + return rStrm; } // ============================================================================ @@ -195,23 +209,21 @@ BiffObjFillModel::BiffObjFillModel() : mnBackColorIdx( BIFF_OBJ_LINE_AUTOCOLOR ), mnPattColorIdx( BIFF_OBJ_FILL_AUTOCOLOR ), mnPattern( BIFF_OBJ_PATT_SOLID ), - mnAuto( BIFF_OBJ_FILL_AUTO ) + mbAuto( true ) { } -bool BiffObjFillModel::isAuto() const -{ - return getFlag( mnAuto, BIFF_OBJ_FILL_AUTO ); -} - bool BiffObjFillModel::isFilled() const { - return isAuto() || (mnPattern != BIFF_OBJ_PATT_NONE); + return mbAuto || (mnPattern != BIFF_OBJ_PATT_NONE); } BiffInputStream& operator>>( BiffInputStream& rStrm, BiffObjFillModel& rModel ) { - return rStrm >> rModel.mnBackColorIdx >> rModel.mnPattColorIdx >> rModel.mnPattern >> rModel.mnAuto; + sal_uInt8 nFlags; + rStrm >> rModel.mnBackColorIdx >> rModel.mnPattColorIdx >> rModel.mnPattern >> nFlags; + rModel.mbAuto = getFlag( nFlags, BIFF_OBJ_FILL_AUTO ); + return rStrm; } // ============================================================================ @@ -335,15 +347,17 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase() case BIFF_OBJTYPE_LINE: xDrawingObj.reset( new BiffLineObject( rHelper ) ); break; case BIFF_OBJTYPE_RECTANGLE: xDrawingObj.reset( new BiffRectObject( rHelper ) ); break; case BIFF_OBJTYPE_OVAL: xDrawingObj.reset( new BiffOvalObject( rHelper ) ); break; + case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new BiffArcObject( rHelper ) ); break; #if 0 - case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new XclImpArcObj( rHelper ) ); break; case BIFF_OBJTYPE_CHART: xDrawingObj.reset( new XclImpChartObj( rHelper ) ); break; case BIFF_OBJTYPE_TEXT: xDrawingObj.reset( new XclImpTextObj( rHelper ) ); break; case BIFF_OBJTYPE_BUTTON: xDrawingObj.reset( new XclImpButtonObj( rHelper ) ); break; case BIFF_OBJTYPE_PICTURE: xDrawingObj.reset( new XclImpPictureObj( rHelper ) ); break; #endif default: +#if 0 OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff3 - unknown object type" ); +#endif xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) ); } } @@ -367,16 +381,18 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase() case BIFF_OBJTYPE_LINE: xDrawingObj.reset( new BiffLineObject( rHelper ) ); break; case BIFF_OBJTYPE_RECTANGLE: xDrawingObj.reset( new BiffRectObject( rHelper ) ); break; case BIFF_OBJTYPE_OVAL: xDrawingObj.reset( new BiffOvalObject( rHelper ) ); break; + case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new BiffArcObject( rHelper ) ); break; + case BIFF_OBJTYPE_POLYGON: xDrawingObj.reset( new BiffPolygonObject( rHelper ) ); break; #if 0 - case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new XclImpArcObj( rHelper ) ); break; case BIFF_OBJTYPE_CHART: xDrawingObj.reset( new XclImpChartObj( rHelper ) ); break; case BIFF_OBJTYPE_TEXT: xDrawingObj.reset( new XclImpTextObj( rHelper ) ); break; case BIFF_OBJTYPE_BUTTON: xDrawingObj.reset( new XclImpButtonObj( rHelper ) ); break; case BIFF_OBJTYPE_PICTURE: xDrawingObj.reset( new XclImpPictureObj( rHelper ) ); break; - case BIFF_OBJTYPE_POLYGON: xDrawingObj.reset( new XclImpPolygonObj( rHelper ) ); break; #endif default: +#if 0 OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff4 - unknown object type" ); +#endif xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) ); } } @@ -399,14 +415,14 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase() case BIFF_OBJTYPE_GROUP: xDrawingObj.reset( new BiffGroupObject( rHelper ) ); break; case BIFF_OBJTYPE_LINE: xDrawingObj.reset( new BiffLineObject( rHelper ) ); break; case BIFF_OBJTYPE_RECTANGLE: xDrawingObj.reset( new BiffRectObject( rHelper ) ); break; - case BIFF_OBJTYPE_OVAL: xDrawingObj.reset( new BiffOvalObject( rHelper ) ); break; + case BIFF_OBJTYPE_OVAL: xDrawingObj.reset( new BiffOvalObject( rHelper ) ); break; + case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new BiffArcObject( rHelper ) ); break; + case BIFF_OBJTYPE_POLYGON: xDrawingObj.reset( new BiffPolygonObject( rHelper ) ); break; #if 0 - case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new XclImpArcObj( rHelper ) ); break; case BIFF_OBJTYPE_CHART: xDrawingObj.reset( new XclImpChartObj( rHelper ) ); break; case BIFF_OBJTYPE_TEXT: xDrawingObj.reset( new XclImpTextObj( rHelper ) ); break; case BIFF_OBJTYPE_BUTTON: xDrawingObj.reset( new XclImpButtonObj( rHelper ) ); break; case BIFF_OBJTYPE_PICTURE: xDrawingObj.reset( new XclImpPictureObj( rHelper ) ); break; - case BIFF_OBJTYPE_POLYGON: xDrawingObj.reset( new XclImpPolygonObj( rHelper ) ); break; case BIFF_OBJTYPE_CHECKBOX: xDrawingObj.reset( new XclImpCheckBoxObj( rHelper ) ); break; case BIFF_OBJTYPE_OPTIONBUTTON: xDrawingObj.reset( new XclImpOptionButtonObj( rHelper ) ); break; case BIFF_OBJTYPE_EDIT: xDrawingObj.reset( new XclImpEditObj( rHelper ) ); break; @@ -419,7 +435,9 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase() case BIFF_OBJTYPE_DROPDOWN: xDrawingObj.reset( new XclImpDropDownObj( rHelper ) ); break; #endif default: +#if 0 OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff5 - unknown object type" ); +#endif xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) ); } } @@ -447,7 +465,7 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase() case BIFF_OBJTYPE_ARC: xDrawingObj.reset( new XclImpTextObj( rHelper ) ); // lines and arcs may be 2-dimensional - xDrawingObj->SetAreaObj( false ); + xDrawingObj->setAreaObj( false ); break; // in BIFF8, all simple objects support text @@ -479,7 +497,9 @@ BiffDrawingObjectBase::~BiffDrawingObjectBase() #endif default: +#if 0 OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff8 - unknown object type" ); +#endif xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) ); } } @@ -574,6 +594,210 @@ void BiffDrawingObjectBase::readMacroBiff8( BiffInputStream& rStrm ) } } +void BiffDrawingObjectBase::convertLineProperties( PropertyMap& rPropMap, const BiffObjLineModel& rLineModel, sal_uInt16 nArrows ) const +{ + if( rLineModel.mbAuto ) + { + BiffObjLineModel aAutoModel; + aAutoModel.mbAuto = false; + convertLineProperties( rPropMap, aAutoModel, nArrows ); + return; + } + + /* Convert line formatting to DrawingML line formatting and let the + DrawingML code do the hard work. */ + LineProperties aLineProps; + + if( rLineModel.mnStyle == BIFF_OBJ_LINE_NONE ) + { + aLineProps.maLineFill.moFillType = XML_noFill; + } + else + { + aLineProps.maLineFill.moFillType = XML_solidFill; + aLineProps.maLineFill.maFillColor.setPaletteClr( rLineModel.mnColorIdx ); + aLineProps.moLineCompound = XML_sng; + aLineProps.moLineCap = XML_flat; + aLineProps.moLineJoint = XML_round; + + // line width: use 0.35 mm per BIFF line width step + sal_Int32 nLineWidth = 0; + switch( rLineModel.mnWidth ) + { + default: + case BIFF_OBJ_LINE_HAIR: nLineWidth = 0; break; + case BIFF_OBJ_LINE_THIN: nLineWidth = 20; break; + case BIFF_OBJ_LINE_MEDIUM: nLineWidth = 40; break; + case BIFF_OBJ_LINE_THICK: nLineWidth = 60; break; + } + aLineProps.moLineWidth = getLimitedValue< sal_Int32, sal_Int64 >( convertHmmToEmu( nLineWidth ), 0, SAL_MAX_INT32 ); + + // dash style and transparency + switch( rLineModel.mnStyle ) + { + default: + case BIFF_OBJ_LINE_SOLID: + aLineProps.moPresetDash = XML_solid; + break; + case BIFF_OBJ_LINE_DASH: + aLineProps.moPresetDash = XML_lgDash; + break; + case BIFF_OBJ_LINE_DOT: + aLineProps.moPresetDash = XML_dot; + break; + case BIFF_OBJ_LINE_DASHDOT: + aLineProps.moPresetDash = XML_lgDashDot; + break; + case BIFF_OBJ_LINE_DASHDOTDOT: + aLineProps.moPresetDash = XML_lgDashDotDot; + break; + case BIFF_OBJ_LINE_MEDTRANS: + aLineProps.moPresetDash = XML_solid; + aLineProps.maLineFill.maFillColor.addTransformation( XML_alpha, 50 * PER_PERCENT ); + break; + case BIFF_OBJ_LINE_DARKTRANS: + aLineProps.moPresetDash = XML_solid; + aLineProps.maLineFill.maFillColor.addTransformation( XML_alpha, 75 * PER_PERCENT ); + break; + case BIFF_OBJ_LINE_LIGHTTRANS: + aLineProps.moPresetDash = XML_solid; + aLineProps.maLineFill.maFillColor.addTransformation( XML_alpha, 25 * PER_PERCENT ); + break; + } + + // line ends + bool bLineStart = false; + bool bLineEnd = false; + bool bFilled = false; + switch( extractValue< sal_uInt8 >( nArrows, 0, 4 ) ) + { + case BIFF_OBJ_ARROW_OPEN: bLineStart = false; bLineEnd = true; bFilled = false; break; + case BIFF_OBJ_ARROW_OPENBOTH: bLineStart = true; bLineEnd = true; bFilled = false; break; + case BIFF_OBJ_ARROW_FILLED: bLineStart = false; bLineEnd = true; bFilled = true; break; + case BIFF_OBJ_ARROW_FILLEDBOTH: bLineStart = true; bLineEnd = true; bFilled = true; break; + } + if( bLineStart || bLineEnd ) + { + // arrow type (open or closed) + sal_Int32 nArrowType = bFilled ? XML_triangle : XML_arrow; + aLineProps.maStartArrow.moArrowType = bLineStart ? nArrowType : XML_none; + aLineProps.maEndArrow.moArrowType = bLineEnd ? nArrowType : XML_none; + + // arrow width + sal_Int32 nArrowWidth = XML_med; + switch( extractValue< sal_uInt8 >( nArrows, 4, 4 ) ) + { + case BIFF_OBJ_ARROW_NARROW: nArrowWidth = XML_sm; break; + case BIFF_OBJ_ARROW_MEDIUM: nArrowWidth = XML_med; break; + case BIFF_OBJ_ARROW_WIDE: nArrowWidth = XML_lg; break; + } + aLineProps.maStartArrow.moArrowWidth = aLineProps.maEndArrow.moArrowWidth = nArrowWidth; + + // arrow length + sal_Int32 nArrowLength = XML_med; + switch( extractValue< sal_uInt8 >( nArrows, 8, 4 ) ) + { + case BIFF_OBJ_ARROW_NARROW: nArrowLength = XML_sm; break; + case BIFF_OBJ_ARROW_MEDIUM: nArrowLength = XML_med; break; + case BIFF_OBJ_ARROW_WIDE: nArrowLength = XML_lg; break; + } + aLineProps.maStartArrow.moArrowLength = aLineProps.maEndArrow.moArrowLength = nArrowLength; + } + } + + aLineProps.pushToPropMap( rPropMap, getBaseFilter().getModelObjectHelper(), getBaseFilter().getGraphicHelper() ); +} + +void BiffDrawingObjectBase::convertFillProperties( PropertyMap& rPropMap, const BiffObjFillModel& rFillModel ) const +{ + if( rFillModel.mbAuto ) + { + BiffObjFillModel aAutoModel; + aAutoModel.mbAuto = false; + convertFillProperties( rPropMap, aAutoModel ); + return; + } + + /* Convert fill formatting to DrawingML fill formatting and let the + DrawingML code do the hard work. */ + FillProperties aFillProps; + + if( rFillModel.mnPattern == BIFF_OBJ_PATT_NONE ) + { + aFillProps.moFillType = XML_noFill; + } + else + { + const sal_Int32 spnPatternPresets[] = { + XML_TOKEN_INVALID, XML_TOKEN_INVALID, XML_pct50, XML_pct50, XML_pct25, + XML_dkHorz, XML_dkVert, XML_dkDnDiag, XML_dkUpDiag, XML_smCheck, XML_trellis, + XML_ltHorz, XML_ltVert, XML_ltDnDiag, XML_ltUpDiag, XML_smGrid, XML_diagCross, + XML_pct20, XML_pct10 }; + sal_Int32 nPatternPreset = STATIC_ARRAY_SELECT( spnPatternPresets, rFillModel.mnPattern, XML_TOKEN_INVALID ); + if( nPatternPreset == XML_TOKEN_INVALID ) + { + aFillProps.moFillType = XML_solidFill; + aFillProps.maFillColor.setPaletteClr( rFillModel.mnPattColorIdx ); + } + else + { + aFillProps.moFillType = XML_pattFill; + aFillProps.maPatternProps.maPattFgColor.setPaletteClr( rFillModel.mnPattColorIdx ); + aFillProps.maPatternProps.maPattBgColor.setPaletteClr( rFillModel.mnBackColorIdx ); + aFillProps.maPatternProps.moPattPreset = nPatternPreset; + } +#if 0 + static const sal_uInt8 sppnPatterns[][ 8 ] = + { + { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 }, + { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD }, + { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 }, + { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 }, + { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }, + { 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 }, + { 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99 }, + { 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 }, + { 0xCC, 0xFF, 0x33, 0xFF, 0xCC, 0xFF, 0x33, 0xFF }, + { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 }, + { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, + { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, + { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, + { 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x11, 0x11, 0x11 }, + { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 }, + { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 }, + { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00 } + }; + const sal_uInt8* const pnPattern = sppnPatterns[ ::std::min< size_t >( rFillData.mnPattern - 2, STATIC_ARRAY_SIZE( sppnPatterns ) ) ]; + // create 2-colored 8x8 DIB + SvMemoryStream aMemStrm; +// { 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00 } + aMemStrm << sal_uInt32( 12 ) << sal_Int16( 8 ) << sal_Int16( 8 ) << sal_uInt16( 1 ) << sal_uInt16( 1 ); + aMemStrm << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF ); + aMemStrm << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 ); + for( size_t nIdx = 0; nIdx < 8; ++nIdx ) + aMemStrm << sal_uInt32( pnPattern[ nIdx ] ); // 32-bit little-endian + aMemStrm.Seek( STREAM_SEEK_TO_BEGIN ); + Bitmap aBitmap; + aBitmap.Read( aMemStrm, FALSE ); + XOBitmap aXOBitmap( aBitmap ); + aXOBitmap.Bitmap2Array(); + aXOBitmap.SetBitmapType( XBITMAP_8X8 ); + if( aXOBitmap.GetBackgroundColor().GetColor() == COL_BLACK ) + ::std::swap( aPattColor, aBackColor ); + aXOBitmap.SetPixelColor( aPattColor ); + aXOBitmap.SetBackgroundColor( aBackColor ); + rSdrObj.SetMergedItem( XFillStyleItem( XFILL_BITMAP ) ); + rSdrObj.SetMergedItem( XFillBitmapItem( EMPTY_STRING, aXOBitmap ) ); +#endif + } + + aFillProps.pushToPropMap( rPropMap, getBaseFilter().getModelObjectHelper(), getBaseFilter().getGraphicHelper() ); +} + +void BiffDrawingObjectBase::convertFrameProperties( PropertyMap& /*rPropMap*/, sal_uInt16 /*nFrameFlags*/ ) const +{ +} + void BiffDrawingObjectBase::implReadObjBiff3( BiffInputStream& /*rStrm*/, sal_uInt16 /*nMacroSize*/ ) { } @@ -820,7 +1044,33 @@ void BiffLineObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameL Reference< XShape > BiffLineObject::implConvertAndInsert( BiffDrawingBase& rDrawing, const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - return rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.LineShape" ), rxShapes, rShapeRect ); + PropertyMap aPropMap; + convertLineProperties( aPropMap, maLineModel, mnArrows ); + + // create the line polygon + PointSequenceSequence aPoints( 1 ); + aPoints[ 0 ].realloc( 2 ); + Point& rBeg = aPoints[ 0 ][ 0 ]; + Point& rEnd = aPoints[ 0 ][ 1 ]; + sal_Int32 nL = rShapeRect.X; + sal_Int32 nT = rShapeRect.Y; + sal_Int32 nR = rShapeRect.X + ::std::max< sal_Int32 >( rShapeRect.Width - 1, 0 ); + sal_Int32 nB = rShapeRect.Y + ::std::max< sal_Int32 >( rShapeRect.Height - 1, 0 ); + switch( mnStartPoint ) + { + default: + case BIFF_OBJ_LINE_TL: rBeg.X = nL; rBeg.Y = nT; rEnd.X = nR; rEnd.Y = nB; break; + case BIFF_OBJ_LINE_TR: rBeg.X = nR; rBeg.Y = nT; rEnd.X = nL; rEnd.Y = nB; break; + case BIFF_OBJ_LINE_BR: rBeg.X = nR; rBeg.Y = nB; rEnd.X = nL; rEnd.Y = nT; break; + case BIFF_OBJ_LINE_BL: rBeg.X = nL; rBeg.Y = nB; rEnd.X = nR; rEnd.Y = nT; break; + } + aPropMap.setProperty( PROP_PolyPolygon, aPoints ); + aPropMap.setProperty( PROP_PolygonKind, PolygonKind_LINE ); + + // create the shape + Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.LineShape" ), rxShapes, rShapeRect ); + PropertySet( xShape ).setProperties( aPropMap ); + return xShape; } // ============================================================================ @@ -837,6 +1087,13 @@ void BiffRectObject::readFrameData( BiffInputStream& rStrm ) rStrm >> maFillModel >> maLineModel >> mnFrameFlags; } +void BiffRectObject::convertRectProperties( PropertyMap& rPropMap ) const +{ + convertLineProperties( rPropMap, maLineModel ); + convertFillProperties( rPropMap, maFillModel ); + convertFrameProperties( rPropMap, mnFrameFlags ); +} + void BiffRectObject::implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) { readFrameData( rStrm ); @@ -859,7 +1116,12 @@ void BiffRectObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameL Reference< XShape > BiffRectObject::implConvertAndInsert( BiffDrawingBase& rDrawing, const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - return rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ), rxShapes, rShapeRect ); + PropertyMap aPropMap; + convertRectProperties( aPropMap ); + + Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ), rxShapes, rShapeRect ); + PropertySet( xShape ).setProperties( aPropMap ); + return xShape; } // ============================================================================ @@ -872,7 +1134,165 @@ BiffOvalObject::BiffOvalObject( const WorksheetHelper& rHelper ) : Reference< XShape > BiffOvalObject::implConvertAndInsert( BiffDrawingBase& rDrawing, const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - return rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ), rxShapes, rShapeRect ); + PropertyMap aPropMap; + convertRectProperties( aPropMap ); + + Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ), rxShapes, rShapeRect ); + PropertySet( xShape ).setProperties( aPropMap ); + return xShape; +} + +// ============================================================================ + +BiffArcObject::BiffArcObject( const WorksheetHelper& rHelper ) : + BiffDrawingObjectBase( rHelper ), + mnQuadrant( BIFF_OBJ_ARC_TR ) +{ + setAreaObj( false ); // arc may be 2-dimensional +} + +void BiffArcObject::implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + rStrm >> maFillModel >> maLineModel >> mnQuadrant; + rStrm.skip( 1 ); + readMacroBiff3( rStrm, nMacroSize ); +} + +void BiffArcObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + rStrm >> maFillModel >> maLineModel >> mnQuadrant; + rStrm.skip( 1 ); + readMacroBiff4( rStrm, nMacroSize ); +} + +void BiffArcObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) +{ + rStrm >> maFillModel >> maLineModel >> mnQuadrant; + rStrm.skip( 1 ); + readNameBiff5( rStrm, nNameLen ); + readMacroBiff5( rStrm, nMacroSize ); +} + +Reference< XShape > BiffArcObject::implConvertAndInsert( BiffDrawingBase& rDrawing, + const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +{ + PropertyMap aPropMap; + convertLineProperties( aPropMap, maLineModel ); + convertFillProperties( aPropMap, maFillModel ); + + /* Simulate arc objects with ellipse sections. While the original arc + object uses the entire object rectangle, only one quarter of the + ellipse shape will be visible. Thus, the size of the ellipse shape + needs to be extended and its position adjusted according to the visible + quadrant. */ + Rectangle aNewRect( rShapeRect.X, rShapeRect.Y, rShapeRect.Width * 2, rShapeRect.Height * 2 ); + long nStartAngle = 0; + switch( mnQuadrant ) + { + default: + case BIFF_OBJ_ARC_TR: nStartAngle = 0; aNewRect.X -= rShapeRect.Width; break; + case BIFF_OBJ_ARC_TL: nStartAngle = 9000; break; + case BIFF_OBJ_ARC_BL: nStartAngle = 18000; aNewRect.Y -= rShapeRect.Height; break; + case BIFF_OBJ_ARC_BR: nStartAngle = 27000; aNewRect.X -= rShapeRect.Width; aNewRect.Y -= rShapeRect.Height; break; + } + long nEndAngle = (nStartAngle + 9000) % 36000; + aPropMap.setProperty( PROP_CircleKind, maFillModel.isFilled() ? CircleKind_SECTION : CircleKind_ARC ); + aPropMap.setProperty( PROP_CircleStartAngle, nStartAngle ); + aPropMap.setProperty( PROP_CircleEndAngle, nEndAngle ); + + // create the shape + Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ), rxShapes, aNewRect ); + PropertySet( xShape ).setProperties( aPropMap ); + return xShape; +} + +// ============================================================================ + +BiffPolygonObject::BiffPolygonObject( const WorksheetHelper& rHelper ) : + BiffRectObject( rHelper ), + mnPolyFlags( 0 ), + mnPointCount( 0 ) +{ + setAreaObj( false ); // polygon may be 2-dimensional +} + +void BiffPolygonObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize ) +{ + readFrameData( rStrm ); + rStrm >> mnPolyFlags; + rStrm.skip( 10 ); + rStrm >> mnPointCount; + rStrm.skip( 8 ); + readMacroBiff4( rStrm, nMacroSize ); + importCoordList( rStrm ); +} + +void BiffPolygonObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) +{ + readFrameData( rStrm ); + rStrm >> mnPolyFlags; + rStrm.skip( 10 ); + rStrm >> mnPointCount; + rStrm.skip( 8 ); + readNameBiff5( rStrm, nNameLen ); + readMacroBiff5( rStrm, nMacroSize ); + importCoordList( rStrm ); +} + +namespace { + +Point lclGetPolyPoint( const Rectangle& rAnchorRect, const Point& rPoint ) +{ + // polygon coordinates are given in 1/16384 of shape size + return Point( + rAnchorRect.X + static_cast< sal_Int32 >( rAnchorRect.Width * getLimitedValue< double >( static_cast< double >( rPoint.X ) / 16384.0, 0.0, 1.0 ) + 0.5 ), + rAnchorRect.Y + static_cast< sal_Int32 >( rAnchorRect.Height * getLimitedValue< double >( static_cast< double >( rPoint.Y ) / 16384.0, 0.0, 1.0 ) + 0.5 ) ); +} + +} // namespace + +Reference< XShape > BiffPolygonObject::implConvertAndInsert( BiffDrawingBase& rDrawing, + const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +{ + Reference< XShape > xShape; + if( maCoords.size() >= 2 ) + { + PropertyMap aPropMap; + convertRectProperties( aPropMap ); + + // create the polygon + PointVector aPolygon; + for( PointVector::const_iterator aIt = maCoords.begin(), aEnd = maCoords.end(); aIt != aEnd; ++aIt ) + aPolygon.push_back( lclGetPolyPoint( rShapeRect, *aIt ) ); + // close polygon if specified + if( getFlag( mnPolyFlags, BIFF_OBJ_POLY_CLOSED ) && ((maCoords.front().X != maCoords.back().X) || (maCoords.front().Y != maCoords.back().Y)) ) + aPolygon.push_back( aPolygon.front() ); + PointSequenceSequence aPoints( 1 ); + aPoints[ 0 ] = ContainerHelper::vectorToSequence( aPolygon ); + aPropMap.setProperty( PROP_PolyPolygon, aPoints ); + + // create the shape + OUString aService = maFillModel.isFilled() ? + CREATE_OUSTRING( "com.sun.star.drawing.PolyPolygonShape" ) : + CREATE_OUSTRING( "com.sun.star.drawing.PolyLineShape" ); + xShape = rDrawing.createAndInsertXShape( aService, rxShapes, rShapeRect ); + PropertySet( xShape ).setProperties( aPropMap ); + } + return xShape; +} + +void BiffPolygonObject::importCoordList( BiffInputStream& rStrm ) +{ + if( (rStrm.getNextRecId() == BIFF_ID_COORDLIST) && rStrm.startNextRecord() ) + { + OSL_ENSURE( rStrm.getRemaining() / 4 == mnPointCount, "BiffPolygonObject::importCoordList - wrong polygon point count" ); + while( rStrm.getRemaining() >= 4 ) + { + sal_uInt16 nX, nY; + rStrm >> nX >> nY; + maCoords.push_back( Point( nX, nY ) ); + } + } } // ============================================================================ diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index 626d3b962ceb..cbdb564ac7c5 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -162,8 +162,6 @@ struct ValueRangeComp inline bool operator()( const ValueRange& rRange, sal_Int32 nValue ) const { return rRange.mnLast < nValue; } }; -typedef ::std::vector< ValueRange > ValueRangeVector; - // ---------------------------------------------------------------------------- class ValueRangeSet -- cgit From d4c7fa84b7856918328bee20a5387cb32442bec3 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Tue, 11 Jan 2011 13:26:59 +0100 Subject: dr78: oox - encapsulate shape property handling in own class ShapePropertyMap --- oox/source/drawingml/chart/objectformatter.cxx | 214 ++++++++++++------------- oox/source/drawingml/color.cxx | 4 +- oox/source/drawingml/fillproperties.cxx | 121 +++----------- oox/source/drawingml/lineproperties.cxx | 148 ++++++----------- oox/source/drawingml/makefile.mk | 1 + oox/source/drawingml/shape.cxx | 30 ++-- oox/source/drawingml/shapepropertymap.cxx | 195 ++++++++++++++++++++++ oox/source/drawingml/table/tablecell.cxx | 8 +- oox/source/helper/modelobjecthelper.cxx | 18 +-- oox/source/helper/propertymap.cxx | 4 - oox/source/helper/propertyset.cxx | 49 ++---- oox/source/ppt/slidefragmenthandler.cxx | 2 +- oox/source/ppt/slidepersist.cxx | 26 +-- oox/source/token/properties.txt | 1 + oox/source/vml/vmlformatting.cxx | 11 +- oox/source/vml/vmlshape.cxx | 14 +- oox/source/xls/drawingmanager.cxx | 26 +-- 17 files changed, 448 insertions(+), 424 deletions(-) create mode 100755 oox/source/drawingml/shapepropertymap.cxx (limited to 'oox/source') diff --git a/oox/source/drawingml/chart/objectformatter.cxx b/oox/source/drawingml/chart/objectformatter.cxx index d96e2d43dd6f..8fd1a376abd6 100644 --- a/oox/source/drawingml/chart/objectformatter.cxx +++ b/oox/source/drawingml/chart/objectformatter.cxx @@ -32,14 +32,15 @@ #include #include "properties.hxx" #include "tokens.hxx" -#include "oox/helper/modelobjecthelper.hxx" #include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/fillproperties.hxx" #include "oox/drawingml/lineproperties.hxx" +#include "oox/drawingml/shapepropertymap.hxx" #include "oox/drawingml/textbody.hxx" #include "oox/drawingml/textparagraph.hxx" #include "oox/drawingml/theme.hxx" #include "oox/drawingml/chart/chartspacemodel.hxx" +#include "oox/helper/modelobjecthelper.hxx" using ::rtl::OStringBuffer; using ::rtl::OUString; @@ -494,19 +495,50 @@ const AutoTextEntry* lclGetAutoTextEntry( const AutoTextEntry* pEntries, sal_Int // ---------------------------------------------------------------------------- -/** Enumerates different sets of property names for chart object formatting. */ -enum PropertyType +/** Property identifiers for common chart objects, to be used in ShapePropertyInfo. */ +static const sal_Int32 spnCommonPropIds[] = +{ + PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDashName, + PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, + PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_FillGradientName, + PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY, + PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint +}; + +/** Property identifiers for linear data series, to be used in ShapePropertyInfo. */ +static const sal_Int32 spnLinearPropIds[] = { - PROPERTYTYPE_COMMON, /// Common objects, no special handling. - PROPERTYTYPE_LINEARSERIES, /// Specific to linear data series. - PROPERTYTYPE_FILLEDSERIES /// Specific to filled data series. + PROP_LineStyle, PROP_LineWidth, PROP_Color, PROP_Transparency, PROP_LineDashName, + PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, + PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, + PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, + PROP_INVALID, PROP_INVALID, PROP_INVALID }; +/** Property identifiers for filled data series, to be used in ShapePropertyInfo. */ +static const sal_Int32 spnFilledPropIds[] = +{ + PROP_BorderStyle, PROP_BorderWidth, PROP_BorderColor, PROP_BorderTransparency, PROP_BorderDashName, + PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, + PROP_FillStyle, PROP_Color, PROP_Transparency, PROP_GradientName, + PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY, + PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint +}; + +/** Property info for common chart objects, to be used in ShapePropertyMap. */ +static const ShapePropertyInfo saCommonPropInfo( spnCommonPropIds, false, true, true, true ); +/** Property info for linear data series, to be used in ShapePropertyMap. */ +static const ShapePropertyInfo saLinearPropInfo( spnLinearPropIds, false, true, true, true ); +/** Property info for filled data series, to be used in ShapePropertyMap. */ +static const ShapePropertyInfo saFilledPropInfo( spnFilledPropIds, false, true, true, true ); + +// ---------------------------------------------------------------------------- + /** Contains information about formatting of a specific chart object type. */ struct ObjectTypeFormatEntry { ObjectType meObjType; /// Object type for automatic format. - PropertyType mePropType; /// Property type for property names. + const ShapePropertyInfo* mpPropInfo; /// Property info for the ShapePropertyMap class. const AutoFormatEntry* mpAutoLines; /// Automatic line formatting for all chart styles. const AutoFormatEntry* mpAutoFills; /// Automatic fill formatting for all chart styles. const AutoFormatEntry* mpAutoEffects; /// Automatic effect formatting for all chart styles. @@ -522,37 +554,38 @@ struct ObjectTypeFormatEntry static const ObjectTypeFormatEntry spObjTypeFormatEntries[] = { - // object type property type auto text auto line auto fill auto effect - TYPEFORMAT_FRAME( OBJECTTYPE_CHARTSPACE, PROPERTYTYPE_COMMON, 0, spChartSpaceLines, spChartSpaceFills, 0 /* eq to Ch2 */ ), - TYPEFORMAT_FRAME( OBJECTTYPE_CHARTTITLE, PROPERTYTYPE_COMMON, spChartTitleTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ), - TYPEFORMAT_FRAME( OBJECTTYPE_LEGEND, PROPERTYTYPE_COMMON, spOtherTexts, spNoFormats, spNoFormats, 0 /* eq to Ch2 */ ), - TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA2D, PROPERTYTYPE_COMMON, 0, 0 /* eq to Ch2 */, spPlotArea2dFills, 0 /* eq to Ch2 */ ), - TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA3D, PROPERTYTYPE_COMMON, 0, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ), - TYPEFORMAT_FRAME( OBJECTTYPE_WALL, PROPERTYTYPE_COMMON, 0, 0 /* eq to Ch2 */, spWallFloorFills, 0 /* eq to Ch2 */ ), - TYPEFORMAT_FRAME( OBJECTTYPE_FLOOR, PROPERTYTYPE_COMMON, 0, spFloorLines, spWallFloorFills, 0 /* eq to Ch2 */ ), - TYPEFORMAT_LINE( OBJECTTYPE_AXIS, PROPERTYTYPE_COMMON, spOtherTexts, spAxisLines ), - TYPEFORMAT_FRAME( OBJECTTYPE_AXISTITLE, PROPERTYTYPE_COMMON, spAxisTitleTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ), - TYPEFORMAT_FRAME( OBJECTTYPE_AXISUNIT, PROPERTYTYPE_COMMON, spAxisTitleTexts, 0 /* eq in Ch2 */, 0 /* eq in Ch2 */, 0 /* eq in Ch2 */ ), - TYPEFORMAT_LINE( OBJECTTYPE_MAJORGRIDLINE, PROPERTYTYPE_COMMON, 0, spMajorGridLines ), - TYPEFORMAT_LINE( OBJECTTYPE_MINORGRIDLINE, PROPERTYTYPE_COMMON, 0, spMinorGridLines ), - TYPEFORMAT_LINE( OBJECTTYPE_LINEARSERIES2D, PROPERTYTYPE_LINEARSERIES, 0, spLinearSeriesLines ), - TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES2D, PROPERTYTYPE_FILLEDSERIES, 0, spFilledSeriesLines, spFilledSeries2dFills, spFilledSeriesEffects ), - TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES3D, PROPERTYTYPE_FILLEDSERIES, 0, spFilledSeriesLines, spFilledSeries3dFills, spFilledSeriesEffects ), - TYPEFORMAT_FRAME( OBJECTTYPE_DATALABEL, PROPERTYTYPE_COMMON, spOtherTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ), - TYPEFORMAT_LINE( OBJECTTYPE_TRENDLINE, PROPERTYTYPE_COMMON, 0, spOtherLines ), - TYPEFORMAT_FRAME( OBJECTTYPE_TRENDLINELABEL, PROPERTYTYPE_COMMON, spOtherTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ), - TYPEFORMAT_LINE( OBJECTTYPE_ERRORBAR, PROPERTYTYPE_COMMON, 0, spOtherLines ), - TYPEFORMAT_LINE( OBJECTTYPE_SERLINE, PROPERTYTYPE_COMMON, 0, spOtherLines ), - TYPEFORMAT_LINE( OBJECTTYPE_LEADERLINE, PROPERTYTYPE_COMMON, 0, spOtherLines ), - TYPEFORMAT_LINE( OBJECTTYPE_DROPLINE, PROPERTYTYPE_COMMON, 0, spOtherLines ), - TYPEFORMAT_LINE( OBJECTTYPE_HILOLINE, PROPERTYTYPE_LINEARSERIES, 0, spOtherLines ), - TYPEFORMAT_FRAME( OBJECTTYPE_UPBAR, PROPERTYTYPE_COMMON, 0, spUpDownBarLines, spUpBarFills, spUpDownBarEffects ), - TYPEFORMAT_FRAME( OBJECTTYPE_DOWNBAR, PROPERTYTYPE_COMMON, 0, spUpDownBarLines, spDownBarFills, spUpDownBarEffects ), - TYPEFORMAT_LINE( OBJECTTYPE_DATATABLE, PROPERTYTYPE_COMMON, spOtherTexts, spChartSpaceLines ) + // object type property info auto text auto line auto fill auto effect + TYPEFORMAT_FRAME( OBJECTTYPE_CHARTSPACE, &saCommonPropInfo, 0, spChartSpaceLines, spChartSpaceFills, 0 /* eq to Ch2 */ ), + TYPEFORMAT_FRAME( OBJECTTYPE_CHARTTITLE, &saCommonPropInfo, spChartTitleTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ), + TYPEFORMAT_FRAME( OBJECTTYPE_LEGEND, &saCommonPropInfo, spOtherTexts, spNoFormats, spNoFormats, 0 /* eq to Ch2 */ ), + TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA2D, &saCommonPropInfo, 0, 0 /* eq to Ch2 */, spPlotArea2dFills, 0 /* eq to Ch2 */ ), + TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA3D, &saCommonPropInfo, 0, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ), + TYPEFORMAT_FRAME( OBJECTTYPE_WALL, &saCommonPropInfo, 0, 0 /* eq to Ch2 */, spWallFloorFills, 0 /* eq to Ch2 */ ), + TYPEFORMAT_FRAME( OBJECTTYPE_FLOOR, &saCommonPropInfo, 0, spFloorLines, spWallFloorFills, 0 /* eq to Ch2 */ ), + TYPEFORMAT_LINE( OBJECTTYPE_AXIS, &saCommonPropInfo, spOtherTexts, spAxisLines ), + TYPEFORMAT_FRAME( OBJECTTYPE_AXISTITLE, &saCommonPropInfo, spAxisTitleTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ), + TYPEFORMAT_FRAME( OBJECTTYPE_AXISUNIT, &saCommonPropInfo, spAxisTitleTexts, 0 /* eq in Ch2 */, 0 /* eq in Ch2 */, 0 /* eq in Ch2 */ ), + TYPEFORMAT_LINE( OBJECTTYPE_MAJORGRIDLINE, &saCommonPropInfo, 0, spMajorGridLines ), + TYPEFORMAT_LINE( OBJECTTYPE_MINORGRIDLINE, &saCommonPropInfo, 0, spMinorGridLines ), + TYPEFORMAT_LINE( OBJECTTYPE_LINEARSERIES2D, &saLinearPropInfo, 0, spLinearSeriesLines ), + TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES2D, &saFilledPropInfo, 0, spFilledSeriesLines, spFilledSeries2dFills, spFilledSeriesEffects ), + TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES3D, &saFilledPropInfo, 0, spFilledSeriesLines, spFilledSeries3dFills, spFilledSeriesEffects ), + TYPEFORMAT_FRAME( OBJECTTYPE_DATALABEL, &saCommonPropInfo, spOtherTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ), + TYPEFORMAT_LINE( OBJECTTYPE_TRENDLINE, &saCommonPropInfo, 0, spOtherLines ), + TYPEFORMAT_FRAME( OBJECTTYPE_TRENDLINELABEL, &saCommonPropInfo, spOtherTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ), + TYPEFORMAT_LINE( OBJECTTYPE_ERRORBAR, &saCommonPropInfo, 0, spOtherLines ), + TYPEFORMAT_LINE( OBJECTTYPE_SERLINE, &saCommonPropInfo, 0, spOtherLines ), + TYPEFORMAT_LINE( OBJECTTYPE_LEADERLINE, &saCommonPropInfo, 0, spOtherLines ), + TYPEFORMAT_LINE( OBJECTTYPE_DROPLINE, &saCommonPropInfo, 0, spOtherLines ), + TYPEFORMAT_LINE( OBJECTTYPE_HILOLINE, &saLinearPropInfo, 0, spOtherLines ), + TYPEFORMAT_FRAME( OBJECTTYPE_UPBAR, &saCommonPropInfo, 0, spUpDownBarLines, spUpBarFills, spUpDownBarEffects ), + TYPEFORMAT_FRAME( OBJECTTYPE_DOWNBAR, &saCommonPropInfo, 0, spUpDownBarLines, spDownBarFills, spUpDownBarEffects ), + TYPEFORMAT_LINE( OBJECTTYPE_DATATABLE, &saCommonPropInfo, spOtherTexts, spChartSpaceLines ) }; #undef TYPEFORMAT_FRAME #undef TYPEFORMAT_LINE + // ---------------------------------------------------------------------------- void lclConvertPictureOptions( FillProperties& orFillProps, const PictureOptionsModel& rPicOptions ) @@ -561,15 +594,6 @@ void lclConvertPictureOptions( FillProperties& orFillProps, const PictureOptions orFillProps.maBlipProps.moBitmapMode = bStacked ? XML_tile : XML_stretch; } -// ---------------------------------------------------------------------------- - -const sal_Int32 spnCommonLineIds[ LineId_END ] = { PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDashName, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID }; -const sal_Int32 spnLinearLineIds[ LineId_END ] = { PROP_LineStyle, PROP_LineWidth, PROP_Color, PROP_Transparency, PROP_LineDashName, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID }; -const sal_Int32 spnFilledLineIds[ LineId_END ] = { PROP_BorderStyle, PROP_BorderWidth, PROP_BorderColor, PROP_BorderTransparency, PROP_BorderDashName, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID }; - -const sal_Int32 spnCommonFillIds[ FillId_END ] = { PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_FillGradientName, PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY, PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint }; -const sal_Int32 spnFilledFillIds[ FillId_END ] = { PROP_FillStyle, PROP_Color, PROP_Transparency, PROP_GradientName, PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY, PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint }; - } // namespace // ============================================================================ @@ -611,18 +635,16 @@ class LineFormatter : public DetailFormatterBase public: explicit LineFormatter( ObjectFormatterData& rData, - const AutoFormatEntry* pAutoFormatEntry, - PropertyType ePropType ); + const AutoFormatEntry* pAutoFormatEntry ); /** Converts line formatting to the passed property set. */ void convertFormatting( - PropertySet& rPropSet, + ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, sal_Int32 nSeriesIdx ); private: LinePropertiesPtr mxAutoLine; /// Automatic line properties. - LinePropertyIds& mrLinePropIds; /// Property identifiers for border/line formatting. }; // ---------------------------------------------------------------------------- @@ -632,19 +654,17 @@ class FillFormatter : public DetailFormatterBase public: explicit FillFormatter( ObjectFormatterData& rData, - const AutoFormatEntry* pAutoFormatEntry, - PropertyType ePropType ); + const AutoFormatEntry* pAutoFormatEntry ); /** Converts area formatting to the passed property set. */ void convertFormatting( - PropertySet& rPropSet, + ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx ); private: FillPropertiesPtr mxAutoFill; /// Automatic fill properties. - FillPropertyIds& mrFillPropIds; /// Property identifiers for fill formatting. }; // ---------------------------------------------------------------------------- @@ -654,12 +674,11 @@ class EffectFormatter : public DetailFormatterBase public: explicit EffectFormatter( ObjectFormatterData& rData, - const AutoFormatEntry* pAutoFormatEntry, - PropertyType ePropType ); + const AutoFormatEntry* pAutoFormatEntry ); /** Converts effect formatting to the passed property set. */ void convertFormatting( - PropertySet& rPropSet, + ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, sal_Int32 nSeriesIdx ); }; @@ -736,6 +755,7 @@ private: FillFormatter maFillFormatter; /// Converter for fill formatting. EffectFormatter maEffectFormatter; /// Converter for effect formatting. TextFormatter maTextFormatter; /// Converter for text formatting. + ModelObjectHelper& mrModelObjHelper; /// Helper for named drawing formatting. const ObjectTypeFormatEntry& mrEntry; /// Additional settings. }; @@ -748,11 +768,6 @@ struct ObjectFormatterData const XmlFilterBase& mrFilter; /// Base filter object. ObjectTypeFormatterMap maTypeFormatters; /// Formatters for all types of objects in a chart. ModelObjectHelper maModelObjHelper; /// Helper for named drawing formatting (dashes, gradients, bitmaps). - LinePropertyIds maCommonLineIds; /// Property identifiers for common border formatting. - LinePropertyIds maLinearLineIds; /// Property identifiers for line formatting of linear series. - LinePropertyIds maFilledLineIds; /// Property identifiers for line formatting of filled series. - FillPropertyIds maCommonFillIds; /// Property identifiers for common area fill. - FillPropertyIds maFilledFillIds; /// Property identifiers for area fill of filled series. Reference< XNumberFormats > mxNumFmts; /// Number formats collection of container document. Reference< XNumberFormatTypes > mxNumTypes; /// Number format types collection of container document. Locale maEnUsLocale; /// Locale struct containing en-US. @@ -765,9 +780,6 @@ struct ObjectFormatterData const ChartSpaceModel& rChartSpace ); ObjectTypeFormatter* getTypeFormatter( ObjectType eObjType ); - - LinePropertyIds& getLinePropertyIds( PropertyType ePropType ); - FillPropertyIds& getFillPropertyIds( PropertyType ePropType ); }; // ============================================================================ @@ -864,9 +876,8 @@ sal_Int32 DetailFormatterBase::getSchemeColor( sal_Int32 nColorToken, sal_Int32 // ============================================================================ -LineFormatter::LineFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, PropertyType ePropType ) : - DetailFormatterBase( rData, pAutoFormatEntry ), - mrLinePropIds( rData.getLinePropertyIds( ePropType ) ) +LineFormatter::LineFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) : + DetailFormatterBase( rData, pAutoFormatEntry ) { if( pAutoFormatEntry ) { @@ -881,21 +892,20 @@ LineFormatter::LineFormatter( ObjectFormatterData& rData, const AutoFormatEntry* } } -void LineFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, sal_Int32 nSeriesIdx ) +void LineFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, sal_Int32 nSeriesIdx ) { LineProperties aLineProps; if( mxAutoLine.get() ) aLineProps.assignUsed( *mxAutoLine ); if( rxShapeProp.is() ) aLineProps.assignUsed( rxShapeProp->getLineProperties() ); - aLineProps.pushToPropSet( rPropSet, mrData.maModelObjHelper, mrData.mrFilter.getGraphicHelper(), mrLinePropIds, getPhColor( nSeriesIdx ) ); + aLineProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), getPhColor( nSeriesIdx ) ); } // ============================================================================ -FillFormatter::FillFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, PropertyType ePropType ) : - DetailFormatterBase( rData, pAutoFormatEntry ), - mrFillPropIds( rData.getFillPropertyIds( ePropType ) ) +FillFormatter::FillFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) : + DetailFormatterBase( rData, pAutoFormatEntry ) { if( pAutoFormatEntry ) { @@ -907,7 +917,7 @@ FillFormatter::FillFormatter( ObjectFormatterData& rData, const AutoFormatEntry* } } -void FillFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx ) +void FillFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx ) { FillProperties aFillProps; if( mxAutoFill.get() ) @@ -916,17 +926,17 @@ void FillFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Sh aFillProps.assignUsed( rxShapeProp->getFillProperties() ); if( pPicOptions ) lclConvertPictureOptions( aFillProps, *pPicOptions ); - aFillProps.pushToPropSet( rPropSet, mrData.maModelObjHelper, mrData.mrFilter.getGraphicHelper(), mrFillPropIds, 0, getPhColor( nSeriesIdx ) ); + aFillProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), 0, getPhColor( nSeriesIdx ) ); } // ============================================================================ -EffectFormatter::EffectFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, PropertyType /*ePropType*/ ) : +EffectFormatter::EffectFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) : DetailFormatterBase( rData, pAutoFormatEntry ) { } -void EffectFormatter::convertFormatting( PropertySet& /*rPropSet*/, const ModelRef< Shape >& /*rxShapeProp*/, sal_Int32 /*nSeriesIdx*/ ) +void EffectFormatter::convertFormatting( ShapePropertyMap& /*rPropMap*/, const ModelRef< Shape >& /*rxShapeProp*/, sal_Int32 /*nSeriesIdx*/ ) { } @@ -984,20 +994,23 @@ void TextFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Te // ============================================================================ ObjectTypeFormatter::ObjectTypeFormatter( ObjectFormatterData& rData, const ObjectTypeFormatEntry& rEntry, const ChartSpaceModel& rChartSpace ) : - maLineFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoLines, rChartSpace.mnStyle ), rEntry.mePropType ), - maFillFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoFills, rChartSpace.mnStyle ), rEntry.mePropType ), - maEffectFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoEffects, rChartSpace.mnStyle ), rEntry.mePropType ), + maLineFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoLines, rChartSpace.mnStyle ) ), + maFillFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoFills, rChartSpace.mnStyle ) ), + maEffectFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoEffects, rChartSpace.mnStyle ) ), maTextFormatter( rData, lclGetAutoTextEntry( rEntry.mpAutoTexts, rChartSpace.mnStyle ), rChartSpace.mxTextProp ), + mrModelObjHelper( rData.maModelObjHelper ), mrEntry( rEntry ) { } void ObjectTypeFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx ) { - maLineFormatter.convertFormatting( rPropSet, rxShapeProp, nSeriesIdx ); + ShapePropertyMap aPropMap( mrModelObjHelper, *mrEntry.mpPropInfo ); + maLineFormatter.convertFormatting( aPropMap, rxShapeProp, nSeriesIdx ); if( mrEntry.mbIsFrame ) - maFillFormatter.convertFormatting( rPropSet, rxShapeProp, pPicOptions, nSeriesIdx ); - maEffectFormatter.convertFormatting( rPropSet, rxShapeProp, nSeriesIdx ); + maFillFormatter.convertFormatting( aPropMap, rxShapeProp, pPicOptions, nSeriesIdx ); + maEffectFormatter.convertFormatting( aPropMap, rxShapeProp, nSeriesIdx ); + rPropSet.setProperties( aPropMap ); } void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp ) @@ -1018,16 +1031,20 @@ void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const Te void ObjectTypeFormatter::convertAutomaticLine( PropertySet& rPropSet, sal_Int32 nSeriesIdx ) { + ShapePropertyMap aPropMap( mrModelObjHelper, *mrEntry.mpPropInfo ); ModelRef< Shape > xShapeProp; - maLineFormatter.convertFormatting( rPropSet, xShapeProp, nSeriesIdx ); - maEffectFormatter.convertFormatting( rPropSet, xShapeProp, nSeriesIdx ); + maLineFormatter.convertFormatting( aPropMap, xShapeProp, nSeriesIdx ); + maEffectFormatter.convertFormatting( aPropMap, xShapeProp, nSeriesIdx ); + rPropSet.setProperties( aPropMap ); } void ObjectTypeFormatter::convertAutomaticFill( PropertySet& rPropSet, sal_Int32 nSeriesIdx ) { + ShapePropertyMap aPropMap( mrModelObjHelper, *mrEntry.mpPropInfo ); ModelRef< Shape > xShapeProp; - maFillFormatter.convertFormatting( rPropSet, xShapeProp, 0, nSeriesIdx ); - maEffectFormatter.convertFormatting( rPropSet, xShapeProp, nSeriesIdx ); + maFillFormatter.convertFormatting( aPropMap, xShapeProp, 0, nSeriesIdx ); + maEffectFormatter.convertFormatting( aPropMap, xShapeProp, nSeriesIdx ); + rPropSet.setProperties( aPropMap ); } // ============================================================================ @@ -1035,11 +1052,6 @@ void ObjectTypeFormatter::convertAutomaticFill( PropertySet& rPropSet, sal_Int32 ObjectFormatterData::ObjectFormatterData( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) : mrFilter( rFilter ), maModelObjHelper( Reference< XMultiServiceFactory >( rxChartDoc, UNO_QUERY ) ), - maCommonLineIds( spnCommonLineIds, true, false ), - maLinearLineIds( spnLinearLineIds, true, false ), - maFilledLineIds( spnFilledLineIds, true, false ), - maCommonFillIds( spnCommonFillIds, true, true ), - maFilledFillIds( spnFilledFillIds, true, true ), maEnUsLocale( CREATE_OUSTRING( "en" ), CREATE_OUSTRING( "US" ), OUString() ), mnMaxSeriesIdx( -1 ) { @@ -1065,28 +1077,6 @@ ObjectTypeFormatter* ObjectFormatterData::getTypeFormatter( ObjectType eObjType return maTypeFormatters.get( eObjType ).get(); } -LinePropertyIds& ObjectFormatterData::getLinePropertyIds( PropertyType ePropType ) -{ - switch( ePropType ) - { - case PROPERTYTYPE_COMMON: return maCommonLineIds; - case PROPERTYTYPE_LINEARSERIES: return maLinearLineIds; - case PROPERTYTYPE_FILLEDSERIES: return maFilledLineIds; - } - return maCommonLineIds; -} - -FillPropertyIds& ObjectFormatterData::getFillPropertyIds( PropertyType ePropType ) -{ - switch( ePropType ) - { - case PROPERTYTYPE_COMMON: return maCommonFillIds; - case PROPERTYTYPE_LINEARSERIES: return maCommonFillIds; - case PROPERTYTYPE_FILLEDSERIES: return maFilledFillIds; - } - return maCommonFillIds; -} - // ============================================================================ ObjectFormatter::ObjectFormatter( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) : @@ -1165,7 +1155,7 @@ void ObjectFormatter::convertNumberFormat( PropertySet& rPropSet, const NumberFo sal_Int32 nPropId = bPercentFormat ? PROP_PercentageNumberFormat : PROP_NumberFormat; if( rNumberFormat.mbSourceLinked || (rNumberFormat.maFormatCode.getLength() == 0) ) { - rPropSet.setProperty( nPropId, Any() ); + rPropSet.setAnyProperty( nPropId, Any() ); } else try { diff --git a/oox/source/drawingml/color.cxx b/oox/source/drawingml/color.cxx index 8653d787517d..ad626b670fae 100644 --- a/oox/source/drawingml/color.cxx +++ b/oox/source/drawingml/color.cxx @@ -512,12 +512,12 @@ sal_Int32 Color::getColor( const GraphicHelper& rGraphicHelper, sal_Int32 nPhClr return mnC1; } -bool Color::hasTransparence() const +bool Color::hasTransparency() const { return mnAlpha < MAX_PERCENT; } -sal_Int16 Color::getTransparence() const +sal_Int16 Color::getTransparency() const { return static_cast< sal_Int16 >( (MAX_PERCENT - mnAlpha) / PER_PERCENT ); } diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx index 08d001f09a62..4285286c623d 100644 --- a/oox/source/drawingml/fillproperties.cxx +++ b/oox/source/drawingml/fillproperties.cxx @@ -39,10 +39,8 @@ #include "properties.hxx" #include "tokens.hxx" #include "oox/helper/graphichelper.hxx" -#include "oox/helper/modelobjecthelper.hxx" -#include "oox/helper/propertymap.hxx" -#include "oox/helper/propertyset.hxx" #include "oox/drawingml/drawingmltypes.hxx" +#include "oox/drawingml/shapepropertymap.hxx" using namespace ::com::sun::star; using namespace ::com::sun::star::drawing; @@ -62,21 +60,6 @@ namespace drawingml { namespace { -static const sal_Int32 spnDefaultFillIds[ FillId_END ] = -{ - PROP_FillStyle, - PROP_FillColor, - PROP_FillTransparence, - PROP_FillGradient, - PROP_FillBitmapURL, - PROP_FillBitmapMode, - PROP_FillBitmapSizeX, - PROP_FillBitmapSizeY, - PROP_FillBitmapPositionOffsetX, - PROP_FillBitmapPositionOffsetY, - PROP_FillBitmapRectanglePoint -}; - BitmapMode lclGetBitmapMode( sal_Int32 nToken ) { switch( nToken ) @@ -130,16 +113,6 @@ const awt::Size lclGetOriginalSize( const GraphicHelper& rGraphicHelper, const R // ============================================================================ -FillPropertyIds::FillPropertyIds( const sal_Int32* pnPropertyIds, bool bNamedFillGradient, bool bNamedFillBitmap ) : - mpnPropertyIds( pnPropertyIds ), - mbNamedFillGradient( bNamedFillGradient ), - mbNamedFillBitmap( bNamedFillBitmap ) -{ - OSL_ENSURE( mpnPropertyIds != 0, "FillPropertyIds::FillPropertyIds - missing property identifiers" ); -} - -// ============================================================================ - void GradientFillProperties::assignUsed( const GradientFillProperties& rSourceProps ) { if( !rSourceProps.maGradientStops.empty() ) @@ -186,8 +159,6 @@ void BlipFillProperties::assignUsed( const BlipFillProperties& rSourceProps ) // ============================================================================ -FillPropertyIds FillProperties::DEFAULT_IDS( spnDefaultFillIds, false, false ); - void FillProperties::assignUsed( const FillProperties& rSourceProps ) { moFillType.assignIfUsed( rSourceProps.moFillType ); @@ -216,9 +187,8 @@ Color FillProperties::getBestSolidColor() const return aSolidColor; } -void FillProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rModelObjHelper, - const GraphicHelper& rGraphicHelper, const FillPropertyIds& rPropIds, - sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const +void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap, + const GraphicHelper& rGraphicHelper, sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const { if( moFillType.has() ) { @@ -232,16 +202,16 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM case XML_solidFill: if( maFillColor.isUsed() ) { - rPropMap.setProperty( rPropIds[ FillColorId ], maFillColor.getColor( rGraphicHelper, nPhClr ) ); - if( maFillColor.hasTransparence() ) - rPropMap.setProperty( rPropIds[ FillTransparenceId ], maFillColor.getTransparence() ); + rPropMap.setProperty( SHAPEPROP_FillColor, maFillColor.getColor( rGraphicHelper, nPhClr ) ); + if( maFillColor.hasTransparency() ) + rPropMap.setProperty( SHAPEPROP_FillTransparency, maFillColor.getTransparency() ); eFillStyle = FillStyle_SOLID; } break; case XML_gradFill: // do not create gradient struct if property is not supported... - if( rPropIds.has( FillGradientId ) ) + if( rPropMap.supportsProperty( SHAPEPROP_FillGradient ) ) { awt::Gradient aGradient; aGradient.Angle = 900; @@ -291,62 +261,35 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM aGradient.Angle = static_cast< sal_Int16 >( (4500 - (nDmlAngle / (PER_DEGREE / 10))) % 3600 ); // push gradient or named gradient to property map - if( rPropIds.mbNamedFillGradient ) - { - OUString aGradientName = rModelObjHelper.insertFillGradient( aGradient ); - if( aGradientName.getLength() > 0 ) - { - rPropMap.setProperty( rPropIds[ FillGradientId ], aGradientName ); - eFillStyle = FillStyle_GRADIENT; - } - } - else - { - rPropMap.setProperty( rPropIds[ FillGradientId ], aGradient ); + if( rPropMap.setProperty( SHAPEPROP_FillGradient, aGradient ) ) eFillStyle = FillStyle_GRADIENT; - } } break; case XML_blipFill: // do not start complex graphic transformation if property is not supported... - if( maBlipProps.mxGraphic.is() && rPropIds.has( FillBitmapUrlId ) ) + if( maBlipProps.mxGraphic.is() && rPropMap.supportsProperty( SHAPEPROP_FillBitmapUrl ) ) { // TODO: "rotate with shape" is not possible with our current core OUString aGraphicUrl = rGraphicHelper.createGraphicObject( maBlipProps.mxGraphic ); - if( aGraphicUrl.getLength() > 0 ) - { - // push bitmap or named bitmap to property map - if( rPropIds.mbNamedFillBitmap ) - { - OUString aBitmapName = rModelObjHelper.insertFillBitmap( aGraphicUrl ); - if( aBitmapName.getLength() > 0 ) - { - rPropMap.setProperty( rPropIds[ FillBitmapUrlId ], aBitmapName ); - eFillStyle = FillStyle_BITMAP; - } - } - else - { - rPropMap.setProperty( rPropIds[ FillBitmapUrlId ], aGraphicUrl ); - eFillStyle = FillStyle_BITMAP; - } - } + // push bitmap or named bitmap to property map + if( (aGraphicUrl.getLength() > 0) && rPropMap.setProperty( SHAPEPROP_FillBitmapUrl, aGraphicUrl ) ) + eFillStyle = FillStyle_BITMAP; // set other bitmap properties, if bitmap has been inserted into the map if( eFillStyle == FillStyle_BITMAP ) { // bitmap mode (single, repeat, stretch) BitmapMode eBitmapMode = lclGetBitmapMode( maBlipProps.moBitmapMode.get( XML_TOKEN_INVALID ) ); - rPropMap.setProperty( rPropIds[ FillBitmapModeId ], eBitmapMode ); + rPropMap.setProperty( SHAPEPROP_FillBitmapMode, eBitmapMode ); // additional settings for repeated bitmap if( eBitmapMode == BitmapMode_REPEAT ) { // anchor position inside bitmap RectanglePoint eRectPoint = lclGetRectanglePoint( maBlipProps.moTileAlign.get( XML_tl ) ); - rPropMap.setProperty( rPropIds[ FillBitmapRectanglePointId ], eRectPoint ); + rPropMap.setProperty( SHAPEPROP_FillBitmapRectanglePoint, eRectPoint ); awt::Size aOriginalSize = lclGetOriginalSize( rGraphicHelper, maBlipProps.mxGraphic ); if( (aOriginalSize.Width > 0) && (aOriginalSize.Height > 0) ) @@ -354,16 +297,16 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM // size of one bitmap tile (given as 1/1000 percent of bitmap size), convert to 1/100 mm double fScaleX = maBlipProps.moTileScaleX.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT ); sal_Int32 nFillBmpSizeX = getLimitedValue< sal_Int32, double >( aOriginalSize.Width * fScaleX, 1, SAL_MAX_INT32 ); - rPropMap.setProperty( rPropIds[ FillBitmapSizeXId ], nFillBmpSizeX ); + rPropMap.setProperty( SHAPEPROP_FillBitmapSizeX, nFillBmpSizeX ); double fScaleY = maBlipProps.moTileScaleY.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT ); sal_Int32 nFillBmpSizeY = getLimitedValue< sal_Int32, double >( aOriginalSize.Height * fScaleY, 1, SAL_MAX_INT32 ); - rPropMap.setProperty( rPropIds[ FillBitmapSizeYId ], nFillBmpSizeY ); + rPropMap.setProperty( SHAPEPROP_FillBitmapSizeY, nFillBmpSizeY ); // offset of the first bitmap tile (given as EMUs), convert to percent sal_Int16 nTileOffsetX = getDoubleIntervalValue< sal_Int16 >( maBlipProps.moTileOffsetX.get( 0 ) / 3.6 / aOriginalSize.Width, 0, 100 ); - rPropMap.setProperty( rPropIds[ FillBitmapOffsetXId ], nTileOffsetX ); + rPropMap.setProperty( SHAPEPROP_FillBitmapOffsetX, nTileOffsetX ); sal_Int16 nTileOffsetY = getDoubleIntervalValue< sal_Int16 >( maBlipProps.moTileOffsetY.get( 0 ) / 3.6 / aOriginalSize.Height, 0, 100 ); - rPropMap.setProperty( rPropIds[ FillBitmapOffsetYId ], nTileOffsetY ); + rPropMap.setProperty( SHAPEPROP_FillBitmapOffsetY, nTileOffsetY ); } } } @@ -376,9 +319,9 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM Color aColor = getBestSolidColor(); if( aColor.isUsed() ) { - rPropMap.setProperty( rPropIds[ FillColorId ], aColor.getColor( rGraphicHelper, nPhClr ) ); - if( aColor.hasTransparence() ) - rPropMap.setProperty( rPropIds[ FillTransparenceId ], aColor.getTransparence() ); + rPropMap.setProperty( SHAPEPROP_FillColor, aColor.getColor( rGraphicHelper, nPhClr ) ); + if( aColor.hasTransparency() ) + rPropMap.setProperty( SHAPEPROP_FillTransparency, aColor.getTransparency() ); eFillStyle = FillStyle_SOLID; } } @@ -391,19 +334,10 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM } // set final fill style property - rPropMap.setProperty( rPropIds[ FillStyleId ], eFillStyle ); + rPropMap.setProperty( SHAPEPROP_FillStyle, eFillStyle ); } } -void FillProperties::pushToPropSet( PropertySet& rPropSet, ModelObjectHelper& rModelObjHelper, - const GraphicHelper& rGraphicHelper, const FillPropertyIds& rPropIds, - sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const -{ - PropertyMap aPropMap; - pushToPropMap( aPropMap, rModelObjHelper, rGraphicHelper, rPropIds, nShapeRotation, nPhClr ); - rPropSet.setProperties( aPropMap ); -} - // ============================================================================ void GraphicProperties::assignUsed( const GraphicProperties& rSourceProps ) @@ -421,9 +355,9 @@ void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelpe { sal_Int32 nFromColor = maBlipProps.maColorChangeFrom.getColor( rGraphicHelper, nPhClr ); sal_Int32 nToColor = maBlipProps.maColorChangeTo.getColor( rGraphicHelper, nPhClr ); - if ( (nFromColor != nToColor) || maBlipProps.maColorChangeTo.hasTransparence() ) try + if ( (nFromColor != nToColor) || maBlipProps.maColorChangeTo.hasTransparency() ) try { - sal_Int16 nToTransparence = maBlipProps.maColorChangeTo.getTransparence(); + sal_Int16 nToTransparence = maBlipProps.maColorChangeTo.getTransparency(); sal_Int8 nToAlpha = static_cast< sal_Int8 >( (100 - nToTransparence) / 39.062 ); // ?!? correct ?!? Reference< XGraphicTransformer > xTransformer( maBlipProps.mxGraphic, UNO_QUERY_THROW ); xGraphic = xTransformer->colorChange( maBlipProps.mxGraphic, nFromColor, 9, nToColor, nToAlpha ); @@ -476,13 +410,6 @@ void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelpe rPropMap[ PROP_AdjustContrast ] <<= nContrast; } -void GraphicProperties::pushToPropSet( PropertySet& rPropSet, const GraphicHelper& rGraphicHelper, sal_Int32 nPhClr ) const -{ - PropertyMap aPropMap; - pushToPropMap( aPropMap, rGraphicHelper, nPhClr ); - rPropSet.setProperties( aPropMap ); -} - // ============================================================================ } // namespace drawingml diff --git a/oox/source/drawingml/lineproperties.cxx b/oox/source/drawingml/lineproperties.cxx index a0836612fafb..c24166e4a8c0 100644 --- a/oox/source/drawingml/lineproperties.cxx +++ b/oox/source/drawingml/lineproperties.cxx @@ -28,6 +28,7 @@ #include "oox/drawingml/lineproperties.hxx" #include #include +#include #include #include #include @@ -38,12 +39,11 @@ #include "properties.hxx" #include "tokens.hxx" #include "oox/helper/graphichelper.hxx" -#include "oox/helper/modelobjecthelper.hxx" -#include "oox/helper/propertymap.hxx" -#include "oox/helper/propertyset.hxx" #include "oox/core/namespaces.hxx" #include "oox/drawingml/drawingmltypes.hxx" +#include "oox/drawingml/shapepropertymap.hxx" +using namespace ::com::sun::star::beans; using namespace ::com::sun::star::drawing; using ::rtl::OUString; @@ -60,24 +60,6 @@ namespace drawingml { namespace { -static const sal_Int32 spnDefaultLineIds[ LineId_END ] = -{ - PROP_LineStyle, - PROP_LineWidth, - PROP_LineColor, - PROP_LineTransparence, - PROP_LineDash, - PROP_LineJoint, - PROP_LineStartName, - PROP_LineStartWidth, - PROP_LineStartCenter, - PROP_LineEndName, - PROP_LineEndWidth, - PROP_LineEndCenter -}; - -// ---------------------------------------------------------------------------- - void lclSetDashData( LineDash& orLineDash, sal_Int16 nDots, sal_Int32 nDotLen, sal_Int16 nDashes, sal_Int32 nDashLen, sal_Int32 nDistance ) { @@ -196,15 +178,16 @@ sal_Int32 lclGetArrowSize( sal_Int32 nToken ) // ---------------------------------------------------------------------------- -void lclPushMarkerProperties( PropertyMap& rPropMap, const LineArrowProperties& rArrowProps, - ModelObjectHelper& rModelObjHelper, const LinePropertyIds& rPropIds, sal_Int32 nLineWidth, bool bLineEnd ) +void lclPushMarkerProperties( ShapePropertyMap& rPropMap, + const LineArrowProperties& rArrowProps, sal_Int32 nLineWidth, bool bLineEnd ) { - PolyPolygonBezierCoords aMarker; - OUString aMarkerName; - sal_Int32 nMarkerWidth = 0; - bool bMarkerCenter = false; + /* Store the marker polygon and the marker name in a single value, to be + able to pass both to the ShapePropertyMap::setProperty() function. */ + NamedValue aNamedMarker; OUStringBuffer aBuffer; + sal_Int32 nMarkerWidth = 0; + bool bMarkerCenter = false; sal_Int32 nArrowType = rArrowProps.moArrowType.get( XML_none ); switch( nArrowType ) { @@ -234,7 +217,7 @@ void lclPushMarkerProperties( PropertyMap& rPropMap, const LineArrowProperties& sal_Int32 nNameIndex = nWidth * 3 + nLength + 1; aBuffer.append( sal_Unicode( ' ' ) ).append( nNameIndex ); - aMarkerName = aBuffer.makeStringAndClear(); + OUString aMarkerName = aBuffer.makeStringAndClear(); bool bIsArrow = nArrowType == XML_arrow; double fArrowLength = 1.0; @@ -255,8 +238,11 @@ void lclPushMarkerProperties( PropertyMap& rPropMap, const LineArrowProperties& sal_Int32 nBaseLineWidth = ::std::max< sal_Int32 >( nLineWidth, 70 ); nMarkerWidth = static_cast< sal_Int32 >( fArrowWidth * nBaseLineWidth ); - // test if the arrow already exists, do not create it again in this case - if( !rPropIds.mbNamedLineMarker || !rModelObjHelper.hasLineMarker( aMarkerName ) ) + /* Test if the marker already exists in the marker table, do not + create it again in this case. If markers are inserted explicitly + instead by their name, the polygon will be created always. + TODO: this can be optimized by using a map. */ + if( !rPropMap.hasNamedLineMarkerInTable( aMarkerName ) ) { // pass X and Y as percentage to OOX_ARROW_POINT #define OOX_ARROW_POINT( x, y ) Point( static_cast< sal_Int32 >( fArrowWidth * x ), static_cast< sal_Int32 >( fArrowLength * y ) ) @@ -311,46 +297,44 @@ void lclPushMarkerProperties( PropertyMap& rPropMap, const LineArrowProperties& } #undef OOX_ARROW_POINT - OSL_ENSURE( !aPoints.empty(), "ApiLineMarkerProperties::ApiLineMarkerProperties - missing arrow coordinates" ); + OSL_ENSURE( !aPoints.empty(), "lclPushMarkerProperties - missing arrow coordinates" ); if( !aPoints.empty() ) { - aMarker.Coordinates.realloc( 1 ); - aMarker.Coordinates[ 0 ] = ContainerHelper::vectorToSequence( aPoints ); + PolyPolygonBezierCoords aMarkerCoords; + aMarkerCoords.Coordinates.realloc( 1 ); + aMarkerCoords.Coordinates[ 0 ] = ContainerHelper::vectorToSequence( aPoints ); ::std::vector< PolygonFlags > aFlags( aPoints.size(), PolygonFlags_NORMAL ); - aMarker.Flags.realloc( 1 ); - aMarker.Flags[ 0 ] = ContainerHelper::vectorToSequence( aFlags ); + aMarkerCoords.Flags.realloc( 1 ); + aMarkerCoords.Flags[ 0 ] = ContainerHelper::vectorToSequence( aFlags ); - if( rPropIds.mbNamedLineMarker && !rModelObjHelper.insertLineMarker( aMarkerName, aMarker ) ) - aMarkerName = OUString(); - } - else - { - aMarkerName = OUString(); + aNamedMarker.Name = aMarkerName; + aNamedMarker.Value <<= aMarkerCoords; } } + else + { + /* Named marker object exists already in the marker table, pass + its name only. This will set the name as property value, but + does not create a new object in the marker table. */ + aNamedMarker.Name = aMarkerName; + } } - // push the properties (filled aMarkerName indicates valid marker) - if( aMarkerName.getLength() > 0 ) + // push the properties (filled aNamedMarker.Name indicates valid marker) + if( aNamedMarker.Name.getLength() > 0 ) { if( bLineEnd ) { - if( rPropIds.mbNamedLineMarker ) - rPropMap.setProperty( rPropIds[ LineEndId ], aMarkerName ); - else - rPropMap.setProperty( rPropIds[ LineEndId ], aMarker ); - rPropMap.setProperty( rPropIds[ LineEndWidthId ], nMarkerWidth ); - rPropMap.setProperty( rPropIds[ LineEndCenterId ], bMarkerCenter ); + rPropMap.setProperty( SHAPEPROP_LineEnd, aNamedMarker ); + rPropMap.setProperty( SHAPEPROP_LineEndWidth, nMarkerWidth ); + rPropMap.setProperty( SHAPEPROP_LineEndCenter, bMarkerCenter ); } else { - if( rPropIds.mbNamedLineMarker ) - rPropMap.setProperty( rPropIds[ LineStartId ], aMarkerName ); - else - rPropMap.setProperty( rPropIds[ LineStartId ], aMarker ); - rPropMap.setProperty( rPropIds[ LineStartWidthId ], nMarkerWidth ); - rPropMap.setProperty( rPropIds[ LineStartCenterId ], bMarkerCenter ); + rPropMap.setProperty( SHAPEPROP_LineStart, aNamedMarker ); + rPropMap.setProperty( SHAPEPROP_LineStartWidth, nMarkerWidth ); + rPropMap.setProperty( SHAPEPROP_LineStartCenter, bMarkerCenter ); } } } @@ -359,16 +343,6 @@ void lclPushMarkerProperties( PropertyMap& rPropMap, const LineArrowProperties& // ============================================================================ -LinePropertyIds::LinePropertyIds( const sal_Int32* pnPropertyIds, bool bNamedLineDash, bool bNamedLineMarker ) : - mpnPropertyIds( pnPropertyIds ), - mbNamedLineDash( bNamedLineDash ), - mbNamedLineMarker( bNamedLineMarker ) -{ - OSL_ENSURE( mpnPropertyIds != 0, "LinePropertyIds::LinePropertyIds - missing property identifiers" ); -} - -// ============================================================================ - void LineArrowProperties::assignUsed( const LineArrowProperties& rSourceProps ) { moArrowType.assignIfUsed( rSourceProps.moArrowType ); @@ -378,8 +352,6 @@ void LineArrowProperties::assignUsed( const LineArrowProperties& rSourceProps ) // ============================================================================ -LinePropertyIds LineProperties::DEFAULT_IDS( spnDefaultLineIds, false, true ); - void LineProperties::assignUsed( const LineProperties& rSourceProps ) { maStartArrow.assignUsed( rSourceProps.maStartArrow ); @@ -394,8 +366,8 @@ void LineProperties::assignUsed( const LineProperties& rSourceProps ) moLineJoint.assignIfUsed( rSourceProps.moLineJoint ); } -void LineProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rModelObjHelper, - const GraphicHelper& rGraphicHelper, const LinePropertyIds& rPropIds, sal_Int32 nPhClr ) const +void LineProperties::pushToPropMap( ShapePropertyMap& rPropMap, + const GraphicHelper& rGraphicHelper, sal_Int32 nPhClr ) const { // line fill type must exist, otherwise ignore other properties if( maLineFill.moFillType.has() ) @@ -424,55 +396,35 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rM aLineDash.DashLen *= nBaseLineWidth; aLineDash.Distance *= nBaseLineWidth; - if( rPropIds.mbNamedLineDash ) - { - OUString aDashName = rModelObjHelper.insertLineDash( aLineDash ); - if( aDashName.getLength() > 0 ) - { - rPropMap.setProperty( rPropIds[ LineDashId ], aDashName ); - eLineStyle = LineStyle_DASH; - } - } - else - { - rPropMap.setProperty( rPropIds[ LineDashId ], aLineDash ); + if( rPropMap.setProperty( SHAPEPROP_LineDash, aLineDash ) ) eLineStyle = LineStyle_DASH; - } } // set final line style property - rPropMap.setProperty( rPropIds[ LineStyleId ], eLineStyle ); + rPropMap.setProperty( SHAPEPROP_LineStyle, eLineStyle ); // line joint type if( moLineJoint.has() ) - rPropMap.setProperty( rPropIds[ LineJointId ], lclGetLineJoint( moLineJoint.get() ) ); + rPropMap.setProperty( SHAPEPROP_LineJoint, lclGetLineJoint( moLineJoint.get() ) ); // line width in 1/100mm - rPropMap.setProperty( rPropIds[ LineWidthId ], nLineWidth ); + rPropMap.setProperty( SHAPEPROP_LineWidth, nLineWidth ); // line color and transparence Color aLineColor = maLineFill.getBestSolidColor(); if( aLineColor.isUsed() ) { - rPropMap.setProperty( rPropIds[ LineColorId ], aLineColor.getColor( rGraphicHelper, nPhClr ) ); - if( aLineColor.hasTransparence() ) - rPropMap.setProperty( rPropIds[ LineTransparenceId ], aLineColor.getTransparence() ); + rPropMap.setProperty( SHAPEPROP_LineColor, aLineColor.getColor( rGraphicHelper, nPhClr ) ); + if( aLineColor.hasTransparency() ) + rPropMap.setProperty( SHAPEPROP_LineTransparency, aLineColor.getTransparency() ); } // line markers - lclPushMarkerProperties( rPropMap, maStartArrow, rModelObjHelper, rPropIds, nLineWidth, false ); - lclPushMarkerProperties( rPropMap, maEndArrow, rModelObjHelper, rPropIds, nLineWidth, true ); + lclPushMarkerProperties( rPropMap, maStartArrow, nLineWidth, false ); + lclPushMarkerProperties( rPropMap, maEndArrow, nLineWidth, true ); } } -void LineProperties::pushToPropSet( PropertySet& rPropSet, ModelObjectHelper& rModelObjHelper, - const GraphicHelper& rGraphicHelper, const LinePropertyIds& rPropIds, sal_Int32 nPhClr ) const -{ - PropertyMap aPropMap; - pushToPropMap( aPropMap, rModelObjHelper, rGraphicHelper, rPropIds, nPhClr ); - rPropSet.setProperties( aPropMap ); -} - // ============================================================================ } // namespace drawingml diff --git a/oox/source/drawingml/makefile.mk b/oox/source/drawingml/makefile.mk index e2d4ea6b8f3d..0546fb4c233d 100644 --- a/oox/source/drawingml/makefile.mk +++ b/oox/source/drawingml/makefile.mk @@ -62,6 +62,7 @@ SLOFILES = \ $(SLO)$/shapecontext.obj\ $(SLO)$/shapegroupcontext.obj\ $(SLO)$/shapepropertiescontext.obj\ + $(SLO)$/shapepropertymap.obj\ $(SLO)$/shapestylecontext.obj\ $(SLO)$/spdefcontext.obj\ $(SLO)$/textbody.obj\ diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 4d15886a641a..af44469a6ced 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -30,6 +30,7 @@ #include "oox/drawingml/theme.hxx" #include "oox/drawingml/fillproperties.hxx" #include "oox/drawingml/lineproperties.hxx" +#include "oox/drawingml/shapepropertymap.hxx" #include "oox/drawingml/textbody.hxx" #include "oox/drawingml/table/tableproperties.hxx" #include "oox/core/namespaces.hxx" @@ -397,7 +398,6 @@ Reference< XShape > Shape::createAndInsert( } } - ModelObjectHelper& rModelObjectHelper = rFilterBase.getModelObjectHelper(); const GraphicHelper& rGraphicHelper = rFilterBase.getGraphicHelper(); LineProperties aLineProperties; @@ -432,33 +432,23 @@ Reference< XShape > Shape::createAndInsert( aLineProperties.assignUsed( getLineProperties() ); aFillProperties.assignUsed( getFillProperties() ); - PropertyMap aShapeProperties; - PropertyMap::const_iterator aShapePropIter; + ShapePropertyMap aShapeProps( rFilterBase.getModelObjectHelper() ); if( mxCreateCallback.get() ) - { - for ( aShapePropIter = mxCreateCallback->getShapeProperties().begin(); - aShapePropIter != mxCreateCallback->getShapeProperties().end(); aShapePropIter++ ) - aShapeProperties[ (*aShapePropIter).first ] = (*aShapePropIter).second; - } + aShapeProps.assignUsed( mxCreateCallback->getShapeProperties() ); // add properties from textbody to shape properties if( mpTextBody.get() ) - { - for ( aShapePropIter = mpTextBody->getTextProperties().maPropertyMap.begin(); - aShapePropIter != mpTextBody->getTextProperties().maPropertyMap.end(); aShapePropIter++ ) - aShapeProperties[ (*aShapePropIter).first ] = (*aShapePropIter).second; - } + aShapeProps.assignUsed( mpTextBody->getTextProperties().maPropertyMap ); - aShapeProperties.insert( getShapeProperties().begin(), getShapeProperties().end() ); // applying properties - PropertySet aPropSet( xSet ); + aShapeProps.assignUsed( getShapeProperties() ); if ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.GraphicObjectShape" ) ) - mpGraphicPropertiesPtr->pushToPropSet( aPropSet, rGraphicHelper ); + mpGraphicPropertiesPtr->pushToPropMap( aShapeProps, rGraphicHelper ); if ( mpTablePropertiesPtr.get() && ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.TableShape" ) ) ) mpTablePropertiesPtr->pushToPropSet( rFilterBase, xSet, mpMasterTextListStyle ); - aFillProperties.pushToPropSet( aPropSet, rModelObjectHelper, rGraphicHelper, FillProperties::DEFAULT_IDS, mnRotation, nFillPhClr ); - aLineProperties.pushToPropSet( aPropSet, rModelObjectHelper, rGraphicHelper, LineProperties::DEFAULT_IDS, nLinePhClr ); + aFillProperties.pushToPropMap( aShapeProps, rGraphicHelper, mnRotation, nFillPhClr ); + aLineProperties.pushToPropMap( aShapeProps, rGraphicHelper, nLinePhClr ); // applying autogrowheight property before setting shape size, because // the shape size might be changed if currently autogrowheight is true @@ -466,12 +456,12 @@ Reference< XShape > Shape::createAndInsert( Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() ); const OUString& rPropName = PropertyMap::getPropertyName( PROP_TextAutoGrowHeight ); if( xSetInfo.is() && xSetInfo->hasPropertyByName( rPropName ) ) - if( /*const Any* pAutoGrowHeight =*/ aShapeProperties.getProperty( PROP_TextAutoGrowHeight ) ) + if( aShapeProps.hasProperty( PROP_TextAutoGrowHeight ) ) xSet->setPropertyValue( rPropName, Any( false ) ); // do not set properties at a group shape (this causes assertions from svx) if( aServiceName != OUString::createFromAscii( "com.sun.star.drawing.GroupShape" ) ) - aPropSet.setProperties( aShapeProperties ); + PropertySet( xSet ).setProperties( aShapeProps ); if( bIsCustomShape ) { diff --git a/oox/source/drawingml/shapepropertymap.cxx b/oox/source/drawingml/shapepropertymap.cxx new file mode 100755 index 000000000000..9d2397cf5f7e --- /dev/null +++ b/oox/source/drawingml/shapepropertymap.cxx @@ -0,0 +1,195 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/drawingml/shapepropertymap.hxx" + +#include +#include +#include +#include +#include "oox/helper/modelobjecthelper.hxx" +#include "properties.hxx" + +namespace oox { +namespace drawingml { + +// ============================================================================ + +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::uno; + +using ::rtl::OUString; + +// ============================================================================ + +namespace { + +static const sal_Int32 spnDefaultShapeIds[ SHAPEPROP_END ] = +{ + PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDash, PROP_LineJoint, + PROP_LineStartName, PROP_LineStartWidth, PROP_LineStartCenter, PROP_LineEndName, PROP_LineEndWidth, PROP_LineEndCenter, + PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_FillGradient, + PROP_FillBitmapURL, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY, + PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint +}; + +} // namespace + +ShapePropertyInfo ShapePropertyInfo::DEFAULT( spnDefaultShapeIds, true, false, false, false ); + +ShapePropertyInfo::ShapePropertyInfo( const sal_Int32* pnPropertyIds, + bool bNamedLineMarker, bool bNamedLineDash, bool bNamedFillGradient, bool bNamedFillBitmapUrl ) : + mpnPropertyIds( pnPropertyIds ), + mbNamedLineMarker( bNamedLineMarker ), + mbNamedLineDash( bNamedLineDash ), + mbNamedFillGradient( bNamedFillGradient ), + mbNamedFillBitmapUrl( bNamedFillBitmapUrl ) +{ + OSL_ENSURE( mpnPropertyIds != 0, "ShapePropertyInfo::ShapePropertyInfo - missing property identifiers" ); +} + +// ============================================================================ + +ShapePropertyMap::ShapePropertyMap( ModelObjectHelper& rModelObjHelper, const ShapePropertyInfo& rShapePropInfo ) : + mrModelObjHelper( rModelObjHelper ), + maShapePropInfo( rShapePropInfo ) +{ +} + +bool ShapePropertyMap::supportsProperty( ShapePropertyId ePropId ) const +{ + return maShapePropInfo.has( ePropId ); +} + +bool ShapePropertyMap::hasNamedLineMarkerInTable( const OUString& rMarkerName ) const +{ + return maShapePropInfo.mbNamedLineMarker && mrModelObjHelper.hasLineMarker( rMarkerName ); +} + +bool ShapePropertyMap::setAnyProperty( ShapePropertyId ePropId, const Any& rValue ) +{ + // get current property identifier for the specified property + sal_Int32 nPropId = maShapePropInfo[ ePropId ]; + if( nPropId < 0 ) return false; + + // special handling for properties supporting named objects in tables + switch( ePropId ) + { + case SHAPEPROP_LineStart: + case SHAPEPROP_LineEnd: + return setLineMarker( nPropId, rValue ); + + case SHAPEPROP_LineDash: + return setLineDash( nPropId, rValue ); + + case SHAPEPROP_FillGradient: + return setFillGradient( nPropId, rValue ); + + case SHAPEPROP_FillBitmapUrl: + return setFillBitmapUrl( nPropId, rValue ); + + default:; // suppress compiler warnings + } + + // set plain property value + operator[]( nPropId ) = rValue; + return true; +} + +// private -------------------------------------------------------------------- + +bool ShapePropertyMap::setLineMarker( sal_Int32 nPropId, const Any& rValue ) +{ + NamedValue aNamedMarker; + if( (rValue >>= aNamedMarker) && (aNamedMarker.Name.getLength() > 0) ) + { + // push line marker explicitly + if( !maShapePropInfo.mbNamedLineMarker ) + return setAnyProperty( nPropId, aNamedMarker.Value ); + + // create named line marker (if coordinates have been passed) and push its name + bool bInserted = !aNamedMarker.Value.has< PolyPolygonBezierCoords >() || + mrModelObjHelper.insertLineMarker( aNamedMarker.Name, aNamedMarker.Value.get< PolyPolygonBezierCoords >() ); + return bInserted && setProperty( nPropId, aNamedMarker.Name ); + } + return false; +} + +bool ShapePropertyMap::setLineDash( sal_Int32 nPropId, const Any& rValue ) +{ + // push line dash explicitly + if( !maShapePropInfo.mbNamedLineDash ) + return setAnyProperty( nPropId, rValue ); + + // create named line dash and push its name + if( rValue.has< LineDash >() ) + { + OUString aDashName = mrModelObjHelper.insertLineDash( rValue.get< LineDash >() ); + return (aDashName.getLength() > 0) && setProperty( nPropId, aDashName ); + } + + return false; +} + +bool ShapePropertyMap::setFillGradient( sal_Int32 nPropId, const Any& rValue ) +{ + // push gradient explicitly + if( !maShapePropInfo.mbNamedFillGradient ) + return setAnyProperty( nPropId, rValue ); + + // create named gradient and push its name + if( rValue.has< Gradient >() ) + { + OUString aGradientName = mrModelObjHelper.insertFillGradient( rValue.get< Gradient >() ); + return (aGradientName.getLength() > 0) && setProperty( nPropId, aGradientName ); + } + + return false; +} + +bool ShapePropertyMap::setFillBitmapUrl( sal_Int32 nPropId, const Any& rValue ) +{ + // push bitmap URL explicitly + if( !maShapePropInfo.mbNamedFillBitmapUrl ) + return setAnyProperty( nPropId, rValue ); + + // create named bitmap URL and push its name + if( rValue.has< OUString >() ) + { + OUString aBitmapUrlName = mrModelObjHelper.insertFillBitmapUrl( rValue.get< OUString >() ); + return (aBitmapUrlName.getLength() > 0) && setProperty( nPropId, aBitmapUrlName ); + } + + return false; +} + +// ============================================================================ + +} // namespace drawingml +} // namespace oox diff --git a/oox/source/drawingml/table/tablecell.cxx b/oox/source/drawingml/table/tablecell.cxx index ee3ac495f4d6..d31627e61148 100644 --- a/oox/source/drawingml/table/tablecell.cxx +++ b/oox/source/drawingml/table/tablecell.cxx @@ -27,12 +27,13 @@ #include "oox/drawingml/table/tablecell.hxx" #include "oox/drawingml/table/tableproperties.hxx" +#include "oox/drawingml/shapepropertymap.hxx" #include "oox/drawingml/textbody.hxx" #include "oox/core/namespaces.hxx" #include "oox/core/xmlfilterbase.hxx" +#include "oox/helper/propertyset.hxx" #include "properties.hxx" #include "tokens.hxx" -#include "oox/helper/propertyset.hxx" #include #include #include @@ -358,9 +359,10 @@ void TableCell::pushToXCell( const ::oox::core::XmlFilterBase& rFilterBase, ::oo applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesBottomLeftToTopRight, PROP_DiagonalBLTR ); aFillProperties.assignUsed( maFillProperties ); - PropertySet aPropSet( xPropSet ); + ShapePropertyMap aPropMap( rFilterBase.getModelObjectHelper() ); // TODO: phClr? - aFillProperties.pushToPropSet( aPropSet, rFilterBase.getModelObjectHelper(), rFilterBase.getGraphicHelper() ); + aFillProperties.pushToPropMap( aPropMap, rFilterBase.getGraphicHelper() ); + PropertySet( xPropSet ).setProperties( aPropMap ); } } } } diff --git a/oox/source/helper/modelobjecthelper.cxx b/oox/source/helper/modelobjecthelper.cxx index 6528fea5634d..21dbe9c3a2eb 100644 --- a/oox/source/helper/modelobjecthelper.cxx +++ b/oox/source/helper/modelobjecthelper.cxx @@ -45,13 +45,13 @@ namespace oox { // ============================================================================ ModelObjectHelper::ModelObjectHelper( const Reference< XMultiServiceFactory >& rxModelFactory ) : - maMarkerContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.MarkerTable" ) ), - maDashContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.DashTable" ) ), - maGradientContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.GradientTable" ) ), - maBitmapContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.BitmapTable" ) ), - maDashNameBase( CREATE_OUSTRING( "msLineDash " ) ), - maGradientNameBase( CREATE_OUSTRING( "msFillGradient " ) ), - maBitmapNameBase( CREATE_OUSTRING( "msFillBitmap " ) ) + maMarkerContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.MarkerTable" ) ), + maDashContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.DashTable" ) ), + maGradientContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.GradientTable" ) ), + maBitmapUrlContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.BitmapTable" ) ), + maDashNameBase( CREATE_OUSTRING( "msLineDash " ) ), + maGradientNameBase( CREATE_OUSTRING( "msFillGradient " ) ), + maBitmapUrlNameBase( CREATE_OUSTRING( "msFillBitmap " ) ) { } @@ -78,10 +78,10 @@ OUString ModelObjectHelper::insertFillGradient( const Gradient& rGradient ) return maGradientContainer.insertObject( maGradientNameBase, Any( rGradient ), true ); } -OUString ModelObjectHelper::insertFillBitmap( const OUString& rGraphicUrl ) +OUString ModelObjectHelper::insertFillBitmapUrl( const OUString& rGraphicUrl ) { if( rGraphicUrl.getLength() > 0 ) - return maBitmapContainer.insertObject( maBitmapNameBase, Any( rGraphicUrl ), true ); + return maBitmapUrlContainer.insertObject( maBitmapUrlNameBase, Any( rGraphicUrl ), true ); return OUString(); } diff --git a/oox/source/helper/propertymap.cxx b/oox/source/helper/propertymap.cxx index 31072fe449e5..155b2015dffa 100644 --- a/oox/source/helper/propertymap.cxx +++ b/oox/source/helper/propertymap.cxx @@ -186,10 +186,6 @@ PropertyMap::PropertyMap() : { } -PropertyMap::~PropertyMap() -{ -} - /*static*/ const OUString& PropertyMap::getPropertyName( sal_Int32 nPropId ) { OSL_ENSURE( (0 <= nPropId) && (nPropId < PROP_COUNT), "PropertyMap::getPropertyName - invalid property identifier" ); diff --git a/oox/source/helper/propertyset.cxx b/oox/source/helper/propertyset.cxx index e7071ba402a2..a46c189f9a2b 100644 --- a/oox/source/helper/propertyset.cxx +++ b/oox/source/helper/propertyset.cxx @@ -52,22 +52,10 @@ void PropertySet::set( const Reference< XPropertySet >& rxPropSet ) // Get properties ------------------------------------------------------------- -bool PropertySet::getAnyProperty( Any& orValue, sal_Int32 nPropId ) const -{ - return getAnyProperty( orValue, PropertyMap::getPropertyName( nPropId ) ); -} - Any PropertySet::getAnyProperty( sal_Int32 nPropId ) const { Any aValue; - return getAnyProperty( aValue, nPropId ) ? aValue : Any(); -} - -bool PropertySet::getBoolProperty( sal_Int32 nPropId ) const -{ - Any aAny; - bool bValue = false; - return getAnyProperty( aAny, nPropId ) && (aAny >>= bValue) && bValue; + return implGetPropertyValue( aValue, PropertyMap::getPropertyName( nPropId ) ) ? aValue : Any(); } void PropertySet::getProperties( Sequence< Any >& orValues, const Sequence< OUString >& rPropNames ) const @@ -90,15 +78,15 @@ void PropertySet::getProperties( Sequence< Any >& orValues, const Sequence< OUSt orValues.realloc( nLen ); Any* pValue = orValues.getArray(); for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue ) - getAnyProperty( *pValue, *pPropName ); + implGetPropertyValue( *pValue, *pPropName ); } } // Set properties ------------------------------------------------------------- -void PropertySet::setAnyProperty( sal_Int32 nPropId, const Any& rValue ) +bool PropertySet::setAnyProperty( sal_Int32 nPropId, const Any& rValue ) { - setAnyProperty( PropertyMap::getPropertyName( nPropId ), rValue ); + return implSetPropertyValue( PropertyMap::getPropertyName( nPropId ), rValue ); } void PropertySet::setProperties( const Sequence< OUString >& rPropNames, const Sequence< Any >& rValues ) @@ -122,7 +110,7 @@ void PropertySet::setProperties( const Sequence< OUString >& rPropNames, const S const OUString* pPropNameEnd = pPropName + rPropNames.getLength(); const Any* pValue = rValues.getConstArray(); for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue ) - setAnyProperty( *pPropName, *pValue ); + implSetPropertyValue( *pPropName, *pValue ); } } @@ -139,37 +127,34 @@ void PropertySet::setProperties( const PropertyMap& rPropertyMap ) // private -------------------------------------------------------------------- -bool PropertySet::getAnyProperty( Any& orValue, const OUString& rPropName ) const +bool PropertySet::implGetPropertyValue( Any& orValue, const OUString& rPropName ) const { - bool bHasValue = false; - try + if( mxPropSet.is() ) try { - if( mxPropSet.is() ) - { - orValue = mxPropSet->getPropertyValue( rPropName ); - bHasValue = true; - } + orValue = mxPropSet->getPropertyValue( rPropName ); + return true; } catch( Exception& ) { - OSL_ENSURE( false, OStringBuffer( "PropertySet::getAnyProperty - cannot get property \"" ). + OSL_ENSURE( false, OStringBuffer( "PropertySet::implGetPropertyValue - cannot get property \"" ). append( OUStringToOString( rPropName, RTL_TEXTENCODING_ASCII_US ) ).append( '"' ).getStr() ); } - return bHasValue; + return false; } -void PropertySet::setAnyProperty( const OUString& rPropName, const Any& rValue ) +bool PropertySet::implSetPropertyValue( const OUString& rPropName, const Any& rValue ) { - try + if( mxPropSet.is() ) try { - if( mxPropSet.is() ) - mxPropSet->setPropertyValue( rPropName, rValue ); + mxPropSet->setPropertyValue( rPropName, rValue ); + return true; } catch( Exception& ) { - OSL_ENSURE( false, OStringBuffer( "PropertySet::setAnyProperty - cannot set property \"" ). + OSL_ENSURE( false, OStringBuffer( "PropertySet::implSetPropertyValue - cannot set property \"" ). append( OUStringToOString( rPropName, RTL_TEXTENCODING_ASCII_US ) ).append( '"' ).getStr() ); } + return false; } #if OSL_DEBUG_LEVEL > 0 diff --git a/oox/source/ppt/slidefragmenthandler.cxx b/oox/source/ppt/slidefragmenthandler.cxx index 7e77f5a54938..7db7cba4c68c 100644 --- a/oox/source/ppt/slidefragmenthandler.cxx +++ b/oox/source/ppt/slidefragmenthandler.cxx @@ -150,7 +150,7 @@ Reference< XFastContextHandler > SlideFragmentHandler::createFastChildContext( s { FillPropertiesPtr pFillPropertiesPtr( new FillProperties( *mpSlidePersistPtr->getTheme()->getFillStyle( xAttribs->getOptionalValue( XML_idx ).toInt32() ) ) ); - xRet.set( new ColorContext( *this, mpSlidePersistPtr->getBackgroundColorRef() ) ); + xRet.set( new ColorContext( *this, mpSlidePersistPtr->getBackgroundColor() ) ); mpSlidePersistPtr->setBackgroundProperties( pFillPropertiesPtr ); } break; diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx index 8555ba371b77..f6f6eb8f42c7 100644 --- a/oox/source/ppt/slidepersist.cxx +++ b/oox/source/ppt/slidepersist.cxx @@ -25,14 +25,16 @@ * ************************************************************************/ -#include "oox/helper/propertyset.hxx" #include "oox/ppt/timenode.hxx" #include "oox/ppt/pptshape.hxx" #include "oox/ppt/slidepersist.hxx" #include "oox/drawingml/fillproperties.hxx" +#include "oox/drawingml/shapepropertymap.hxx" +#include "oox/helper/propertyset.hxx" #include "oox/vml/vmldrawing.hxx" #include "oox/core/namespaces.hxx" #include "oox/core/xmlfilterbase.hxx" +#include "properties.hxx" #include "tokens.hxx" #include @@ -171,24 +173,12 @@ void SlidePersist::createBackground( const XmlFilterBase& rFilterBase ) { if ( mpBackgroundPropertiesPtr ) { - try - { - sal_Int32 nPhClr = API_RGB_TRANSPARENT; - if ( maBackgroundColorRef.isUsed() ) - nPhClr = maBackgroundColorRef.getColor( rFilterBase.getGraphicHelper() ); + sal_Int32 nPhClr = maBackgroundColor.isUsed() ? + maBackgroundColor.getColor( rFilterBase.getGraphicHelper() ) : API_RGB_TRANSPARENT; - PropertyMap aPropMap; - static const rtl::OUString sBackground( RTL_CONSTASCII_USTRINGPARAM( "Background" ) ); - uno::Reference< beans::XPropertySet > xPagePropSet( mxPage, uno::UNO_QUERY_THROW ); - uno::Reference< beans::XPropertySet > xPropertySet( aPropMap.makePropertySet() ); - PropertySet aPropSet( xPropertySet ); - mpBackgroundPropertiesPtr->pushToPropSet( aPropSet, rFilterBase.getModelObjectHelper(), - rFilterBase.getGraphicHelper(), oox::drawingml::FillProperties::DEFAULT_IDS, 0, nPhClr ); - xPagePropSet->setPropertyValue( sBackground, Any( xPropertySet ) ); - } - catch( Exception ) - { - } + ::oox::drawingml::ShapePropertyMap aPropMap( rFilterBase.getModelObjectHelper() ); + mpBackgroundPropertiesPtr->pushToPropMap( aPropMap, rFilterBase.getGraphicHelper(), 0, nPhClr ); + PropertySet( mxPage ).setProperty( PROP_Background, aPropMap.makePropertySet() ); } } diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index 2850d422e234..d1b7cb8c3bf2 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -16,6 +16,7 @@ AutoShowInfo Autocomplete BackGraphicLocation BackGraphicURL +Background BackgroundColor BasicLibraries BlackDay diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx index 9ee8a4ec3215..1e846457f9a5 100644 --- a/oox/source/vml/vmlformatting.cxx +++ b/oox/source/vml/vmlformatting.cxx @@ -43,6 +43,7 @@ using ::oox::drawingml::Color; using ::oox::drawingml::FillProperties; using ::oox::drawingml::LineArrowProperties; using ::oox::drawingml::LineProperties; +using ::oox::drawingml::ShapePropertyMap; namespace oox { namespace vml { @@ -430,8 +431,7 @@ void StrokeModel::assignUsed( const StrokeModel& rSource ) moJoinStyle.assignIfUsed( rSource.moJoinStyle ); } -void StrokeModel::pushToPropMap( PropertyMap& rPropMap, - ModelObjectHelper& rModelObjectHelper, const GraphicHelper& rGraphicHelper ) const +void StrokeModel::pushToPropMap( ShapePropertyMap& rPropMap, const GraphicHelper& rGraphicHelper ) const { /* Convert VML line formatting to DrawingML line formatting and let the DrawingML code do the hard work. */ @@ -454,7 +454,7 @@ void StrokeModel::pushToPropMap( PropertyMap& rPropMap, aLineProps.maLineFill.moFillType = XML_noFill; } - aLineProps.pushToPropMap( rPropMap, rModelObjectHelper, rGraphicHelper ); + aLineProps.pushToPropMap( rPropMap, rGraphicHelper ); } // ============================================================================ @@ -475,8 +475,7 @@ void FillModel::assignUsed( const FillModel& rSource ) moRotate.assignIfUsed( rSource.moRotate ); } -void FillModel::pushToPropMap( PropertyMap& rPropMap, - ModelObjectHelper& rModelObjectHelper, const GraphicHelper& rGraphicHelper ) const +void FillModel::pushToPropMap( ShapePropertyMap& rPropMap, const GraphicHelper& rGraphicHelper ) const { /* Convert VML fill formatting to DrawingML fill formatting and let the DrawingML code do the hard work. */ @@ -594,7 +593,7 @@ void FillModel::pushToPropMap( PropertyMap& rPropMap, aFillProps.moFillType = XML_noFill; } - aFillProps.pushToPropMap( rPropMap, rModelObjectHelper, rGraphicHelper ); + aFillProps.pushToPropMap( rPropMap, rGraphicHelper ); } // ============================================================================ diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index d557a7f50354..52b2217b290d 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -36,8 +36,8 @@ #include #include #include "properties.hxx" +#include "oox/drawingml/shapepropertymap.hxx" #include "oox/helper/graphichelper.hxx" -#include "oox/helper/propertymap.hxx" #include "oox/helper/propertyset.hxx" #include "oox/core/xmlfilterbase.hxx" #include "oox/ole/axcontrol.hxx" @@ -313,15 +313,11 @@ Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) const { - ModelObjectHelper& rModelObjectHelper = mrDrawing.getFilter().getModelObjectHelper(); + ::oox::drawingml::ShapePropertyMap aPropMap( mrDrawing.getFilter().getModelObjectHelper() ); const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper(); - - PropertyMap aPropMap; - maTypeModel.maStrokeModel.pushToPropMap( aPropMap, rModelObjectHelper, rGraphicHelper ); - maTypeModel.maFillModel.pushToPropMap( aPropMap, rModelObjectHelper, rGraphicHelper ); - - PropertySet aPropSet( rxShape ); - aPropSet.setProperties( aPropMap ); + maTypeModel.maStrokeModel.pushToPropMap( aPropMap, rGraphicHelper ); + maTypeModel.maFillModel.pushToPropMap( aPropMap, rGraphicHelper ); + PropertySet( rxShape ).setProperties( aPropMap ); } // ============================================================================ diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx index e1607e99e6c6..dbc6ae19b703 100755 --- a/oox/source/xls/drawingmanager.cxx +++ b/oox/source/xls/drawingmanager.cxx @@ -33,9 +33,9 @@ #include #include #include "oox/core/filterbase.hxx" +#include "oox/drawingml/fillproperties.hxx" #include "oox/drawingml/lineproperties.hxx" -#include "oox/helper/propertymap.hxx" -#include "oox/helper/propertyset.hxx" +#include "oox/drawingml/shapepropertymap.hxx" #include "oox/xls/biffinputstream.hxx" #include "oox/xls/unitconverter.hxx" #include "properties.hxx" @@ -594,7 +594,7 @@ void BiffDrawingObjectBase::readMacroBiff8( BiffInputStream& rStrm ) } } -void BiffDrawingObjectBase::convertLineProperties( PropertyMap& rPropMap, const BiffObjLineModel& rLineModel, sal_uInt16 nArrows ) const +void BiffDrawingObjectBase::convertLineProperties( ShapePropertyMap& rPropMap, const BiffObjLineModel& rLineModel, sal_uInt16 nArrows ) const { if( rLineModel.mbAuto ) { @@ -705,10 +705,10 @@ void BiffDrawingObjectBase::convertLineProperties( PropertyMap& rPropMap, const } } - aLineProps.pushToPropMap( rPropMap, getBaseFilter().getModelObjectHelper(), getBaseFilter().getGraphicHelper() ); + aLineProps.pushToPropMap( rPropMap, getBaseFilter().getGraphicHelper() ); } -void BiffDrawingObjectBase::convertFillProperties( PropertyMap& rPropMap, const BiffObjFillModel& rFillModel ) const +void BiffDrawingObjectBase::convertFillProperties( ShapePropertyMap& rPropMap, const BiffObjFillModel& rFillModel ) const { if( rFillModel.mbAuto ) { @@ -791,10 +791,10 @@ void BiffDrawingObjectBase::convertFillProperties( PropertyMap& rPropMap, const #endif } - aFillProps.pushToPropMap( rPropMap, getBaseFilter().getModelObjectHelper(), getBaseFilter().getGraphicHelper() ); + aFillProps.pushToPropMap( rPropMap, getBaseFilter().getGraphicHelper() ); } -void BiffDrawingObjectBase::convertFrameProperties( PropertyMap& /*rPropMap*/, sal_uInt16 /*nFrameFlags*/ ) const +void BiffDrawingObjectBase::convertFrameProperties( ShapePropertyMap& /*rPropMap*/, sal_uInt16 /*nFrameFlags*/ ) const { } @@ -1044,7 +1044,7 @@ void BiffLineObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameL Reference< XShape > BiffLineObject::implConvertAndInsert( BiffDrawingBase& rDrawing, const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - PropertyMap aPropMap; + ShapePropertyMap aPropMap( getBaseFilter().getModelObjectHelper() ); convertLineProperties( aPropMap, maLineModel, mnArrows ); // create the line polygon @@ -1087,7 +1087,7 @@ void BiffRectObject::readFrameData( BiffInputStream& rStrm ) rStrm >> maFillModel >> maLineModel >> mnFrameFlags; } -void BiffRectObject::convertRectProperties( PropertyMap& rPropMap ) const +void BiffRectObject::convertRectProperties( ShapePropertyMap& rPropMap ) const { convertLineProperties( rPropMap, maLineModel ); convertFillProperties( rPropMap, maFillModel ); @@ -1116,7 +1116,7 @@ void BiffRectObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameL Reference< XShape > BiffRectObject::implConvertAndInsert( BiffDrawingBase& rDrawing, const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - PropertyMap aPropMap; + ShapePropertyMap aPropMap( getBaseFilter().getModelObjectHelper() ); convertRectProperties( aPropMap ); Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ), rxShapes, rShapeRect ); @@ -1134,7 +1134,7 @@ BiffOvalObject::BiffOvalObject( const WorksheetHelper& rHelper ) : Reference< XShape > BiffOvalObject::implConvertAndInsert( BiffDrawingBase& rDrawing, const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - PropertyMap aPropMap; + ShapePropertyMap aPropMap( getBaseFilter().getModelObjectHelper() ); convertRectProperties( aPropMap ); Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ), rxShapes, rShapeRect ); @@ -1176,7 +1176,7 @@ void BiffArcObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLe Reference< XShape > BiffArcObject::implConvertAndInsert( BiffDrawingBase& rDrawing, const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - PropertyMap aPropMap; + ShapePropertyMap aPropMap( getBaseFilter().getModelObjectHelper() ); convertLineProperties( aPropMap, maLineModel ); convertFillProperties( aPropMap, maFillModel ); @@ -1257,7 +1257,7 @@ Reference< XShape > BiffPolygonObject::implConvertAndInsert( BiffDrawingBase& rD Reference< XShape > xShape; if( maCoords.size() >= 2 ) { - PropertyMap aPropMap; + ShapePropertyMap aPropMap( getBaseFilter().getModelObjectHelper() ); convertRectProperties( aPropMap ); // create the polygon -- cgit From 46609bbf0fbcef0c4b9cc835c31e54a93d80c404 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Wed, 12 Jan 2011 18:03:09 +0100 Subject: dr78: build errors after rebase --- oox/source/drawingml/shapepropertymap.cxx | 1 - oox/source/xls/commentsbuffer.cxx | 3 ++- oox/source/xls/drawingbase.cxx | 1 - oox/source/xls/drawingfragment.cxx | 13 ++----------- oox/source/xls/drawingmanager.cxx | 4 ++-- oox/source/xls/formulaparser.cxx | 2 +- oox/source/xls/sheetdatacontext.cxx | 2 +- oox/source/xls/workbookfragment.cxx | 7 ++++--- 8 files changed, 12 insertions(+), 21 deletions(-) (limited to 'oox/source') diff --git a/oox/source/drawingml/shapepropertymap.cxx b/oox/source/drawingml/shapepropertymap.cxx index 9d2397cf5f7e..521ed28871ee 100755 --- a/oox/source/drawingml/shapepropertymap.cxx +++ b/oox/source/drawingml/shapepropertymap.cxx @@ -32,7 +32,6 @@ #include #include #include "oox/helper/modelobjecthelper.hxx" -#include "properties.hxx" namespace oox { namespace drawingml { diff --git a/oox/source/xls/commentsbuffer.cxx b/oox/source/xls/commentsbuffer.cxx index e900d48fa3d9..f55dac0ca6f2 100644 --- a/oox/source/xls/commentsbuffer.cxx +++ b/oox/source/xls/commentsbuffer.cxx @@ -46,6 +46,7 @@ namespace xls { using namespace ::com::sun::star::drawing; using namespace ::com::sun::star::sheet; using namespace ::com::sun::star::table; +using namespace ::com::sun::star::text; using namespace ::com::sun::star::uno; using ::rtl::OUString; @@ -148,7 +149,7 @@ void Comment::finalizeImport() sal_Bool bVisible = sal_True; switch( getFilterType() ) { - case FILTER_OOX: + case FILTER_OOXML: if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) ) { // position and formatting diff --git a/oox/source/xls/drawingbase.cxx b/oox/source/xls/drawingbase.cxx index c7a901ead30a..99c96a7f87b1 100755 --- a/oox/source/xls/drawingbase.cxx +++ b/oox/source/xls/drawingbase.cxx @@ -28,7 +28,6 @@ #include "oox/xls/drawingbase.hxx" #include -#include "oox/core/namespaces.hxx" #include "oox/helper/attributelist.hxx" #include "oox/helper/binaryinputstream.hxx" #include "oox/xls/unitconverter.hxx" diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx index 9888fcb2b5f9..47b7e6cb2565 100644 --- a/oox/source/xls/drawingfragment.cxx +++ b/oox/source/xls/drawingfragment.cxx @@ -259,7 +259,6 @@ void DrawingFragment::onEndElement() EmuRectangle aShapeRectEmu = mxAnchor->calcAnchorRectEmu( getDrawPageSize() ); if( (aShapeRectEmu.X >= 0) && (aShapeRectEmu.Y >= 0) && (aShapeRectEmu.Width >= 0) && (aShapeRectEmu.Height >= 0) ) { -<<<<<<< local // TODO: DrawingML implementation expects 32-bit coordinates for EMU rectangles (change that to EmuRectangle) Rectangle aShapeRectEmu32( getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.X, 0, SAL_MAX_INT32 ), @@ -267,20 +266,12 @@ void DrawingFragment::onEndElement() getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Width, 0, SAL_MAX_INT32 ), getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Height, 0, SAL_MAX_INT32 ) ); mxShape->addShape( getOoxFilter(), &getTheme(), mxDrawPage, &aShapeRectEmu32 ); - // collect all shape positions in the WorksheetHelper base class - extendShapeBoundingBox( aShapeRectEmu32 ); -======= - mxShape->addShape( getOoxFilter(), &getTheme(), mxDrawPage, &aShapeRect ); /* Collect all shape positions in the WorksheetHelper base class. But first, scale EMUs to 1/100 mm. */ - const UnitConverter& rUnitConv = getUnitConverter(); Rectangle aShapeRectHmm( - rUnitConv.scaleToMm100( aShapeRect.X, UNIT_EMU ), - rUnitConv.scaleToMm100( aShapeRect.Y, UNIT_EMU ), - rUnitConv.scaleToMm100( aShapeRect.Width, UNIT_EMU ), - rUnitConv.scaleToMm100( aShapeRect.Height, UNIT_EMU ) ); + convertEmuToHmm( aShapeRectEmu.X ), convertEmuToHmm( aShapeRectEmu.Y ), + convertEmuToHmm( aShapeRectEmu.Width ), convertEmuToHmm( aShapeRectEmu.Height ) ); extendShapeBoundingBox( aShapeRectHmm ); ->>>>>>> other } } mxShape.reset(); diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx index dbc6ae19b703..61bc0dff3fbb 100755 --- a/oox/source/xls/drawingmanager.cxx +++ b/oox/source/xls/drawingmanager.cxx @@ -36,10 +36,10 @@ #include "oox/drawingml/fillproperties.hxx" #include "oox/drawingml/lineproperties.hxx" #include "oox/drawingml/shapepropertymap.hxx" +#include "oox/helper/containerhelper.hxx" +#include "oox/token/tokens.hxx" #include "oox/xls/biffinputstream.hxx" #include "oox/xls/unitconverter.hxx" -#include "properties.hxx" -#include "tokens.hxx" namespace oox { namespace xls { diff --git a/oox/source/xls/formulaparser.cxx b/oox/source/xls/formulaparser.cxx index 5442f0c16e48..26bf66986638 100644 --- a/oox/source/xls/formulaparser.cxx +++ b/oox/source/xls/formulaparser.cxx @@ -376,7 +376,7 @@ void FormulaFinalizer::appendEmptyParameter( const FunctionInfo& rFuncInfo, size switch( rFuncInfo.mnBiff12FuncId ) { - case BIFF12_FUNC_IF: + case BIFF_FUNC_IF: if( (nParam == 1) || (nParam == 2) ) maTokens.append< double >( OPCODE_PUSH, 0.0 ); break; diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx index d12e84b27b09..2d678aec72ca 100644 --- a/oox/source/xls/sheetdatacontext.cxx +++ b/oox/source/xls/sheetdatacontext.cxx @@ -715,7 +715,7 @@ void BiffSheetDataContext::importXfId( BiffInputStream& rStrm, bool bBiff2 ) mobBiff2HasXfs = getStyles().getCellXf( 0 ).get() != 0; // read formatting information (includes the XF identifier) sal_uInt8 nFlags1, nFlags2, nFlags3; - mrStrm >> nFlags1 >> nFlags2 >> nFlags3; + rStrm >> nFlags1 >> nFlags2 >> nFlags3; /* If the file contains XFs, extract and set the XF identifier, otherwise get the explicit formatting. */ if( mobBiff2HasXfs.get() ) diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx index 7318e12e2b61..69daca13812e 100644 --- a/oox/source/xls/workbookfragment.cxx +++ b/oox/source/xls/workbookfragment.cxx @@ -358,6 +358,7 @@ bool BiffWorkbookFragment::importFragment() { case BIFF_FRAGMENT_GLOBALS: { + BiffInputStream& rStrm = getInputStream(); // import workbook globals fragment and create sheets in document ISegmentProgressBarRef xGlobalsProgress = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS ); bRet = importGlobalsFragment( *xGlobalsProgress ); @@ -373,15 +374,15 @@ bool BiffWorkbookFragment::importFragment() first record of the sheet fragment which is usually a BOF record. */ BiffFragmentType eSheetFragment = BIFF_FRAGMENT_UNKNOWN; sal_Int64 nRecHandle = rWorksheets.getBiffRecordHandle( nWorksheet ); - if( mrStrm.startRecordByHandle( nRecHandle ) ) + if( rStrm.startRecordByHandle( nRecHandle ) ) { /* #i109800# Stream may point to any record of the sheet fragment. Check the record identifier before calling startFragment(). */ - bool bIsBofRec = isBofRecord(); + bool bIsBofRec = BiffHelper::isBofRecord( rStrm ); /* Rewind the record. If it is the BOF record, it will be read in startFragment(). In every case, stream will point before the first available non-BOF record. */ - mrStrm.rewindRecord(); + rStrm.rewindRecord(); // if the BOF record is missing, a regular worksheet will be assumed eSheetFragment = bIsBofRec ? startFragment( getBiff() ) : BIFF_FRAGMENT_WORKSHEET; } -- cgit From 2fba65d4ec2c6ecee91cd5af3411b613bd490444 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Thu, 13 Jan 2011 10:55:32 +0100 Subject: dr78: unx build errors --- oox/source/xls/drawingbase.cxx | 2 -- oox/source/xls/drawingmanager.cxx | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'oox/source') diff --git a/oox/source/xls/drawingbase.cxx b/oox/source/xls/drawingbase.cxx index 99c96a7f87b1..fc2ab64059c8 100755 --- a/oox/source/xls/drawingbase.cxx +++ b/oox/source/xls/drawingbase.cxx @@ -200,8 +200,6 @@ void ShapeAnchor::importBiffAnchor( BinaryInputStream& rStrm ) EmuRectangle ShapeAnchor::calcAnchorRectEmu( const Size& rPageSizeHmm ) const { AddressConverter& rAddrConv = getAddressConverter(); - const UnitConverter& rUnitConv = getUnitConverter(); - EmuSize aPageSize( lclHmmToEmu( rPageSizeHmm.Width ), lclHmmToEmu( rPageSizeHmm.Height ) ); EmuRectangle aAnchorRect( -1, -1, -1, -1 ); diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx index 61bc0dff3fbb..3ee5c45a80b6 100755 --- a/oox/source/xls/drawingmanager.cxx +++ b/oox/source/xls/drawingmanager.cxx @@ -311,10 +311,10 @@ void BiffDrawingObjectContainer::convertAndInsert( BiffDrawingBase& rDrawing, co BiffDrawingObjectBase::BiffDrawingObjectBase( const WorksheetHelper& rHelper ) : WorksheetHelper( rHelper ), maAnchor( rHelper ), - mnObjId( BIFF_OBJ_INVALID_ID ), - mnObjType( BIFF_OBJTYPE_UNKNOWN ), mnDffShapeId( 0 ), mnDffFlags( 0 ), + mnObjId( BIFF_OBJ_INVALID_ID ), + mnObjType( BIFF_OBJTYPE_UNKNOWN ), mbHasAnchor( false ), mbHidden( false ), mbVisible( true ), -- cgit From fd2917575b28c5fde2af29ed7738447bb0aae99b Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Mon, 17 Jan 2011 10:59:07 +0100 Subject: dr78: minor changes in token macros --- oox/source/token/namespaces.hxx.tail | 39 +++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 18 deletions(-) (limited to 'oox/source') diff --git a/oox/source/token/namespaces.hxx.tail b/oox/source/token/namespaces.hxx.tail index 651fc38511d4..1e6ba5881589 100755 --- a/oox/source/token/namespaces.hxx.tail +++ b/oox/source/token/namespaces.hxx.tail @@ -1,8 +1,8 @@ // ============================================================================ -const sal_Int32 TOKEN_MASK = static_cast< sal_Int32 >( (1 << NMSP_SHIFT) - 1 ); -const sal_Int32 NMSP_MASK = static_cast< sal_Int32 >( SAL_MAX_INT16 & ~TOKEN_MASK ); +const sal_Int32 TOKEN_MASK = static_cast< sal_Int32 >( (1 << NMSP_SHIFT) - 1 ); +const sal_Int32 NMSP_MASK = static_cast< sal_Int32 >( SAL_MAX_INT16 & ~TOKEN_MASK ); /** Returns the raw token identifier without namespace of the passed token. */ inline sal_Int32 getBaseToken( sal_Int32 nToken ) { return nToken & TOKEN_MASK; } @@ -10,23 +10,26 @@ inline sal_Int32 getBaseToken( sal_Int32 nToken ) { return nToken & TOKEN_MASK; /** Returns the namespace without token identifier of the passed token. */ inline sal_Int32 getNamespace( sal_Int32 nToken ) { return nToken & NMSP_MASK; } + // defines for tokens with specific namespaces -#define A_TOKEN( token ) (::oox::NMSP_dml | XML_##token) -#define AX_TOKEN( token ) (::oox::NMSP_ax | XML_##token) -#define C_TOKEN( token ) (::oox::NMSP_dmlChart | XML_##token) -#define CDR_TOKEN( token ) (::oox::NMSP_dmlChartDr | XML_##token) -#define DGM_TOKEN( token ) (::oox::NMSP_dmlDiagram | XML_##token) -#define O_TOKEN( token ) (::oox::NMSP_vmlOffice | XML_##token) -#define PC_TOKEN( token ) (::oox::NMSP_packageContentTypes | XML_##token) -#define PPT_TOKEN( token ) (::oox::NMSP_ppt | XML_##token) -#define PR_TOKEN( token ) (::oox::NMSP_packageRel | XML_##token) -#define R_TOKEN( token ) (::oox::NMSP_officeRel | XML_##token) -#define VML_TOKEN( token ) (::oox::NMSP_vml | XML_##token) -#define VMLX_TOKEN( token ) (::oox::NMSP_vmlExcel | XML_##token) -#define XDR_TOKEN( token ) (::oox::NMSP_dmlSpreadDr | XML_##token) -#define XLS_TOKEN( token ) (::oox::NMSP_xls | XML_##token) -#define XM_TOKEN( token ) (::oox::NMSP_xm | XML_##token) -#define XML_TOKEN( token ) (::oox::NMSP_xml | XML_##token) +#define OOX_TOKEN( token, namespace ) (::oox::XML_##token | ::oox::NMSP_##namespace) + +#define A_TOKEN( token ) OOX_TOKEN( token, dml ) +#define AX_TOKEN( token ) OOX_TOKEN( token, ax ) +#define C_TOKEN( token ) OOX_TOKEN( token, dmlChart ) +#define CDR_TOKEN( token ) OOX_TOKEN( token, dmlChartDr ) +#define DGM_TOKEN( token ) OOX_TOKEN( token, dmlDiagram ) +#define O_TOKEN( token ) OOX_TOKEN( token, vmlOffice ) +#define PC_TOKEN( token ) OOX_TOKEN( token, packageContentTypes ) +#define PPT_TOKEN( token ) OOX_TOKEN( token, ppt ) +#define PR_TOKEN( token ) OOX_TOKEN( token, packageRel ) +#define R_TOKEN( token ) OOX_TOKEN( token, officeRel ) +#define VML_TOKEN( token ) OOX_TOKEN( token, vml ) +#define VMLX_TOKEN( token ) OOX_TOKEN( token, vmlExcel ) +#define XDR_TOKEN( token ) OOX_TOKEN( token, dmlSpreadDr ) +#define XLS_TOKEN( token ) OOX_TOKEN( token, xls ) +#define XM_TOKEN( token ) OOX_TOKEN( token, xm ) +#define XML_TOKEN( token ) OOX_TOKEN( token, xml ) // ============================================================================ -- cgit From f9a70973626de755d37fe31b8ccec359dffeb1a0 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Tue, 18 Jan 2011 17:22:36 +0100 Subject: dr78: switch module oox to new gbuild system --- oox/source/core/makefile.mk | 66 ---------- oox/source/docprop/makefile.mk | 49 ------- oox/source/drawingml/chart/makefile.mk | 74 ----------- oox/source/drawingml/diagram/makefile.mk | 53 -------- oox/source/drawingml/makefile.mk | 92 ------------- oox/source/drawingml/table/makefile.mk | 62 --------- oox/source/dump/makefile.mk | 53 -------- oox/source/export/ooxml-export-notes.txt | 220 +++++++++++++++++++++++++++++++ oox/source/helper/makefile.mk | 60 --------- oox/source/ole/makefile.mk | 60 --------- oox/source/ppt/makefile.mk | 76 ----------- oox/source/shape/makefile.mk | 49 ------- oox/source/token/makefile.mk | 78 ----------- oox/source/token/namespacemap.cxx | 2 +- oox/source/token/namespaces.pl | 58 +++----- oox/source/token/properties.pl | 52 +++----- oox/source/token/propertynames.cxx | 3 +- oox/source/token/tokenmap.cxx | 4 +- oox/source/token/tokens.pl | 80 ++++++----- oox/source/vml/makefile.mk | 56 -------- oox/source/xls/makefile.mk | 105 --------------- 21 files changed, 301 insertions(+), 1051 deletions(-) delete mode 100644 oox/source/core/makefile.mk delete mode 100644 oox/source/docprop/makefile.mk delete mode 100644 oox/source/drawingml/chart/makefile.mk delete mode 100644 oox/source/drawingml/diagram/makefile.mk delete mode 100644 oox/source/drawingml/makefile.mk delete mode 100644 oox/source/drawingml/table/makefile.mk delete mode 100644 oox/source/dump/makefile.mk create mode 100644 oox/source/export/ooxml-export-notes.txt delete mode 100644 oox/source/helper/makefile.mk delete mode 100644 oox/source/ole/makefile.mk delete mode 100644 oox/source/ppt/makefile.mk delete mode 100644 oox/source/shape/makefile.mk delete mode 100644 oox/source/token/makefile.mk delete mode 100644 oox/source/vml/makefile.mk delete mode 100644 oox/source/xls/makefile.mk (limited to 'oox/source') diff --git a/oox/source/core/makefile.mk b/oox/source/core/makefile.mk deleted file mode 100644 index 2b58b95777df..000000000000 --- a/oox/source/core/makefile.mk +++ /dev/null @@ -1,66 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=oox -TARGET=core -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -.IF "$(SYSTEM_OPENSSL)" == "YES" -CFLAGS+= $(OPENSSL_CFLAGS) -.ENDIF - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/binarycodec.obj \ - $(SLO)$/binaryfilterbase.obj \ - $(SLO)$/contexthandler.obj \ - $(SLO)$/contexthandler2.obj \ - $(SLO)$/fastparser.obj \ - $(SLO)$/fasttokenhandler.obj \ - $(SLO)$/filterbase.obj \ - $(SLO)$/filterdetect.obj \ - $(SLO)$/fragmenthandler.obj \ - $(SLO)$/fragmenthandler2.obj \ - $(SLO)$/recordparser.obj \ - $(SLO)$/relations.obj \ - $(SLO)$/relationshandler.obj \ - $(SLO)$/services.obj \ - $(SLO)$/xmlfilterbase.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/source/docprop/makefile.mk b/oox/source/docprop/makefile.mk deleted file mode 100644 index 5687178da9e0..000000000000 --- a/oox/source/docprop/makefile.mk +++ /dev/null @@ -1,49 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=oox -TARGET=docprop -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/ooxmldocpropimport.obj \ - $(SLO)$/docprophandler.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/source/drawingml/chart/makefile.mk b/oox/source/drawingml/chart/makefile.mk deleted file mode 100644 index 84762e6a2540..000000000000 --- a/oox/source/drawingml/chart/makefile.mk +++ /dev/null @@ -1,74 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/..$/.. - -PRJNAME=oox -TARGET=chart -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/axiscontext.obj \ - $(SLO)$/axisconverter.obj \ - $(SLO)$/axismodel.obj \ - $(SLO)$/chartcontextbase.obj \ - $(SLO)$/chartconverter.obj \ - $(SLO)$/chartdrawingfragment.obj \ - $(SLO)$/chartspaceconverter.obj \ - $(SLO)$/chartspacefragment.obj \ - $(SLO)$/chartspacemodel.obj \ - $(SLO)$/converterbase.obj \ - $(SLO)$/datasourcecontext.obj \ - $(SLO)$/datasourceconverter.obj \ - $(SLO)$/datasourcemodel.obj \ - $(SLO)$/modelbase.obj \ - $(SLO)$/objectformatter.obj \ - $(SLO)$/plotareacontext.obj \ - $(SLO)$/plotareaconverter.obj \ - $(SLO)$/plotareamodel.obj \ - $(SLO)$/seriescontext.obj \ - $(SLO)$/seriesconverter.obj \ - $(SLO)$/seriesmodel.obj \ - $(SLO)$/titlecontext.obj \ - $(SLO)$/titleconverter.obj \ - $(SLO)$/titlemodel.obj \ - $(SLO)$/typegroupcontext.obj \ - $(SLO)$/typegroupconverter.obj \ - $(SLO)$/typegroupmodel.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/source/drawingml/diagram/makefile.mk b/oox/source/drawingml/diagram/makefile.mk deleted file mode 100644 index 9d526ed3d3fb..000000000000 --- a/oox/source/drawingml/diagram/makefile.mk +++ /dev/null @@ -1,53 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/..$/.. - -PRJNAME=oox -TARGET=diagram -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/diagram.obj \ - $(SLO)$/diagramfragmenthandler.obj \ - $(SLO)$/diagramdefinitioncontext.obj \ - $(SLO)$/diagramlayoutatoms.obj \ - $(SLO)$/datamodelcontext.obj \ - $(SLO)$/layoutnodecontext.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/source/drawingml/makefile.mk b/oox/source/drawingml/makefile.mk deleted file mode 100644 index 0546fb4c233d..000000000000 --- a/oox/source/drawingml/makefile.mk +++ /dev/null @@ -1,92 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=oox -TARGET=drawingml -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/clrscheme.obj\ - $(SLO)$/clrschemecontext.obj\ - $(SLO)$/color.obj\ - $(SLO)$/colorchoicecontext.obj\ - $(SLO)$/connectorshapecontext.obj\ - $(SLO)$/customshapegeometry.obj\ - $(SLO)$/customshapeproperties.obj\ - $(SLO)$/drawingmltypes.obj\ - $(SLO)$/embeddedwavaudiofile.obj\ - $(SLO)$/fillproperties.obj\ - $(SLO)$/fillpropertiesgroupcontext.obj\ - $(SLO)$/graphicshapecontext.obj\ - $(SLO)$/guidcontext.obj\ - $(SLO)$/hyperlinkcontext.obj\ - $(SLO)$/lineproperties.obj\ - $(SLO)$/linepropertiescontext.obj\ - $(SLO)$/objectdefaultcontext.obj\ - $(SLO)$/shape.obj\ - $(SLO)$/shapecontext.obj\ - $(SLO)$/shapegroupcontext.obj\ - $(SLO)$/shapepropertiescontext.obj\ - $(SLO)$/shapepropertymap.obj\ - $(SLO)$/shapestylecontext.obj\ - $(SLO)$/spdefcontext.obj\ - $(SLO)$/textbody.obj\ - $(SLO)$/textbodycontext.obj\ - $(SLO)$/textbodyproperties.obj\ - $(SLO)$/textbodypropertiescontext.obj\ - $(SLO)$/textcharacterproperties.obj\ - $(SLO)$/textcharacterpropertiescontext.obj\ - $(SLO)$/textfield.obj\ - $(SLO)$/textfieldcontext.obj\ - $(SLO)$/textfont.obj\ - $(SLO)$/textliststyle.obj \ - $(SLO)$/textliststylecontext.obj\ - $(SLO)$/textparagraph.obj\ - $(SLO)$/textparagraphproperties.obj\ - $(SLO)$/textparagraphpropertiescontext.obj\ - $(SLO)$/textrun.obj\ - $(SLO)$/textspacingcontext.obj\ - $(SLO)$/texttabstoplistcontext.obj\ - $(SLO)$/theme.obj\ - $(SLO)$/themeelementscontext.obj\ - $(SLO)$/themefragmenthandler.obj\ - $(SLO)$/transform2dcontext.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/source/drawingml/table/makefile.mk b/oox/source/drawingml/table/makefile.mk deleted file mode 100644 index fa71971fc278..000000000000 --- a/oox/source/drawingml/table/makefile.mk +++ /dev/null @@ -1,62 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/..$/.. - -PRJNAME=oox -TARGET=table -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/tablecontext.obj \ - $(SLO)$/tableproperties.obj \ - $(SLO)$/tablerow.obj \ - $(SLO)$/tablerowcontext.obj \ - $(SLO)$/tablecell.obj \ - $(SLO)$/tablecellcontext.obj \ - $(SLO)$/tablestylelist.obj \ - $(SLO)$/tablestylelistfragmenthandler.obj \ - $(SLO)$/tablestylecontext.obj \ - $(SLO)$/tablestyle.obj \ - $(SLO)$/tablebackgroundstylecontext.obj \ - $(SLO)$/tablepartstylecontext.obj \ - $(SLO)$/tablestyletextstylecontext.obj \ - $(SLO)$/tablestylecellstylecontext.obj \ - $(SLO)$/tablestylepart.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/source/dump/makefile.mk b/oox/source/dump/makefile.mk deleted file mode 100644 index 1e5f615675cc..000000000000 --- a/oox/source/dump/makefile.mk +++ /dev/null @@ -1,53 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=oox -TARGET=dump -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/biffdumper.obj \ - $(SLO)$/dffdumper.obj \ - $(SLO)$/dumperbase.obj \ - $(SLO)$/oledumper.obj \ - $(SLO)$/pptxdumper.obj \ - $(SLO)$/xlsbdumper.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/source/export/ooxml-export-notes.txt b/oox/source/export/ooxml-export-notes.txt new file mode 100644 index 000000000000..8da4582b72b1 --- /dev/null +++ b/oox/source/export/ooxml-export-notes.txt @@ -0,0 +1,220 @@ +How to install this +------------------- + +> cd instsetoo_native/util +> LOCALINSTALLDIR=/where/you/want dmake openoffice_en-US PKGFORMAT=installed + +OOXML generally +--------------- + +- http://www.ecma-international.org/publications/standards/Ecma-376.htm +- http://www.asahi-net.or.jp/~eb2m-mrt/ooxml/dependencies.html + +Related modules +--------------- + +- oox + - .xlsx and .pptx import + +- writerfilter + - import of .docx, uses also oox for the graphics etc. + - can also parse .doc; but used for ooxml only for now + +- filter + - the configuration stuff (so that the filters appear in the filepicker) + +Old binary filters (export) +--------------------------- + +- doc export + - sw/source/filter/ww8/wrtww8* + - wrtww8.cxx:2191 [SwWW8Writer::StoreDoc()] is the entry point + + - eg. + #0 SwWW8Writer::WriteText (this=0x2aaab3dfb7c0) at /local/ooxml/ooxml/sw/source/filter/ww8/wrtww8.cxx:1846 + #1 0x00002aaaae75a545 in SwWW8Writer::WriteMainText (this=0x2aaab3d6a870) + at /local/ooxml/ooxml/sw/source/filter/ww8/wrtww8.cxx:1925 + #2 0x00002aaaae75e357 in SwWW8Writer::StoreDoc1 (this=0x2aaab3d6a870) + at /local/ooxml/ooxml/sw/source/filter/ww8/wrtww8.cxx:2076 + #3 0x00002aaaae7605ec in SwWW8Writer::StoreDoc (this=0x2aaab3d6a870) + at /local/ooxml/ooxml/sw/source/filter/ww8/wrtww8.cxx:2383 + #4 0x00002aaaae760fd5 in SwWW8Writer::WriteStorage (this=0x2aaab3d6a870) + at /local/ooxml/ooxml/sw/source/filter/ww8/wrtww8.cxx:2547 + #5 0x00002aaaae70b793 in StgWriter::Write (this=0x2aaab3d6a870, rPaM=@0x2b3802a2b640, rStg=@0x2aaab3d621c0, + pFName=0x7fffb1b285c0) at /local/ooxml/ooxml/sw/source/filter/writer/writer.cxx:653 + #6 0x00002aaaae70b84d in Writer::Write (this=0x2aaab3d6a870, rPaM=@0x2b3802a2b640, rStrm=@0x2aaaad979d20, + pFName=0x7fffb1b285c0) at /local/ooxml/ooxml/sw/source/filter/writer/writer.cxx:358 + #7 0x00002aaaae70b993 in Writer::Write (this=0x2aaab3d6a870, rPam=@0x2b3802a2b640, rMed=@0x2aaaad999f30, + pFileName=0x7fffb1b285c0) at /local/ooxml/ooxml/sw/source/filter/writer/writer.cxx:385 + #8 0x00002aaaae6375d7 in SwWriter::Write (this=0x7fffb1b28410, rxWriter=@0x7fffb1b285d0, + pRealFileName=0x7fffb1b285c0) at /local/ooxml/ooxml/sw/source/filter/basflt/shellio.cxx:963 + #9 0x00002aaaae87cc1e in SwDocShell::ConvertTo (this=0xcc27f0, rMedium=@0x2aaaad999f30) + at /local/ooxml/ooxml/sw/source/ui/app/docsh.cxx:924 + #10 0x00002b37faae6b58 in SfxObjectShell::DoLoad () + from /local/ooxml/inst/openoffice.org3.0/program/../basis-link/program//libsfxlx.so + +- xls export + - sc/source/filter/excel/xe* + + - eg. + #0 XclExpRecord::Save (this=0x11ae4c0, rStrm=@0x7fff5e6335d0) + at /local/ooxml/ooxml/sc/source/filter/excel/xerecord.cxx:88 + #1 0x00002aaaae562c4a in ExcRecord::Save (this=0x11ae4c0, rStrm=@0x7fff5e6335d0) + at /local/ooxml/ooxml/sc/source/filter/excel/excrecds.cxx:168 + #2 0x00002aaaae54b0fa in XclExpRecordList::Save (this=0x11c5d18, rStrm=@0x7fff5e6335d0) + at ../inc/xerecord.hxx:281 + #3 0x00002aaaae547541 in ExcTable::Write (this=0x11c5cf8, rStr=@0x7fff5e6335d0) + at /local/ooxml/ooxml/sc/source/filter/excel/excdoc.cxx:455 + #4 0x00002aaaae5475fb in ExcDocument::Write (this=0x11c5ce0, rSvStrm=@0x2aaab3dcd070) + at /local/ooxml/ooxml/sc/source/filter/excel/excdoc.cxx:525 + #5 0x00002aaaae568add in ExportBiff5::Write (this=0x7fff5e6339c0) + at /local/ooxml/ooxml/sc/source/filter/excel/expop2.cxx:119 + #6 0x00002aaaae54f4af in ScExportExcel5 (rMedium=@0x2aaab3d87410, pDocument=0xce6a00, bBiff8=1 '\001', eNach=1) + at /local/ooxml/ooxml/sc/source/filter/excel/excel.cxx:252 + #7 0x00002aaaadf1b70a in ScDocShell::ConvertTo (this=0xce6990, rMed=@0x2aaab3d87410) + at /local/ooxml/ooxml/sc/source/ui/docshell/docsh.cxx:2080 + #8 0x00002b354dfd8b58 in SfxObjectShell::DoLoad () + from /local/ooxml/inst/openoffice.org3.0/program/../basis-link/program//libsfxlx.so + + - Current approach is to add a XclExpRecordBase::SaveXml() method, which + would be used to write the XML content (while Save() would continue + writing the BIFF format). + - Q: How do we get to the Save()/SaveXml() methods (e.g. the SST export code) + #0 XclExpSstImpl::Save (this=0x1b170b0, rStrm=@0x7fffd4d5c4a0) + at /home/jon/Development/OpenOffice.org/ooxml/sc/source/filter/excel/xecontent.cxx:224 + #1 0x00007f68b7e46ff7 in XclExpSst::Save (this=0x1abc300, + rStrm=@0x7fffd4d5c4a0) + at /home/jon/Development/OpenOffice.org/ooxml/sc/source/filter/excel/xecontent.cxx:351 + #2 0x00007f68b7de5090 in XclExpRecordList::Save ( + this=0x1b2d168, rStrm=@0x7fffd4d5c4a0) at ../inc/xerecord.hxx:282 + // as above, starting at frame 2 + + - Thus, to get to the SaveXml() method, we need to add a slew of WriteXml() + methods that will (eventually) invoke the SaveXml() methods. + + - ZipStorage for XML handling and StorageRef (XStorage interface) + - To construct ZipStorage, need XMultiServiceFactory (!), and + XInputStream. + - Have an SvStream; need to wrap SvStream with XInputStream + - OInputStreamWrapper in + - Where do I get XMultiServiceFactory? + - Lots of places -- just grep + - perhaps XmlFilterBase _does_ make sense here. + - Do it anyway. + - Looking into having XclExpXmlStream inherit from ZipFilterBase + - problem: exception during construction, because ZipStorage hates me: + #0 OStorageFactory::createInstanceWithArguments (this=0x10612a0, + aArguments=@0x7fffe2ef76d0) + at /home/jon/Development/OpenOffice.org/ooxml/package/source/xstor/xfactory.cxx:275 + #1 0x00007f12d93f0d5c in comphelper::OStorageHelper::GetStorageOfFormatFromStream (aFormat=@0x7fffe2ef7780, xStream=@0x1a502d8, nStorageMode=15, + xFactory=@0x1a502c0) + at /home/jon/Development/OpenOffice.org/ooxml/comphelper/source/misc/storagehelper.cxx:342 + #2 0x00007f12c33d1a6d in ZipStorage (this=0x1a92550, rxFactory=@0x1a502c0, + rxStream=@0x1a502d8) + at /home/jon/Development/OpenOffice.org/ooxml/oox/source/helper/zipstorage.cxx:87 + #3 0x00007f12c33f089e in oox::core::XmlFilterBase::implCreateStorage ( + this=0x7fffe2ef7930, rxInStream=@0x1a502d0, rxStream=@0x1a502d8) + at /home/jon/Development/OpenOffice.org/ooxml/oox/source/core/xmlfilterbase.cxx:298 + #4 0x00007f12c33dd204 in oox::core::FilterBase::filter (this=0x7fffe2ef7930, + rDescriptor=@0x7fffe2ef78d0) + at /home/jon/Development/OpenOffice.org/ooxml/oox/source/core/filterbase.cxx:284 + #5 0x00007f12c68097a2 in XclExpXmlStream (this=0x7fffe2ef7930, + rSMgr=@0x7fffe2ef79a0, rStrm=@0x18d6f90) + at /home/jon/Development/OpenOffice.org/ooxml/sc/source/filter/excel/xestream.cxx:659 + #6 0x00007f12c674c8c1 in ExcDocument::WriteXml (this=0x15911f0, + rStrm=@0x18d6f90) + at /home/jon/Development/OpenOffice.org/ooxml/sc/source/filter/excel/excdoc.cxx:575 + ... + - Actual problem: xfactory.cxx:274, the CheckPackageSignature_Impl() call. + - fails because the empty file has content (!), thus fails the "package + signature check" (which tries to ensure the file format is correct). + - Underlying file is an SvFileStream, created in + SfxMedium::GetOutStream(). + - So why's CheckPackageSignature_Impl() fail? Because + lcl_ExportExcel2007Xml() had the code: + + SotStorageRef xRootStrg = new SotStorage( pMedStrm, FALSE ); + + That is, it was creating an OLE Structured Storage document over the + SvStream, and then (later) used the *same* SvStream and passed it to + ZipStorage. This caused ZipStorage to complain because OLESS data was + already present in the file, with a different file signature than what + ZipPackage was expecting (go figure). + +- ppt export + - sd/source/filter/eppt/* + - svx/source/msfilter + - for eg. Escher export + - Escher: http://chicago.sourceforge.net/devel/docs/escher/index.html + + - eg. + #0 PPTWriter (this=0x15807d0, rSvStorage=@0x7fff894f5340, rXModel=@0x142a2e8, rXStatInd=@0x142a2f0, pVBA=0x0, + nCnvrtFlags=15) at /local/ooxml/ooxml/sd/source/filter/eppt/eppt.cxx:268 + #1 0x00002aaab3895719 in ExportPPT (rSvStorage=@0x7fff894f5340, rXModel=@0x142a2e8, rXStatInd=@0x142a2f0, + pVBA=0x0, nCnvrtFlags=15) at /local/ooxml/ooxml/sd/source/filter/eppt/eppt.cxx:2503 + #2 0x00002aaaadef85b7 in SdPage::onParagraphRemoving () + from /local/ooxml/inst/openoffice.org3.0/program/../basis-link/program/libsdlx.so + #3 0x00002aaaade202e3 in sd::DrawDocShell::ConvertTo () + from /local/ooxml/inst/openoffice.org3.0/program/../basis-link/program/libsdlx.so + #4 0x00002aec23119b58 in SfxObjectShell::DoLoad () + from /local/ooxml/inst/openoffice.org3.0/program/../basis-link/program//libsfxlx.so + +- odp export + #0 ZipPackage (this=0x1805e80, xNewFactory=@0x7fffe284e990) at /home/rodo/git/ooxml/package/source/zippackage/ZipPackage.cxx:279 + #1 0x00002aaaadd3dc94 in ZipPackage_createInstance (xMgr=@0x7fffe284e990) at /home/rodo/git/ooxml/package/source/zippackage/ZipPackage.cxx:1546 + #2 0x00002b0fca7ab6b3 in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3 + #3 0x00002b0fca7a7fda in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3 + #4 0x00002b0fca7a811e in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3 + #5 0x00002b0fca7aa7cc in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3 + #6 0x00002b0fca7aacbe in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3 + #7 0x00002b0fca7aa035 in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3 + #8 0x00002aaaaadae1b3 in ?? () from /opt/openoffice.org/ure/lib/bootstrap.uno.so + #9 0x00002aaaaadaa84c in ?? () from /opt/openoffice.org/ure/lib/bootstrap.uno.so + #10 0x00002aaab5c7a7e5 in OStorage_Impl::OpenOwnPackage (this=0x185cac0) at /home/rodo/git/ooxml/package/source/xstor/xstorage.cxx:549 + #11 0x00002aaab5c7ab3e in OStorage_Impl::ReadContents (this=0x185cac0) at /home/rodo/git/ooxml/package/source/xstor/xstorage.cxx:649 + #12 0x00002aaab5c7d32f in OStorage_Impl::FindElement (this=0x185cac0, rName=@0x7fffe284f280) at /home/rodo/git/ooxml/package/source/xstor/xstorage.cxx:1387 + #13 0x00002aaab5c7dc45 in OStorage::hasByName (this=0x1808880, aName=@0x7fffe284f280) at /home/rodo/git/ooxml/package/source/xstor/xstorage.cxx:4045 + #14 0x00002aaab1fde8c5 in XMLVersionListPersistence::load () from /opt/openoffice.org3.0/program/../basis-link/program/libxolx.so + #15 0x00002b0fcb058bb2 in SfxMedium::GetVersionList (this=0x1750050, _bNoReload=false) at /home/rodo/git/ooxml/sfx2/source/doc/docfile.cxx:3247 + #16 0x00002b0fcb0571b5 in SfxMedium::GetStorage (this=0x1750050) at /home/rodo/git/ooxml/sfx2/source/doc/docfile.cxx:1328 + #17 0x00002b0fcb05d0d7 in SfxMedium::GetOutputStorage (this=0x1750050) at /home/rodo/git/ooxml/sfx2/source/doc/docfile.cxx:1068 + #18 0x00002b0fcb091227 in SfxObjectShell::SaveTo_Impl (this=0xf44d60, rMedium=@0x1750050, pSet=0x0) at /home/rodo/git/ooxml/sfx2/source/doc/objstor.cxx:1557 + #19 0x00002b0fcb09443c in SfxObjectShell::PreDoSaveAs_Impl (this=0xf44d60, rFileName=@0x7fffe2850700, aFilterName=@0x7fffe28507f0, pParams=0xf10c10) + at /home/rodo/git/ooxml/sfx2/source/doc/objstor.cxx:2984 + #20 0x00002b0fcb094ea5 in SfxObjectShell::CommonSaveAs_Impl (this=0xf44d60, aURL=@0x7fffe2850870, aFilterName=@0x7fffe28507f0, aParams=0x1740310) + at /home/rodo/git/ooxml/sfx2/source/doc/objstor.cxx:2855 + #21 0x00002b0fcb0a1da2 in SfxObjectShell::APISaveAs_Impl (this=0xf44d60, aFileName=@0x7fffe2850b70, aParams=0x1740310) + at /home/rodo/git/ooxml/sfx2/source/doc/objserv.cxx:432 + #22 0x00002b0fcb0e74c8 in SfxBaseModel::impl_store (this=0xf96a00, sURL=@0x7fffe28516b0, seqArguments=@0x7fffe2851ae0, bSaveTo=0 '\0') + at /home/rodo/git/ooxml/sfx2/source/doc/sfxbasemodel.cxx:2591 + #23 0x00002b0fcb0f124b in SfxBaseModel::storeAsURL (this=0xf96a00, rURL=@0x7fffe28516b0, rArgs=@0x7fffe2851ae0) + at /home/rodo/git/ooxml/sfx2/source/doc/sfxbasemodel.cxx:1568 + #24 0x00002b0fcb101d3d in SfxStoringHelper::GUIStoreModel (this=0x7fffe28519f0, xModel=@0xf18798, aSlotName=@0x7fffe2852200, aArgsSequence=@0x7fffe2851ae0, + bPreselectPassword=0 '\0') at /home/rodo/git/ooxml/sfx2/source/doc/guisaveas.cxx:1529 + #25 0x00002b0fcb0a4051 in SfxObjectShell::ExecFile_Impl (this=0xf44d60, rReq=@0x1484f20) at /home/rodo/git/ooxml/sfx2/source/doc/objserv.cxx:744 + #26 0x00002b0fcb0a5c73 in SfxStubSfxObjectShellExecFile_Impl (pShell=0xf44d60, rReq=@0x1484f20) at ../../unxlngx6.pro/inc/sfxslots.hxx:161 + #27 0x00002b0fcb17f398 in SfxShell::CallExec (this=0xf44d60, pFunc=0x2b0fcb0a5c56 , rReq=@0x1484f20) + at ../../inc/sfx2/shell.hxx:226 + #28 0x00002b0fcb17cec3 in SfxDispatcher::Call_Impl (this=0x110fde0, rShell=@0xf44d60, rSlot=@0x2b0fcb576368, rReq=@0x1484f20, bRecord=1 '\001') + at /home/rodo/git/ooxml/sfx2/source/control/dispatch.cxx:338 + #29 0x00002b0fcb17d3f2 in SfxDispatcher::PostMsgHandler (this=0x110fde0, pReq=0x1484f20) at /home/rodo/git/ooxml/sfx2/source/control/dispatch.cxx:1643 + #30 0x00002b0fcb17d51d in SfxDispatcher::LinkStubPostMsgHandler (pThis=0x110fde0, pCaller=0x1484f20) at /home/rodo/git/ooxml/sfx2/source/control/dispatch.cxx:1610 + #31 0x00002b0fcafb3e70 in Link::Call (this=0x11488f8, pCaller=0x1484f20) at /home/rodo/git/ooxml/solver/300/unxlngx6.pro/inc/tools/link.hxx:158 + #32 0x00002b0fcb1a9952 in GenLink::Call (this=0x11488f8, pCaller=0x1484f20) at ../../inc/sfx2/genlink.hxx:63 + #33 0x00002b0fcb1a9773 in SfxHintPoster::Event (this=0x11488e0, pPostedHint=0x1484f20) at /home/rodo/git/ooxml/sfx2/source/notify/hintpost.cxx:98 + #34 0x00002b0fcb1a9984 in SfxHintPoster::DoEvent_Impl (this=0x11488e0, pPostedHint=0x1484f20) at /home/rodo/git/ooxml/sfx2/source/notify/hintpost.cxx:88 + #35 0x00002b0fcb1a974f in SfxHintPoster::LinkStubDoEvent_Impl (pThis=0x11488e0, pCaller=0x1484f20) at /home/rodo/git/ooxml/sfx2/source/notify/hintpost.cxx:92 + #36 0x00002b0fccef69f8 in ImplWindowFrameProc () from /opt/openoffice.org3.0/program/../basis-link/program/libvcllx.so + #37 0x00002b0fd3f91f8f in SalDisplay::DispatchInternalEvent () from /opt/openoffice.org/basis3.0/program/libvclplug_genlx.so + #38 0x00002b0fd0fa4a84 in GtkXLib::userEventFn () from /opt/openoffice.org/basis3.0/program/libvclplug_gtklx.so + #39 0x00002b0fd3cb0204 in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0 + #40 0x00002b0fd3cb34fd in ?? () from /usr/lib64/libglib-2.0.so.0 + #41 0x00002b0fd3cb39ce in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0 + #42 0x00002b0fd0fa4fd9 in GtkXLib::Yield () from /opt/openoffice.org/basis3.0/program/libvclplug_gtklx.so + #43 0x00002b0fccd1859e in Application::Yield () from /opt/openoffice.org3.0/program/../basis-link/program/libvcllx.so + #44 0x00002b0fccd18677 in Application::Execute () from /opt/openoffice.org3.0/program/../basis-link/program/libvcllx.so + #45 0x00002b0fc86fd803 in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/libsoffice.so + #46 0x00002b0fccd1da24 in ImplSVMain () from /opt/openoffice.org3.0/program/../basis-link/program/libvcllx.so + #47 0x00002b0fccd1db15 in SVMain () from /opt/openoffice.org3.0/program/../basis-link/program/libvcllx.so + #48 0x00002b0fc872fe6c in soffice_main () from /opt/openoffice.org3.0/program/../basis-link/program/libsoffice.so + #49 0x000000000040114b in main () diff --git a/oox/source/helper/makefile.mk b/oox/source/helper/makefile.mk deleted file mode 100644 index f31736faac8d..000000000000 --- a/oox/source/helper/makefile.mk +++ /dev/null @@ -1,60 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=oox -TARGET=helper -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/attributelist.obj \ - $(SLO)$/binaryinputstream.obj \ - $(SLO)$/binaryoutputstream.obj \ - $(SLO)$/binarystreambase.obj \ - $(SLO)$/containerhelper.obj \ - $(SLO)$/graphichelper.obj \ - $(SLO)$/modelobjecthelper.obj \ - $(SLO)$/progressbar.obj \ - $(SLO)$/propertymap.obj \ - $(SLO)$/propertyset.obj \ - $(SLO)$/storagebase.obj \ - $(SLO)$/textinputstream.obj \ - $(SLO)$/zipstorage.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/source/ole/makefile.mk b/oox/source/ole/makefile.mk deleted file mode 100644 index a5232247cfa5..000000000000 --- a/oox/source/ole/makefile.mk +++ /dev/null @@ -1,60 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=oox -TARGET=ole -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/axbinaryreader.obj \ - $(SLO)$/axcontrol.obj \ - $(SLO)$/axcontrolfragment.obj \ - $(SLO)$/olehelper.obj \ - $(SLO)$/oleobjecthelper.obj \ - $(SLO)$/olestorage.obj \ - $(SLO)$/vbacontrol.obj \ - $(SLO)$/vbahelper.obj \ - $(SLO)$/vbainputstream.obj \ - $(SLO)$/vbamodule.obj \ - $(SLO)$/vbaproject.obj \ - $(SLO)$/vbaprojectfilter.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk - diff --git a/oox/source/ppt/makefile.mk b/oox/source/ppt/makefile.mk deleted file mode 100644 index 8d902ed51337..000000000000 --- a/oox/source/ppt/makefile.mk +++ /dev/null @@ -1,76 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=oox -TARGET=ppt -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/animationspersist.obj \ - $(SLO)$/animationtypes.obj \ - $(SLO)$/animvariantcontext.obj \ - $(SLO)$/backgroundproperties.obj\ - $(SLO)$/buildlistcontext.obj \ - $(SLO)$/commonbehaviorcontext.obj \ - $(SLO)$/commontimenodecontext.obj \ - $(SLO)$/conditioncontext.obj \ - $(SLO)$/customshowlistcontext.obj \ - $(SLO)$/headerfootercontext.obj \ - $(SLO)$/layoutfragmenthandler.obj\ - $(SLO)$/pptfilterhelpers.obj\ - $(SLO)$/pptimport.obj\ - $(SLO)$/pptshape.obj \ - $(SLO)$/pptshapecontext.obj \ - $(SLO)$/pptshapegroupcontext.obj \ - $(SLO)$/pptshapepropertiescontext.obj \ - $(SLO)$/presentationfragmenthandler.obj\ - $(SLO)$/slidefragmenthandler.obj\ - $(SLO)$/slidemastertextstylescontext.obj \ - $(SLO)$/slidepersist.obj\ - $(SLO)$/slidetimingcontext.obj\ - $(SLO)$/slidetransition.obj\ - $(SLO)$/slidetransitioncontext.obj\ - $(SLO)$/soundactioncontext.obj \ - $(SLO)$/timeanimvaluecontext.obj \ - $(SLO)$/timenode.obj\ - $(SLO)$/timenodelistcontext.obj \ - $(SLO)$/timetargetelementcontext.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/source/shape/makefile.mk b/oox/source/shape/makefile.mk deleted file mode 100644 index c6534b3a8a6f..000000000000 --- a/oox/source/shape/makefile.mk +++ /dev/null @@ -1,49 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=oox -TARGET=shape -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/ShapeContextHandler.obj \ - $(SLO)$/ShapeFilterBase.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/source/token/makefile.mk b/oox/source/token/makefile.mk deleted file mode 100644 index ff42967f0bb1..000000000000 --- a/oox/source/token/makefile.mk +++ /dev/null @@ -1,78 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=oox -TARGET=token - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/namespacemap.obj \ - $(SLO)$/propertynames.obj \ - $(SLO)$/tokenmap.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk - -GENHEADERPATH = $(INCCOM)$/oox$/token - -$(MISC)$/tokenhash.gperf $(INCCOM)$/tokennames.inc $(GENHEADERPATH)$/tokens.hxx $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt $(GENHEADERPATH)$/namespaces.hxx $(INCCOM)$/propertynames.inc $(GENHEADERPATH)$/properties.hxx : - @@noop $(assign do_phony:=.PHONY) - -$(SLO)$/tokenmap.obj : $(INCCOM)$/tokenhash.inc $(INCCOM)$/tokennames.inc $(GENHEADERPATH)$/tokens.hxx $(MISC)$/do_tokens - -$(INCCOM)$/tokenhash.inc : $(MISC)$/tokenhash.gperf $(MISC)$/do_tokens - $(AUGMENT_LIBRARY_PATH) gperf --compare-strncmp $(MISC)$/tokenhash.gperf | $(SED) -e "s/(char\*)0/(char\*)0, 0/g" | $(GREP) -v "^#line" >$(INCCOM)$/tokenhash.inc - -$(MISC)$/do_tokens $(do_phony) : tokens.txt tokens.pl tokens.hxx.head tokens.hxx.tail $(GENHEADERPATH)$/tokens.hxx $(INCCOM)$/tokennames.inc $(MISC)$/tokenhash.gperf - @@-$(RM) $@ - $(MKDIRHIER) $(GENHEADERPATH) - $(PERL) tokens.pl tokens.txt $(MISC)$/tokenids.inc $(INCCOM)$/tokennames.inc $(MISC)$/tokenhash.gperf && $(TYPE) tokens.hxx.head $(MISC)$/tokenids.inc tokens.hxx.tail > $(GENHEADERPATH)$/tokens.hxx && $(TOUCH) $@ - -$(SLO)$/namespacemap.obj : $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt $(GENHEADERPATH)$/namespaces.hxx $(MISC)$/do_namespaces - -$(MISC)$/do_namespaces $(do_phony) : namespaces.txt namespaces.pl namespaces.hxx.head namespaces.hxx.tail $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt $(GENHEADERPATH)$/namespaces.hxx - @@-$(RM) $@ - $(MKDIRHIER) $(GENHEADERPATH) - $(PERL) namespaces.pl namespaces.txt $(MISC)$/namespaceids.inc $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt && $(TYPE) namespaces.hxx.head $(MISC)$/namespaceids.inc namespaces.hxx.tail > $(GENHEADERPATH)$/namespaces.hxx && $(TOUCH) $@ - -$(SLO)$/propertynames.obj : $(INCCOM)$/propertynames.inc $(GENHEADERPATH)$/properties.hxx $(MISC)$/do_properties - -$(MISC)$/do_properties $(do_phony) : properties.txt properties.pl properties.hxx.head properties.hxx.tail $(INCCOM)$/propertynames.inc $(GENHEADERPATH)$/properties.hxx - @@-$(RM) $@ - $(MKDIRHIER) $(GENHEADERPATH) - $(PERL) properties.pl properties.txt $(MISC)$/propertyids.inc $(INCCOM)$/propertynames.inc && $(TYPE) properties.hxx.head $(MISC)$/propertyids.inc properties.hxx.tail > $(GENHEADERPATH)$/properties.hxx && $(TOUCH) $@ diff --git a/oox/source/token/namespacemap.cxx b/oox/source/token/namespacemap.cxx index 0f4373d2dc59..d021f2a3a353 100755 --- a/oox/source/token/namespacemap.cxx +++ b/oox/source/token/namespacemap.cxx @@ -36,7 +36,7 @@ NamespaceMap::NamespaceMap() static const struct NamespaceUrl { sal_Int32 mnId; const sal_Char* mpcUrl; } spNamespaceUrls[] = { // include auto-generated C array with namespace URLs as C strings -#include "namespacenames.inc" +#include { -1, "" } }; diff --git a/oox/source/token/namespaces.pl b/oox/source/token/namespaces.pl index 3c741fa7b2af..7c602f70128d 100644 --- a/oox/source/token/namespaces.pl +++ b/oox/source/token/namespaces.pl @@ -25,17 +25,19 @@ # #************************************************************************* -$ARGV0 = shift @ARGV; -$ARGV1 = shift @ARGV; -$ARGV2 = shift @ARGV; -$ARGV3 = shift @ARGV; +# operation mode (1 = identifiers, 2 = names, 3 = plain) +$op = shift @ARGV; +die "Error: invalid operation" unless( $op >= 1 && $op <= 3); -# parse input file +# number of bits to shift the namespace identifier +$shift = 16; + +if( $op == 1 ) { + print( "const size_t NMSP_SHIFT = $shift;\n" ); +} -open( INFILE, $ARGV0 ) or die "cannot open input file: $!"; -my %namespaces; -while( ) -{ +$i = 1; +while( <> ) { # trim newline chomp( $_ ); # trim leading/trailing whitespace @@ -44,36 +46,14 @@ while( ) # trim comments $_ =~ s/^#.*//; # skip empty lines - if( $_ ) - { + if( $_ ) { # check for valid characters - $_ =~ /^([a-zA-Z]+)\s+([a-zA-Z0-9-.:\/]+)\s*$/ or die "Error: invalid character in input data"; - $namespaces{$1} = $2; + $_ =~ /^([a-zA-Z]+)\s+([a-zA-Z0-9-.:\/]+)\s*$/ or die "Error: invalid entry: '$_'"; + # generate output + $id = $i << $shift; + if( $op == 1 ) { print( "const sal_Int32 NMSP_$1 = $i << NMSP_SHIFT;\n" ); } + elsif( $op == 2 ) { print( "{ $id, \"$2\" },\n" ); } + elsif( $op == 3 ) { print( "$id $1 $2\n" ); } + ++$i; } } -close( INFILE ); - -# generate output files - -open( IDFILE, ">$ARGV1" ) or die "Error: cannot open output file: $!"; -open( NAMEFILE, ">$ARGV2" ) or die "Error: cannot open output file: $!"; -open( TXTFILE, ">$ARGV3" ) or die "Error: cannot open output file: $!"; - -# number of bits to shift the namespace identifier -$shift = 16; - -print ( IDFILE "const size_t NMSP_SHIFT = $shift;\n" ); - -$i = 1; -foreach( keys( %namespaces ) ) -{ - print( IDFILE "const sal_Int32 NMSP_$_ = $i << NMSP_SHIFT;\n" ); - $id = $i << $shift; - print( NAMEFILE "{ $id, \"$namespaces{$_}\" },\n" ); - print( TXTFILE "$id $_ $namespaces{$_}\n" ); - ++$i; -} - -close( IDFILE ); -close( nameFILE ); -close( TXTFILE ); diff --git a/oox/source/token/properties.pl b/oox/source/token/properties.pl index f341924bbb90..448cec632343 100644 --- a/oox/source/token/properties.pl +++ b/oox/source/token/properties.pl @@ -25,43 +25,33 @@ # #************************************************************************* -$ARGV0 = shift @ARGV; -$ARGV1 = shift @ARGV; -$ARGV2 = shift @ARGV; +# operation mode (1 = identifiers, 2 = names) +$op = shift @ARGV; +die "Error: invalid operation" unless( $op >= 1 && $op <= 2); -# parse input file - -open( INFILE, $ARGV0 ) or die "Error: cannot open input file: $!"; -my %props; -while( ) -{ +$i = 0; +while( <> ) { # trim newline chomp( $_ ); # trim leading/trailing whitespace $_ =~ s/^\s*//g; $_ =~ s/\s*$//g; - # check for valid characters - $_ =~ /^[A-Z][a-zA-Z0-9]*$/ or die "Error: invalid character in property '$_'"; - $id = "PROP_$_"; - $props{$_} = $id; + # skip empty lines + if( $_ ) { + # check for valid characters + $_ =~ /^[A-Z][a-zA-Z0-9]+$/ or die "Error: invalid entry: '$_'"; + # generate output + if( $op == 1 ) { + print( "const sal_Int32 PROP_$_ = $i;\n" ); + } elsif( $op == 2 ) { + print( "/* $i */ \"$_\",\n" ); + } + ++$i; + } } -close( INFILE ); - -# generate output files - -open( IDFILE, ">$ARGV1" ) or die "Error: cannot open output file: $!"; -open( NAMEFILE, ">$ARGV2" ) or die "Error: cannot open output file: $!"; -$i = 0; -foreach( sort( keys( %props ) ) ) -{ - print( IDFILE "const sal_Int32 $props{$_} = $i;\n" ); - print( NAMEFILE "/* $i */ \"$_\",\n" ); - ++$i; +if( $op == 1 ) { + print( "const sal_Int32 PROP_COUNT = $i;\nconst sal_Int32 PROP_INVALID = -1;\n" ); +} elsif( $op == 2 ) { + print( " \"\"" ); } - -print( IDFILE "const sal_Int32 PROP_COUNT = $i;\n" ); -print( IDFILE "const sal_Int32 PROP_INVALID = -1;\n" ); - -close( IDFILE ); -close( NAMEFILE ); diff --git a/oox/source/token/propertynames.cxx b/oox/source/token/propertynames.cxx index 401d168fe696..b8f06496c7ff 100644 --- a/oox/source/token/propertynames.cxx +++ b/oox/source/token/propertynames.cxx @@ -36,8 +36,7 @@ PropertyNameVector::PropertyNameVector() static const sal_Char* sppcPropertyNames[] = { // include auto-generated C array with property names as C strings -#include "propertynames.inc" - "" +#include }; size_t nArraySize = (sizeof( sppcPropertyNames ) / sizeof( *sppcPropertyNames )) - 1; diff --git a/oox/source/token/tokenmap.cxx b/oox/source/token/tokenmap.cxx index a5189269c3c8..8f097b10c7fb 100644 --- a/oox/source/token/tokenmap.cxx +++ b/oox/source/token/tokenmap.cxx @@ -44,7 +44,7 @@ using ::rtl::OUString; namespace { // include auto-generated Perfect_Hash -#include "tokenhash.inc" +#include } // namespace // ============================================================================ @@ -55,7 +55,7 @@ TokenMap::TokenMap() : static const sal_Char* sppcTokenNames[] = { // include auto-generated C array with token names as C strings -#include "tokennames.inc" +#include "" }; diff --git a/oox/source/token/tokens.pl b/oox/source/token/tokens.pl index a951cee80db2..4307a7d9047a 100644 --- a/oox/source/token/tokens.pl +++ b/oox/source/token/tokens.pl @@ -25,56 +25,50 @@ # #************************************************************************* -$ARGV0 = shift @ARGV; -$ARGV1 = shift @ARGV; -$ARGV2 = shift @ARGV; -$ARGV3 = shift @ARGV; +# operation mode (1 = identifiers, 2 = names, 3 = gperf) +$op = shift @ARGV; +die "Error: invalid operation" unless( $op >= 1 && $op <= 3); -open( INFILE, $ARGV0 ) or die "Error: cannot open input file: $!"; -my %tokens; -while ( ) +if( $op == 3 ) { + print( "%language=C++\n" ); + print( "%global-table\n" ); + print( "%null-strings\n" ); + print( "%struct-type\n" ); + print( "struct xmltoken {\n" ); + print( " const sal_Char *name;\n" ); + print( " sal_Int32 nToken;\n" ); + print( "};\n" ); + print( "%%\n" ); +} + +$i = 0; +while( <> ) { # trim newline chomp( $_ ); # trim leading/trailing whitespace $_ =~ s/^\s*//g; $_ =~ s/\s*$//g; - # check for valid characters - $_ =~ /^[a-zA-Z0-9-_]+$/ or die "Error: invalid character in token '$_'"; - $id = "XML_$_"; - $id =~ s/-/_/g; - $tokens{$_} = $id; + # skip empty lines + if( $_ ) { + # check for valid characters + $_ =~ /^[a-zA-Z0-9-_]+$/ or die "Error: invalid entry: '$_'"; + # generate output + $id = "XML_$_"; + $id =~ s/-/_/g; + if( $op == 1 ) { + print( "const sal_Int32 $id = $i;\n" ); + } elsif( $op == 2 ) { + print( "\"$_\",\n" ); + } elsif( $op == 3 ) { + print( "$_,$id\n" ); + } + ++$i; + } } -close ( INFILE ); - -# generate output files - -open ( IDFILE, ">$ARGV1" ) or die "Error: cannot open output file: $!"; -open ( NAMEFILE, ">$ARGV2" ) or die "Error: cannot open output file: $!"; -open ( GPERFFILE, ">$ARGV3" ) or die "Error: cannot open output file: $!"; -print( GPERFFILE "%language=C++\n" ); -print( GPERFFILE "%global-table\n" ); -print( GPERFFILE "%null-strings\n" ); -print( GPERFFILE "%struct-type\n" ); -print( GPERFFILE "struct xmltoken {\n" ); -print( GPERFFILE " const sal_Char *name;\n" ); -print( GPERFFILE " sal_Int32 nToken;\n" ); -print( GPERFFILE "};\n" ); -print( GPERFFILE "%%\n" ); - -$i = 0; -foreach( sort( keys( %tokens ) ) ) -{ - print( IDFILE "const sal_Int32 $tokens{$_} = $i;\n" ); - print( NAMEFILE "\"$_\",\n" ); - print( GPERFFILE "$_,$tokens{$_}\n" ); - ++$i; +if( $op == 1 ) { + print( "const sal_Int32 XML_TOKEN_COUNT = $i;\n" ); +} elsif( $op == 3 ) { + print( "%%\n" ); } - -print( IDFILE "const sal_Int32 XML_TOKEN_COUNT = $i;\n" ); -print( GPERFFILE "%%\n" ); - -close( IDFILE ); -close( NAMEFILE ); -close( GPERFFILE ); diff --git a/oox/source/vml/makefile.mk b/oox/source/vml/makefile.mk deleted file mode 100644 index 094d37cd8c1c..000000000000 --- a/oox/source/vml/makefile.mk +++ /dev/null @@ -1,56 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=oox -TARGET=vml -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/vmldrawing.obj \ - $(SLO)$/vmldrawingfragment.obj \ - $(SLO)$/vmlformatting.obj \ - $(SLO)$/vmlinputstream.obj \ - $(SLO)$/vmlshape.obj \ - $(SLO)$/vmlshapecontainer.obj \ - $(SLO)$/vmlshapecontext.obj \ - $(SLO)$/vmltextbox.obj \ - $(SLO)$/vmltextboxcontext.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/oox/source/xls/makefile.mk b/oox/source/xls/makefile.mk deleted file mode 100644 index e337afe786a8..000000000000 --- a/oox/source/xls/makefile.mk +++ /dev/null @@ -1,105 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=oox -TARGET=xls -AUTOSEG=true - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/addressconverter.obj \ - $(SLO)$/autofilterbuffer.obj \ - $(SLO)$/autofiltercontext.obj \ - $(SLO)$/biffcodec.obj \ - $(SLO)$/biffdetector.obj \ - $(SLO)$/biffhelper.obj \ - $(SLO)$/biffinputstream.obj \ - $(SLO)$/biffoutputstream.obj \ - $(SLO)$/chartsheetfragment.obj \ - $(SLO)$/commentsbuffer.obj \ - $(SLO)$/commentsfragment.obj \ - $(SLO)$/condformatbuffer.obj \ - $(SLO)$/condformatcontext.obj \ - $(SLO)$/connectionsbuffer.obj \ - $(SLO)$/connectionsfragment.obj \ - $(SLO)$/defnamesbuffer.obj \ - $(SLO)$/drawingbase.obj \ - $(SLO)$/drawingfragment.obj \ - $(SLO)$/drawingmanager.obj \ - $(SLO)$/excelchartconverter.obj \ - $(SLO)$/excelfilter.obj \ - $(SLO)$/excelhandlers.obj \ - $(SLO)$/excelvbaproject.obj \ - $(SLO)$/externallinkbuffer.obj \ - $(SLO)$/externallinkfragment.obj \ - $(SLO)$/formulabase.obj \ - $(SLO)$/formulaparser.obj \ - $(SLO)$/numberformatsbuffer.obj \ - $(SLO)$/ooxformulaparser.obj \ - $(SLO)$/pagesettings.obj \ - $(SLO)$/pivotcachebuffer.obj \ - $(SLO)$/pivotcachefragment.obj \ - $(SLO)$/pivottablebuffer.obj \ - $(SLO)$/pivottablefragment.obj \ - $(SLO)$/querytablebuffer.obj \ - $(SLO)$/querytablefragment.obj \ - $(SLO)$/richstring.obj \ - $(SLO)$/richstringcontext.obj \ - $(SLO)$/scenariobuffer.obj \ - $(SLO)$/scenariocontext.obj \ - $(SLO)$/sharedformulabuffer.obj \ - $(SLO)$/sharedstringsbuffer.obj \ - $(SLO)$/sharedstringsfragment.obj \ - $(SLO)$/sheetdatacontext.obj \ - $(SLO)$/stylesbuffer.obj \ - $(SLO)$/stylesfragment.obj \ - $(SLO)$/tablebuffer.obj \ - $(SLO)$/tablefragment.obj \ - $(SLO)$/themebuffer.obj \ - $(SLO)$/unitconverter.obj \ - $(SLO)$/viewsettings.obj \ - $(SLO)$/workbookfragment.obj \ - $(SLO)$/workbookhelper.obj \ - $(SLO)$/workbooksettings.obj \ - $(SLO)$/worksheetbuffer.obj \ - $(SLO)$/worksheetfragment.obj \ - $(SLO)$/worksheethelper.obj \ - $(SLO)$/worksheetsettings.obj - -# --- Targets ------------------------------------------------------- - -.INCLUDE : target.mk -- cgit From ae88ed70d0742110277b5f64ce616fa4e5256926 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Wed, 19 Jan 2011 10:56:53 +0100 Subject: dr78: minor changes in gperf usage --- oox/source/token/tokenmap.cxx | 18 ++++++++++-------- oox/source/token/tokens.pl | 13 +++++++++---- 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'oox/source') diff --git a/oox/source/token/tokenmap.cxx b/oox/source/token/tokenmap.cxx index 8f097b10c7fb..0be0a1c4c470 100644 --- a/oox/source/token/tokenmap.cxx +++ b/oox/source/token/tokenmap.cxx @@ -43,8 +43,10 @@ using ::rtl::OUString; // ============================================================================ namespace { -// include auto-generated Perfect_Hash + +// include auto-generated Perfect_Hash class #include + } // namespace // ============================================================================ @@ -68,14 +70,14 @@ TokenMap::TokenMap() : } #if OSL_DEBUG_LEVEL > 0 - // check that the perfect_hash is in sync with the token name list + // check that the Perfect_Hash is in sync with the token name list bool bOk = true; for( sal_Int32 nToken = 0; bOk && (nToken < XML_TOKEN_COUNT); ++nToken ) { // check that the getIdentifier <-> getToken roundtrip works OString aUtf8Name = OUStringToOString( maTokenNames[ nToken ].maUniName, RTL_TEXTENCODING_UTF8 ); - struct xmltoken* pToken = Perfect_Hash::in_word_set( aUtf8Name.getStr(), aUtf8Name.getLength() ); - bOk = pToken && (pToken->nToken == nToken); + const XMLTokenInfo* pTokenInfo = Perfect_Hash::getTokenInfo( aUtf8Name.getStr(), aUtf8Name.getLength() ); + bOk = pTokenInfo && (pTokenInfo->mnToken == nToken); OSL_ENSURE( bOk, ::rtl::OStringBuffer( "TokenMap::TokenMap - token list broken, #" ). append( nToken ).append( ", '" ).append( aUtf8Name ).append( '\'' ).getStr() ); } @@ -96,8 +98,8 @@ OUString TokenMap::getUnicodeTokenName( sal_Int32 nToken ) const sal_Int32 TokenMap::getTokenFromUnicode( const OUString& rUnicodeName ) const { OString aUtf8Name = OUStringToOString( rUnicodeName, RTL_TEXTENCODING_UTF8 ); - struct xmltoken* pToken = Perfect_Hash::in_word_set( aUtf8Name.getStr(), aUtf8Name.getLength() ); - return pToken ? pToken->nToken : XML_TOKEN_INVALID; + const XMLTokenInfo* pTokenInfo = Perfect_Hash::getTokenInfo( aUtf8Name.getStr(), aUtf8Name.getLength() ); + return pTokenInfo ? pTokenInfo->mnToken : XML_TOKEN_INVALID; } Sequence< sal_Int8 > TokenMap::getUtf8TokenName( sal_Int32 nToken ) const @@ -109,9 +111,9 @@ Sequence< sal_Int8 > TokenMap::getUtf8TokenName( sal_Int32 nToken ) const sal_Int32 TokenMap::getTokenFromUtf8( const Sequence< sal_Int8 >& rUtf8Name ) const { - struct xmltoken* pToken = Perfect_Hash::in_word_set( + const XMLTokenInfo* pTokenInfo = Perfect_Hash::getTokenInfo( reinterpret_cast< const char* >( rUtf8Name.getConstArray() ), rUtf8Name.getLength() ); - return pToken ? pToken->nToken : XML_TOKEN_INVALID; + return pTokenInfo ? pTokenInfo->mnToken : XML_TOKEN_INVALID; } // ============================================================================ diff --git a/oox/source/token/tokens.pl b/oox/source/token/tokens.pl index 4307a7d9047a..ba7f39f2be39 100644 --- a/oox/source/token/tokens.pl +++ b/oox/source/token/tokens.pl @@ -31,12 +31,17 @@ die "Error: invalid operation" unless( $op >= 1 && $op <= 3); if( $op == 3 ) { print( "%language=C++\n" ); - print( "%global-table\n" ); + print( "%define slot-name mpcName\n" ); + print( "%define initializer-suffix ,0\n" ); + print( "%define lookup-function-name getTokenInfo\n" ); + print( "%compare-strncmp\n" ); + print( "%readonly-tables\n" ); + print( "%enum\n" ); print( "%null-strings\n" ); print( "%struct-type\n" ); - print( "struct xmltoken {\n" ); - print( " const sal_Char *name;\n" ); - print( " sal_Int32 nToken;\n" ); + print( "struct XMLTokenInfo {\n" ); + print( " const sal_Char* mpcName;\n" ); + print( " sal_Int32 mnToken;\n" ); print( "};\n" ); print( "%%\n" ); } -- cgit From 09f7fc99c442d71852396d97ee1079f0d03901a0 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Thu, 27 Jan 2011 13:20:10 +0100 Subject: dr78: revert migration of oox to gbuild (will be done in a dedicated CWS) --- oox/source/core/makefile.mk | 66 +++++++++++++++++++ oox/source/docprop/makefile.mk | 49 +++++++++++++++ oox/source/drawingml/chart/makefile.mk | 74 ++++++++++++++++++++++ oox/source/drawingml/diagram/makefile.mk | 53 ++++++++++++++++ oox/source/drawingml/makefile.mk | 92 +++++++++++++++++++++++++++ oox/source/drawingml/table/makefile.mk | 62 ++++++++++++++++++ oox/source/dump/makefile.mk | 53 ++++++++++++++++ oox/source/helper/makefile.mk | 60 ++++++++++++++++++ oox/source/ole/makefile.mk | 60 ++++++++++++++++++ oox/source/ppt/makefile.mk | 76 ++++++++++++++++++++++ oox/source/shape/makefile.mk | 49 +++++++++++++++ oox/source/token/makefile.mk | 78 +++++++++++++++++++++++ oox/source/token/namespacemap.cxx | 2 +- oox/source/token/namespaces.hxx.tail | 36 +++++------ oox/source/token/namespaces.pl | 58 +++++++++++------ oox/source/token/properties.pl | 52 ++++++++------- oox/source/token/propertynames.cxx | 3 +- oox/source/token/tokenmap.cxx | 22 +++---- oox/source/token/tokens.pl | 85 ++++++++++++------------- oox/source/vml/makefile.mk | 56 +++++++++++++++++ oox/source/xls/makefile.mk | 105 +++++++++++++++++++++++++++++++ 21 files changed, 1077 insertions(+), 114 deletions(-) create mode 100755 oox/source/core/makefile.mk create mode 100755 oox/source/docprop/makefile.mk create mode 100755 oox/source/drawingml/chart/makefile.mk create mode 100755 oox/source/drawingml/diagram/makefile.mk create mode 100755 oox/source/drawingml/makefile.mk create mode 100755 oox/source/drawingml/table/makefile.mk create mode 100755 oox/source/dump/makefile.mk create mode 100755 oox/source/helper/makefile.mk create mode 100755 oox/source/ole/makefile.mk create mode 100755 oox/source/ppt/makefile.mk create mode 100755 oox/source/shape/makefile.mk create mode 100755 oox/source/token/makefile.mk create mode 100755 oox/source/vml/makefile.mk create mode 100755 oox/source/xls/makefile.mk (limited to 'oox/source') diff --git a/oox/source/core/makefile.mk b/oox/source/core/makefile.mk new file mode 100755 index 000000000000..2b58b95777df --- /dev/null +++ b/oox/source/core/makefile.mk @@ -0,0 +1,66 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=core +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +.IF "$(SYSTEM_OPENSSL)" == "YES" +CFLAGS+= $(OPENSSL_CFLAGS) +.ENDIF + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/binarycodec.obj \ + $(SLO)$/binaryfilterbase.obj \ + $(SLO)$/contexthandler.obj \ + $(SLO)$/contexthandler2.obj \ + $(SLO)$/fastparser.obj \ + $(SLO)$/fasttokenhandler.obj \ + $(SLO)$/filterbase.obj \ + $(SLO)$/filterdetect.obj \ + $(SLO)$/fragmenthandler.obj \ + $(SLO)$/fragmenthandler2.obj \ + $(SLO)$/recordparser.obj \ + $(SLO)$/relations.obj \ + $(SLO)$/relationshandler.obj \ + $(SLO)$/services.obj \ + $(SLO)$/xmlfilterbase.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/docprop/makefile.mk b/oox/source/docprop/makefile.mk new file mode 100755 index 000000000000..5687178da9e0 --- /dev/null +++ b/oox/source/docprop/makefile.mk @@ -0,0 +1,49 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=docprop +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/ooxmldocpropimport.obj \ + $(SLO)$/docprophandler.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/drawingml/chart/makefile.mk b/oox/source/drawingml/chart/makefile.mk new file mode 100755 index 000000000000..84762e6a2540 --- /dev/null +++ b/oox/source/drawingml/chart/makefile.mk @@ -0,0 +1,74 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=oox +TARGET=chart +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/axiscontext.obj \ + $(SLO)$/axisconverter.obj \ + $(SLO)$/axismodel.obj \ + $(SLO)$/chartcontextbase.obj \ + $(SLO)$/chartconverter.obj \ + $(SLO)$/chartdrawingfragment.obj \ + $(SLO)$/chartspaceconverter.obj \ + $(SLO)$/chartspacefragment.obj \ + $(SLO)$/chartspacemodel.obj \ + $(SLO)$/converterbase.obj \ + $(SLO)$/datasourcecontext.obj \ + $(SLO)$/datasourceconverter.obj \ + $(SLO)$/datasourcemodel.obj \ + $(SLO)$/modelbase.obj \ + $(SLO)$/objectformatter.obj \ + $(SLO)$/plotareacontext.obj \ + $(SLO)$/plotareaconverter.obj \ + $(SLO)$/plotareamodel.obj \ + $(SLO)$/seriescontext.obj \ + $(SLO)$/seriesconverter.obj \ + $(SLO)$/seriesmodel.obj \ + $(SLO)$/titlecontext.obj \ + $(SLO)$/titleconverter.obj \ + $(SLO)$/titlemodel.obj \ + $(SLO)$/typegroupcontext.obj \ + $(SLO)$/typegroupconverter.obj \ + $(SLO)$/typegroupmodel.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/drawingml/diagram/makefile.mk b/oox/source/drawingml/diagram/makefile.mk new file mode 100755 index 000000000000..9d526ed3d3fb --- /dev/null +++ b/oox/source/drawingml/diagram/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=oox +TARGET=diagram +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/diagram.obj \ + $(SLO)$/diagramfragmenthandler.obj \ + $(SLO)$/diagramdefinitioncontext.obj \ + $(SLO)$/diagramlayoutatoms.obj \ + $(SLO)$/datamodelcontext.obj \ + $(SLO)$/layoutnodecontext.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/drawingml/makefile.mk b/oox/source/drawingml/makefile.mk new file mode 100755 index 000000000000..0546fb4c233d --- /dev/null +++ b/oox/source/drawingml/makefile.mk @@ -0,0 +1,92 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=drawingml +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/clrscheme.obj\ + $(SLO)$/clrschemecontext.obj\ + $(SLO)$/color.obj\ + $(SLO)$/colorchoicecontext.obj\ + $(SLO)$/connectorshapecontext.obj\ + $(SLO)$/customshapegeometry.obj\ + $(SLO)$/customshapeproperties.obj\ + $(SLO)$/drawingmltypes.obj\ + $(SLO)$/embeddedwavaudiofile.obj\ + $(SLO)$/fillproperties.obj\ + $(SLO)$/fillpropertiesgroupcontext.obj\ + $(SLO)$/graphicshapecontext.obj\ + $(SLO)$/guidcontext.obj\ + $(SLO)$/hyperlinkcontext.obj\ + $(SLO)$/lineproperties.obj\ + $(SLO)$/linepropertiescontext.obj\ + $(SLO)$/objectdefaultcontext.obj\ + $(SLO)$/shape.obj\ + $(SLO)$/shapecontext.obj\ + $(SLO)$/shapegroupcontext.obj\ + $(SLO)$/shapepropertiescontext.obj\ + $(SLO)$/shapepropertymap.obj\ + $(SLO)$/shapestylecontext.obj\ + $(SLO)$/spdefcontext.obj\ + $(SLO)$/textbody.obj\ + $(SLO)$/textbodycontext.obj\ + $(SLO)$/textbodyproperties.obj\ + $(SLO)$/textbodypropertiescontext.obj\ + $(SLO)$/textcharacterproperties.obj\ + $(SLO)$/textcharacterpropertiescontext.obj\ + $(SLO)$/textfield.obj\ + $(SLO)$/textfieldcontext.obj\ + $(SLO)$/textfont.obj\ + $(SLO)$/textliststyle.obj \ + $(SLO)$/textliststylecontext.obj\ + $(SLO)$/textparagraph.obj\ + $(SLO)$/textparagraphproperties.obj\ + $(SLO)$/textparagraphpropertiescontext.obj\ + $(SLO)$/textrun.obj\ + $(SLO)$/textspacingcontext.obj\ + $(SLO)$/texttabstoplistcontext.obj\ + $(SLO)$/theme.obj\ + $(SLO)$/themeelementscontext.obj\ + $(SLO)$/themefragmenthandler.obj\ + $(SLO)$/transform2dcontext.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/drawingml/table/makefile.mk b/oox/source/drawingml/table/makefile.mk new file mode 100755 index 000000000000..fa71971fc278 --- /dev/null +++ b/oox/source/drawingml/table/makefile.mk @@ -0,0 +1,62 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=oox +TARGET=table +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/tablecontext.obj \ + $(SLO)$/tableproperties.obj \ + $(SLO)$/tablerow.obj \ + $(SLO)$/tablerowcontext.obj \ + $(SLO)$/tablecell.obj \ + $(SLO)$/tablecellcontext.obj \ + $(SLO)$/tablestylelist.obj \ + $(SLO)$/tablestylelistfragmenthandler.obj \ + $(SLO)$/tablestylecontext.obj \ + $(SLO)$/tablestyle.obj \ + $(SLO)$/tablebackgroundstylecontext.obj \ + $(SLO)$/tablepartstylecontext.obj \ + $(SLO)$/tablestyletextstylecontext.obj \ + $(SLO)$/tablestylecellstylecontext.obj \ + $(SLO)$/tablestylepart.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/dump/makefile.mk b/oox/source/dump/makefile.mk new file mode 100755 index 000000000000..1e5f615675cc --- /dev/null +++ b/oox/source/dump/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=dump +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/biffdumper.obj \ + $(SLO)$/dffdumper.obj \ + $(SLO)$/dumperbase.obj \ + $(SLO)$/oledumper.obj \ + $(SLO)$/pptxdumper.obj \ + $(SLO)$/xlsbdumper.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/helper/makefile.mk b/oox/source/helper/makefile.mk new file mode 100755 index 000000000000..f31736faac8d --- /dev/null +++ b/oox/source/helper/makefile.mk @@ -0,0 +1,60 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=helper +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/attributelist.obj \ + $(SLO)$/binaryinputstream.obj \ + $(SLO)$/binaryoutputstream.obj \ + $(SLO)$/binarystreambase.obj \ + $(SLO)$/containerhelper.obj \ + $(SLO)$/graphichelper.obj \ + $(SLO)$/modelobjecthelper.obj \ + $(SLO)$/progressbar.obj \ + $(SLO)$/propertymap.obj \ + $(SLO)$/propertyset.obj \ + $(SLO)$/storagebase.obj \ + $(SLO)$/textinputstream.obj \ + $(SLO)$/zipstorage.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/ole/makefile.mk b/oox/source/ole/makefile.mk new file mode 100755 index 000000000000..a5232247cfa5 --- /dev/null +++ b/oox/source/ole/makefile.mk @@ -0,0 +1,60 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=ole +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/axbinaryreader.obj \ + $(SLO)$/axcontrol.obj \ + $(SLO)$/axcontrolfragment.obj \ + $(SLO)$/olehelper.obj \ + $(SLO)$/oleobjecthelper.obj \ + $(SLO)$/olestorage.obj \ + $(SLO)$/vbacontrol.obj \ + $(SLO)$/vbahelper.obj \ + $(SLO)$/vbainputstream.obj \ + $(SLO)$/vbamodule.obj \ + $(SLO)$/vbaproject.obj \ + $(SLO)$/vbaprojectfilter.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/oox/source/ppt/makefile.mk b/oox/source/ppt/makefile.mk new file mode 100755 index 000000000000..8d902ed51337 --- /dev/null +++ b/oox/source/ppt/makefile.mk @@ -0,0 +1,76 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=ppt +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/animationspersist.obj \ + $(SLO)$/animationtypes.obj \ + $(SLO)$/animvariantcontext.obj \ + $(SLO)$/backgroundproperties.obj\ + $(SLO)$/buildlistcontext.obj \ + $(SLO)$/commonbehaviorcontext.obj \ + $(SLO)$/commontimenodecontext.obj \ + $(SLO)$/conditioncontext.obj \ + $(SLO)$/customshowlistcontext.obj \ + $(SLO)$/headerfootercontext.obj \ + $(SLO)$/layoutfragmenthandler.obj\ + $(SLO)$/pptfilterhelpers.obj\ + $(SLO)$/pptimport.obj\ + $(SLO)$/pptshape.obj \ + $(SLO)$/pptshapecontext.obj \ + $(SLO)$/pptshapegroupcontext.obj \ + $(SLO)$/pptshapepropertiescontext.obj \ + $(SLO)$/presentationfragmenthandler.obj\ + $(SLO)$/slidefragmenthandler.obj\ + $(SLO)$/slidemastertextstylescontext.obj \ + $(SLO)$/slidepersist.obj\ + $(SLO)$/slidetimingcontext.obj\ + $(SLO)$/slidetransition.obj\ + $(SLO)$/slidetransitioncontext.obj\ + $(SLO)$/soundactioncontext.obj \ + $(SLO)$/timeanimvaluecontext.obj \ + $(SLO)$/timenode.obj\ + $(SLO)$/timenodelistcontext.obj \ + $(SLO)$/timetargetelementcontext.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/shape/makefile.mk b/oox/source/shape/makefile.mk new file mode 100755 index 000000000000..c6534b3a8a6f --- /dev/null +++ b/oox/source/shape/makefile.mk @@ -0,0 +1,49 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=shape +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/ShapeContextHandler.obj \ + $(SLO)$/ShapeFilterBase.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/token/makefile.mk b/oox/source/token/makefile.mk new file mode 100755 index 000000000000..ff42967f0bb1 --- /dev/null +++ b/oox/source/token/makefile.mk @@ -0,0 +1,78 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=token + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/namespacemap.obj \ + $(SLO)$/propertynames.obj \ + $(SLO)$/tokenmap.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + +GENHEADERPATH = $(INCCOM)$/oox$/token + +$(MISC)$/tokenhash.gperf $(INCCOM)$/tokennames.inc $(GENHEADERPATH)$/tokens.hxx $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt $(GENHEADERPATH)$/namespaces.hxx $(INCCOM)$/propertynames.inc $(GENHEADERPATH)$/properties.hxx : + @@noop $(assign do_phony:=.PHONY) + +$(SLO)$/tokenmap.obj : $(INCCOM)$/tokenhash.inc $(INCCOM)$/tokennames.inc $(GENHEADERPATH)$/tokens.hxx $(MISC)$/do_tokens + +$(INCCOM)$/tokenhash.inc : $(MISC)$/tokenhash.gperf $(MISC)$/do_tokens + $(AUGMENT_LIBRARY_PATH) gperf --compare-strncmp $(MISC)$/tokenhash.gperf | $(SED) -e "s/(char\*)0/(char\*)0, 0/g" | $(GREP) -v "^#line" >$(INCCOM)$/tokenhash.inc + +$(MISC)$/do_tokens $(do_phony) : tokens.txt tokens.pl tokens.hxx.head tokens.hxx.tail $(GENHEADERPATH)$/tokens.hxx $(INCCOM)$/tokennames.inc $(MISC)$/tokenhash.gperf + @@-$(RM) $@ + $(MKDIRHIER) $(GENHEADERPATH) + $(PERL) tokens.pl tokens.txt $(MISC)$/tokenids.inc $(INCCOM)$/tokennames.inc $(MISC)$/tokenhash.gperf && $(TYPE) tokens.hxx.head $(MISC)$/tokenids.inc tokens.hxx.tail > $(GENHEADERPATH)$/tokens.hxx && $(TOUCH) $@ + +$(SLO)$/namespacemap.obj : $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt $(GENHEADERPATH)$/namespaces.hxx $(MISC)$/do_namespaces + +$(MISC)$/do_namespaces $(do_phony) : namespaces.txt namespaces.pl namespaces.hxx.head namespaces.hxx.tail $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt $(GENHEADERPATH)$/namespaces.hxx + @@-$(RM) $@ + $(MKDIRHIER) $(GENHEADERPATH) + $(PERL) namespaces.pl namespaces.txt $(MISC)$/namespaceids.inc $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt && $(TYPE) namespaces.hxx.head $(MISC)$/namespaceids.inc namespaces.hxx.tail > $(GENHEADERPATH)$/namespaces.hxx && $(TOUCH) $@ + +$(SLO)$/propertynames.obj : $(INCCOM)$/propertynames.inc $(GENHEADERPATH)$/properties.hxx $(MISC)$/do_properties + +$(MISC)$/do_properties $(do_phony) : properties.txt properties.pl properties.hxx.head properties.hxx.tail $(INCCOM)$/propertynames.inc $(GENHEADERPATH)$/properties.hxx + @@-$(RM) $@ + $(MKDIRHIER) $(GENHEADERPATH) + $(PERL) properties.pl properties.txt $(MISC)$/propertyids.inc $(INCCOM)$/propertynames.inc && $(TYPE) properties.hxx.head $(MISC)$/propertyids.inc properties.hxx.tail > $(GENHEADERPATH)$/properties.hxx && $(TOUCH) $@ diff --git a/oox/source/token/namespacemap.cxx b/oox/source/token/namespacemap.cxx index d021f2a3a353..0f4373d2dc59 100755 --- a/oox/source/token/namespacemap.cxx +++ b/oox/source/token/namespacemap.cxx @@ -36,7 +36,7 @@ NamespaceMap::NamespaceMap() static const struct NamespaceUrl { sal_Int32 mnId; const sal_Char* mpcUrl; } spNamespaceUrls[] = { // include auto-generated C array with namespace URLs as C strings -#include +#include "namespacenames.inc" { -1, "" } }; diff --git a/oox/source/token/namespaces.hxx.tail b/oox/source/token/namespaces.hxx.tail index 1e6ba5881589..60ce5b18305d 100755 --- a/oox/source/token/namespaces.hxx.tail +++ b/oox/source/token/namespaces.hxx.tail @@ -12,24 +12,24 @@ inline sal_Int32 getNamespace( sal_Int32 nToken ) { return nToken & NMSP_MASK; } // defines for tokens with specific namespaces -#define OOX_TOKEN( token, namespace ) (::oox::XML_##token | ::oox::NMSP_##namespace) - -#define A_TOKEN( token ) OOX_TOKEN( token, dml ) -#define AX_TOKEN( token ) OOX_TOKEN( token, ax ) -#define C_TOKEN( token ) OOX_TOKEN( token, dmlChart ) -#define CDR_TOKEN( token ) OOX_TOKEN( token, dmlChartDr ) -#define DGM_TOKEN( token ) OOX_TOKEN( token, dmlDiagram ) -#define O_TOKEN( token ) OOX_TOKEN( token, vmlOffice ) -#define PC_TOKEN( token ) OOX_TOKEN( token, packageContentTypes ) -#define PPT_TOKEN( token ) OOX_TOKEN( token, ppt ) -#define PR_TOKEN( token ) OOX_TOKEN( token, packageRel ) -#define R_TOKEN( token ) OOX_TOKEN( token, officeRel ) -#define VML_TOKEN( token ) OOX_TOKEN( token, vml ) -#define VMLX_TOKEN( token ) OOX_TOKEN( token, vmlExcel ) -#define XDR_TOKEN( token ) OOX_TOKEN( token, dmlSpreadDr ) -#define XLS_TOKEN( token ) OOX_TOKEN( token, xls ) -#define XM_TOKEN( token ) OOX_TOKEN( token, xm ) -#define XML_TOKEN( token ) OOX_TOKEN( token, xml ) +#define OOX_TOKEN( namespace, token ) (::oox::NMSP_##namespace | ::oox::XML_##token) + +#define A_TOKEN( token ) OOX_TOKEN( dml, token ) +#define AX_TOKEN( token ) OOX_TOKEN( ax, token ) +#define C_TOKEN( token ) OOX_TOKEN( dmlChart, token ) +#define CDR_TOKEN( token ) OOX_TOKEN( dmlChartDr, token ) +#define DGM_TOKEN( token ) OOX_TOKEN( dmlDiagram, token ) +#define O_TOKEN( token ) OOX_TOKEN( vmlOffice, token ) +#define PC_TOKEN( token ) OOX_TOKEN( packageContentTypes, token ) +#define PPT_TOKEN( token ) OOX_TOKEN( ppt, token ) +#define PR_TOKEN( token ) OOX_TOKEN( packageRel, token ) +#define R_TOKEN( token ) OOX_TOKEN( officeRel, token ) +#define VML_TOKEN( token ) OOX_TOKEN( vml, token ) +#define VMLX_TOKEN( token ) OOX_TOKEN( vmlExcel, token ) +#define XDR_TOKEN( token ) OOX_TOKEN( dmlSpreadDr, token ) +#define XLS_TOKEN( token ) OOX_TOKEN( xls, token ) +#define XM_TOKEN( token ) OOX_TOKEN( xm, token ) +#define XML_TOKEN( token ) OOX_TOKEN( xml, token ) // ============================================================================ diff --git a/oox/source/token/namespaces.pl b/oox/source/token/namespaces.pl index 7c602f70128d..3c741fa7b2af 100644 --- a/oox/source/token/namespaces.pl +++ b/oox/source/token/namespaces.pl @@ -25,19 +25,17 @@ # #************************************************************************* -# operation mode (1 = identifiers, 2 = names, 3 = plain) -$op = shift @ARGV; -die "Error: invalid operation" unless( $op >= 1 && $op <= 3); +$ARGV0 = shift @ARGV; +$ARGV1 = shift @ARGV; +$ARGV2 = shift @ARGV; +$ARGV3 = shift @ARGV; -# number of bits to shift the namespace identifier -$shift = 16; - -if( $op == 1 ) { - print( "const size_t NMSP_SHIFT = $shift;\n" ); -} +# parse input file -$i = 1; -while( <> ) { +open( INFILE, $ARGV0 ) or die "cannot open input file: $!"; +my %namespaces; +while( ) +{ # trim newline chomp( $_ ); # trim leading/trailing whitespace @@ -46,14 +44,36 @@ while( <> ) { # trim comments $_ =~ s/^#.*//; # skip empty lines - if( $_ ) { + if( $_ ) + { # check for valid characters - $_ =~ /^([a-zA-Z]+)\s+([a-zA-Z0-9-.:\/]+)\s*$/ or die "Error: invalid entry: '$_'"; - # generate output - $id = $i << $shift; - if( $op == 1 ) { print( "const sal_Int32 NMSP_$1 = $i << NMSP_SHIFT;\n" ); } - elsif( $op == 2 ) { print( "{ $id, \"$2\" },\n" ); } - elsif( $op == 3 ) { print( "$id $1 $2\n" ); } - ++$i; + $_ =~ /^([a-zA-Z]+)\s+([a-zA-Z0-9-.:\/]+)\s*$/ or die "Error: invalid character in input data"; + $namespaces{$1} = $2; } } +close( INFILE ); + +# generate output files + +open( IDFILE, ">$ARGV1" ) or die "Error: cannot open output file: $!"; +open( NAMEFILE, ">$ARGV2" ) or die "Error: cannot open output file: $!"; +open( TXTFILE, ">$ARGV3" ) or die "Error: cannot open output file: $!"; + +# number of bits to shift the namespace identifier +$shift = 16; + +print ( IDFILE "const size_t NMSP_SHIFT = $shift;\n" ); + +$i = 1; +foreach( keys( %namespaces ) ) +{ + print( IDFILE "const sal_Int32 NMSP_$_ = $i << NMSP_SHIFT;\n" ); + $id = $i << $shift; + print( NAMEFILE "{ $id, \"$namespaces{$_}\" },\n" ); + print( TXTFILE "$id $_ $namespaces{$_}\n" ); + ++$i; +} + +close( IDFILE ); +close( nameFILE ); +close( TXTFILE ); diff --git a/oox/source/token/properties.pl b/oox/source/token/properties.pl index 448cec632343..f341924bbb90 100644 --- a/oox/source/token/properties.pl +++ b/oox/source/token/properties.pl @@ -25,33 +25,43 @@ # #************************************************************************* -# operation mode (1 = identifiers, 2 = names) -$op = shift @ARGV; -die "Error: invalid operation" unless( $op >= 1 && $op <= 2); +$ARGV0 = shift @ARGV; +$ARGV1 = shift @ARGV; +$ARGV2 = shift @ARGV; -$i = 0; -while( <> ) { +# parse input file + +open( INFILE, $ARGV0 ) or die "Error: cannot open input file: $!"; +my %props; +while( ) +{ # trim newline chomp( $_ ); # trim leading/trailing whitespace $_ =~ s/^\s*//g; $_ =~ s/\s*$//g; - # skip empty lines - if( $_ ) { - # check for valid characters - $_ =~ /^[A-Z][a-zA-Z0-9]+$/ or die "Error: invalid entry: '$_'"; - # generate output - if( $op == 1 ) { - print( "const sal_Int32 PROP_$_ = $i;\n" ); - } elsif( $op == 2 ) { - print( "/* $i */ \"$_\",\n" ); - } - ++$i; - } + # check for valid characters + $_ =~ /^[A-Z][a-zA-Z0-9]*$/ or die "Error: invalid character in property '$_'"; + $id = "PROP_$_"; + $props{$_} = $id; } +close( INFILE ); + +# generate output files + +open( IDFILE, ">$ARGV1" ) or die "Error: cannot open output file: $!"; +open( NAMEFILE, ">$ARGV2" ) or die "Error: cannot open output file: $!"; -if( $op == 1 ) { - print( "const sal_Int32 PROP_COUNT = $i;\nconst sal_Int32 PROP_INVALID = -1;\n" ); -} elsif( $op == 2 ) { - print( " \"\"" ); +$i = 0; +foreach( sort( keys( %props ) ) ) +{ + print( IDFILE "const sal_Int32 $props{$_} = $i;\n" ); + print( NAMEFILE "/* $i */ \"$_\",\n" ); + ++$i; } + +print( IDFILE "const sal_Int32 PROP_COUNT = $i;\n" ); +print( IDFILE "const sal_Int32 PROP_INVALID = -1;\n" ); + +close( IDFILE ); +close( NAMEFILE ); diff --git a/oox/source/token/propertynames.cxx b/oox/source/token/propertynames.cxx index b8f06496c7ff..401d168fe696 100644 --- a/oox/source/token/propertynames.cxx +++ b/oox/source/token/propertynames.cxx @@ -36,7 +36,8 @@ PropertyNameVector::PropertyNameVector() static const sal_Char* sppcPropertyNames[] = { // include auto-generated C array with property names as C strings -#include +#include "propertynames.inc" + "" }; size_t nArraySize = (sizeof( sppcPropertyNames ) / sizeof( *sppcPropertyNames )) - 1; diff --git a/oox/source/token/tokenmap.cxx b/oox/source/token/tokenmap.cxx index 0be0a1c4c470..a5189269c3c8 100644 --- a/oox/source/token/tokenmap.cxx +++ b/oox/source/token/tokenmap.cxx @@ -43,10 +43,8 @@ using ::rtl::OUString; // ============================================================================ namespace { - -// include auto-generated Perfect_Hash class -#include - +// include auto-generated Perfect_Hash +#include "tokenhash.inc" } // namespace // ============================================================================ @@ -57,7 +55,7 @@ TokenMap::TokenMap() : static const sal_Char* sppcTokenNames[] = { // include auto-generated C array with token names as C strings -#include +#include "tokennames.inc" "" }; @@ -70,14 +68,14 @@ TokenMap::TokenMap() : } #if OSL_DEBUG_LEVEL > 0 - // check that the Perfect_Hash is in sync with the token name list + // check that the perfect_hash is in sync with the token name list bool bOk = true; for( sal_Int32 nToken = 0; bOk && (nToken < XML_TOKEN_COUNT); ++nToken ) { // check that the getIdentifier <-> getToken roundtrip works OString aUtf8Name = OUStringToOString( maTokenNames[ nToken ].maUniName, RTL_TEXTENCODING_UTF8 ); - const XMLTokenInfo* pTokenInfo = Perfect_Hash::getTokenInfo( aUtf8Name.getStr(), aUtf8Name.getLength() ); - bOk = pTokenInfo && (pTokenInfo->mnToken == nToken); + struct xmltoken* pToken = Perfect_Hash::in_word_set( aUtf8Name.getStr(), aUtf8Name.getLength() ); + bOk = pToken && (pToken->nToken == nToken); OSL_ENSURE( bOk, ::rtl::OStringBuffer( "TokenMap::TokenMap - token list broken, #" ). append( nToken ).append( ", '" ).append( aUtf8Name ).append( '\'' ).getStr() ); } @@ -98,8 +96,8 @@ OUString TokenMap::getUnicodeTokenName( sal_Int32 nToken ) const sal_Int32 TokenMap::getTokenFromUnicode( const OUString& rUnicodeName ) const { OString aUtf8Name = OUStringToOString( rUnicodeName, RTL_TEXTENCODING_UTF8 ); - const XMLTokenInfo* pTokenInfo = Perfect_Hash::getTokenInfo( aUtf8Name.getStr(), aUtf8Name.getLength() ); - return pTokenInfo ? pTokenInfo->mnToken : XML_TOKEN_INVALID; + struct xmltoken* pToken = Perfect_Hash::in_word_set( aUtf8Name.getStr(), aUtf8Name.getLength() ); + return pToken ? pToken->nToken : XML_TOKEN_INVALID; } Sequence< sal_Int8 > TokenMap::getUtf8TokenName( sal_Int32 nToken ) const @@ -111,9 +109,9 @@ Sequence< sal_Int8 > TokenMap::getUtf8TokenName( sal_Int32 nToken ) const sal_Int32 TokenMap::getTokenFromUtf8( const Sequence< sal_Int8 >& rUtf8Name ) const { - const XMLTokenInfo* pTokenInfo = Perfect_Hash::getTokenInfo( + struct xmltoken* pToken = Perfect_Hash::in_word_set( reinterpret_cast< const char* >( rUtf8Name.getConstArray() ), rUtf8Name.getLength() ); - return pTokenInfo ? pTokenInfo->mnToken : XML_TOKEN_INVALID; + return pToken ? pToken->nToken : XML_TOKEN_INVALID; } // ============================================================================ diff --git a/oox/source/token/tokens.pl b/oox/source/token/tokens.pl index ba7f39f2be39..a951cee80db2 100644 --- a/oox/source/token/tokens.pl +++ b/oox/source/token/tokens.pl @@ -25,55 +25,56 @@ # #************************************************************************* -# operation mode (1 = identifiers, 2 = names, 3 = gperf) -$op = shift @ARGV; -die "Error: invalid operation" unless( $op >= 1 && $op <= 3); +$ARGV0 = shift @ARGV; +$ARGV1 = shift @ARGV; +$ARGV2 = shift @ARGV; +$ARGV3 = shift @ARGV; -if( $op == 3 ) { - print( "%language=C++\n" ); - print( "%define slot-name mpcName\n" ); - print( "%define initializer-suffix ,0\n" ); - print( "%define lookup-function-name getTokenInfo\n" ); - print( "%compare-strncmp\n" ); - print( "%readonly-tables\n" ); - print( "%enum\n" ); - print( "%null-strings\n" ); - print( "%struct-type\n" ); - print( "struct XMLTokenInfo {\n" ); - print( " const sal_Char* mpcName;\n" ); - print( " sal_Int32 mnToken;\n" ); - print( "};\n" ); - print( "%%\n" ); -} - -$i = 0; -while( <> ) +open( INFILE, $ARGV0 ) or die "Error: cannot open input file: $!"; +my %tokens; +while ( ) { # trim newline chomp( $_ ); # trim leading/trailing whitespace $_ =~ s/^\s*//g; $_ =~ s/\s*$//g; - # skip empty lines - if( $_ ) { - # check for valid characters - $_ =~ /^[a-zA-Z0-9-_]+$/ or die "Error: invalid entry: '$_'"; - # generate output - $id = "XML_$_"; - $id =~ s/-/_/g; - if( $op == 1 ) { - print( "const sal_Int32 $id = $i;\n" ); - } elsif( $op == 2 ) { - print( "\"$_\",\n" ); - } elsif( $op == 3 ) { - print( "$_,$id\n" ); - } - ++$i; - } + # check for valid characters + $_ =~ /^[a-zA-Z0-9-_]+$/ or die "Error: invalid character in token '$_'"; + $id = "XML_$_"; + $id =~ s/-/_/g; + $tokens{$_} = $id; } +close ( INFILE ); + +# generate output files + +open ( IDFILE, ">$ARGV1" ) or die "Error: cannot open output file: $!"; +open ( NAMEFILE, ">$ARGV2" ) or die "Error: cannot open output file: $!"; +open ( GPERFFILE, ">$ARGV3" ) or die "Error: cannot open output file: $!"; -if( $op == 1 ) { - print( "const sal_Int32 XML_TOKEN_COUNT = $i;\n" ); -} elsif( $op == 3 ) { - print( "%%\n" ); +print( GPERFFILE "%language=C++\n" ); +print( GPERFFILE "%global-table\n" ); +print( GPERFFILE "%null-strings\n" ); +print( GPERFFILE "%struct-type\n" ); +print( GPERFFILE "struct xmltoken {\n" ); +print( GPERFFILE " const sal_Char *name;\n" ); +print( GPERFFILE " sal_Int32 nToken;\n" ); +print( GPERFFILE "};\n" ); +print( GPERFFILE "%%\n" ); + +$i = 0; +foreach( sort( keys( %tokens ) ) ) +{ + print( IDFILE "const sal_Int32 $tokens{$_} = $i;\n" ); + print( NAMEFILE "\"$_\",\n" ); + print( GPERFFILE "$_,$tokens{$_}\n" ); + ++$i; } + +print( IDFILE "const sal_Int32 XML_TOKEN_COUNT = $i;\n" ); +print( GPERFFILE "%%\n" ); + +close( IDFILE ); +close( NAMEFILE ); +close( GPERFFILE ); diff --git a/oox/source/vml/makefile.mk b/oox/source/vml/makefile.mk new file mode 100755 index 000000000000..094d37cd8c1c --- /dev/null +++ b/oox/source/vml/makefile.mk @@ -0,0 +1,56 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=vml +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/vmldrawing.obj \ + $(SLO)$/vmldrawingfragment.obj \ + $(SLO)$/vmlformatting.obj \ + $(SLO)$/vmlinputstream.obj \ + $(SLO)$/vmlshape.obj \ + $(SLO)$/vmlshapecontainer.obj \ + $(SLO)$/vmlshapecontext.obj \ + $(SLO)$/vmltextbox.obj \ + $(SLO)$/vmltextboxcontext.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/oox/source/xls/makefile.mk b/oox/source/xls/makefile.mk new file mode 100755 index 000000000000..e337afe786a8 --- /dev/null +++ b/oox/source/xls/makefile.mk @@ -0,0 +1,105 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=oox +TARGET=xls +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/addressconverter.obj \ + $(SLO)$/autofilterbuffer.obj \ + $(SLO)$/autofiltercontext.obj \ + $(SLO)$/biffcodec.obj \ + $(SLO)$/biffdetector.obj \ + $(SLO)$/biffhelper.obj \ + $(SLO)$/biffinputstream.obj \ + $(SLO)$/biffoutputstream.obj \ + $(SLO)$/chartsheetfragment.obj \ + $(SLO)$/commentsbuffer.obj \ + $(SLO)$/commentsfragment.obj \ + $(SLO)$/condformatbuffer.obj \ + $(SLO)$/condformatcontext.obj \ + $(SLO)$/connectionsbuffer.obj \ + $(SLO)$/connectionsfragment.obj \ + $(SLO)$/defnamesbuffer.obj \ + $(SLO)$/drawingbase.obj \ + $(SLO)$/drawingfragment.obj \ + $(SLO)$/drawingmanager.obj \ + $(SLO)$/excelchartconverter.obj \ + $(SLO)$/excelfilter.obj \ + $(SLO)$/excelhandlers.obj \ + $(SLO)$/excelvbaproject.obj \ + $(SLO)$/externallinkbuffer.obj \ + $(SLO)$/externallinkfragment.obj \ + $(SLO)$/formulabase.obj \ + $(SLO)$/formulaparser.obj \ + $(SLO)$/numberformatsbuffer.obj \ + $(SLO)$/ooxformulaparser.obj \ + $(SLO)$/pagesettings.obj \ + $(SLO)$/pivotcachebuffer.obj \ + $(SLO)$/pivotcachefragment.obj \ + $(SLO)$/pivottablebuffer.obj \ + $(SLO)$/pivottablefragment.obj \ + $(SLO)$/querytablebuffer.obj \ + $(SLO)$/querytablefragment.obj \ + $(SLO)$/richstring.obj \ + $(SLO)$/richstringcontext.obj \ + $(SLO)$/scenariobuffer.obj \ + $(SLO)$/scenariocontext.obj \ + $(SLO)$/sharedformulabuffer.obj \ + $(SLO)$/sharedstringsbuffer.obj \ + $(SLO)$/sharedstringsfragment.obj \ + $(SLO)$/sheetdatacontext.obj \ + $(SLO)$/stylesbuffer.obj \ + $(SLO)$/stylesfragment.obj \ + $(SLO)$/tablebuffer.obj \ + $(SLO)$/tablefragment.obj \ + $(SLO)$/themebuffer.obj \ + $(SLO)$/unitconverter.obj \ + $(SLO)$/viewsettings.obj \ + $(SLO)$/workbookfragment.obj \ + $(SLO)$/workbookhelper.obj \ + $(SLO)$/workbooksettings.obj \ + $(SLO)$/worksheetbuffer.obj \ + $(SLO)$/worksheetfragment.obj \ + $(SLO)$/worksheethelper.obj \ + $(SLO)$/worksheetsettings.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk -- cgit From 7a5084f1acacb0858588d4d0c82651e47ca9914f Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Mon, 7 Feb 2011 17:18:11 +0100 Subject: dr78: rework of stream handling, improve handling of very large streams (prevent loading entire stream into array or string, esp. dumper and VML import), full support of XComponentContext --- oox/source/core/binaryfilterbase.cxx | 4 +- oox/source/core/contexthandler.cxx | 2 +- oox/source/core/filterdetect.cxx | 188 ++++++++-------- oox/source/core/fragmenthandler.cxx | 4 +- oox/source/core/xmlfilterbase.cxx | 4 +- oox/source/dump/biffdumper.cxx | 18 +- oox/source/dump/dumperbase.cxx | 358 ++++++++++++++----------------- oox/source/dump/oledumper.cxx | 46 ++-- oox/source/dump/pptxdumper.cxx | 23 +- oox/source/dump/xlsbdumper.cxx | 29 ++- oox/source/helper/binaryinputstream.cxx | 179 +++++++++------- oox/source/helper/binaryoutputstream.cxx | 73 ++++--- oox/source/helper/binarystreambase.cxx | 63 +++--- oox/source/helper/containerhelper.cxx | 15 +- oox/source/helper/graphichelper.cxx | 11 +- oox/source/helper/modelobjecthelper.cxx | 11 +- oox/source/helper/propertyset.cxx | 20 ++ oox/source/helper/textinputstream.cxx | 223 ++++++++++++++----- oox/source/helper/zipstorage.cxx | 25 ++- oox/source/ole/axbinaryreader.cxx | 57 +++-- oox/source/ole/axcontrol.cxx | 12 +- oox/source/ole/axcontrolfragment.cxx | 2 +- oox/source/ole/oleobjecthelper.cxx | 18 +- oox/source/ole/olestorage.cxx | 59 +++-- oox/source/ole/vbacontrol.cxx | 12 +- oox/source/ole/vbainputstream.cxx | 51 +++-- oox/source/ole/vbamodule.cxx | 6 +- oox/source/ole/vbaproject.cxx | 27 ++- oox/source/vml/vmldrawing.cxx | 4 +- oox/source/vml/vmldrawingfragment.cxx | 3 +- oox/source/vml/vmlinputstream.cxx | 300 ++++++++++++++++---------- oox/source/vml/vmlshape.cxx | 5 +- oox/source/vml/vmltextboxcontext.cxx | 27 ++- oox/source/xls/addressconverter.cxx | 4 +- oox/source/xls/biffdetector.cxx | 7 +- oox/source/xls/biffhelper.cxx | 15 +- oox/source/xls/biffinputstream.cxx | 137 +++++------- oox/source/xls/biffoutputstream.cxx | 92 ++++---- oox/source/xls/drawingmanager.cxx | 3 +- oox/source/xls/excelchartconverter.cxx | 4 +- oox/source/xls/formulabase.cxx | 20 +- oox/source/xls/formulaparser.cxx | 2 +- oox/source/xls/numberformatsbuffer.cxx | 2 +- oox/source/xls/ooxformulaparser.cxx | 20 +- oox/source/xls/pagesettings.cxx | 3 +- oox/source/xls/pivotcachebuffer.cxx | 2 +- oox/source/xls/viewsettings.cxx | 4 +- oox/source/xls/workbookfragment.cxx | 2 +- oox/source/xls/workbookhelper.cxx | 10 - oox/source/xls/workbooksettings.cxx | 2 +- oox/source/xls/worksheethelper.cxx | 4 +- 51 files changed, 1187 insertions(+), 1025 deletions(-) (limited to 'oox/source') diff --git a/oox/source/core/binaryfilterbase.cxx b/oox/source/core/binaryfilterbase.cxx index 9bebedb9c96b..edff8a788808 100644 --- a/oox/source/core/binaryfilterbase.cxx +++ b/oox/source/core/binaryfilterbase.cxx @@ -55,12 +55,12 @@ BinaryFilterBase::~BinaryFilterBase() StorageRef BinaryFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const { - return StorageRef( new ::oox::ole::OleStorage( getServiceFactory(), rxInStream, true ) ); + return StorageRef( new ::oox::ole::OleStorage( getComponentContext(), rxInStream, true ) ); } StorageRef BinaryFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const { - return StorageRef( new ::oox::ole::OleStorage( getServiceFactory(), rxOutStream, true ) ); + return StorageRef( new ::oox::ole::OleStorage( getComponentContext(), rxOutStream, true ) ); } // ============================================================================ diff --git a/oox/source/core/contexthandler.cxx b/oox/source/core/contexthandler.cxx index 8bf2c4eadfeb..1ff793cd0c84 100644 --- a/oox/source/core/contexthandler.cxx +++ b/oox/source/core/contexthandler.cxx @@ -42,7 +42,7 @@ using ::rtl::OUString; // ============================================================================ ContextHandler::ContextHandler( ContextHandler& rParent ) : - ContextHandlerImplBase(), + ContextHandler_BASE(), mxBaseData( rParent.mxBaseData ) { } diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index cdab111e9898..f836720a48a2 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -269,9 +269,9 @@ const sal_uInt32 ENCRYPT_HASH_SHA1 = 0x00008004; // ---------------------------------------------------------------------------- -bool lclIsZipPackage( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm ) +bool lclIsZipPackage( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm ) { - ZipStorage aZipStorage( rxFactory, rxInStrm ); + ZipStorage aZipStorage( rxContext, rxInStrm ); return aZipStorage.isStorage(); } @@ -499,109 +499,106 @@ PasswordVerifier::PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo ) Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescriptor& rMediaDesc ) const { - Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY ); - if( xFactory.is() ) + // try the plain input stream + Reference< XInputStream > xInStrm( rMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY ); + if( !xInStrm.is() || lclIsZipPackage( mxContext, xInStrm ) ) + return xInStrm; + + // check if a temporary file is passed in the 'ComponentData' property + Reference< XStream > xDecrypted( rMediaDesc.getComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ) ), UNO_QUERY ); + if( xDecrypted.is() ) { - // try the plain input stream - Reference< XInputStream > xInStrm( rMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY ); - if( !xInStrm.is() || lclIsZipPackage( xFactory, xInStrm ) ) - return xInStrm; - - // check if a temporary file is passed in the 'ComponentData' property - Reference< XStream > xDecrypted( rMediaDesc.getComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ) ), UNO_QUERY ); - if( xDecrypted.is() ) - { - Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream(); - if( lclIsZipPackage( xFactory, xDecrInStrm ) ) - return xDecrInStrm; - } + Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream(); + if( lclIsZipPackage( mxContext, xDecrInStrm ) ) + return xDecrInStrm; + } - // try to decrypt an encrypted OLE package - ::oox::ole::OleStorage aOleStorage( xFactory, xInStrm, false ); - if( aOleStorage.isStorage() ) try + // try to decrypt an encrypted OLE package + ::oox::ole::OleStorage aOleStorage( mxContext, xInStrm, false ); + if( aOleStorage.isStorage() ) try + { + // open the required input streams in the encrypted package + Reference< XInputStream > xEncryptionInfo( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptionInfo" ) ), UNO_SET_THROW ); + Reference< XInputStream > xEncryptedPackage( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptedPackage" ) ), UNO_SET_THROW ); + + // read the encryption info stream + PackageEncryptionInfo aEncryptInfo; + BinaryXInputStream aInfoStrm( xEncryptionInfo, true ); + bool bValidInfo = lclReadEncryptionInfo( aEncryptInfo, aInfoStrm ); + + // check flags and agorithm IDs, requiered are AES128 and SHA-1 + bool bImplemented = bValidInfo && + getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_CRYPTOAPI ) && + getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_AES ) && + // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set + ((aEncryptInfo.mnAlgorithmId == 0) || (aEncryptInfo.mnAlgorithmId == ENCRYPT_ALGO_AES128)) && + // hash algorithm ID 0 defaults to SHA-1 too + ((aEncryptInfo.mnAlgorithmIdHash == 0) || (aEncryptInfo.mnAlgorithmIdHash == ENCRYPT_HASH_SHA1)) && + (aEncryptInfo.mnVerifierHashSize == 20); + + if( bImplemented ) { - // open the required input streams in the encrypted package - Reference< XInputStream > xEncryptionInfo( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptionInfo" ) ), UNO_SET_THROW ); - Reference< XInputStream > xEncryptedPackage( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptedPackage" ) ), UNO_SET_THROW ); - - // read the encryption info stream - PackageEncryptionInfo aEncryptInfo; - BinaryXInputStream aInfoStrm( xEncryptionInfo, true ); - bool bValidInfo = lclReadEncryptionInfo( aEncryptInfo, aInfoStrm ); - - // check flags and agorithm IDs, requiered are AES128 and SHA-1 - bool bImplemented = bValidInfo && - getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_CRYPTOAPI ) && - getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_AES ) && - // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set - ((aEncryptInfo.mnAlgorithmId == 0) || (aEncryptInfo.mnAlgorithmId == ENCRYPT_ALGO_AES128)) && - // hash algorithm ID 0 defaults to SHA-1 too - ((aEncryptInfo.mnAlgorithmIdHash == 0) || (aEncryptInfo.mnAlgorithmIdHash == ENCRYPT_HASH_SHA1)) && - (aEncryptInfo.mnVerifierHashSize == 20); - - if( bImplemented ) + /* "VelvetSweatshop" is the built-in default encryption + password used by MS Excel for the "workbook protection" + feature with password. Try this first before prompting the + user for a password. */ + ::std::vector< OUString > aDefaultPasswords; + aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) ); + + /* Use the comphelper password helper to request a password. + This helper returns either with the correct password + (according to the verifier), or with an empty string if + user has cancelled the password input dialog. */ + PasswordVerifier aVerifier( aEncryptInfo ); + Sequence< NamedValue > aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( + aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords ); + + if( aEncryptionData.getLength() == 0 ) { - /* "VelvetSweatshop" is the built-in default encryption - password used by MS Excel for the "workbook protection" - feature with password. Try this first before prompting the - user for a password. */ - ::std::vector< OUString > aDefaultPasswords; - aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) ); - - /* Use the comphelper password helper to request a password. - This helper returns either with the correct password - (according to the verifier), or with an empty string if - user has cancelled the password input dialog. */ - PasswordVerifier aVerifier( aEncryptInfo ); - Sequence< NamedValue > aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( - aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords ); - - if( aEncryptionData.getLength() == 0 ) - { - rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true; - } - else + rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true; + } + else + { + // create temporary file for unencrypted package + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); + Reference< XOutputStream > xDecryptedPackage( xTempFile->getOutputStream(), UNO_SET_THROW ); + BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true ); + BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true ); + + EVP_CIPHER_CTX aes_ctx; + EVP_CIPHER_CTX_init( &aes_ctx ); + EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 ); + EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); + + sal_uInt8 pnInBuffer[ 1024 ]; + sal_uInt8 pnOutBuffer[ 1024 ]; + sal_Int32 nInLen; + int nOutLen; + aEncryptedPackage.skip( 8 ); // decrypted size + while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 ) { - // create temporary file for unencrypted package - Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); - Reference< XOutputStream > xDecryptedPackage( xTempFile->getOutputStream(), UNO_SET_THROW ); - BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true ); - BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true ); - - EVP_CIPHER_CTX aes_ctx; - EVP_CIPHER_CTX_init( &aes_ctx ); - EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 ); - EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); - - sal_uInt8 pnInBuffer[ 1024 ]; - sal_uInt8 pnOutBuffer[ 1024 ]; - sal_Int32 nInLen; - int nOutLen; - aEncryptedPackage.skip( 8 ); // decrypted size - while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 ) - { - EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen ); - aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); - } - EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen ); + EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen ); aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); + } + EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen ); + aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); - EVP_CIPHER_CTX_cleanup( &aes_ctx ); - xDecryptedPackage->flush(); - aDecryptedPackage.seekToStart(); + EVP_CIPHER_CTX_cleanup( &aes_ctx ); + xDecryptedPackage->flush(); + aDecryptedPackage.seekToStart(); - // store temp file in media descriptor to keep it alive - rMediaDesc.setComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ), Any( xTempFile ) ); + // store temp file in media descriptor to keep it alive + rMediaDesc.setComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ), Any( xTempFile ) ); - Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream(); - if( lclIsZipPackage( xFactory, xDecrInStrm ) ) - return xDecrInStrm; - } + Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream(); + if( lclIsZipPackage( mxContext, xDecrInStrm ) ) + return xDecrInStrm; } } - catch( Exception& ) - { - } + } + catch( Exception& ) + { } return Reference< XInputStream >(); @@ -633,7 +630,6 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq { OUString aFilterName; MediaDescriptor aMediaDesc( rMediaDescSeq ); - Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); /* Check that the user has not choosen to abort detection, e.g. by hitting 'Cancel' in the password input dialog. This may happen because this @@ -650,7 +646,7 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq Reference< XInputStream > xInStrm( extractUnencryptedPackage( aMediaDesc ), UNO_SET_THROW ); // stream must be a ZIP package - ZipStorage aZipStorage( xFactory, xInStrm ); + ZipStorage aZipStorage( mxContext, xInStrm ); if( aZipStorage.isStorage() ) { // create the fast parser, register the XML namespaces, set document handler diff --git a/oox/source/core/fragmenthandler.cxx b/oox/source/core/fragmenthandler.cxx index a1c42e56c155..14abe0d537fc 100644 --- a/oox/source/core/fragmenthandler.cxx +++ b/oox/source/core/fragmenthandler.cxx @@ -52,12 +52,12 @@ FragmentBaseData::FragmentBaseData( XmlFilterBase& rFilter, const OUString& rFra // ============================================================================ FragmentHandler::FragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath ) : - FragmentHandlerImplBase( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, rFilter.importRelations( rFragmentPath ) ) ) ) + FragmentHandler_BASE( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, rFilter.importRelations( rFragmentPath ) ) ) ) { } FragmentHandler::FragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath, RelationsRef xRelations ) : - FragmentHandlerImplBase( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, xRelations ) ) ) + FragmentHandler_BASE( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, xRelations ) ) ) { } diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index fe13d9322346..a77789edbeb8 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -496,12 +496,12 @@ Reference< XInputStream > XmlFilterBase::implGetInputStream( MediaDescriptor& rM StorageRef XmlFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const { - return StorageRef( new ZipStorage( getServiceFactory(), rxInStream ) ); + return StorageRef( new ZipStorage( getComponentContext(), rxInStream ) ); } StorageRef XmlFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const { - return StorageRef( new ZipStorage( getServiceFactory(), rxOutStream ) ); + return StorageRef( new ZipStorage( getComponentContext(), rxOutStream ) ); } // ============================================================================ diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index 279c9d3c0487..54e1fad7febc 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -166,7 +166,7 @@ void BiffCtlsStreamObject::implDump() { IndentGuard aIndGuard( mxOut ); mxStrm->seek( mnStartPos ); - RelativeInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, mnLength ) ); + BinaryInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, mnLength ) ); FormControlStreamObject( *this, xRelStrm ).dump(); } writeEmptyItem( "CTLS-END" ); @@ -356,7 +356,7 @@ bool BiffObjectBase::implStartRecord( BinaryInputStream&, sal_Int64& ornRecPos, break; } - ornRecSize = mxBiffStrm->getLength(); + ornRecSize = mxBiffStrm->size(); return bValid; } @@ -810,7 +810,7 @@ void FormulaObject::implDump() if( mnSize == 0 ) return; sal_Int64 nStartPos = mxStrm->tell(); - sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->getLength() ); + sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->size() ); bool bValid = mxTokens.get(); mxStack.reset( new FormulaStack ); @@ -1603,7 +1603,7 @@ void WorkbookStreamObject::implDumpRecordBody() { BiffInputStream& rStrm = getBiffStream(); sal_uInt16 nRecId = rStrm.getRecId(); - sal_Int64 nRecSize = rStrm.getLength(); + sal_Int64 nRecSize = rStrm.size(); BiffType eBiff = getBiff(); switch( nRecId ) @@ -4524,7 +4524,7 @@ RootStorageObject::RootStorageObject( const DumperBase& rParent ) addPreferredStream( "Workbook" ); } -void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { if( (rStrgPath.getLength() == 0) && (rStrmName.equalsAscii( "Book" ) || rStrmName.equalsAscii( "Workbook" )) ) WorkbookStreamObject( *this, rxStrm, rSysFileName ).dump(); @@ -4562,13 +4562,13 @@ Dumper::Dumper( const FilterBase& rFilter ) DumperBase::construct( xCfg ); } -Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) +Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) { - if( rxFactory.is() && rxInStrm.is() ) + if( rxContext.is() && rxInStrm.is() ) { - StorageRef xStrg( new ::oox::ole::OleStorage( rxFactory, rxInStrm, true ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( rxContext, rxInStrm, true ) ); MediaDescriptor aMediaDesc; - ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) ); + ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName, aMediaDesc ) ); DumperBase::construct( xCfg ); } } diff --git a/oox/source/dump/dumperbase.cxx b/oox/source/dump/dumperbase.cxx index f7c6c6102b1d..eeca65e88cc5 100644 --- a/oox/source/dump/dumperbase.cxx +++ b/oox/source/dump/dumperbase.cxx @@ -29,14 +29,13 @@ #include #include -#include #include -#include #include #include #include #include #include +#include #include "oox/core/filterbase.hxx" #include "oox/helper/binaryoutputstream.hxx" #include "oox/helper/textinputstream.hxx" @@ -112,20 +111,14 @@ OUString InputOutputHelper::getFileNameExtension( const OUString& rFileUrl ) // input streams -------------------------------------------------------------- -Reference< XInputStream > InputOutputHelper::getXInputStream( BinaryInputStream& rStrm ) -{ - if( BinaryXInputStream* pXStrm = dynamic_cast< BinaryXInputStream* >( &rStrm ) ) - return pXStrm->getXInputStream(); - return 0; -} - Reference< XInputStream > InputOutputHelper::openInputStream( - const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName ) + const Reference< XComponentContext >& rxContext, const OUString& rFileName ) { Reference< XInputStream > xInStrm; - if( rxFactory.is() ) try + if( rxContext.is() ) try { - Reference< XSimpleFileAccess > xFileAccess( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XSimpleFileAccess > xFileAccess( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); xInStrm = xFileAccess->openFileRead( rFileName ); } catch( Exception& ) @@ -134,38 +127,16 @@ Reference< XInputStream > InputOutputHelper::openInputStream( return xInStrm; } -Reference< XTextInputStream > InputOutputHelper::openTextInputStream( - const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rEncoding ) -{ - Reference< XTextInputStream > xTextInStrm; - if( rxFactory.is() && rxInStrm.is() ) try - { - Reference< XActiveDataSink > xDataSink( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextInputStream" ) ), UNO_QUERY_THROW ); - xDataSink->setInputStream( rxInStrm ); - xTextInStrm.set( xDataSink, UNO_QUERY_THROW ); - xTextInStrm->setEncoding( rEncoding ); - } - catch( Exception& ) - { - } - return xTextInStrm; -} - -Reference< XTextInputStream > InputOutputHelper::openTextInputStream( - const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName, const OUString& rEncoding ) -{ - return openTextInputStream( rxFactory, openInputStream( rxFactory, rFileName ), rEncoding ); -} - // output streams ------------------------------------------------------------- Reference< XOutputStream > InputOutputHelper::openOutputStream( - const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName ) + const Reference< XComponentContext >& rxContext, const OUString& rFileName ) { Reference< XOutputStream > xOutStrm; - if( rxFactory.is() ) try + if( rxContext.is() ) try { - Reference< XSimpleFileAccess > xFileAccess( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XSimpleFileAccess > xFileAccess( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); xOutStrm = xFileAccess->openFileWrite( rFileName ); } catch( Exception& ) @@ -175,15 +146,17 @@ Reference< XOutputStream > InputOutputHelper::openOutputStream( } Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream( - const Reference< XMultiServiceFactory >& rxFactory, const Reference< XOutputStream >& rxOutStrm, const OUString& rEncoding ) + const Reference< XComponentContext >& rxContext, const Reference< XOutputStream >& rxOutStrm, rtl_TextEncoding eTextEnc ) { Reference< XTextOutputStream > xTextOutStrm; - if( rxFactory.is() && rxOutStrm.is() ) try + const char* pcCharset = rtl_getMimeCharsetFromTextEncoding( eTextEnc ); + if( rxContext.is() && rxOutStrm.is() && pcCharset ) try { - Reference< XActiveDataSource > xDataSource( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextOutputStream" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XActiveDataSource > xDataSource( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextOutputStream" ) ), UNO_QUERY_THROW ); xDataSource->setOutputStream( rxOutStrm ); xTextOutStrm.set( xDataSource, UNO_QUERY_THROW ); - xTextOutStrm->setEncoding( rEncoding ); + xTextOutStrm->setEncoding( OUString::createFromAscii( pcCharset ) ); } catch( Exception& ) { @@ -192,9 +165,9 @@ Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream( } Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream( - const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName, const OUString& rEncoding ) + const Reference< XComponentContext >& rxContext, const OUString& rFileName, rtl_TextEncoding eTextEnc ) { - return openTextOutputStream( rxFactory, openOutputStream( rxFactory, rFileName ), rEncoding ); + return openTextOutputStream( rxContext, openOutputStream( rxContext, rFileName ), eTextEnc ); } // ============================================================================ @@ -1531,9 +1504,9 @@ NameListRef NameListWrapper::getNameList( const Config& rCfg ) const // ============================================================================ SharedConfigData::SharedConfigData( const OUString& rFileName, - const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, + const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) : - mxFactory( rxFactory ), + mxContext( rxContext ), mxRootStrg( rxRootStrg ), maSysFileName( rSysFileName ), mrMediaDesc( rMediaDesc ), @@ -1600,7 +1573,7 @@ Sequence< NamedValue > SharedConfigData::requestEncryptionData( ::comphelper::ID bool SharedConfigData::implIsValid() const { - return mbLoaded && mxFactory.is() && mxRootStrg.get() && (maSysFileName.getLength() > 0); + return mbLoaded && mxContext.is() && mxRootStrg.get() && (maSysFileName.getLength() > 0); } void SharedConfigData::implProcessConfigItemStr( @@ -1629,9 +1602,8 @@ bool SharedConfigData::readConfigFile( const OUString& rFileUrl ) bool bLoaded = maConfigFiles.count( rFileUrl ) > 0; if( !bLoaded ) { - Reference< XInputStream > xInStrm = InputOutputHelper::openInputStream( mxFactory, rFileUrl ); - BinaryXInputStream aInStrm( xInStrm, true ); - TextInputStream aTxtStrm( aInStrm, RTL_TEXTENCODING_UTF8 ); + Reference< XInputStream > xInStrm = InputOutputHelper::openInputStream( mxContext, rFileUrl ); + TextInputStream aTxtStrm( mxContext, xInStrm, RTL_TEXTENCODING_UTF8 ); if( !aTxtStrm.isEof() ) { maConfigFiles.insert( rFileUrl ); @@ -1698,9 +1670,9 @@ Config::Config( const sal_Char* pcEnvVar, const FilterBase& rFilter ) construct( pcEnvVar, rFilter ); } -Config::Config( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) +Config::Config( const sal_Char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) { - construct( pcEnvVar, rxFactory, rxRootStrg, rSysFileName, rMediaDesc ); + construct( pcEnvVar, rxContext, rxRootStrg, rSysFileName, rMediaDesc ); } Config::~Config() @@ -1715,14 +1687,14 @@ void Config::construct( const Config& rParent ) void Config::construct( const sal_Char* pcEnvVar, const FilterBase& rFilter ) { if( rFilter.getFileUrl().getLength() > 0 ) - construct( pcEnvVar, rFilter.getServiceFactory(), rFilter.getStorage(), rFilter.getFileUrl(), rFilter.getMediaDescriptor() ); + construct( pcEnvVar, rFilter.getComponentContext(), rFilter.getStorage(), rFilter.getFileUrl(), rFilter.getMediaDescriptor() ); } -void Config::construct( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) +void Config::construct( const sal_Char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) { if( pcEnvVar && rxRootStrg.get() && (rSysFileName.getLength() > 0) ) if( const sal_Char* pcFileName = ::getenv( pcEnvVar ) ) - mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxFactory, rxRootStrg, rSysFileName, rMediaDesc ) ); + mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxContext, rxRootStrg, rSysFileName, rMediaDesc ) ); } void Config::setStringOption( const String& rKey, const String& rData ) @@ -1795,14 +1767,16 @@ NameListRef Config::implGetNameList( const OUString& rListName ) const // ============================================================================ // ============================================================================ -Output::Output( const Reference< XTextOutputStream >& rxStrm ) -{ - construct( rxStrm ); -} - -Output::Output( const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName ) +Output::Output( const Reference< XComponentContext >& rxContext, const OUString& rFileName ) : + mxStrm( InputOutputHelper::openTextOutputStream( rxContext, rFileName, RTL_TEXTENCODING_UTF8 ) ), + mnCol( 0 ), + mnItemLevel( 0 ), + mnMultiLevel( 0 ), + mnItemIdx( 0 ), + mnLastItem( 0 ) { - construct( InputOutputHelper::openTextOutputStream( rxFactory, rFileName, CREATE_OUSTRING( "UTF-8" ) ) ); + if( mxStrm.is() ) + mxStrm->writeString( OUString( OOX_DUMP_BOM ) ); } // ---------------------------------------------------------------------------- @@ -2084,19 +2058,6 @@ void Output::writeRangeList( const RangeList& rRanges ) // ---------------------------------------------------------------------------- -void Output::construct( const Reference< XTextOutputStream >& rxStrm ) -{ - mxStrm = rxStrm; - mnCol = mnItemLevel = mnMultiLevel = 0; - mnItemIdx = 0; - mnLastItem = 0; - if( mxStrm.is() ) - { - writeChar( OOX_DUMP_BOM ); - newLine(); - } -} - bool Output::implIsValid() const { return mxStrm.is(); @@ -2240,7 +2201,8 @@ void StorageObjectBase::implDump() if( bIsRoot ) try { aSysOutPath += OOX_DUMP_DUMPEXT; - Reference< XSimpleFileAccess > xFileAccess( getFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( getContext()->getServiceManager(), UNO_QUERY_THROW ); + Reference< XSimpleFileAccess > xFileAccess( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW ); xFileAccess->kill( aSysOutPath ); } catch( Exception& ) @@ -2259,7 +2221,7 @@ void StorageObjectBase::implDump() } } -void StorageObjectBase::implDumpStream( const BinaryInputStreamRef&, const OUString&, const OUString&, const OUString& ) +void StorageObjectBase::implDumpStream( const Reference< XInputStream >&, const OUString&, const OUString&, const OUString& ) { } @@ -2305,12 +2267,12 @@ void StorageObjectBase::extractStream( StorageBase& rStrg, const OUString& rStrg BinaryXInputStream aInStrm( rStrg.openInputStream( rStrmName ), true ); if( !aInStrm.isEof() ) { - BinaryXOutputStream aOutStrm( InputOutputHelper::openOutputStream( getFactory(), rSysFileName ), true ); + BinaryXOutputStream aOutStrm( InputOutputHelper::openOutputStream( getContext(), rSysFileName ), true ); if( !aOutStrm.isEof() ) aInStrm.copyToStream( aOutStrm ); } - BinaryXInputStreamRef xDumpStrm( new BinaryXInputStream( InputOutputHelper::openInputStream( getFactory(), rSysFileName ), true ) ); - if( !xDumpStrm->isEof() ) + Reference< XInputStream > xDumpStrm = InputOutputHelper::openInputStream( getContext(), rSysFileName ); + if( xDumpStrm.is() ) implDumpStream( xDumpStrm, rStrgPath, rStrmName, rSysFileName ); } @@ -2366,13 +2328,10 @@ void OutputObjectBase::construct( const ObjectBase& rParent, const OUString& rSy { ObjectBase::construct( rParent ); if( ObjectBase::implIsValid() ) - mxOut.reset( new Output( getFactory(), rSysFileName + OOX_DUMP_DUMPEXT ) ); -} - -void OutputObjectBase::construct( const ObjectBase& rParent, const OutputRef& rxOut ) -{ - ObjectBase::construct( rParent ); - mxOut = rxOut; + { + maSysFileName = rSysFileName; + mxOut.reset( new Output( getContext(), rSysFileName + OOX_DUMP_DUMPEXT ) ); + } } void OutputObjectBase::construct( const OutputObjectBase& rParent ) @@ -2551,12 +2510,6 @@ void InputObjectBase::construct( const ObjectBase& rParent, const BinaryInputStr mxStrm = rxStrm; } -void InputObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OutputRef& rxOut ) -{ - OutputObjectBase::construct( rParent, rxOut ); - mxStrm = rxStrm; -} - void InputObjectBase::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm ) { OutputObjectBase::construct( rParent ); @@ -2575,7 +2528,7 @@ bool InputObjectBase::implIsValid() const void InputObjectBase::skipBlock( sal_Int64 nBytes, bool bShowSize ) { - sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->getLength() ); + sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() ); if( mxStrm->tell() < nEndPos ) { if( bShowSize ) @@ -2595,8 +2548,8 @@ void InputObjectBase::dumpRawBinary( sal_Int64 nBytes, bool bShowOffset, bool bS sal_Int64 nMaxShowSize = cfg().getIntOption< sal_Int64 >( bStream ? "max-binary-stream-size" : "max-binary-data-size", SAL_MAX_INT64 ); - bool bSeekable = mxStrm->getLength() >= 0; - sal_Int64 nEndPos = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->getLength() ) : 0; + bool bSeekable = mxStrm->size() >= 0; + sal_Int64 nEndPos = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() ) : 0; sal_Int64 nDumpEnd = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nMaxShowSize, nEndPos ) : nMaxShowSize; sal_Int64 nPos = bSeekable ? mxStrm->tell() : 0; bool bLoop = true; @@ -2671,12 +2624,12 @@ void InputObjectBase::dumpRemainingTo( sal_Int64 nPos ) void InputObjectBase::dumpRemainingStream() { - dumpRemainingTo( mxStrm->getLength() ); + dumpRemainingTo( mxStrm->size() ); } void InputObjectBase::dumpArray( const String& rName, sal_Int32 nBytes, sal_Unicode cSep ) { - sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->getLength() - mxStrm->tell(), 0, nBytes ); + sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nBytes ); if( nDumpSize > OOX_DUMP_MAXARRAY ) { dumpBinary( rName, nBytes, false ); @@ -2712,7 +2665,7 @@ sal_Unicode InputObjectBase::dumpUnicode( const String& rName ) OUString InputObjectBase::dumpCharArray( const String& rName, sal_Int32 nLen, rtl_TextEncoding eTextEnc, bool bHideTrailingNul ) { - sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->getLength() - mxStrm->tell(), 0, nLen ); + sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nLen ); OUString aString; if( nDumpSize > 0 ) { @@ -2892,7 +2845,7 @@ BinaryStreamObject::BinaryStreamObject( const OutputObjectBase& rParent, const B void BinaryStreamObject::dumpBinaryStream( bool bShowOffset ) { mxStrm->seekToStart(); - dumpRawBinary( mxStrm->getLength(), bShowOffset, true ); + dumpRawBinary( mxStrm->size(), bShowOffset, true ); mxOut->emptyLine(); } @@ -2901,43 +2854,71 @@ void BinaryStreamObject::implDump() dumpBinaryStream(); } +// ============================================================================ // ============================================================================ -TextStreamObject::TextStreamObject( const ObjectBase& rParent, +void TextStreamObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName ) { InputObjectBase::construct( rParent, rxStrm, rSysFileName ); - if( rxStrm.get() ) - mxTextStrm.reset( new TextInputStream( *rxStrm, eTextEnc ) ); + constructTextStrmObj( eTextEnc ); } -TextStreamObject::TextStreamObject( const OutputObjectBase& rParent, +void TextStreamObjectBase::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc ) { InputObjectBase::construct( rParent, rxStrm ); - if( rxStrm.get() ) - mxTextStrm.reset( new TextInputStream( *rxStrm, eTextEnc ) ); + constructTextStrmObj( eTextEnc ); +} + +void TextStreamObjectBase::construct( const InputObjectBase& rParent, rtl_TextEncoding eTextEnc ) +{ + InputObjectBase::construct( rParent ); + constructTextStrmObj( eTextEnc ); } -bool TextStreamObject::implIsValid() const +bool TextStreamObjectBase::implIsValid() const { return InputObjectBase::implIsValid() && mxTextStrm.get(); } -void TextStreamObject::implDump() +void TextStreamObjectBase::implDump() +{ + implDumpText( *mxTextStrm ); +} + +void TextStreamObjectBase::constructTextStrmObj( rtl_TextEncoding eTextEnc ) +{ + if( mxStrm.get() ) + mxTextStrm.reset( new TextInputStream( getContext(), *mxStrm, eTextEnc ) ); +} + +// ============================================================================ + +TextLineStreamObject::TextLineStreamObject( const ObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName ) +{ + TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc, rSysFileName ); +} + +TextLineStreamObject::TextLineStreamObject( const OutputObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc ) +{ + TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc ); +} + +void TextLineStreamObject::implDumpText( TextInputStream& rTextStrm ) { - OUString aLine; sal_uInt32 nLine = 0; - while( !mxTextStrm->isEof() ) + while( !rTextStrm.isEof() ) { - aLine = mxTextStrm->readLine(); - if( !mxTextStrm->isEof() ) + OUString aLine = rTextStrm.readLine(); + if( !rTextStrm.isEof() || (aLine.getLength() > 0) ) implDumpLine( aLine, ++nLine ); } - mxOut->emptyLine(); } -void TextStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine ) +void TextLineStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine ) { TableGuard aTabGuard( mxOut, 8 ); mxOut->writeDec( nLine, 6 ); @@ -2948,110 +2929,93 @@ void TextStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine ) // ============================================================================ -XmlStreamObject::XmlStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName ) : - TextStreamObject( rParent, rxStrm, RTL_TEXTENCODING_UTF8, rSysFileName ) +XmlStreamObject::XmlStreamObject( const ObjectBase& rParent, + const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName ) { + TextStreamObjectBase::construct( rParent, rxStrm, RTL_TEXTENCODING_UTF8, rSysFileName ); } -void XmlStreamObject::implDump() +XmlStreamObject::XmlStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm ) { - maIncompleteLine = OUString(); - TextStreamObject::implDump(); - if( maIncompleteLine.getLength() > 0 ) - { - mxOut->resetIndent(); - mxOut->writeString( maIncompleteLine ); - mxOut->emptyLine(); - writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM ); - } + TextStreamObjectBase::construct( rParent, rxStrm, RTL_TEXTENCODING_UTF8 ); } -void XmlStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 ) +void XmlStreamObject::implDumpText( TextInputStream& rTextStrm ) { - // build input line from cached incomplete element and new text data - OUStringBuffer aLine; - if( maIncompleteLine.getLength() > 0 ) - aLine.append( maIncompleteLine ).append( sal_Unicode( ' ' ) ); - aLine.append( rLine ); - maIncompleteLine = OUString(); + /* Buffers a start element and the following element text. Needed to dump + matching start/end elements and the element text on the same line. */ + OUStringBuffer aOldStartElem; + // special handling for VML + bool bIsVml = InputOutputHelper::getFileNameExtension( maSysFileName ).equalsIgnoreAsciiCaseAscii( "vml" ); - if( aLine.getLength() == 0 ) + while( !rTextStrm.isEof() ) { - mxOut->newLine(); - return; - } + // get the next element and the following element text from text stream + OUString aElem = rTextStrm.readToChar( '>', true ).trim(); + OUString aText = rTextStrm.readToChar( '<', false ); - const sal_Unicode* pcPos = aLine.getStr(); - const sal_Unicode* pcEnd = pcPos + aLine.getLength(); - while( pcPos < pcEnd ) - { - OUStringBuffer aOutLine; - bool bIsStartElement = false; - bool bIsComplElement = false; - bool bIsEndElement = false; - - /* check for start element at beginning of the line - pcEnd and thus (pcPos+1) - are dereferenceable, because OUStringBuffer::getStr is null-terminated. */ - if( (*pcPos == '<') && (pcPos[ 1 ] != '/') ) + // remove multiple whitespace from element + sal_Int32 nPos = 0; + while( nPos < aElem.getLength() ) { - const sal_Unicode* pcElementEnd = ::std::find( pcPos, pcEnd, '>' ); - if( pcElementEnd == pcEnd ) - { - // incomplete start element - maIncompleteLine = OUString( pcPos, static_cast< sal_Int32 >( pcEnd - pcPos ) ); - pcPos = pcEnd; - } - else - { - bIsComplElement = (pcPos[ 1 ] == '?') || (pcPos[ 1 ] == '!') || (pcElementEnd[ -1 ] == '/'); - bIsStartElement = !bIsComplElement; - ++pcElementEnd; - aOutLine.append( pcPos, static_cast< sal_Int32 >( pcElementEnd - pcPos ) ); - pcPos = pcElementEnd; - } + while( (nPos < aElem.getLength()) && (aElem[ nPos ] >= 32) ) ++nPos; + if( nPos < aElem.getLength() ) + aElem = OUStringBuffer( aElem.copy( 0, nPos ) ).append( sal_Unicode( ' ' ) ).append( aElem.copy( nPos ).trim() ).makeStringAndClear(); + ++nPos; } - // check for following element text - if( !bIsComplElement && (pcPos < pcEnd) ) + sal_Int32 nElemLen = aElem.getLength(); + if( (nElemLen >= 2) && (aElem[ 0 ] == '<') && (aElem[ nElemLen - 1 ] == '>') ) { - const sal_Unicode* pcElementStart = ::std::find( pcPos, pcEnd, '<' ); - // append text between elements - if( pcPos < pcElementStart ) + // determine type of the element + bool bSimpleElem = (aElem[ 1 ] == '!') || (aElem[ 1 ] == '?') || (aElem[ nElemLen - 2 ] == '/') || + (bIsVml && (nElemLen == 4) && (aElem[ 1 ] == 'b') && (aElem[ 2 ] == 'r')); + bool bStartElem = !bSimpleElem && (aElem[ 1 ] != '/'); + bool bEndElem = !bSimpleElem && !bStartElem; + + /* Start element or simple element: flush old start element and + its text from previous iteration, and start a new indentation + level for the new element. Trim whitespace and line breaks from + the text of the old start element. */ + if( (bSimpleElem || bStartElem) && (aOldStartElem.getLength() > 0) ) { - OUString aText( pcPos, static_cast< sal_Int32 >( pcElementStart - pcPos ) ); - if( aText.trim().getLength() > 0 ) - aOutLine.append( aText ); - pcPos = pcElementStart; + mxOut->writeString( aOldStartElem.makeStringAndClear().trim() ); + mxOut->newLine(); + mxOut->incIndent(); } - } - // check for stand-alone or following end element - if( !bIsComplElement && (pcPos < pcEnd) && (pcPos[ 1 ] == '/') ) - { - const sal_Unicode* pcElementEnd = ::std::find( pcPos, pcEnd, '>' ); - if( pcElementEnd == pcEnd ) + /* Start element: remember it and its text, to be able to print the + matching end element on the same line in the next iteration. */ + if( bStartElem ) { - // incomplete end element - aOutLine.append( pcPos, static_cast< sal_Int32 >( pcEnd - pcPos ) ); - maIncompleteLine = aOutLine.makeStringAndClear(); - pcPos = pcEnd; + aOldStartElem.append( aElem ).append( aText ); } else { - bIsEndElement = true; - ++pcElementEnd; - aOutLine.append( pcPos, static_cast< sal_Int32 >( pcElementEnd - pcPos ) ); - pcPos = pcElementEnd; - } - } + /* End element: if a start element has been remembered in the + previous iteration, write it out here untrimmed, to show + all whitespace in the element text, and without trailing + line break. Code below will add the end element right after + it. Otherwise, return to previous indentation level. */ + if( bEndElem ) + { + if( aOldStartElem.getLength() == 0 ) + mxOut->decIndent(); + else + mxOut->writeString( aOldStartElem.makeStringAndClear() ); + } - // flush output line - if( maIncompleteLine.getLength() == 0 ) - { - if( !bIsStartElement && bIsEndElement ) mxOut->decIndent(); - mxOut->writeString( aOutLine.makeStringAndClear() ); - mxOut->newLine(); - if( bIsStartElement && !bIsEndElement ) mxOut->incIndent(); + /* Write the element. Write following element text in a new + line, but only, if it does not contain of white space + entirely. */ + mxOut->writeString( aElem ); + mxOut->newLine(); + if( aText.trim().getLength() > 0 ) + { + mxOut->writeString( aText ); + mxOut->newLine(); + } + } } } } @@ -3167,7 +3131,7 @@ bool SequenceRecordObjectBase::implStartRecord( BinaryInputStream& rBaseStrm, sa { ornRecPos = rBaseStrm.tell(); // do not try to overread seekable streams, may cause assertions - bValid = ornRecPos < rBaseStrm.getLength(); + bValid = ornRecPos < rBaseStrm.size(); } // read the record header diff --git a/oox/source/dump/oledumper.cxx b/oox/source/dump/oledumper.cxx index bd2a0e05ecce..e0135af1604f 100644 --- a/oox/source/dump/oledumper.cxx +++ b/oox/source/dump/oledumper.cxx @@ -469,9 +469,9 @@ void OlePropertyStreamObject::dumpCodePageProperty( sal_uInt32 nStartPos ) if( nType == OLEPROP_TYPE_INT16 ) { sal_uInt16 nCodePage = dumpDec< sal_uInt16 >( "codepage", "CODEPAGES" ); - rtl_TextEncoding nNewTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage ); - if( nNewTextEnc != RTL_TEXTENCODING_DONTKNOW ) - meTextEnc = nNewTextEnc; + rtl_TextEncoding eNewTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage ); + if( eNewTextEnc != RTL_TEXTENCODING_DONTKNOW ) + meTextEnc = eNewTextEnc; mbIsUnicode = nCodePage == CODEPAGE_UNICODE; } else @@ -586,15 +586,8 @@ OUString OlePropertyStreamObject::dumpString8( const String& rName ) OUString OlePropertyStreamObject::dumpCharArray8( const String& rName, sal_Int32 nLen ) { - OUString aData; - size_t nNewLen = getLimitedValue< size_t, sal_Int32 >( nLen, 0, 1024 ); - if( nNewLen > 0 ) - { - ::std::vector< sal_Char > aBuffer( nNewLen + 1 ); - mxStrm->readMemory( &aBuffer.front(), nNewLen ); - aBuffer[ nNewLen ] = 0; - aData = OStringToOUString( OString( &aBuffer.front() ), meTextEnc ); - } + sal_Int32 nNewLen = getLimitedValue< sal_Int32, sal_Int32 >( nLen, 0, 1024 ); + OUString aData = mxStrm->readCharArrayUC( nNewLen, meTextEnc ); writeStringItem( rName, aData ); return aData; } @@ -607,13 +600,8 @@ OUString OlePropertyStreamObject::dumpString16( const String& rName ) OUString OlePropertyStreamObject::dumpCharArray16( const String& rName, sal_Int32 nLen ) { - size_t nNewLen = getLimitedValue< size_t, sal_Int32 >( nLen, 0, 1024 ); - ::std::vector< sal_Unicode > aBuffer; - aBuffer.reserve( nNewLen + 1 ); - for( size_t nIdx = 0; nIdx < nNewLen; ++nIdx ) - aBuffer.push_back( static_cast< sal_Unicode >( mxStrm->readuInt16() ) ); - aBuffer.push_back( 0 ); - OUString aData( &aBuffer.front() ); + sal_Int32 nNewLen = getLimitedValue< sal_Int32, sal_Int32 >( nLen, 0, 1024 ); + OUString aData = mxStrm->readUnicodeArray( nNewLen ); writeStringItem( rName, aData ); if( nNewLen & 1 ) dumpUnused( 2 ); // always padding to 32bit return aData; @@ -687,7 +675,7 @@ void OleStorageObject::construct( const ObjectBase& rParent ) StorageObjectBase::construct( rParent ); } -void OleStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& /*rStrgPath*/, const OUString& rStrmName, const OUString& rSysFileName ) +void OleStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& /*rStrgPath*/, const OUString& rStrmName, const OUString& rSysFileName ) { if( rStrmName.equalsAscii( "\001CompObj" ) ) OleCompObjObject( *this, rxStrm, rSysFileName ).dump(); @@ -1926,7 +1914,7 @@ void VbaFStreamObject::dumpSiteData() sal_uInt32 nSiteCount = dumpDec< sal_uInt32 >( "site-count" ); sal_uInt32 nSiteLength = dumpDec< sal_uInt32 >( "site-data-size" ); sal_Int64 nEndPos = mxStrm->tell() + nSiteLength; - if( ensureValid( nEndPos <= mxStrm->getLength() ) ) + if( ensureValid( nEndPos <= mxStrm->size() ) ) { mxOut->resetItemIndex(); sal_uInt32 nSiteIdx = 0; @@ -1984,7 +1972,7 @@ void VbaOStreamObject::implDump() writeDecItem( "control-id", aIt->mnId ); writeInfoItem( "prog-id", aIt->maProgId ); IndentGuard aIndGuard( mxOut ); - RelativeInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, aIt->mnLength ) ); + BinaryInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, aIt->mnLength ) ); FormControlStreamObject( *this, xRelStrm, &aIt->maProgId ).dump(); } } @@ -2068,7 +2056,7 @@ VbaContainerStorageObject::VbaContainerStorageObject( const ObjectBase& rParent, addPreferredStream( "f" ); } -void VbaContainerStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void VbaContainerStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { if( rStrmName.equalsAscii( "f" ) ) VbaFStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump(); @@ -2280,7 +2268,7 @@ void VbaModuleStreamObject::implDump() writeEmptyItem( "source-code" ); IndentGuard aIndGuard( mxOut ); BinaryInputStreamRef xVbaStrm( new ::oox::ole::VbaInputStream( *mxStrm ) ); - TextStreamObject( *this, xVbaStrm, mrVbaData.meTextEnc ).dump(); + TextLineStreamObject( *this, xVbaStrm, mrVbaData.meTextEnc ).dump(); } // ============================================================================ @@ -2292,7 +2280,7 @@ VbaStorageObject::VbaStorageObject( const ObjectBase& rParent, const StorageRef& addPreferredStream( "dir" ); } -void VbaStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void VbaStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { if( (rStrgPath.getLength() == 0) && rStrmName.equalsAscii( "dir" ) ) VbaDirStreamObject( *this, rxStrm, rSysFileName, mrVbaData ).dump(); @@ -2310,10 +2298,10 @@ VbaFormStorageObject::VbaFormStorageObject( const ObjectBase& rParent, const Sto { } -void VbaFormStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void VbaFormStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { if( rStrmName.equalsAscii( "\003VBFrame" ) ) - TextStreamObject( *this, rxStrm, mrVbaData.meTextEnc, rSysFileName ).dump(); + TextLineStreamObject( *this, rxStrm, mrVbaData.meTextEnc, rSysFileName ).dump(); else VbaContainerStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName ); } @@ -2326,10 +2314,10 @@ VbaProjectStorageObject::VbaProjectStorageObject( const ObjectBase& rParent, con addPreferredStorage( "VBA" ); } -void VbaProjectStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void VbaProjectStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { if( (rStrgPath.getLength() == 0) && rStrmName.equalsAscii( "PROJECT" ) ) - TextStreamObject( *this, rxStrm, maVbaData.meTextEnc, rSysFileName ).dump(); + TextLineStreamObject( *this, rxStrm, maVbaData.meTextEnc, rSysFileName ).dump(); else OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName ); } diff --git a/oox/source/dump/pptxdumper.cxx b/oox/source/dump/pptxdumper.cxx index 39e0ccc2be55..c98ffac7e38d 100644 --- a/oox/source/dump/pptxdumper.cxx +++ b/oox/source/dump/pptxdumper.cxx @@ -56,14 +56,13 @@ RootStorageObject::RootStorageObject( const DumperBase& rParent ) StorageObjectBase::construct( rParent ); } -void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { OUString aExt = InputOutputHelper::getFileNameExtension( rStrmName ); - Reference< XInputStream > xInStrm = InputOutputHelper::getXInputStream( *rxStrm ); if( aExt.equalsIgnoreAsciiCaseAscii( "pptx" ) || aExt.equalsIgnoreAsciiCaseAscii( "potx" ) ) { - Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "xlsb" ) || @@ -72,7 +71,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons aExt.equalsIgnoreAsciiCaseAscii( "xltm" ) || aExt.equalsIgnoreAsciiCaseAscii( "xltx" ) ) { - ::oox::dump::xlsb::Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + ::oox::dump::xlsb::Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "xla" ) || @@ -82,7 +81,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons aExt.equalsIgnoreAsciiCaseAscii( "xlt" ) || aExt.equalsIgnoreAsciiCaseAscii( "xlw" ) ) { - ::oox::dump::biff::Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + ::oox::dump::biff::Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "xml" ) || @@ -95,17 +94,17 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons { if( rStrgPath.equalsAscii( "ppt" ) && rStrmName.equalsAscii( "vbaProject.bin" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) ); VbaProjectStorageObject( *this, xStrg, rSysFileName ).dump(); } else if( rStrgPath.equalsAscii( "ppt/embeddings" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) ); OleStorageObject( *this, xStrg, rSysFileName ).dump(); } else if( rStrgPath.equalsAscii( "ppt/activeX" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, true ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, true ) ); ActiveXStorageObject( *this, xStrg, rSysFileName ).dump(); } else @@ -125,13 +124,13 @@ Dumper::Dumper( const FilterBase& rFilter ) DumperBase::construct( xCfg ); } -Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) +Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) { - if( rxFactory.is() && rxInStrm.is() ) + if( rxContext.is() && rxInStrm.is() ) { - StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) ); + StorageRef xStrg( new ZipStorage( rxContext, rxInStrm ) ); MediaDescriptor aMediaDesc; - ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) ); + ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName, aMediaDesc ) ); DumperBase::construct( xCfg ); } } diff --git a/oox/source/dump/xlsbdumper.cxx b/oox/source/dump/xlsbdumper.cxx index 3dc2974420a6..a5ffab059b52 100644 --- a/oox/source/dump/xlsbdumper.cxx +++ b/oox/source/dump/xlsbdumper.cxx @@ -368,7 +368,7 @@ void FormulaObject::implDump() if( mnSize < 0 ) return; sal_Int64 nStartPos = mxStrm->tell(); - sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->getLength() ); + sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->size() ); bool bValid = mxTokens.get(); mxStack.reset( new FormulaStack ); @@ -889,8 +889,8 @@ bool FormulaObject::dumpAttrToken() void FormulaObject::dumpAddTokenData() { mxOut->resetItemIndex(); - sal_Int32 nAddDataSize = (mxStrm->getLength() - mxStrm->tell() >= 4) ? dumpDec< sal_Int32 >( "add-data-size" ) : 0; - sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nAddDataSize, mxStrm->getLength() ); + sal_Int32 nAddDataSize = (mxStrm->size() - mxStrm->tell() >= 4) ? dumpDec< sal_Int32 >( "add-data-size" ) : 0; + sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nAddDataSize, mxStrm->size() ); for( AddDataTypeVec::const_iterator aIt = maAddData.begin(), aEnd = maAddData.end(); (aIt != aEnd) && !mxStrm->isEof() && (mxStrm->tell() < nEndPos); ++aIt ) { AddDataType eType = *aIt; @@ -2231,10 +2231,9 @@ RootStorageObject::RootStorageObject( const DumperBase& rParent ) StorageObjectBase::construct( rParent ); } -void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) +void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName ) { OUString aExt = InputOutputHelper::getFileNameExtension( rStrmName ); - Reference< XInputStream > xInStrm = InputOutputHelper::getXInputStream( *rxStrm ); if( aExt.equalsIgnoreAsciiCaseAscii( "xlsb" ) || aExt.equalsIgnoreAsciiCaseAscii( "xlsm" ) || @@ -2242,7 +2241,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons aExt.equalsIgnoreAsciiCaseAscii( "xltm" ) || aExt.equalsIgnoreAsciiCaseAscii( "xltx" ) ) { - Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "xla" ) || @@ -2252,13 +2251,13 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons aExt.equalsIgnoreAsciiCaseAscii( "xlt" ) || aExt.equalsIgnoreAsciiCaseAscii( "xlw" ) ) { - ::oox::dump::biff::Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + ::oox::dump::biff::Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "pptx" ) || aExt.equalsIgnoreAsciiCaseAscii( "potx" ) ) { - ::oox::dump::pptx::Dumper( getFactory(), xInStrm, rSysFileName ).dump(); + ::oox::dump::pptx::Dumper( getContext(), rxStrm, rSysFileName ).dump(); } else if( aExt.equalsIgnoreAsciiCaseAscii( "xml" ) || @@ -2271,12 +2270,12 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons { if( rStrgPath.equalsAscii( "xl" ) && rStrmName.equalsAscii( "vbaProject.bin" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) ); VbaProjectStorageObject( *this, xStrg, rSysFileName ).dump(); } else if( rStrgPath.equalsAscii( "xl/embeddings" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) ); OleStorageObject( *this, xStrg, rSysFileName ).dump(); } else if( @@ -2295,7 +2294,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons } else if( rStrgPath.equalsAscii( "xl/activeX" ) ) { - StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, true ) ); + StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, true ) ); ActiveXStorageObject( *this, xStrg, rSysFileName ).dump(); } else @@ -2315,13 +2314,13 @@ Dumper::Dumper( const FilterBase& rFilter ) DumperBase::construct( xCfg ); } -Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) +Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName ) { - if( rxFactory.is() && rxInStrm.is() ) + if( rxContext.is() && rxInStrm.is() ) { - StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) ); + StorageRef xStrg( new ZipStorage( getContext(), rxInStrm ) ); MediaDescriptor aMediaDesc; - ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) ); + ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName, aMediaDesc ) ); DumperBase::construct( xCfg ); } } diff --git a/oox/source/helper/binaryinputstream.cxx b/oox/source/helper/binaryinputstream.cxx index 2d547cdbf724..e61000675006 100644 --- a/oox/source/helper/binaryinputstream.cxx +++ b/oox/source/helper/binaryinputstream.cxx @@ -27,6 +27,8 @@ #include "oox/helper/binaryinputstream.hxx" +#include +#include #include #include #include @@ -80,11 +82,16 @@ OString BinaryInputStream::readCharArray( sal_Int32 nChars, bool bAllowNulChars if( nChars <= 0 ) return OString(); - ::std::vector< sal_Char > aBuffer( static_cast< size_t >( nChars ) ); - size_t nCharsRead = static_cast< size_t >( readMemory( &aBuffer.front(), nChars ) ); + ::std::vector< sal_uInt8 > aBuffer; + sal_Int32 nCharsRead = readArray( aBuffer, nChars ); + if( nCharsRead <= 0 ) + return OString(); + + aBuffer.resize( static_cast< size_t >( nCharsRead ) ); if( !bAllowNulChars ) - ::std::replace( aBuffer.begin(), aBuffer.begin() + nCharsRead, '\0', '?' ); - return OString( &aBuffer.front(), nCharsRead ); + ::std::replace( aBuffer.begin(), aBuffer.end(), '\0', '?' ); + + return OString( reinterpret_cast< sal_Char* >( &aBuffer.front() ), nCharsRead ); } OUString BinaryInputStream::readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding eTextEnc, bool bAllowNulChars ) @@ -94,30 +101,44 @@ OUString BinaryInputStream::readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding OUString BinaryInputStream::readUnicodeArray( sal_Int32 nChars, bool bAllowNulChars ) { - OUStringBuffer aBuffer; - if( nChars > 0 ) - { - aBuffer.ensureCapacity( nChars ); - sal_uInt16 nChar; - for( sal_uInt16 nCharIdx = 0; !mbEof && (nCharIdx < nChars); ++nCharIdx ) - { - readValue( nChar ); - aBuffer.append( static_cast< sal_Unicode >( (!bAllowNulChars && (nChar == 0)) ? '?' : nChar ) ); - } - } - return aBuffer.makeStringAndClear(); + if( nChars <= 0 ) + return OUString(); + + ::std::vector< sal_uInt16 > aBuffer; + sal_Int32 nCharsRead = readArray( aBuffer, nChars ); + if( nCharsRead <= 0 ) + return OUString(); + + aBuffer.resize( static_cast< size_t >( nCharsRead ) ); + if( !bAllowNulChars ) + ::std::replace( aBuffer.begin(), aBuffer.begin() + nCharsRead, '\0', '?' ); + + OUStringBuffer aStringBuffer; + aStringBuffer.ensureCapacity( nCharsRead ); + for( ::std::vector< sal_uInt16 >::iterator aIt = aBuffer.begin(), aEnd = aBuffer.end(); aIt != aEnd; ++aIt ) + aStringBuffer.append( static_cast< sal_Unicode >( *aIt ) ); + return aStringBuffer.makeStringAndClear(); +} + +OUString BinaryInputStream::readCompressedUnicodeArray( sal_Int32 nChars, bool bCompressed, bool bAllowNulChars ) +{ + return bCompressed ? + // ISO-8859-1 maps all byte values 0xHH to the same Unicode code point U+00HH + readCharArrayUC( nChars, RTL_TEXTENCODING_ISO_8859_1, bAllowNulChars ) : + readUnicodeArray( nChars, bAllowNulChars ); } -void BinaryInputStream::copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes ) +void BinaryInputStream::copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes, sal_Int32 nAtomSize ) { if( nBytes > 0 ) { - sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, INPUTSTREAM_BUFFERSIZE ); + // make buffer size a multiple of the passed atom size + sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, (INPUTSTREAM_BUFFERSIZE / nAtomSize) * nAtomSize ); StreamDataSequence aBuffer( nBufferSize ); while( nBytes > 0 ) { sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, nBufferSize ); - sal_Int32 nBytesRead = readData( aBuffer, nReadSize ); + sal_Int32 nBytesRead = readData( aBuffer, nReadSize, nAtomSize ); rOutStrm.writeData( aBuffer ); if( nReadSize == nBytesRead ) nBytes -= nReadSize; @@ -127,14 +148,10 @@ void BinaryInputStream::copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nB } } -void BinaryInputStream::readAtom( void* opMem, sal_uInt8 nSize ) -{ - readMemory( opMem, nSize ); -} - // ============================================================================ BinaryXInputStream::BinaryXInputStream( const Reference< XInputStream >& rxInStrm, bool bAutoClose ) : + BinaryStreamBase( Reference< XSeekable >( rxInStrm, UNO_QUERY ).is() ), BinaryXSeekableStream( Reference< XSeekable >( rxInStrm, UNO_QUERY ) ), maBuffer( INPUTSTREAM_BUFFERSIZE ), mxInStrm( rxInStrm ), @@ -145,16 +162,29 @@ BinaryXInputStream::BinaryXInputStream( const Reference< XInputStream >& rxInStr BinaryXInputStream::~BinaryXInputStream() { - if( mbAutoClose ) - close(); + close(); +} + +void BinaryXInputStream::close() +{ + OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::close - invalid call" ); + if( mbAutoClose && mxInStrm.is() ) try + { + mxInStrm->closeInput(); + } + catch( Exception& ) + { + OSL_ENSURE( false, "BinaryXInputStream::close - closing input stream failed" ); + } + mxInStrm.clear(); + BinaryXSeekableStream::close(); } -sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t /*nAtomSize*/ ) { sal_Int32 nRet = 0; if( !mbEof && (nBytes > 0) ) try { - OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::readData - invalid call" ); nRet = mxInStrm->readBytes( orData, nBytes ); mbEof = nRet != nBytes; } @@ -165,7 +195,7 @@ sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nB return nRet; } -sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nRet = 0; if( !mbEof && (nBytes > 0) ) @@ -175,7 +205,7 @@ sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes ) while( !mbEof && (nBytes > 0) ) { sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, nBufferSize ); - sal_Int32 nBytesRead = readData( maBuffer, nReadSize ); + sal_Int32 nBytesRead = readData( maBuffer, nReadSize, nAtomSize ); if( nBytesRead > 0 ) memcpy( opnMem, maBuffer.getConstArray(), static_cast< size_t >( nBytesRead ) ); opnMem += nBytesRead; @@ -186,11 +216,10 @@ sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes ) return nRet; } -void BinaryXInputStream::skip( sal_Int32 nBytes ) +void BinaryXInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ ) { if( !mbEof ) try { - OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::skip - invalid call" ); mxInStrm->skipBytes( nBytes ); } catch( Exception& ) @@ -199,60 +228,48 @@ void BinaryXInputStream::skip( sal_Int32 nBytes ) } } -void BinaryXInputStream::close() -{ - if( mxInStrm.is() ) try - { - mxInStrm->closeInput(); - mxInStrm.clear(); - } - catch( Exception& ) - { - OSL_ENSURE( false, "BinaryXInputStream::close - closing input stream failed" ); - } -} - // ============================================================================ SequenceInputStream::SequenceInputStream( const StreamDataSequence& rData ) : + BinaryStreamBase( true ), SequenceSeekableStream( rData ) { } -sal_Int32 SequenceInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +sal_Int32 SequenceInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t /*nAtomSize*/ ) { sal_Int32 nReadBytes = 0; if( !mbEof ) { - nReadBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos ); + nReadBytes = getMaxBytes( nBytes ); orData.realloc( nReadBytes ); if( nReadBytes > 0 ) - memcpy( orData.getArray(), mrData.getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) ); + memcpy( orData.getArray(), mpData->getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) ); mnPos += nReadBytes; mbEof = nReadBytes < nBytes; } return nReadBytes; } -sal_Int32 SequenceInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 SequenceInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t /*nAtomSize*/ ) { sal_Int32 nReadBytes = 0; if( !mbEof ) { - nReadBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos ); + nReadBytes = getMaxBytes( nBytes ); if( nReadBytes > 0 ) - memcpy( opMem, mrData.getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) ); + memcpy( opMem, mpData->getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) ); mnPos += nReadBytes; mbEof = nReadBytes < nBytes; } return nReadBytes; } -void SequenceInputStream::skip( sal_Int32 nBytes ) +void SequenceInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ ) { if( !mbEof ) { - sal_Int32 nSkipBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos ); + sal_Int32 nSkipBytes = getMaxBytes( nBytes ); mnPos += nSkipBytes; mbEof = nSkipBytes < nBytes; } @@ -260,73 +277,75 @@ void SequenceInputStream::skip( sal_Int32 nBytes ) // ============================================================================ -RelativeInputStream::RelativeInputStream( BinaryInputStream& rInStrm, sal_Int64 nLength ) : - mrInStrm( rInStrm ), +RelativeInputStream::RelativeInputStream( BinaryInputStream& rInStrm, sal_Int64 nSize ) : + BinaryStreamBase( rInStrm.isSeekable() ), + mpInStrm( &rInStrm ), mnStartPos( rInStrm.tell() ), mnRelPos( 0 ) { sal_Int64 nRemaining = rInStrm.getRemaining(); - mnLength = (nRemaining >= 0) ? ::std::min( nLength, nRemaining ) : nLength; - mbEof = mnLength < 0; + mnSize = (nRemaining >= 0) ? ::std::min( nSize, nRemaining ) : nSize; + mbEof = mbEof || rInStrm.isEof() || (mnSize < 0); } -bool RelativeInputStream::isSeekable() const +sal_Int64 RelativeInputStream::size() const { - return mrInStrm.isSeekable(); -} - -sal_Int64 RelativeInputStream::getLength() const -{ - return mnLength; + return mpInStrm ? mnSize : -1; } sal_Int64 RelativeInputStream::tell() const { - return mnRelPos; + return mpInStrm ? mnRelPos : -1; } void RelativeInputStream::seek( sal_Int64 nPos ) { - if( mrInStrm.isSeekable() && (mnStartPos >= 0) ) + if( mpInStrm && isSeekable() && (mnStartPos >= 0) ) { - mnRelPos = getLimitedValue< sal_Int64, sal_Int64 >( nPos, 0, mnLength ); - mrInStrm.seek( mnStartPos + mnRelPos ); - mbEof = (mnRelPos != nPos) || mrInStrm.isEof(); + mnRelPos = getLimitedValue< sal_Int64, sal_Int64 >( nPos, 0, mnSize ); + mpInStrm->seek( mnStartPos + mnRelPos ); + mbEof = (mnRelPos != nPos) || mpInStrm->isEof(); } } -sal_Int32 RelativeInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +void RelativeInputStream::close() +{ + mpInStrm = 0; + mbEof = true; +} + +sal_Int32 RelativeInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nReadBytes = 0; if( !mbEof ) { - sal_Int32 nRealBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos ); - nReadBytes = mrInStrm.readData( orData, nRealBytes ); + sal_Int32 nMaxBytes = getMaxBytes( nBytes ); + nReadBytes = mpInStrm->readData( orData, nMaxBytes, nAtomSize ); mnRelPos += nReadBytes; - mbEof = (nRealBytes < nBytes) || mrInStrm.isEof(); + mbEof = (nMaxBytes < nBytes) || mpInStrm->isEof(); } return nReadBytes; } -sal_Int32 RelativeInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 RelativeInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nReadBytes = 0; if( !mbEof ) { - sal_Int32 nRealBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos ); - nReadBytes = mrInStrm.readMemory( opMem, nRealBytes ); + sal_Int32 nMaxBytes = getMaxBytes( nBytes ); + nReadBytes = mpInStrm->readMemory( opMem, nMaxBytes, nAtomSize ); mnRelPos += nReadBytes; - mbEof = (nRealBytes < nBytes) || mrInStrm.isEof(); + mbEof = (nMaxBytes < nBytes) || mpInStrm->isEof(); } return nReadBytes; } -void RelativeInputStream::skip( sal_Int32 nBytes ) +void RelativeInputStream::skip( sal_Int32 nBytes, size_t nAtomSize ) { if( !mbEof ) { - sal_Int32 nSkipBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos ); - mrInStrm.skip( nSkipBytes ); + sal_Int32 nSkipBytes = getMaxBytes( nBytes ); + mpInStrm->skip( nSkipBytes, nAtomSize ); mnRelPos += nSkipBytes; mbEof = nSkipBytes < nBytes; } diff --git a/oox/source/helper/binaryoutputstream.cxx b/oox/source/helper/binaryoutputstream.cxx index f4ea9378aa90..1ae7b15d7595 100644 --- a/oox/source/helper/binaryoutputstream.cxx +++ b/oox/source/helper/binaryoutputstream.cxx @@ -27,6 +27,8 @@ #include "oox/helper/binaryoutputstream.hxx" +#include +#include #include #include @@ -45,14 +47,8 @@ const sal_Int32 OUTPUTSTREAM_BUFFERSIZE = 0x8000; // ============================================================================ -void BinaryOutputStream::writeAtom( const void* pMem, sal_uInt8 nSize ) -{ - writeMemory( pMem, nSize ); -} - -// ============================================================================ - BinaryXOutputStream::BinaryXOutputStream( const Reference< XOutputStream >& rxOutStrm, bool bAutoClose ) : + BinaryStreamBase( Reference< XSeekable >( rxOutStrm, UNO_QUERY ).is() ), BinaryXSeekableStream( Reference< XSeekable >( rxOutStrm, UNO_QUERY ) ), maBuffer( OUTPUTSTREAM_BUFFERSIZE ), mxOutStrm( rxOutStrm ), @@ -63,15 +59,30 @@ BinaryXOutputStream::BinaryXOutputStream( const Reference< XOutputStream >& rxOu BinaryXOutputStream::~BinaryXOutputStream() { - if( mbAutoClose ) - close(); + close(); +} + +void BinaryXOutputStream::close() +{ + OSL_ENSURE( mxOutStrm.is(), "BinaryXOutputStream::close - invalid call" ); + if( mxOutStrm.is() ) try + { + mxOutStrm->flush(); + if( mbAutoClose ) + mxOutStrm->closeOutput(); + } + catch( Exception& ) + { + OSL_ENSURE( false, "BinaryXOutputStream::close - closing output stream failed" ); + } + mxOutStrm.clear(); + BinaryXSeekableStream::close(); } -void BinaryXOutputStream::writeData( const StreamDataSequence& rData ) +void BinaryXOutputStream::writeData( const StreamDataSequence& rData, size_t /*nAtomSize*/ ) { - try + if( mxOutStrm.is() ) try { - OSL_ENSURE( mxOutStrm.is(), "BinaryXOutputStream::writeData - invalid call" ); mxOutStrm->writeBytes( rData ); } catch( Exception& ) @@ -80,57 +91,45 @@ void BinaryXOutputStream::writeData( const StreamDataSequence& rData ) } } -void BinaryXOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) +void BinaryXOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize ) { - if( nBytes > 0 ) + if( mxOutStrm.is() && (nBytes > 0) ) { - sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, OUTPUTSTREAM_BUFFERSIZE ); + sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, (OUTPUTSTREAM_BUFFERSIZE / nAtomSize) * nAtomSize ); const sal_uInt8* pnMem = reinterpret_cast< const sal_uInt8* >( pMem ); while( nBytes > 0 ) { sal_Int32 nWriteSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, nBufferSize ); maBuffer.realloc( nWriteSize ); memcpy( maBuffer.getArray(), pnMem, static_cast< size_t >( nWriteSize ) ); - writeData( maBuffer ); + writeData( maBuffer, nAtomSize ); pnMem += nWriteSize; nBytes -= nWriteSize; } } } -void BinaryXOutputStream::close() -{ - if( mxOutStrm.is() ) try - { - mxOutStrm->flush(); - mxOutStrm->closeOutput(); - } - catch( Exception& ) - { - OSL_ENSURE( false, "BinaryXOutputStream::close - closing output stream failed" ); - } -} - // ============================================================================ SequenceOutputStream::SequenceOutputStream( StreamDataSequence& rData ) : + BinaryStreamBase( true ), SequenceSeekableStream( rData ) { } -void SequenceOutputStream::writeData( const StreamDataSequence& rData ) +void SequenceOutputStream::writeData( const StreamDataSequence& rData, size_t nAtomSize ) { - if( rData.hasElements() ) - writeMemory( rData.getConstArray(), rData.getLength() ); + if( mpData && rData.hasElements() ) + writeMemory( rData.getConstArray(), rData.getLength(), nAtomSize ); } -void SequenceOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) +void SequenceOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t /*nAtomSize*/ ) { - if( nBytes > 0 ) + if( mpData && (nBytes > 0) ) { - if( mrData.getLength() - mnPos < nBytes ) - const_cast< StreamDataSequence& >( mrData ).realloc( mnPos + nBytes ); - memcpy( const_cast< StreamDataSequence& >( mrData ).getArray() + mnPos, pMem, static_cast< size_t >( nBytes ) ); + if( mpData->getLength() - mnPos < nBytes ) + const_cast< StreamDataSequence* >( mpData )->realloc( mnPos + nBytes ); + memcpy( const_cast< StreamDataSequence* >( mpData )->getArray() + mnPos, pMem, static_cast< size_t >( nBytes ) ); mnPos += nBytes; } } diff --git a/oox/source/helper/binarystreambase.cxx b/oox/source/helper/binarystreambase.cxx index d1e11850a68c..f189a37f97f5 100644 --- a/oox/source/helper/binarystreambase.cxx +++ b/oox/source/helper/binarystreambase.cxx @@ -27,6 +27,7 @@ #include "oox/helper/binarystreambase.hxx" +#include #include namespace oox { @@ -42,30 +43,11 @@ BinaryStreamBase::~BinaryStreamBase() { } -bool BinaryStreamBase::isSeekable() const -{ - return false; -} - -sal_Int64 BinaryStreamBase::getLength() const -{ - return -1; -} - -sal_Int64 BinaryStreamBase::tell() const -{ - return -1; -} - -void BinaryStreamBase::seek( sal_Int64 ) -{ -} - sal_Int64 BinaryStreamBase::getRemaining() const { // do not use isSeekable(), implementations may provide stream position and size even if not seekable sal_Int64 nPos = tell(); - sal_Int64 nLen = getLength(); + sal_Int64 nLen = size(); return ((nPos >= 0) && (nLen >= 0)) ? ::std::max< sal_Int64 >( nLen - nPos, 0 ) : -1; } @@ -73,7 +55,7 @@ void BinaryStreamBase::alignToBlock( sal_Int32 nBlockSize, sal_Int64 nAnchorPos { sal_Int64 nStrmPos = tell(); // nothing to do, if stream is at anchor position - if( isSeekable() && (0 <= nAnchorPos) && (nAnchorPos != nStrmPos) && (nBlockSize > 1) ) + if( mbSeekable && (0 <= nAnchorPos) && (nAnchorPos != nStrmPos) && (nBlockSize > 1) ) { // prevent modulo with negative arguments... sal_Int64 nSkipSize = (nAnchorPos < nStrmPos) ? @@ -86,16 +68,16 @@ void BinaryStreamBase::alignToBlock( sal_Int32 nBlockSize, sal_Int64 nAnchorPos // ============================================================================ BinaryXSeekableStream::BinaryXSeekableStream( const Reference< XSeekable >& rxSeekable ) : + BinaryStreamBase( mxSeekable.is() ), mxSeekable( rxSeekable ) { } -bool BinaryXSeekableStream::isSeekable() const +BinaryXSeekableStream::~BinaryXSeekableStream() { - return mxSeekable.is(); } -sal_Int64 BinaryXSeekableStream::getLength() const +sal_Int64 BinaryXSeekableStream::size() const { if( mxSeekable.is() ) try { @@ -103,7 +85,7 @@ sal_Int64 BinaryXSeekableStream::getLength() const } catch( Exception& ) { - OSL_ENSURE( false, "BinaryXSeekableStream::getLength - exception caught" ); + OSL_ENSURE( false, "BinaryXSeekableStream::size - exception caught" ); } return -1; } @@ -134,27 +116,44 @@ void BinaryXSeekableStream::seek( sal_Int64 nPos ) } } +void BinaryXSeekableStream::close() +{ + mxSeekable.clear(); + mbEof = true; +} + // ============================================================================ -bool SequenceSeekableStream::isSeekable() const +SequenceSeekableStream::SequenceSeekableStream( const StreamDataSequence& rData ) : + BinaryStreamBase( true ), + mpData( &rData ), + mnPos( 0 ) { - return true; } -sal_Int64 SequenceSeekableStream::getLength() const +sal_Int64 SequenceSeekableStream::size() const { - return mrData.getLength(); + return mpData ? mpData->getLength() : -1; } sal_Int64 SequenceSeekableStream::tell() const { - return mnPos; + return mpData ? mnPos : -1; } void SequenceSeekableStream::seek( sal_Int64 nPos ) { - mnPos = getLimitedValue< sal_Int32, sal_Int64 >( nPos, 0, mrData.getLength() ); - mbEof = mnPos != nPos; + if( mpData ) + { + mnPos = getLimitedValue< sal_Int32, sal_Int64 >( nPos, 0, mpData->getLength() ); + mbEof = mnPos != nPos; + } +} + +void SequenceSeekableStream::close() +{ + mpData = 0; + mbEof = true; } // ============================================================================ diff --git a/oox/source/helper/containerhelper.cxx b/oox/source/helper/containerhelper.cxx index e7f322ff10e3..4fb0d93d6224 100644 --- a/oox/source/helper/containerhelper.cxx +++ b/oox/source/helper/containerhelper.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "oox/helper/helper.hxx" @@ -46,12 +47,13 @@ using ::rtl::OUStringBuffer; // ============================================================================ -Reference< XIndexContainer > ContainerHelper::createIndexContainer( const Reference< XMultiServiceFactory >& rxFactory ) +Reference< XIndexContainer > ContainerHelper::createIndexContainer( const Reference< XComponentContext >& rxContext ) { Reference< XIndexContainer > xContainer; - if( rxFactory.is() ) try + if( rxContext.is() ) try { - xContainer.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.IndexedPropertyValues" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + xContainer.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.IndexedPropertyValues" ) ), UNO_QUERY_THROW ); } catch( Exception& ) { @@ -78,12 +80,13 @@ bool ContainerHelper::insertByIndex( return bRet; } -Reference< XNameContainer > ContainerHelper::createNameContainer( const Reference< XMultiServiceFactory >& rxFactory ) +Reference< XNameContainer > ContainerHelper::createNameContainer( const Reference< XComponentContext >& rxContext ) { Reference< XNameContainer > xContainer; - if( rxFactory.is() ) try + if( rxContext.is() ) try { - xContainer.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.NamedPropertyValues" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + xContainer.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.NamedPropertyValues" ) ), UNO_QUERY_THROW ); } catch( Exception& ) { diff --git a/oox/source/helper/graphichelper.cxx b/oox/source/helper/graphichelper.cxx index 2e5a612699e2..aeed0322b536 100755 --- a/oox/source/helper/graphichelper.cxx +++ b/oox/source/helper/graphichelper.cxx @@ -69,14 +69,13 @@ inline sal_Int32 lclConvertScreenPixelToHmm( double fPixel, double fPixelPerHmm // ============================================================================ GraphicHelper::GraphicHelper( const Reference< XComponentContext >& rxContext, const Reference< XFrame >& rxTargetFrame, const StorageRef& rxStorage ) : - mxCompContext( rxContext ), + mxContext( rxContext ), mxStorage( rxStorage ), maGraphicObjScheme( CREATE_OUSTRING( "vnd.sun.star.GraphicObject:" ) ) { - OSL_ENSURE( mxCompContext.is(), "GraphicHelper::GraphicHelper - missing component context" ); - Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW ); + OSL_ENSURE( mxContext.is(), "GraphicHelper::GraphicHelper - missing component context" ); + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY ); OSL_ENSURE( xFactory.is(), "GraphicHelper::GraphicHelper - missing service factory" ); - if( xFactory.is() ) mxGraphicProvider.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.graphic.GraphicProvider" ) ), UNO_QUERY ); @@ -319,9 +318,9 @@ Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStr OUString GraphicHelper::createGraphicObject( const Reference< XGraphic >& rxGraphic ) const { OUString aGraphicObjUrl; - if( mxCompContext.is() && rxGraphic.is() ) try + if( mxContext.is() && rxGraphic.is() ) try { - Reference< XGraphicObject > xGraphicObj( GraphicObject::create( mxCompContext ), UNO_SET_THROW ); + Reference< XGraphicObject > xGraphicObj( GraphicObject::create( mxContext ), UNO_SET_THROW ); xGraphicObj->setGraphic( rxGraphic ); maGraphicObjects.push_back( xGraphicObj ); aGraphicObjUrl = maGraphicObjScheme + xGraphicObj->getUniqueID(); diff --git a/oox/source/helper/modelobjecthelper.cxx b/oox/source/helper/modelobjecthelper.cxx index f9d8af74bcb8..d9c5bddff0f2 100644 --- a/oox/source/helper/modelobjecthelper.cxx +++ b/oox/source/helper/modelobjecthelper.cxx @@ -48,12 +48,12 @@ using ::rtl::OUString; // ============================================================================ -ObjectContainer::ObjectContainer( const Reference< XMultiServiceFactory >& rxFactory, const OUString& rServiceName ) : - mxFactory( rxFactory ), +ObjectContainer::ObjectContainer( const Reference< XMultiServiceFactory >& rxModelFactory, const OUString& rServiceName ) : + mxModelFactory( rxModelFactory ), maServiceName( rServiceName ), mnIndex( 0 ) { - OSL_ENSURE( mxFactory.is(), "ObjectContainer::ObjectContainer - missing service factory" ); + OSL_ENSURE( mxModelFactory.is(), "ObjectContainer::ObjectContainer - missing service factory" ); } ObjectContainer::~ObjectContainer() @@ -94,9 +94,10 @@ OUString ObjectContainer::insertObject( const OUString& rObjName, const Any& rOb void ObjectContainer::createContainer() const { - if( !mxContainer.is() && mxFactory.is() ) try + if( !mxContainer.is() && mxModelFactory.is() ) try { - mxContainer.set( mxFactory->createInstance( maServiceName ), UNO_QUERY_THROW ); + mxContainer.set( mxModelFactory->createInstance( maServiceName ), UNO_QUERY_THROW ); + mxModelFactory.clear(); } catch( Exception& ) { diff --git a/oox/source/helper/propertyset.cxx b/oox/source/helper/propertyset.cxx index 769bd9974fb9..c21b8959e2bc 100644 --- a/oox/source/helper/propertyset.cxx +++ b/oox/source/helper/propertyset.cxx @@ -48,6 +48,26 @@ void PropertySet::set( const Reference< XPropertySet >& rxPropSet ) { mxPropSet = rxPropSet; mxMultiPropSet.set( mxPropSet, UNO_QUERY ); + if( mxPropSet.is() ) try + { + mxPropSetInfo = mxPropSet->getPropertySetInfo(); + } + catch( Exception& ) + { + } +} + +bool PropertySet::hasProperty( sal_Int32 nPropId ) const +{ + if( mxPropSetInfo.is() ) try + { + const OUString& rPropName = PropertyMap::getPropertyName( nPropId ); + return mxPropSetInfo->hasPropertyByName( rPropName ); + } + catch( Exception& ) + { + } + return false; } // Get properties ------------------------------------------------------------- diff --git a/oox/source/helper/textinputstream.cxx b/oox/source/helper/textinputstream.cxx index d590781c6fd3..9087dea7b26f 100644 --- a/oox/source/helper/textinputstream.cxx +++ b/oox/source/helper/textinputstream.cxx @@ -27,102 +27,209 @@ #include "oox/helper/textinputstream.hxx" -#include -#include +#include +#include +#include +#include #include "oox/helper/binaryinputstream.hxx" namespace oox { // ============================================================================ -using ::rtl::OStringBuffer; -using ::rtl::OStringToOUString; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; + using ::rtl::OUString; -using ::rtl::OUStringBuffer; // ============================================================================ namespace { -/** Reads a text line from stream. First, tries to skip the second character of - a two-character line end sequence. Returns the new line-end character. */ -template< typename BufferType, typename CharType, typename StreamDataType > -sal_Unicode lclReadLine( BufferType& orBuffer, BinaryInputStream& rInStrm, sal_Unicode cLastEolChar ) +typedef ::cppu::WeakImplHelper1< XInputStream > UnoBinaryInputStream_BASE; + +/** Implementation of a UNO input stream wrapping a binary input stream. + */ +class UnoBinaryInputStream : public UnoBinaryInputStream_BASE { - // try to skip LF following CR, or CR following LF - if( !rInStrm.isEof() && (cLastEolChar != 0) ) - { - CharType cChar = static_cast< CharType >( rInStrm.readValue< StreamDataType >() ); - // return on EOF after line-end - if( rInStrm.isEof() ) - return 0; - // return on sequence of equal line-end characters - bool bIsEolChar = (cChar == 10) || (cChar == 13); - if( bIsEolChar && (cChar == cLastEolChar) ) - return cChar; - // append the character, if it is not the other line-end charcter - if( !bIsEolChar ) - orBuffer.append( cChar ); - } +public: + explicit UnoBinaryInputStream( BinaryInputStream& rInStrm ); + + virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + virtual sal_Int32 SAL_CALL available() + throw (NotConnectedException, IOException, RuntimeException); + virtual void SAL_CALL closeInput() + throw (NotConnectedException, IOException, RuntimeException); + +private: + void ensureConnected() const throw (NotConnectedException); + +private: + BinaryInputStream* mpInStrm; +}; + +// ---------------------------------------------------------------------------- + +UnoBinaryInputStream::UnoBinaryInputStream( BinaryInputStream& rInStrm ) : + mpInStrm( &rInStrm ) +{ +} - // read chars until EOF or line end character (LF or CR) - while( true ) - { - CharType cChar = static_cast< CharType >( rInStrm.readValue< StreamDataType >() ); - if( rInStrm.isEof() ) - return 0; - if( (cChar == 10) || (cChar == 13) ) - return cChar; - orBuffer.append( cChar ); - } +sal_Int32 SAL_CALL UnoBinaryInputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + ensureConnected(); + return mpInStrm->readData( rData, nBytesToRead, 1 ); +} + +sal_Int32 SAL_CALL UnoBinaryInputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + ensureConnected(); + return mpInStrm->readData( rData, nMaxBytesToRead, 1 ); +} + +void SAL_CALL UnoBinaryInputStream::skipBytes( sal_Int32 nBytesToSkip ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + ensureConnected(); + mpInStrm->skip( nBytesToSkip, 1 ); +} + +sal_Int32 SAL_CALL UnoBinaryInputStream::available() throw (NotConnectedException, IOException, RuntimeException) +{ + ensureConnected(); + throw RuntimeException( CREATE_OUSTRING( "Functionality not supported" ), Reference< XInputStream >() ); +} + +void SAL_CALL UnoBinaryInputStream::closeInput() throw (NotConnectedException, IOException, RuntimeException) +{ + ensureConnected(); + mpInStrm->close(); + mpInStrm = 0; +} + +void UnoBinaryInputStream::ensureConnected() const throw (NotConnectedException) +{ + if( !mpInStrm ) + throw NotConnectedException( CREATE_OUSTRING( "Stream closed" ), Reference< XInterface >() ); } } // namespace // ============================================================================ -TextInputStream::TextInputStream( BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc ) : - mrInStrm( rInStrm ), - meTextEnc( eTextEnc ), - mcLastEolChar( 0 ) +TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) +{ + init( rxContext, rxInStrm, eTextEnc ); +} + +TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc ) +{ + init( rxContext, new UnoBinaryInputStream( rInStrm ), eTextEnc ); +} + +TextInputStream::~TextInputStream() { } bool TextInputStream::isEof() const { - // do not return EOF, if last text line missed line-end character (see below) - return mrInStrm.isEof() && (mcLastEolChar == 0); + if( mxTextStrm.is() ) try + { + return mxTextStrm->isEOF(); + } + catch( Exception& ) + { + } + return true; } OUString TextInputStream::readLine() { - if( mrInStrm.isEof() ) + if( mxTextStrm.is() ) try + { + /* The function createFinalString() adds a character that may have + been buffered in the previous call of readToChar() (see below). */ + return createFinalString( mxTextStrm->readLine() ); + } + catch( Exception& ) { - mcLastEolChar = 0; - return OUString(); + mxTextStrm.clear(); } + return OUString(); +} - OUString aLine; - if( meTextEnc == RTL_TEXTENCODING_UCS2 ) +OUString TextInputStream::readToChar( sal_Unicode cChar, bool bIncludeChar ) +{ + if( mxTextStrm.is() ) try { - // read 16-bit characters for UCS2 encoding - OUStringBuffer aBuffer; - mcLastEolChar = lclReadLine< OUStringBuffer, sal_Unicode, sal_uInt16 >( aBuffer, mrInStrm, mcLastEolChar ); - aLine = aBuffer.makeStringAndClear(); + Sequence< sal_Unicode > aDelimiters( 1 ); + aDelimiters[ 0 ] = cChar; + /* Always get the delimiter character from the UNO text input stream. + In difference to this implementation, it will not return it in the + next call but silently skip it. If caller specifies to exclude the + character in this call, it will be returned in the next call of one + of the own member functions. The function createFinalString() adds + a character that has been buffered in the previous call. */ + OUString aString = createFinalString( mxTextStrm->readString( aDelimiters, sal_False ) ); + // remove last character from string and remember it for next call + if( !bIncludeChar && (aString.getLength() > 0) && (aString[ aString.getLength() - 1 ] == cChar) ) + { + mcPendingChar = cChar; + aString = aString.copy( 0, aString.getLength() - 1 ); + } + return aString; } - else + catch( Exception& ) { - // otherwise, read 8-bit characters and convert according to text encoding - OStringBuffer aBuffer; - mcLastEolChar = lclReadLine< OStringBuffer, sal_Char, sal_uInt8 >( aBuffer, mrInStrm, mcLastEolChar ); - aLine = OStringToOUString( aBuffer.makeStringAndClear(), meTextEnc ); + mxTextStrm.clear(); } + return OUString(); +} - // if last line is not empty but line-end character is missing, do not return EOF - if( mrInStrm.isEof() && (aLine.getLength() > 0) ) - mcLastEolChar = 10; +/*static*/ Reference< XTextInputStream > TextInputStream::createXTextInputStream( + const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) +{ + Reference< XTextInputStream > xTextStrm; + const char* pcCharset = rtl_getMimeCharsetFromTextEncoding( eTextEnc ); + OSL_ENSURE( pcCharset, "TextInputStream::createXTextInputStream - unsupported text encoding" ); + if( rxContext.is() && rxInStrm.is() && pcCharset ) try + { + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XActiveDataSink > xDataSink( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextInputStream" ) ), UNO_QUERY_THROW ); + xDataSink->setInputStream( rxInStrm ); + xTextStrm.set( xDataSink, UNO_QUERY_THROW ); + xTextStrm->setEncoding( OUString::createFromAscii( pcCharset ) ); + } + catch( Exception& ) + { + } + return xTextStrm; +} - return aLine; +// private -------------------------------------------------------------------- + +OUString TextInputStream::createFinalString( const OUString& rString ) +{ + if( mcPendingChar == 0 ) + return rString; + + OUString aString = OUString( mcPendingChar ) + rString; + mcPendingChar = 0; + return aString; +} + +void TextInputStream::init( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc ) +{ + mcPendingChar = 0; + mxTextStrm = createXTextInputStream( rxContext, rxInStrm, eTextEnc ); } // ============================================================================ diff --git a/oox/source/helper/zipstorage.cxx b/oox/source/helper/zipstorage.cxx index 8145e7c4e5ce..fc976d8d7537 100644 --- a/oox/source/helper/zipstorage.cxx +++ b/oox/source/helper/zipstorage.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "oox/helper/helper.hxx" @@ -50,14 +51,12 @@ using ::rtl::OUString; // ============================================================================ -ZipStorage::ZipStorage( - const Reference< XMultiServiceFactory >& rxFactory, - const Reference< XInputStream >& rxInStream ) : +ZipStorage::ZipStorage( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStream ) : StorageBase( rxInStream, false ) { - OSL_ENSURE( rxFactory.is(), "ZipStorage::ZipStorage - missing service factory" ); + OSL_ENSURE( rxContext.is(), "ZipStorage::ZipStorage - missing component context" ); // create base storage object - try + if( rxContext.is() ) try { /* #i105325# ::comphelper::OStorageHelper::GetStorageFromInputStream() cannot be used here as it will open a storage with format type @@ -69,26 +68,26 @@ ZipStorage::ZipStorage( TODO: #i105410# switch to 'OFOPXMLFormat' and use its implementation of relations handling. */ + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( - ZIP_STORAGE_FORMAT_STRING, rxInStream, rxFactory, sal_True ); + ZIP_STORAGE_FORMAT_STRING, rxInStream, xFactory, sal_True ); } catch( Exception& ) { } } -ZipStorage::ZipStorage( - const Reference< XMultiServiceFactory >& rxFactory, - const Reference< XStream >& rxStream ) : +ZipStorage::ZipStorage( const Reference< XComponentContext >& rxContext, const Reference< XStream >& rxStream ) : StorageBase( rxStream, false ) { - OSL_ENSURE( rxFactory.is(), "ZipStorage::ZipStorage - missing service factory" ); + OSL_ENSURE( rxContext.is(), "ZipStorage::ZipStorage - missing component context" ); // create base storage object - try + if( rxContext.is() ) try { - using namespace ::com::sun::star::embed::ElementModes; + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + const sal_Int32 nOpenMode = ElementModes::READWRITE | ElementModes::TRUNCATE; mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( - OFOPXML_STORAGE_FORMAT_STRING, rxStream, READWRITE | TRUNCATE, rxFactory, sal_True ); + OFOPXML_STORAGE_FORMAT_STRING, rxStream, nOpenMode, xFactory, sal_True ); } catch( Exception& ) { diff --git a/oox/source/ole/axbinaryreader.cxx b/oox/source/ole/axbinaryreader.cxx index 493d6b68c6ff..58610e419f32 100644 --- a/oox/source/ole/axbinaryreader.cxx +++ b/oox/source/ole/axbinaryreader.cxx @@ -48,14 +48,22 @@ const sal_uInt32 AX_STRING_COMPRESSED = 0x80000000; // ============================================================================ AxAlignedInputStream::AxAlignedInputStream( BinaryInputStream& rInStrm ) : - mrInStrm( rInStrm ), - mnStrmPos( 0 ) + BinaryStreamBase( false ), + mpInStrm( &rInStrm ), + mnStrmPos( 0 ), + mnStrmSize( rInStrm.getRemaining() ) { + mbEof = mbEof || rInStrm.isEof(); +} + +sal_Int64 AxAlignedInputStream::size() const +{ + return mpInStrm ? mnStrmSize : -1; } sal_Int64 AxAlignedInputStream::tell() const { - return mnStrmPos; + return mpInStrm ? mnStrmPos : -1; } void AxAlignedInputStream::seek( sal_Int64 nPos ) @@ -65,24 +73,44 @@ void AxAlignedInputStream::seek( sal_Int64 nPos ) skip( static_cast< sal_Int32 >( nPos - mnStrmPos ) ); } -sal_Int32 AxAlignedInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +void AxAlignedInputStream::close() +{ + mpInStrm = 0; + mbEof = true; +} + +sal_Int32 AxAlignedInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize ) { - sal_Int32 nReadSize = mrInStrm.readData( orData, nBytes ); - mnStrmPos += nReadSize; + sal_Int32 nReadSize = 0; + if( !mbEof ) + { + nReadSize = mpInStrm->readData( orData, nBytes, nAtomSize ); + mnStrmPos += nReadSize; + mbEof = mpInStrm->isEof(); + } return nReadSize; } -sal_Int32 AxAlignedInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 AxAlignedInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize ) { - sal_Int32 nReadSize = mrInStrm.readMemory( opMem, nBytes ); - mnStrmPos += nReadSize; + sal_Int32 nReadSize = 0; + if( !mbEof ) + { + nReadSize = mpInStrm->readMemory( opMem, nBytes, nAtomSize ); + mnStrmPos += nReadSize; + mbEof = mpInStrm->isEof(); + } return nReadSize; } -void AxAlignedInputStream::skip( sal_Int32 nBytes ) +void AxAlignedInputStream::skip( sal_Int32 nBytes, size_t nAtomSize ) { - mrInStrm.skip( nBytes ); - mnStrmPos += nBytes; + if( !mbEof ) + { + mpInStrm->skip( nBytes, nAtomSize ); + mnStrmPos += nBytes; + mbEof = mpInStrm->isEof(); + } } void AxAlignedInputStream::align( size_t nSize ) @@ -174,10 +202,7 @@ bool lclReadString( AxAlignedInputStream& rInStrm, OUString& rValue, sal_uInt32 OSL_ENSURE( bValidChars, "lclReadString - string too long" ); sal_Int64 nEndPos = rInStrm.tell() + nChars * (bCompressed ? 1 : 2); nChars = ::std::min< sal_Int32 >( nChars, 65536 ); - rValue = bCompressed ? - // ISO-8859-1 maps all byte values xx to the same Unicode code point U+00xx - rInStrm.readCharArrayUC( nChars, RTL_TEXTENCODING_ISO_8859_1 ) : - rInStrm.readUnicodeArray( nChars ); + rValue = rInStrm.readCompressedUnicodeArray( nChars, bCompressed ); rInStrm.seek( nEndPos ); return bValidChars; } diff --git a/oox/source/ole/axcontrol.cxx b/oox/source/ole/axcontrol.cxx index 86cc55df3127..40dfdf1ca84e 100644 --- a/oox/source/ole/axcontrol.cxx +++ b/oox/source/ole/axcontrol.cxx @@ -226,11 +226,11 @@ void lclPrepareConverter( PropertySet& rConverter, const Reference< XModel >& rx { if( !rConverter.is() ) try { - Reference< XMultiServiceFactory > xFactory( rxDocModel, UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xModelFactory( rxDocModel, UNO_QUERY_THROW ); OUString aServiceName = bRange ? CREATE_OUSTRING( "com.sun.star.table.CellRangeAddressConversion" ) : CREATE_OUSTRING( "com.sun.star.table.CellAddressConversion" ); - rConverter.set( xFactory->createInstance( aServiceName ) ); + rConverter.set( xModelFactory->createInstance( aServiceName ) ); } catch( Exception& ) { @@ -344,8 +344,8 @@ void ControlConverter::bindToSources( const Reference< XControlModel >& rxCtrlMo aArgs[ 0 ] <<= aValue; // create the CellValueBinding instance and set at the control model - Reference< XMultiServiceFactory > xFactory( mxDocModel, UNO_QUERY_THROW ); - Reference< XValueBinding > xBinding( xFactory->createInstanceWithArguments( + Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW ); + Reference< XValueBinding > xBinding( xModelFactory->createInstanceWithArguments( CREATE_OUSTRING( "com.sun.star.table.CellValueBinding" ), aArgs ), UNO_QUERY_THROW ); xBindable->setValueBinding( xBinding ); } @@ -376,8 +376,8 @@ void ControlConverter::bindToSources( const Reference< XControlModel >& rxCtrlMo aArgs[ 0 ] <<= aValue; // create the EntrySource instance and set at the control model - Reference< XMultiServiceFactory > xFactory( mxDocModel, UNO_QUERY_THROW ); - Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments( + Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW ); + Reference< XListEntrySource > xEntrySource( xModelFactory->createInstanceWithArguments( CREATE_OUSTRING( "com.sun.star.table.CellRangeListSource" ), aArgs ), UNO_QUERY_THROW ); xEntrySink->setListEntrySource( xEntrySource ); } diff --git a/oox/source/ole/axcontrolfragment.cxx b/oox/source/ole/axcontrolfragment.cxx index f45e8e2590c9..a81ae99f0c11 100644 --- a/oox/source/ole/axcontrolfragment.cxx +++ b/oox/source/ole/axcontrolfragment.cxx @@ -140,7 +140,7 @@ ContextHandlerRef AxControlFragment::onCreateContext( sal_Int32 nElement, const Reference< XInputStream > xStrgStrm = getFilter().openInputStream( aFragmentPath ); if( xStrgStrm.is() ) { - OleStorage aStorage( getFilter().getServiceFactory(), xStrgStrm, false ); + OleStorage aStorage( getFilter().getComponentContext(), xStrgStrm, false ); BinaryXInputStream aInStrm( aStorage.openInputStream( CREATE_OUSTRING( "f" ) ), true ); if( !aInStrm.isEof() ) if( AxContainerModelBase* pModel = dynamic_cast< AxContainerModelBase* >( mrControl.createModelFromGuid( aClassId ) ) ) diff --git a/oox/source/ole/oleobjecthelper.cxx b/oox/source/ole/oleobjecthelper.cxx index 396cd6b53874..5a38d9316a36 100644 --- a/oox/source/ole/oleobjecthelper.cxx +++ b/oox/source/ole/oleobjecthelper.cxx @@ -44,6 +44,7 @@ namespace ole { using namespace ::com::sun::star::awt; using namespace ::com::sun::star::container; +using namespace ::com::sun::star::embed; using namespace ::com::sun::star::io; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::uno; @@ -61,12 +62,17 @@ OleObjectInfo::OleObjectInfo() : // ============================================================================ -OleObjectHelper::OleObjectHelper( const Reference< XMultiServiceFactory >& rxFactory ) : +OleObjectHelper::OleObjectHelper( const Reference< XMultiServiceFactory >& rxModelFactory ) : maEmbeddedObjScheme( CREATE_OUSTRING( "vnd.sun.star.EmbeddedObject:" ) ), mnObjectId( 100 ) { - if( rxFactory.is() ) - mxResolver.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.ImportEmbeddedObjectResolver" ) ), UNO_QUERY ); + if( rxModelFactory.is() ) try + { + mxResolver.set( rxModelFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.ImportEmbeddedObjectResolver" ) ), UNO_QUERY ); + } + catch( Exception& ) + { + } } OleObjectHelper::~OleObjectHelper() @@ -122,11 +128,7 @@ bool OleObjectHelper::importOleObject( PropertyMap& rPropMap, const OleObjectInf if( bRet ) { - // aspect mode - using namespace ::com::sun::star::embed::Aspects; - sal_Int64 nAspect = rOleObject.mbShowAsIcon ? MSOLE_ICON : MSOLE_CONTENT; - rPropMap[ PROP_Aspect ] <<= nAspect; - // visual area + rPropMap[ PROP_Aspect ] <<= (rOleObject.mbShowAsIcon ? Aspects::MSOLE_ICON : Aspects::MSOLE_CONTENT); rPropMap[ PROP_VisualArea ] <<= Rectangle( 0, 0, rObjSize.Width, rObjSize.Height ); } return bRet; diff --git a/oox/source/ole/olestorage.cxx b/oox/source/ole/olestorage.cxx index cf55d6463778..2db4aed76834 100644 --- a/oox/source/ole/olestorage.cxx +++ b/oox/source/ole/olestorage.cxx @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "oox/helper/binaryinputstream.hxx" #include "oox/helper/binaryoutputstream.hxx" @@ -68,7 +69,7 @@ class OleOutputStream : public OleOutputStreamBase { public: explicit OleOutputStream( - const Reference< XMultiServiceFactory >& rxFactory, + const Reference< XComponentContext >& rxContext, const Reference< XNameContainer >& rxStorage, const OUString& rElementName ); virtual ~OleOutputStream(); @@ -95,14 +96,15 @@ private: // ---------------------------------------------------------------------------- -OleOutputStream::OleOutputStream( const Reference< XMultiServiceFactory >& rxFactory, +OleOutputStream::OleOutputStream( const Reference< XComponentContext >& rxContext, const Reference< XNameContainer >& rxStorage, const OUString& rElementName ) : mxStorage( rxStorage ), maElementName( rElementName ) { try { - mxTempFile.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW ); + mxTempFile.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); mxOutStrm = mxTempFile->getOutputStream(); mxSeekable.set( mxOutStrm, UNO_QUERY ); } @@ -179,49 +181,40 @@ void OleOutputStream::ensureConnected() const throw( NotConnectedException ) // ============================================================================ -OleStorage::OleStorage( - const Reference< XMultiServiceFactory >& rxFactory, - const Reference< XInputStream >& rxInStream, - bool bBaseStreamAccess ) : +OleStorage::OleStorage( const Reference< XComponentContext >& rxContext, + const Reference< XInputStream >& rxInStream, bool bBaseStreamAccess ) : StorageBase( rxInStream, bBaseStreamAccess ), - mxFactory( rxFactory ), + mxContext( rxContext ), mpParentStorage( 0 ) { - OSL_ENSURE( mxFactory.is(), "OleStorage::OleStorage - missing service factory" ); + OSL_ENSURE( mxContext.is(), "OleStorage::OleStorage - missing component context" ); initStorage( rxInStream ); } -OleStorage::OleStorage( - const Reference< XMultiServiceFactory >& rxFactory, - const Reference< XStream >& rxOutStream, - bool bBaseStreamAccess ) : +OleStorage::OleStorage( const Reference< XComponentContext >& rxContext, + const Reference< XStream >& rxOutStream, bool bBaseStreamAccess ) : StorageBase( rxOutStream, bBaseStreamAccess ), - mxFactory( rxFactory ), + mxContext( rxContext ), mpParentStorage( 0 ) { - OSL_ENSURE( mxFactory.is(), "OleStorage::OleStorage - missing service factory" ); + OSL_ENSURE( mxContext.is(), "OleStorage::OleStorage - missing component context" ); initStorage( rxOutStream ); } -OleStorage::OleStorage( - const OleStorage& rParentStorage, - const Reference< XNameContainer >& rxStorage, - const OUString& rElementName, - bool bReadOnly ) : +OleStorage::OleStorage( const OleStorage& rParentStorage, + const Reference< XNameContainer >& rxStorage, const OUString& rElementName, bool bReadOnly ) : StorageBase( rParentStorage, rElementName, bReadOnly ), - mxFactory( rParentStorage.mxFactory ), + mxContext( rParentStorage.mxContext ), mxStorage( rxStorage ), mpParentStorage( &rParentStorage ) { OSL_ENSURE( mxStorage.is(), "OleStorage::OleStorage - missing substorage elements" ); } -OleStorage::OleStorage( - const OleStorage& rParentStorage, - const Reference< XStream >& rxOutStream, - const OUString& rElementName ) : +OleStorage::OleStorage( const OleStorage& rParentStorage, + const Reference< XStream >& rxOutStream, const OUString& rElementName ) : StorageBase( rParentStorage, rElementName, false ), - mxFactory( rParentStorage.mxFactory ), + mxContext( rParentStorage.mxContext ), mpParentStorage( &rParentStorage ) { initStorage( rxOutStream ); @@ -239,7 +232,8 @@ void OleStorage::initStorage( const Reference< XInputStream >& rxInStream ) Reference< XInputStream > xInStrm = rxInStream; if( !Reference< XSeekable >( xInStrm, UNO_QUERY ).is() ) try { - Reference< XStream > xTempFile( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); { Reference< XOutputStream > xOutStrm( xTempFile->getOutputStream(), UNO_SET_THROW ); /* Pass false to both binary stream objects to keep the UNO @@ -259,10 +253,11 @@ void OleStorage::initStorage( const Reference< XInputStream >& rxInStream ) // create base storage object if( xInStrm.is() ) try { + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); Sequence< Any > aArgs( 2 ); aArgs[ 0 ] <<= xInStrm; aArgs[ 1 ] <<= true; // true = do not create a copy of the input stream - mxStorage.set( mxFactory->createInstanceWithArguments( + mxStorage.set( xFactory->createInstanceWithArguments( CREATE_OUSTRING( "com.sun.star.embed.OLESimpleStorage" ), aArgs ), UNO_QUERY_THROW ); } catch( Exception& ) @@ -275,10 +270,11 @@ void OleStorage::initStorage( const Reference< XStream >& rxOutStream ) // create base storage object if( rxOutStream.is() ) try { + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); Sequence< Any > aArgs( 2 ); aArgs[ 0 ] <<= rxOutStream; aArgs[ 1 ] <<= true; // true = do not create a copy of the stream - mxStorage.set( mxFactory->createInstanceWithArguments( + mxStorage.set( xFactory->createInstanceWithArguments( CREATE_OUSTRING( "com.sun.star.embed.OLESimpleStorage" ), aArgs ), UNO_QUERY_THROW ); } catch( Exception& ) @@ -347,7 +343,8 @@ StorageRef OleStorage::implOpenSubStorage( const OUString& rElementName, bool bC if( !isReadOnly() && (bCreateMissing || xSubStorage.get()) ) try { // create new storage based on a temp file - Reference< XStream > xTempFile( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); StorageRef xTempStorage( new OleStorage( *this, xTempFile, rElementName ) ); // copy existing substorage into temp storage if( xSubStorage.get() ) @@ -379,7 +376,7 @@ Reference< XOutputStream > OleStorage::implOpenOutputStream( const OUString& rEl { Reference< XOutputStream > xOutStream; if( mxStorage.is() && (rElementName.getLength() > 0) ) - xOutStream.set( new OleOutputStream( mxFactory, mxStorage, rElementName ) ); + xOutStream.set( new OleOutputStream( mxContext, mxStorage, rElementName ) ); return xOutStream; } diff --git a/oox/source/ole/vbacontrol.cxx b/oox/source/ole/vbacontrol.cxx index 39deb77576d9..45a2b9c70ee3 100644 --- a/oox/source/ole/vbacontrol.cxx +++ b/oox/source/ole/vbacontrol.cxx @@ -756,11 +756,11 @@ bool lclEatKeyword( OUString& rCodeLine, const OUString& rKeyword ) VbaUserForm::VbaUserForm( const Reference< XComponentContext >& rxContext, const Reference< XModel >& rxDocModel, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) : - mxCompContext( rxContext ), + mxContext( rxContext ), mxDocModel( rxDocModel ), maConverter( rxDocModel, rGraphicHelper, bDefaultColorBgr ) { - OSL_ENSURE( mxCompContext.is(), "VbaUserForm::VbaUserForm - missing component context" ); + OSL_ENSURE( mxContext.is(), "VbaUserForm::VbaUserForm - missing component context" ); OSL_ENSURE( mxDocModel.is(), "VbaUserForm::VbaUserForm - missing document model" ); } @@ -768,7 +768,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib, StorageBase& rVbaFormStrg, const OUString& rModuleName, rtl_TextEncoding eTextEnc ) { OSL_ENSURE( rxDialogLib.is(), "VbaUserForm::importForm - missing dialog library" ); - if( !mxCompContext.is() || !mxDocModel.is() || !rxDialogLib.is() ) + if( !mxContext.is() || !mxDocModel.is() || !rxDialogLib.is() ) return; // check that the '03VBFrame' stream exists, this is required for forms @@ -778,7 +778,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib, return; // scan for the line 'Begin {GUID} ' - TextInputStream aFrameTextStrm( aInStrm, eTextEnc ); + TextInputStream aFrameTextStrm( mxContext, aInStrm, eTextEnc ); const OUString aBegin = CREATE_OUSTRING( "Begin" ); OUString aLine; bool bBeginFound = false; @@ -826,7 +826,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib, { // create the dialog model OUString aServiceName = mxCtrlModel->getServiceName(); - Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); Reference< XControlModel > xDialogModel( xFactory->createInstance( aServiceName ), UNO_QUERY_THROW ); Reference< XNameContainer > xDialogNC( xDialogModel, UNO_QUERY_THROW ); @@ -834,7 +834,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib, if( convertProperties( xDialogModel, maConverter, 0 ) ) { // export the dialog to XML and insert it into the dialog library - Reference< XInputStreamProvider > xDialogSource( ::xmlscript::exportDialogModel( xDialogNC, mxCompContext ), UNO_SET_THROW ); + Reference< XInputStreamProvider > xDialogSource( ::xmlscript::exportDialogModel( xDialogNC, mxContext ), UNO_SET_THROW ); OSL_ENSURE( !rxDialogLib->hasByName( aFormName ), "VbaUserForm::importForm - multiple dialogs with equal name" ); ContainerHelper::insertByName( rxDialogLib, aFormName, Any( xDialogSource ) ); } diff --git a/oox/source/ole/vbainputstream.cxx b/oox/source/ole/vbainputstream.cxx index e56e8b5fbc89..7e2c88dc480f 100644 --- a/oox/source/ole/vbainputstream.cxx +++ b/oox/source/ole/vbainputstream.cxx @@ -47,17 +47,38 @@ const sal_uInt16 VBACHUNK_LENMASK = 0x0FFF; // ============================================================================ VbaInputStream::VbaInputStream( BinaryInputStream& rInStrm ) : - mrInStrm( rInStrm ), + BinaryStreamBase( false ), + mpInStrm( &rInStrm ), mnChunkPos( 0 ) { maChunk.reserve( 4096 ); - sal_uInt8 nSig = mrInStrm.readuInt8(); + sal_uInt8 nSig = rInStrm.readuInt8(); OSL_ENSURE( nSig == VBASTREAM_SIGNATURE, "VbaInputStream::VbaInputStream - wrong signature" ); - mbEof = nSig != VBASTREAM_SIGNATURE; + mbEof = mbEof || rInStrm.isEof() || (nSig != VBASTREAM_SIGNATURE); } -sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +sal_Int64 VbaInputStream::size() const +{ + return -1; +} + +sal_Int64 VbaInputStream::tell() const +{ + return -1; +} + +void VbaInputStream::seek( sal_Int64 ) +{ +} + +void VbaInputStream::close() +{ + mpInStrm = 0; + mbEof = true; +} + +sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nRet = 0; if( !mbEof ) @@ -65,7 +86,7 @@ sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes orData.realloc( ::std::max< sal_Int32 >( nBytes, 0 ) ); if( nBytes > 0 ) { - nRet = readMemory( orData.getArray(), nBytes ); + nRet = readMemory( orData.getArray(), nBytes, nAtomSize ); if( nRet < nBytes ) orData.realloc( nRet ); } @@ -73,7 +94,7 @@ sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes return nRet; } -sal_Int32 VbaInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 VbaInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t /*nAtomSize*/ ) { sal_Int32 nRet = 0; sal_uInt8* opnMem = reinterpret_cast< sal_uInt8* >( opMem ); @@ -90,7 +111,7 @@ sal_Int32 VbaInputStream::readMemory( void* opMem, sal_Int32 nBytes ) return nRet; } -void VbaInputStream::skip( sal_Int32 nBytes ) +void VbaInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ ) { while( (nBytes > 0) && updateChunk() ) { @@ -108,8 +129,8 @@ bool VbaInputStream::updateChunk() if( mbEof || (mnChunkPos < maChunk.size()) ) return !mbEof; // try to read next chunk header, this may trigger EOF - sal_uInt16 nHeader = mrInStrm.readuInt16(); - mbEof = mrInStrm.isEof(); + sal_uInt16 nHeader = mpInStrm->readuInt16(); + mbEof = mpInStrm->isEof(); if( mbEof ) return false; // check header signature @@ -126,15 +147,15 @@ bool VbaInputStream::updateChunk() maChunk.clear(); sal_uInt8 nBitCount = 4; sal_uInt16 nChunkPos = 0; - while( !mbEof && !mrInStrm.isEof() && (nChunkPos < nChunkLen) ) + while( !mbEof && !mpInStrm->isEof() && (nChunkPos < nChunkLen) ) { - sal_uInt8 nTokenFlags = mrInStrm.readuInt8(); + sal_uInt8 nTokenFlags = mpInStrm->readuInt8(); ++nChunkPos; - for( int nBit = 0; !mbEof && !mrInStrm.isEof() && (nBit < 8) && (nChunkPos < nChunkLen); ++nBit, nTokenFlags >>= 1 ) + for( int nBit = 0; !mbEof && !mpInStrm->isEof() && (nBit < 8) && (nChunkPos < nChunkLen); ++nBit, nTokenFlags >>= 1 ) { if( nTokenFlags & 1 ) { - sal_uInt16 nCopyToken = mrInStrm.readuInt16(); + sal_uInt16 nCopyToken = mpInStrm->readuInt16(); nChunkPos = nChunkPos + 2; // update bit count used for offset/length in the token while( static_cast< size_t >( 1 << nBitCount ) < maChunk.size() ) ++nBitCount; @@ -164,7 +185,7 @@ bool VbaInputStream::updateChunk() else { maChunk.resize( maChunk.size() + 1 ); - mrInStrm >> maChunk.back(); + *mpInStrm >> maChunk.back(); ++nChunkPos; } } @@ -173,7 +194,7 @@ bool VbaInputStream::updateChunk() else { maChunk.resize( nChunkLen ); - mrInStrm.readMemory( &maChunk.front(), nChunkLen ); + mpInStrm->readMemory( &maChunk.front(), nChunkLen ); } mnChunkPos = 0; diff --git a/oox/source/ole/vbamodule.cxx b/oox/source/ole/vbamodule.cxx index 2da92b935004..628c2abb8441 100644 --- a/oox/source/ole/vbamodule.cxx +++ b/oox/source/ole/vbamodule.cxx @@ -54,7 +54,9 @@ using ::rtl::OUStringBuffer; // ============================================================================ -VbaModule::VbaModule( const Reference< XModel >& rxDocModel, const OUString& rName, rtl_TextEncoding eTextEnc, bool bExecutable ) : +VbaModule::VbaModule( const Reference< XComponentContext >& rxContext, const Reference< XModel >& rxDocModel, + const OUString& rName, rtl_TextEncoding eTextEnc, bool bExecutable ) : + mxContext( rxContext ), mxDocModel( rxDocModel ), maName( rName ), meTextEnc( eTextEnc ), @@ -161,7 +163,7 @@ OUString VbaModule::readSourceCode( StorageBase& rVbaStrg ) const // decompression starts at current stream position of aInStrm VbaInputStream aVbaStrm( aInStrm ); // load the source code line-by-line, with some more processing - TextInputStream aVbaTextStrm( aVbaStrm, meTextEnc ); + TextInputStream aVbaTextStrm( mxContext, aVbaStrm, meTextEnc ); while( !aVbaTextStrm.isEof() ) { OUString aCodeLine = aVbaTextStrm.readLine(); diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx index 35e6b7911012..57979f6c72d4 100644 --- a/oox/source/ole/vbaproject.cxx +++ b/oox/source/ole/vbaproject.cxx @@ -155,11 +155,11 @@ void VbaMacroAttacherBase::resolveAndAttachMacro( const Reference< XVBAMacroReso VbaProject::VbaProject( const Reference< XComponentContext >& rxContext, const Reference< XModel >& rxDocModel, const OUString& rConfigCompName ) : VbaFilterConfig( rxContext, rConfigCompName ), - mxCompContext( rxContext ), + mxContext( rxContext ), mxDocModel( rxDocModel ), maPrjName( CREATE_OUSTRING( "Standard" ) ) { - OSL_ENSURE( mxCompContext.is(), "VbaProject::VbaProject - missing component context" ); + OSL_ENSURE( mxContext.is(), "VbaProject::VbaProject - missing component context" ); OSL_ENSURE( mxDocModel.is(), "VbaProject::VbaProject - missing document model" ); mxBasicLib = openLibrary( PROP_BasicLibraries, false ); mxDialogLib = openLibrary( PROP_DialogLibraries, false ); @@ -332,7 +332,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap OSL_ENSURE( aName.getLength() > 0, "VbaProject::importVba - invalid module name" ); OSL_ENSURE( !aModules.has( aName ), "VbaProject::importVba - multiple modules with the same name" ); VbaModuleMap::mapped_type& rxModule = aModules[ aName ]; - rxModule.reset( new VbaModule( mxDocModel, aName, eTextEnc, bExecutable ) ); + rxModule.reset( new VbaModule( mxContext, mxDocModel, aName, eTextEnc, bExecutable ) ); // read all remaining records until the MODULEEND record rxModule->importDirRecords( aDirStrm ); OSL_ENSURE( !aModulesByStrm.has( rxModule->getStreamName() ), "VbaProject::importVba - multiple modules with the same stream name" ); @@ -369,7 +369,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap // do not exit if this stream does not exist, but proceed to load the modules below if( !aPrjStrm.isEof() ) { - TextInputStream aPrjTextStrm( aPrjStrm, eTextEnc ); + TextInputStream aPrjTextStrm( mxContext, aPrjStrm, eTextEnc ); OUString aKey, aValue; bool bExitLoop = false; while( !bExitLoop && !aPrjTextStrm.isEof() ) @@ -413,7 +413,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap { OSL_ENSURE( !aModules.has( aIt->first ) && !aDummyModules.has( aIt->first ), "VbaProject::importVba - multiple modules with the same name" ); VbaModuleMap::mapped_type& rxModule = aDummyModules[ aIt->first ]; - rxModule.reset( new VbaModule( mxDocModel, aIt->first, eTextEnc, bExecutable ) ); + rxModule.reset( new VbaModule( mxContext, mxDocModel, aIt->first, eTextEnc, bExecutable ) ); rxModule->setType( aIt->second ); } @@ -489,7 +489,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap // create and import the form Reference< XNameContainer > xDialogLib( createDialogLibrary(), UNO_SET_THROW ); - VbaUserForm aForm( mxCompContext, mxDocModel, rGraphicHelper, bDefaultColorBgr ); + VbaUserForm aForm( mxContext, mxDocModel, rGraphicHelper, bDefaultColorBgr ); aForm.importForm( xDialogLib, *xSubStrg, aModuleName, eTextEnc ); } catch( Exception& ) @@ -506,14 +506,14 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap void VbaProject::attachMacros() { - if( !maMacroAttachers.empty() && mxCompContext.is() ) try + if( !maMacroAttachers.empty() && mxContext.is() ) try { - Reference< XMultiComponentFactory > xFactory( mxCompContext->getServiceManager(), UNO_SET_THROW ); + Reference< XMultiComponentFactory > xFactory( mxContext->getServiceManager(), UNO_SET_THROW ); Sequence< Any > aArgs( 2 ); aArgs[ 0 ] <<= mxDocModel; aArgs[ 1 ] <<= maPrjName; Reference< XVBAMacroResolver > xResolver( xFactory->createInstanceWithArgumentsAndContext( - CREATE_OUSTRING( "com.sun.star.script.vba.VBAMacroResolver" ), aArgs, mxCompContext ), UNO_QUERY_THROW ); + CREATE_OUSTRING( "com.sun.star.script.vba.VBAMacroResolver" ), aArgs, mxContext ), UNO_QUERY_THROW ); maMacroAttachers.forEachMem( &VbaMacroAttacherBase::resolveAndAttachMacro, ::boost::cref( xResolver ) ); } catch( Exception& ) @@ -523,15 +523,14 @@ void VbaProject::attachMacros() void VbaProject::copyStorage( StorageBase& rVbaPrjStrg ) { - if( mxCompContext.is() ) try + if( mxContext.is() ) try { - Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW ); Reference< XStorageBasedDocument > xStorageBasedDoc( mxDocModel, UNO_QUERY_THROW ); Reference< XStorage > xDocStorage( xStorageBasedDoc->getDocumentStorage(), UNO_QUERY_THROW ); { - using namespace ::com::sun::star::embed::ElementModes; - Reference< XStream > xDocStream( xDocStorage->openStreamElement( CREATE_OUSTRING( "_MS_VBA_Macros" ), SEEKABLE | WRITE | TRUNCATE ), UNO_SET_THROW ); - OleStorage aDestStorage( xFactory, xDocStream, false ); + const sal_Int32 nOpenMode = ElementModes::SEEKABLE | ElementModes::WRITE | ElementModes::TRUNCATE; + Reference< XStream > xDocStream( xDocStorage->openStreamElement( CREATE_OUSTRING( "_MS_VBA_Macros" ), nOpenMode ), UNO_SET_THROW ); + OleStorage aDestStorage( mxContext, xDocStream, false ); rVbaPrjStrg.copyStorageToStorage( aDestStorage ); aDestStorage.commit(); } diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx index ccf0fe567235..44eb8106ee8e 100644 --- a/oox/source/vml/vmldrawing.cxx +++ b/oox/source/vml/vmldrawing.cxx @@ -214,8 +214,8 @@ Reference< XShape > Drawing::createAndInsertXShape( const OUString& rService, Reference< XShape > xShape; if( (rService.getLength() > 0) && rxShapes.is() ) try { - Reference< XMultiServiceFactory > xFactory( mrFilter.getModelFactory(), UNO_SET_THROW ); - xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xModelFactory( mrFilter.getModelFactory(), UNO_SET_THROW ); + xShape.set( xModelFactory->createInstance( rService ), UNO_QUERY_THROW ); // insert shape into passed shape collection (maybe drawpage or group shape) rxShapes->add( xShape ); xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx index dc5c82515691..591e85482448 100644 --- a/oox/source/vml/vmldrawingfragment.cxx +++ b/oox/source/vml/vmldrawingfragment.cxx @@ -27,6 +27,7 @@ #include "oox/vml/vmldrawingfragment.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "oox/vml/vmldrawing.hxx" #include "oox/vml/vmlinputstream.hxx" #include "oox/vml/vmlshapecontext.hxx" @@ -53,7 +54,7 @@ DrawingFragment::DrawingFragment( XmlFilterBase& rFilter, const OUString& rFragm Reference< XInputStream > DrawingFragment::openFragmentStream() const { // #i104719# create an input stream that preprocesses the VML data - return new InputStream( FragmentHandler2::openFragmentStream() ); + return new InputStream( getFilter().getComponentContext(), FragmentHandler2::openFragmentStream() ); } ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) diff --git a/oox/source/vml/vmlinputstream.cxx b/oox/source/vml/vmlinputstream.cxx index fb2443aba4c4..ef2f408d79b0 100644 --- a/oox/source/vml/vmlinputstream.cxx +++ b/oox/source/vml/vmlinputstream.cxx @@ -27,10 +27,12 @@ #include "oox/vml/vmlinputstream.hxx" +#include #include -#include +#include #include #include "oox/helper/helper.hxx" +#include "oox/helper/textinputstream.hxx" namespace oox { namespace vml { @@ -55,7 +57,7 @@ inline const sal_Char* lclFindCharacter( const sal_Char* pcBeg, const sal_Char* inline bool lclIsWhiteSpace( sal_Char cChar ) { - return (cChar == ' ') || (cChar == '\t') || (cChar == '\n') || (cChar == '\r'); + return cChar < 32; } const sal_Char* lclFindWhiteSpace( const sal_Char* pcBeg, const sal_Char* pcEnd ) @@ -151,14 +153,78 @@ void lclProcessAttribs( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal lclAppendToBuffer( rBuffer, pcBeg, pcEnd ); } -void lclProcessContents( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal_Char* pcEnd ) +void lclProcessElement( OStringBuffer& rBuffer, const OString& rElement ) +{ + // check that passed string starts and ends with the brackets of an XML element + sal_Int32 nElementLen = rElement.getLength(); + if( nElementLen == 0 ) + return; + + const sal_Char* pcOpen = rElement.getStr(); + const sal_Char* pcClose = pcOpen + nElementLen - 1; + + // no complete element found + if( (pcOpen >= pcClose) || (*pcOpen != '<') || (*pcClose != '>') ) + { + // just append all passed characters + rBuffer.append( rElement ); + } + + // skip parser instructions: '' + else if( (nElementLen >= 5) && (pcOpen[ 1 ] == '!') && (pcOpen[ 2 ] == '[') && (pcClose[ -1 ] == ']') ) + { + // do nothing + } + + // replace '
' element with newline + else if( (nElementLen >= 4) && (pcOpen[ 1 ] == 'b') && (pcOpen[ 2 ] == 'r') && (lclFindNonWhiteSpace( pcOpen + 3, pcClose ) == pcClose) ) + { + rBuffer.append( '\n' ); + } + + // check start elements and simple elements for repeated attributes + else if( pcOpen[ 1 ] != '/' ) + { + // find positions of text content inside brackets, exclude '/' in '' + const sal_Char* pcContentBeg = pcOpen + 1; + bool bIsEmptyElement = pcClose[ -1 ] == '/'; + const sal_Char* pcContentEnd = bIsEmptyElement ? (pcClose - 1) : pcClose; + // append opening bracket and element name to buffer + const sal_Char* pcWhiteSpace = lclFindWhiteSpace( pcContentBeg, pcContentEnd ); + lclAppendToBuffer( rBuffer, pcOpen, pcWhiteSpace ); + // find begin of attributes, and process all attributes + const sal_Char* pcAttribBeg = lclFindNonWhiteSpace( pcWhiteSpace, pcContentEnd ); + if( pcAttribBeg < pcContentEnd ) + lclProcessAttribs( rBuffer, pcAttribBeg, pcContentEnd ); + // close the element + if( bIsEmptyElement ) + rBuffer.append( '/' ); + rBuffer.append( '>' ); + } + + // append end elements without further processing + else + { + rBuffer.append( rElement ); + } +} + +bool lclProcessCharacters( OStringBuffer& rBuffer, const OString& rChars ) { /* MSO has a very weird way to store and handle whitespaces. The stream may contain lots of spaces, tabs, and newlines which have to be handled as single space character. This will be done in this function. If the element text contains a literal line break, it will be stored as -
tag (without matching closing
element). +
tag (without matching
element). This input stream wrapper + will replace this element with a literal LF character (see below). + + A single space character for its own is stored as is. Example: The + element + + represents a single space character. The XML parser will ignore this + space character completely without issuing a 'characters' event. The + VML import filter implementation has to react on this case manually. A single space character following another character is stored literally and must not be stipped away here. Example: The element @@ -167,20 +233,23 @@ void lclProcessContents( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sa Consecutive space characters, or a leading single space character, are stored in a element. If there are N space characters (N > 1), - then the element contains exactly (N-1) NBSP characters - (non-breaking space), followed by a regular space character. Example: + then the element contains exactly (N-1) NBSP (non-breaking + space) characters, followed by a regular space character. Examples: The element \xA0\xA0\xA0 represents 4 consecutive space characters. Has to be handled by the - implementation. - - A single space character for its own is stored in an empty element. - Example: The element - - represents a single space character. Has to be handled by the - implementation. + implementation. The element + abc + represents a space characters followed by the letters a, b, c. These + strings have to be handled by the VML import filter implementation. */ + // passed string ends with the leading opening bracket of an XML element + const sal_Char* pcBeg = rChars.getStr(); + const sal_Char* pcEnd = pcBeg + rChars.getLength(); + bool bHasBracket = (pcBeg < pcEnd) && (pcEnd[ -1 ] == '<'); + if( bHasBracket ) --pcEnd; + // skip leading whitespace const sal_Char* pcContentsBeg = lclFindNonWhiteSpace( pcBeg, pcEnd ); while( pcContentsBeg < pcEnd ) @@ -191,132 +260,139 @@ void lclProcessContents( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sa rBuffer.append( ' ' ); pcContentsBeg = lclFindNonWhiteSpace( pcWhitespaceBeg, pcEnd ); } + + return bHasBracket; } } // namespace // ============================================================================ -StreamDataContainer::StreamDataContainer( const Reference< XInputStream >& rxInStrm ) +InputStream::InputStream( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm ) : + // use single-byte ISO-8859-1 encoding which maps all byte characters to the first 256 Unicode characters + mxTextStrm( TextInputStream::createXTextInputStream( rxContext, rxInStrm, RTL_TEXTENCODING_ISO_8859_1 ) ), + maOpeningBracket( 1 ), + maClosingBracket( 1 ), + maOpeningCData( CREATE_OSTRING( "" ) ), + mnBufferPos( 0 ) { - if( rxInStrm.is() ) try + maOpeningBracket[ 0 ] = '<'; + maClosingBracket[ 0 ] = '>'; +} + +InputStream::~InputStream() +{ +} + +sal_Int32 SAL_CALL InputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + if( nBytesToRead < 0 ) + throw IOException(); + + rData.realloc( nBytesToRead ); + sal_Int8* pcDest = rData.getArray(); + sal_Int32 nRet = 0; + while( (nBytesToRead > 0) && !mxTextStrm->isEOF() ) { - // read all bytes we can read - rxInStrm->readBytes( maDataSeq, SAL_MAX_INT32 ); + updateBuffer(); + sal_Int32 nReadSize = ::std::min( nBytesToRead, maBuffer.getLength() - mnBufferPos ); + if( nReadSize > 0 ) + { + memcpy( pcDest + nRet, maBuffer.getStr() + mnBufferPos, static_cast< size_t >( nReadSize ) ); + mnBufferPos += nReadSize; + nBytesToRead -= nReadSize; + nRet += nReadSize; + } } - catch( Exception& ) + if( nRet < rData.getLength() ) + rData.realloc( nRet ); + return nRet; +} + +sal_Int32 SAL_CALL InputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + return readBytes( rData, nMaxBytesToRead ); +} + +void SAL_CALL InputStream::skipBytes( sal_Int32 nBytesToSkip ) + throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + if( nBytesToSkip < 0 ) + throw IOException(); + + while( (nBytesToSkip > 0) && !mxTextStrm->isEOF() ) { + updateBuffer(); + sal_Int32 nSkipSize = ::std::min( nBytesToSkip, maBuffer.getLength() - mnBufferPos ); + mnBufferPos += nSkipSize; + nBytesToSkip -= nSkipSize; } +} - if( maDataSeq.hasElements() ) - { - const OString aCDataOpen = CREATE_OSTRING( "" ); +sal_Int32 SAL_CALL InputStream::available() throw (NotConnectedException, IOException, RuntimeException) +{ + updateBuffer(); + return maBuffer.getLength() - mnBufferPos; +} - OStringBuffer aBuffer; - aBuffer.ensureCapacity( maDataSeq.getLength() + 256 ); - const sal_Char* pcCurr = reinterpret_cast< const sal_Char* >( maDataSeq.getConstArray() ); - const sal_Char* pcEnd = pcCurr + maDataSeq.getLength(); - while( pcCurr < pcEnd ) - { - // look for the next opening angle bracket - const sal_Char* pcOpen = lclFindCharacter( pcCurr, pcEnd, '<' ); +void SAL_CALL InputStream::closeInput() throw (NotConnectedException, IOException, RuntimeException) +{ + mxTextStrm->closeInput(); +} - // copy all characters from current position to opening bracket - lclProcessContents( aBuffer, pcCurr, pcOpen ); +// private -------------------------------------------------------------------- - // nothing to do if no opening bracket has been found - if( pcOpen < pcEnd ) - { - // string length from opening bracket to end - sal_Int32 nLengthToEnd = static_cast< sal_Int32 >( pcEnd - pcOpen ); +void InputStream::updateBuffer() throw (IOException, RuntimeException) +{ + while( (mnBufferPos >= maBuffer.getLength()) && !mxTextStrm->isEOF() ) + { + // collect new contents in a string buffer + OStringBuffer aBuffer; - // check for CDATA part, starting with '' - sal_Int32 nClosePos = rtl_str_indexOfStr_WithLength( pcOpen, nLengthToEnd, aCDataClose.getStr(), aCDataClose.getLength() ); - pcCurr = (nClosePos < 0) ? pcEnd : (pcOpen + nClosePos + aCDataClose.getLength()); - // copy the entire CDATA part - lclAppendToBuffer( aBuffer, pcOpen, pcCurr ); - } + // read and process characters until the opening bracket of the next XML element + OString aChars = readToElementBegin(); + bool bHasOpeningBracket = lclProcessCharacters( aBuffer, aChars ); - // no CDATA part - process the element starting at pcOpen - else - { - // look for the next closing angle bracket - const sal_Char* pcClose = lclFindCharacter( pcOpen + 1, pcEnd, '>' ); - // complete element found? - if( pcClose < pcEnd ) - { - // continue after closing bracket - pcCurr = pcClose + 1; - // length of entire element with angle brackets - sal_Int32 nElementLen = static_cast< sal_Int32 >( pcCurr - pcOpen ); - - // skip parser instructions: '' - if( (nElementLen >= 5) && (pcOpen[ 1 ] == '!') && (pcOpen[ 2 ] == '[') && (pcClose[ -1 ] == ']') ) - { - // do nothing - } - - // replace '
' element with newline - else if( (nElementLen >= 4) && (pcOpen[ 1 ] == 'b') && (pcOpen[ 2 ] == 'r') && (lclFindNonWhiteSpace( pcOpen + 3, pcClose ) == pcClose) ) - { - aBuffer.append( '\n' ); - } - - // check start elements and empty elements for repeated attributes - else if( pcOpen[ 1 ] != '/' ) - { - // find positions of text content inside brackets, exclude '/' in '' - const sal_Char* pcContentBeg = pcOpen + 1; - bool bIsEmptyElement = pcClose[ -1 ] == '/'; - const sal_Char* pcContentEnd = bIsEmptyElement ? (pcClose - 1) : pcClose; - // append element name to buffer - const sal_Char* pcWhiteSpace = lclFindWhiteSpace( pcContentBeg, pcContentEnd ); - lclAppendToBuffer( aBuffer, pcOpen, pcWhiteSpace ); - // find begin of attributes, and process all attributes - const sal_Char* pcAttribBeg = lclFindNonWhiteSpace( pcWhiteSpace, pcContentEnd ); - if( pcAttribBeg < pcContentEnd ) - lclProcessAttribs( aBuffer, pcAttribBeg, pcContentEnd ); - // close the element - if( bIsEmptyElement ) - aBuffer.append( '/' ); - aBuffer.append( '>' ); - } - - // append end elements without further processing - else - { - lclAppendToBuffer( aBuffer, pcOpen, pcCurr ); - } - } - else - { - // no complete element found, copy all from opening bracket to end - lclAppendToBuffer( aBuffer, pcOpen, pcEnd ); - pcCurr = pcEnd; - } - } + // read and process characters until (and including) closing bracket (an XML element) + OSL_ENSURE( bHasOpeningBracket || mxTextStrm->isEOF(), "InputStream::updateBuffer - missing opening bracket of XML element" ); + if( bHasOpeningBracket && !mxTextStrm->isEOF() ) + { + // read the element text (add the leading opening bracket manually) + OString aElement = OString( '<' ) + readToElementEnd(); + // check for CDATA part, starting with '' + while( ((aElement.getLength() < maClosingCData.getLength()) || !aElement.match( maClosingCData, aElement.getLength() - maClosingCData.getLength() )) && !mxTextStrm->isEOF() ) + aElement += readToElementEnd(); + // copy the entire CDATA part + aBuffer.append( aElement ); + } + else + { + // no CDATA part - process the contents of the element + lclProcessElement( aBuffer, aElement ); } } - // set the final data sequence - maDataSeq = ::comphelper::ByteSequence( reinterpret_cast< const sal_Int8* >( aBuffer.getStr() ), aBuffer.getLength() ); + maBuffer = aBuffer.makeStringAndClear(); + mnBufferPos = 0; } } -// ============================================================================ - -InputStream::InputStream( const Reference< XInputStream >& rxInStrm ) : - StreamDataContainer( rxInStrm ), - ::comphelper::SequenceInputStream( maDataSeq ) +OString InputStream::readToElementBegin() throw (IOException, RuntimeException) { + return OUStringToOString( mxTextStrm->readString( maOpeningBracket, sal_False ), RTL_TEXTENCODING_ISO_8859_1 ); } -InputStream::~InputStream() +OString InputStream::readToElementEnd() throw (IOException, RuntimeException) { + OString aText = OUStringToOString( mxTextStrm->readString( maClosingBracket, sal_False ), RTL_TEXTENCODING_ISO_8859_1 ); + OSL_ENSURE( (aText.getLength() > 0) && (aText[ aText.getLength() - 1 ] == '>'), "InputStream::readToElementEnd - missing closing bracket of XML element" ); + return aText; } // ============================================================================ diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index d266e054691f..5e1a9a8d3e1d 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -274,9 +274,10 @@ Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxS xShape = implConvertAndInsert( rxShapes, aShapeRect ); if( xShape.is() ) { - // set shape name (imported or generated) + // set imported or generated shape name (not supported by form controls) PropertySet aShapeProp( xShape ); - aShapeProp.setProperty( PROP_Name, getShapeName() ); + if( aShapeProp.hasProperty( PROP_Name ) ) + aShapeProp.setProperty( PROP_Name, getShapeName() ); /* Notify the drawing that a new shape has been inserted. For convenience, pass the rectangle that contains position and diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx index 4b57656b4f78..6feae68127e7 100755 --- a/oox/source/vml/vmltextboxcontext.cxx +++ b/oox/source/vml/vmltextboxcontext.cxx @@ -75,6 +75,8 @@ TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent, OSL_ENSURE( !maFont.mobStrikeout, "TextPortionContext::TextPortionContext - nested elements" ); maFont.mobStrikeout = true; break; + case XML_span: + break; default: OSL_ENSURE( false, "TextPortionContext::TextPortionContext - unknown element" ); } @@ -92,7 +94,7 @@ void TextPortionContext::onCharacters( const OUString& rChars ) { case XML_span: // replace all NBSP characters with SP - mrTextBox.appendPortion( maFont, rChars.replace( 160, ' ' ) ); + mrTextBox.appendPortion( maFont, rChars.replace( 0xA0, ' ' ) ); break; default: mrTextBox.appendPortion( maFont, rChars ); @@ -101,19 +103,23 @@ void TextPortionContext::onCharacters( const OUString& rChars ) void TextPortionContext::onEndElement() { - /* An empty child element without own child elements represents a single - space character, for example: + /* A child element without own child elements may contain a single space + character, for example: - - abc - - def - +
+ abc + + def +
represents the italic text 'abc', an unformatted space character, and - the bold text 'def'. + the bold text 'def'. Unfortunately, the XML parser skips the space + character without issuing a 'characters' event. The class member + 'mnInitialPortions' contains the number of text portions existing when + this context has been constructed. If no text has been added in the + meantime, the space character has to be added manually. */ - if( (mnInitialPortions > 0) && (mrTextBox.getPortionCount() == mnInitialPortions) ) + if( mrTextBox.getPortionCount() == mnInitialPortions ) mrTextBox.appendPortion( maFont, OUString( sal_Unicode( ' ' ) ) ); } @@ -143,4 +149,3 @@ ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const Att } // namespace vml } // namespace oox - diff --git a/oox/source/xls/addressconverter.cxx b/oox/source/xls/addressconverter.cxx index 6d53be0c155b..ca216bb8a84f 100644 --- a/oox/source/xls/addressconverter.cxx +++ b/oox/source/xls/addressconverter.cxx @@ -98,12 +98,12 @@ const sal_Unicode BIFF_DCON_ENCODED = '\x01'; /// First character of an en const sal_Unicode BIFF_DCON_INTERN = '\x02'; /// First character of an encoded sheet name from DCON* records. -inline sal_uInt16 lclGetBiffAddressSize( bool bCol16Bit, bool bRow32Bit ) +inline sal_uInt8 lclGetBiffAddressSize( bool bCol16Bit, bool bRow32Bit ) { return (bCol16Bit ? 2 : 1) + (bRow32Bit ? 4 : 2); } -inline sal_uInt16 lclGetBiffRangeSize( bool bCol16Bit, bool bRow32Bit ) +inline sal_uInt8 lclGetBiffRangeSize( bool bCol16Bit, bool bRow32Bit ) { return 2 * lclGetBiffAddressSize( bCol16Bit, bRow32Bit ); } diff --git a/oox/source/xls/biffdetector.cxx b/oox/source/xls/biffdetector.cxx index 038d7d732425..9c8267f8d84d 100644 --- a/oox/source/xls/biffdetector.cxx +++ b/oox/source/xls/biffdetector.cxx @@ -82,14 +82,14 @@ BiffDetector::~BiffDetector() /*static*/ BiffType BiffDetector::detectStreamBiffVersion( BinaryInputStream& rInStream ) { BiffType eBiff = BIFF_UNKNOWN; - if( !rInStream.isEof() && rInStream.isSeekable() && (rInStream.getLength() > 4) ) + if( !rInStream.isEof() && rInStream.isSeekable() && (rInStream.size() > 4) ) { sal_Int64 nOldPos = rInStream.tell(); rInStream.seekToStart(); sal_uInt16 nBofId, nBofSize; rInStream >> nBofId >> nBofSize; - if( (4 <= nBofSize) && (nBofSize <= 16) && (rInStream.tell() + nBofSize <= rInStream.getLength()) ) + if( (4 <= nBofSize) && (nBofSize <= 16) && (rInStream.tell() + nBofSize <= rInStream.size()) ) { switch( nBofId ) { @@ -207,9 +207,8 @@ OUString SAL_CALL BiffDetector::detect( Sequence< PropertyValue >& rDescriptor ) MediaDescriptor aDescriptor( rDescriptor ); aDescriptor.addInputStream(); - Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); Reference< XInputStream > xInStrm( aDescriptor[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY_THROW ); - StorageRef xStorage( new ::oox::ole::OleStorage( xFactory, xInStrm, true ) ); + StorageRef xStorage( new ::oox::ole::OleStorage( mxContext, xInStrm, true ) ); OUString aWorkbookName; switch( detectStorageBiffVersion( aWorkbookName, xStorage ) ) diff --git a/oox/source/xls/biffhelper.cxx b/oox/source/xls/biffhelper.cxx index 55839043865e..b4a3a982b50c 100644 --- a/oox/source/xls/biffhelper.cxx +++ b/oox/source/xls/biffhelper.cxx @@ -269,7 +269,7 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, // BIFF12 import -------------------------------------------------------------- -/*static*/ OUString BiffHelper::readString( SequenceInputStream& rStrm, bool b32BitLen ) +/*static*/ OUString BiffHelper::readString( SequenceInputStream& rStrm, bool b32BitLen, bool bAllowNulChars ) { OUString aString; if( !rStrm.isEof() ) @@ -279,16 +279,9 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, OSL_ENSURE( !rStrm.isEof() && (nCharCount >= -1), "BiffHelper::readString - invalid string length" ); if( !rStrm.isEof() && (nCharCount > 0) ) { - ::std::vector< sal_Unicode > aBuffer; - aBuffer.reserve( getLimitedValue< size_t, sal_Int32 >( nCharCount + 1, 0, 0xFFFF ) ); - for( sal_Int32 nCharIdx = 0; !rStrm.isEof() && (nCharIdx < nCharCount); ++nCharIdx ) - { - sal_uInt16 nChar; - rStrm.readValue( nChar ); - aBuffer.push_back( static_cast< sal_Unicode >( nChar ) ); - } - aBuffer.push_back( 0 ); - aString = OUString( &aBuffer.front() ); + // SequenceInputStream always supports getRemaining() + nCharCount = ::std::min( nCharCount, static_cast< sal_Int32 >( rStrm.getRemaining() / 2 ) ); + aString = rStrm.readUnicodeArray( nCharCount, bAllowNulChars ); } } return aString; diff --git a/oox/source/xls/biffinputstream.cxx b/oox/source/xls/biffinputstream.cxx index 6dfa8f755c25..b11137aab6b9 100644 --- a/oox/source/xls/biffinputstream.cxx +++ b/oox/source/xls/biffinputstream.cxx @@ -87,7 +87,7 @@ void BiffInputRecordBuffer::enableDecoder( bool bEnable ) bool BiffInputRecordBuffer::startRecord( sal_Int64 nHeaderPos ) { - mbValidHeader = (0 <= nHeaderPos) && (nHeaderPos + 4 <= mrInStrm.getLength()); + mbValidHeader = (0 <= nHeaderPos) && (nHeaderPos + 4 <= mrInStrm.size()); if( mbValidHeader ) { mnHeaderPos = nHeaderPos; @@ -95,7 +95,7 @@ bool BiffInputRecordBuffer::startRecord( sal_Int64 nHeaderPos ) mrInStrm >> mnRecId >> mnRecSize; mnBodyPos = mrInStrm.tell(); mnNextHeaderPos = mnBodyPos + mnRecSize; - mbValidHeader = !mrInStrm.isEof() && (mnNextHeaderPos <= mrInStrm.getLength()); + mbValidHeader = !mrInStrm.isEof() && (mnNextHeaderPos <= mrInStrm.size()); } if( !mbValidHeader ) { @@ -116,7 +116,7 @@ bool BiffInputRecordBuffer::startNextRecord() sal_uInt16 BiffInputRecordBuffer::getNextRecId() { sal_uInt16 nRecId = BIFF_ID_UNKNOWN; - if( mbValidHeader && (mnNextHeaderPos + 4 <= mrInStrm.getLength()) ) + if( mbValidHeader && (mnNextHeaderPos + 4 <= mrInStrm.size()) ) { mrInStrm.seek( mnNextHeaderPos ); mrInStrm >> nRecId; @@ -169,6 +169,7 @@ void BiffInputRecordBuffer::updateDecoded() // ============================================================================ BiffInputStream::BiffInputStream( BinaryInputStream& rInStream, bool bContLookup ) : + BinaryStreamBase( true ), maRecBuffer( rInStream ), mnRecHandle( -1 ), mnRecId( BIFF_ID_UNKNOWN ), @@ -257,9 +258,11 @@ sal_uInt16 BiffInputStream::getNextRecId() // BinaryStreamBase interface (seeking) --------------------------------------- -bool BiffInputStream::isSeekable() const +sal_Int64 BiffInputStream::size() const { - return true; + if( !mbHasComplRec ) + const_cast< BiffInputStream* >( this )->calcRecordLength(); + return mnComplRecSize; } sal_Int64 BiffInputStream::tell() const @@ -267,13 +270,6 @@ sal_Int64 BiffInputStream::tell() const return mbEof ? -1 : (mnCurrRecSize - maRecBuffer.getRecLeft()); } -sal_Int64 BiffInputStream::getLength() const -{ - if( !mbHasComplRec ) - const_cast< BiffInputStream* >( this )->calcRecordLength(); - return mnComplRecSize; -} - void BiffInputStream::seek( sal_Int64 nRecPos ) { if( isInRecord() ) @@ -285,35 +281,35 @@ void BiffInputStream::seek( sal_Int64 nRecPos ) } } +void BiffInputStream::close() +{ +} + sal_Int64 BiffInputStream::tellBase() const { return maRecBuffer.getBaseStream().tell(); } -sal_Int64 BiffInputStream::getBaseLength() const +sal_Int64 BiffInputStream::sizeBase() const { - return maRecBuffer.getBaseStream().getLength(); + return maRecBuffer.getBaseStream().size(); } // BinaryInputStream interface (stream read access) --------------------------- -sal_Int32 BiffInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes ) +sal_Int32 BiffInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nRet = 0; if( !mbEof ) { orData.realloc( ::std::max< sal_Int32 >( nBytes, 0 ) ); if( nBytes > 0 ) - { - nRet = readMemory( orData.getArray(), nBytes ); - if( nRet < nBytes ) - orData.realloc( nRet ); - } + nRet = readMemory( orData.getArray(), nBytes, nAtomSize ); } return nRet; } -sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes ) +sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nRet = 0; if( !mbEof && opMem && (nBytes > 0) ) @@ -323,7 +319,7 @@ sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes ) while( !mbEof && (nBytesLeft > 0) ) { - sal_uInt16 nReadSize = getMaxRawReadSize( nBytesLeft ); + sal_uInt16 nReadSize = getMaxRawReadSize( nBytesLeft, nAtomSize ); // check nReadSize, stream may already be located at end of a raw record if( nReadSize > 0 ) { @@ -340,12 +336,12 @@ sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes ) return nRet; } -void BiffInputStream::skip( sal_Int32 nBytes ) +void BiffInputStream::skip( sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nBytesLeft = nBytes; while( !mbEof && (nBytesLeft > 0) ) { - sal_uInt16 nSkipSize = getMaxRawReadSize( nBytesLeft ); + sal_uInt16 nSkipSize = getMaxRawReadSize( nBytesLeft, nAtomSize ); // check nSkipSize, stream may already be located at end of a raw record if( nSkipSize > 0 ) { @@ -383,28 +379,22 @@ OUString BiffInputStream::readUniStringChars( sal_uInt16 nChars, bool b16BitChar OUStringBuffer aBuffer; aBuffer.ensureCapacity( nChars ); - /* This function has to react on CONTINUE records to read the repeated - flags field, so readUnicodeArray() cannot be used here. */ - sal_uInt16 nCharsLeft = nChars; + /* This function has to react on CONTINUE records which repeat the flags + field in their first byte and may change the 8bit/16bit character mode, + thus a plain call to readCompressedUnicodeArray() cannot be used here. */ + sal_Int32 nCharsLeft = nChars; while( !mbEof && (nCharsLeft > 0) ) { - sal_uInt16 nPortionCount = 0; - if( b16BitChars ) - { - nPortionCount = ::std::min< sal_uInt16 >( nCharsLeft, maRecBuffer.getRecLeft() / 2 ); - OSL_ENSURE( (nPortionCount <= nCharsLeft) || ((maRecBuffer.getRecLeft() & 1) == 0), - "BiffInputStream::readUniStringChars - missing a byte" ); - } - else - { - nPortionCount = getMaxRawReadSize( nCharsLeft ); - } - - // read the character array - appendUnicodeArray( aBuffer, nPortionCount, b16BitChars, bAllowNulChars ); - - // prepare for next CONTINUE record - nCharsLeft = nCharsLeft - nPortionCount; + /* Read the character array from the remaining part of the current raw + record. First, calculate the maximum number of characters that can + be read without triggering to start a following CONTINUE record. */ + sal_Int32 nRawChars = b16BitChars ? (getMaxRawReadSize( nCharsLeft * 2, 2 ) / 2) : getMaxRawReadSize( nCharsLeft, 1 ); + aBuffer.append( readCompressedUnicodeArray( nRawChars, !b16BitChars, bAllowNulChars ) ); + + /* Prepare for next CONTINUE record. Calling jumpToNextStringContinue() + reads the leading byte in the following CONTINUE record and updates + the b16BitChars flag. */ + nCharsLeft -= nRawChars; if( nCharsLeft > 0 ) jumpToNextStringContinue( b16BitChars ); } @@ -429,25 +419,15 @@ OUString BiffInputStream::readUniString( bool bAllowNulChars ) void BiffInputStream::skipUniStringChars( sal_uInt16 nChars, bool b16BitChars ) { - sal_uInt16 nCharsLeft = nChars; + sal_Int32 nCharsLeft = nChars; while( !mbEof && (nCharsLeft > 0) ) { - sal_uInt16 nPortionCount; - if( b16BitChars ) - { - nPortionCount = ::std::min< sal_uInt16 >( nCharsLeft, maRecBuffer.getRecLeft() / 2 ); - OSL_ENSURE( (nPortionCount <= nCharsLeft) || ((maRecBuffer.getRecLeft() & 1) == 0), - "BiffInputStream::skipUniStringChars - missing a byte" ); - skip( 2 * nPortionCount ); - } - else - { - nPortionCount = getMaxRawReadSize( nCharsLeft ); - skip( nPortionCount ); - } + // skip the character array + sal_Int32 nSkipSize = b16BitChars ? getMaxRawReadSize( 2 * nCharsLeft, 2 ) : getMaxRawReadSize( nCharsLeft, 1 ); + skip( nSkipSize ); // prepare for next CONTINUE record - nCharsLeft = nCharsLeft - nPortionCount; + nCharsLeft -= (b16BitChars ? (nSkipSize / 2) : nSkipSize); if( nCharsLeft > 0 ) jumpToNextStringContinue( b16BitChars ); } @@ -469,13 +449,6 @@ void BiffInputStream::skipUniString() // private -------------------------------------------------------------------- -void BiffInputStream::readAtom( void* opMem, sal_uInt8 nSize ) -{ - // byte swapping is done in calling BinaryInputStream::readValue() template function - if( ensureRawReadSize( nSize ) ) - maRecBuffer.read( opMem, nSize ); -} - void BiffInputStream::setupRecord() { // initialize class members @@ -529,7 +502,7 @@ bool BiffInputStream::jumpToNextContinue() bool BiffInputStream::jumpToNextStringContinue( bool& rb16BitChars ) { - OSL_ENSURE( maRecBuffer.getRecLeft() == 0, "BiffInputStream::jumpToNextStringContinue - unexpected garbage" ); + OSL_ENSURE( maRecBuffer.getRecLeft() == 0, "BiffInputStream::jumpToNextStringContinue - alignment error" ); if( mbCont && (getRemaining() > 0) ) { @@ -561,31 +534,17 @@ void BiffInputStream::calcRecordLength() seek( nCurrPos ); // restore position, seek() resets old mbValid state } -bool BiffInputStream::ensureRawReadSize( sal_uInt16 nBytes ) -{ - if( !mbEof && (nBytes > 0) ) - { - while( !mbEof && (maRecBuffer.getRecLeft() == 0) ) jumpToNextContinue(); - mbEof = mbEof || (nBytes > maRecBuffer.getRecLeft()); - OSL_ENSURE( !mbEof, "BiffInputStream::ensureRawReadSize - record overread" ); - } - return !mbEof; -} - -sal_uInt16 BiffInputStream::getMaxRawReadSize( sal_Int32 nBytes ) const -{ - return getLimitedValue< sal_uInt16, sal_Int32 >( nBytes, 0, maRecBuffer.getRecLeft() ); -} - -void BiffInputStream::appendUnicodeArray( OUStringBuffer& orBuffer, sal_uInt16 nChars, bool b16BitChars, bool bAllowNulChars ) +sal_uInt16 BiffInputStream::getMaxRawReadSize( sal_Int32 nBytes, size_t nAtomSize ) const { - orBuffer.ensureCapacity( orBuffer.getLength() + nChars ); - sal_uInt16 nChar; - for( sal_uInt16 nCharIdx = 0; !mbEof && (nCharIdx < nChars); ++nCharIdx ) + sal_uInt16 nMaxSize = getLimitedValue< sal_uInt16, sal_Int32 >( nBytes, 0, maRecBuffer.getRecLeft() ); + if( (0 < nMaxSize) && (nMaxSize < nBytes) && (nAtomSize > 1) ) { - if( b16BitChars ) readValue( nChar ); else nChar = readuInt8(); - orBuffer.append( static_cast< sal_Unicode >( (!bAllowNulChars && (nChar == 0)) ? '?' : nChar ) ); + // check that remaining data in record buffer is a multiple of the passed atom size + sal_uInt16 nPadding = static_cast< sal_uInt16 >( nMaxSize % nAtomSize ); + OSL_ENSURE( nPadding == 0, "BiffInputStream::getMaxRawReadSize - alignment error" ); + nMaxSize = nMaxSize - nPadding; } + return nMaxSize; } void BiffInputStream::readUniStringHeader( bool& orb16BitChars, sal_Int32& ornAddSize ) diff --git a/oox/source/xls/biffoutputstream.cxx b/oox/source/xls/biffoutputstream.cxx index ba59f50bea4d..14608414c91d 100644 --- a/oox/source/xls/biffoutputstream.cxx +++ b/oox/source/xls/biffoutputstream.cxx @@ -85,6 +85,7 @@ void BiffOutputRecordBuffer::fill( sal_uInt8 nValue, sal_uInt16 nBytes ) // ============================================================================ BiffOutputStream::BiffOutputStream( BinaryOutputStream& rOutStream, sal_uInt16 nMaxRecSize ) : + BinaryStreamBase( true ), maRecBuffer( rOutStream, nMaxRecSize ), mnPortionSize( 0 ), mnPortionPos( 0 ) @@ -96,19 +97,19 @@ BiffOutputStream::BiffOutputStream( BinaryOutputStream& rOutStream, sal_uInt16 n void BiffOutputStream::startRecord( sal_uInt16 nRecId ) { maRecBuffer.startRecord( nRecId ); - setPortionSize( 0 ); + setPortionSize( 1 ); } void BiffOutputStream::endRecord() { - setPortionSize( 0 ); + setPortionSize( 1 ); maRecBuffer.endRecord(); } -void BiffOutputStream::setPortionSize( sal_uInt16 nSize ) +void BiffOutputStream::setPortionSize( sal_uInt8 nSize ) { OSL_ENSURE( mnPortionPos == 0, "BiffOutputStream::setPortionSize - block operation inside portion" ); - mnPortionSize = nSize; + mnPortionSize = ::std::max< sal_uInt8 >( nSize, 1 ); mnPortionPos = 0; } @@ -119,20 +120,20 @@ sal_Int64 BiffOutputStream::tellBase() const return maRecBuffer.getBaseStream().tell(); } -sal_Int64 BiffOutputStream::getBaseLength() const +sal_Int64 BiffOutputStream::sizeBase() const { - return maRecBuffer.getBaseStream().getLength(); + return maRecBuffer.getBaseStream().size(); } // BinaryOutputStream interface (stream write access) ------------------------- -void BiffOutputStream::writeData( const StreamDataSequence& rData ) +void BiffOutputStream::writeData( const StreamDataSequence& rData, size_t nAtomSize ) { if( rData.hasElements() ) - writeMemory( rData.getConstArray(), rData.getLength() ); + writeMemory( rData.getConstArray(), rData.getLength(), nAtomSize ); } -void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) +void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize ) { if( pMem && (nBytes > 0) ) { @@ -140,7 +141,7 @@ void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) sal_Int32 nBytesLeft = nBytes; while( nBytesLeft > 0 ) { - sal_uInt16 nBlockSize = prepareRawBlock( nBytesLeft ); + sal_uInt16 nBlockSize = prepareWriteBlock( nBytesLeft, nAtomSize ); maRecBuffer.write( pnBuffer, nBlockSize ); pnBuffer += nBlockSize; nBytesLeft -= nBlockSize; @@ -148,59 +149,60 @@ void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes ) } } -void BiffOutputStream::fill( sal_uInt8 nValue, sal_Int32 nBytes ) +void BiffOutputStream::fill( sal_uInt8 nValue, sal_Int32 nBytes, size_t nAtomSize ) { sal_Int32 nBytesLeft = nBytes; while( nBytesLeft > 0 ) { - sal_uInt16 nBlockSize = prepareRawBlock( nBytesLeft ); + sal_uInt16 nBlockSize = prepareWriteBlock( nBytesLeft, nAtomSize ); maRecBuffer.fill( nValue, nBlockSize ); nBytesLeft -= nBlockSize; } } -void BiffOutputStream::writeBlock( const void* pMem, sal_uInt16 nBytes ) -{ - ensureRawBlock( nBytes ); - maRecBuffer.write( pMem, nBytes ); -} - // private -------------------------------------------------------------------- -void BiffOutputStream::writeAtom( const void* pMem, sal_uInt8 nSize ) -{ - // byte swapping is done in calling BinaryOutputStream::writeValue() template function - writeBlock( pMem, nSize ); -} - -void BiffOutputStream::ensureRawBlock( sal_uInt16 nSize ) +sal_uInt16 BiffOutputStream::prepareWriteBlock( sal_Int32 nTotalSize, size_t nAtomSize ) { - if( (maRecBuffer.getRecLeft() < nSize) || - ((mnPortionSize > 0) && (mnPortionPos == 0) && (maRecBuffer.getRecLeft() < mnPortionSize)) ) + sal_uInt16 nRecLeft = maRecBuffer.getRecLeft(); + if( mnPortionSize <= 1 ) { - maRecBuffer.endRecord(); - maRecBuffer.startRecord( BIFF_ID_CONT ); + // no portions: restrict remaining record size to entire atoms + nRecLeft = static_cast< sal_uInt16 >( (nRecLeft / nAtomSize) * nAtomSize ); } - if( mnPortionSize > 0 ) + else { - OSL_ENSURE( mnPortionPos + nSize <= mnPortionSize, "BiffOutputStream::ensureRawBlock - portion overflow" ); - mnPortionPos = (mnPortionPos + nSize) % mnPortionSize; // prevent compiler warning, do not use operator+=, operator%= + sal_Int32 nPortionLeft = mnPortionSize - mnPortionPos; + if( nTotalSize <= nPortionLeft ) + { + // block fits into the current portion + OSL_ENSURE( nPortionLeft <= nRecLeft, "BiffOutputStream::prepareWriteBlock - portion exceeds record" ); + mnPortionPos = static_cast< sal_uInt8 >( (mnPortionPos + nTotalSize) % mnPortionSize ); + } + else + { + // restrict remaining record size to entire portions + OSL_ENSURE( mnPortionPos == 0, "BiffOutputStream::prepareWriteBlock - writing over multiple portions starts inside portion" ); + mnPortionPos = 0; + // check that atom size matches portion size + OSL_ENSURE( mnPortionSize % nAtomSize == 0, "BiffOutputStream::prepareWriteBlock - atom size does not match portion size" ); + sal_uInt8 nPortionSize = static_cast< sal_uInt8 >( (mnPortionSize / nAtomSize) * nAtomSize ); + // restrict remaining record size to entire portions + nRecLeft = (nRecLeft / nPortionSize) * nPortionSize; + } } -} -sal_uInt16 BiffOutputStream::prepareRawBlock( sal_Int32 nTotalSize ) -{ - sal_uInt16 nRecLeft = maRecBuffer.getRecLeft(); - if( mnPortionSize > 0 ) - { - OSL_ENSURE( mnPortionPos == 0, "BiffOutputStream::prepareRawBlock - block operation inside portion" ); - OSL_ENSURE( nTotalSize % mnPortionSize == 0, "BiffOutputStream::prepareRawBlock - portion size does not match block size" ); - nRecLeft = (nRecLeft / mnPortionSize) * mnPortionSize; - } - sal_uInt16 nSize = getLimitedValue< sal_uInt16, sal_Int32 >( nTotalSize, 0, nRecLeft ); - ensureRawBlock( nSize ); - return nSize; + // current record has space for some data: return size of available space + if( nRecLeft > 0 ) + return getLimitedValue< sal_uInt16, sal_Int32 >( nTotalSize, 0, nRecLeft ); + + // finish current record and start a new CONTINUE record + maRecBuffer.endRecord(); + maRecBuffer.startRecord( BIFF_ID_CONT ); + mnPortionPos = 0; + return prepareWriteBlock( nTotalSize, nAtomSize ); } + // ============================================================================ } // namespace xls diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx index 3ee5c45a80b6..efba6824c8ac 100755 --- a/oox/source/xls/drawingmanager.cxx +++ b/oox/source/xls/drawingmanager.cxx @@ -1374,8 +1374,7 @@ Reference< XShape > BiffDrawingBase::createAndInsertXShape( const OUString& rSer Reference< XShape > xShape; if( (rService.getLength() > 0) && rxShapes.is() ) try { - Reference< XMultiServiceFactory > xFactory( getDocumentFactory(), UNO_SET_THROW ); - xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW ); + xShape.set( getBaseFilter().getModelFactory()->createInstance( rService ), UNO_QUERY_THROW ); // insert shape into passed shape collection (maybe drawpage or group shape) rxShapes->add( xShape ); xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); diff --git a/oox/source/xls/excelchartconverter.cxx b/oox/source/xls/excelchartconverter.cxx index 53c0a3b83bf2..702a12fbde50 100644 --- a/oox/source/xls/excelchartconverter.cxx +++ b/oox/source/xls/excelchartconverter.cxx @@ -30,6 +30,7 @@ #include #include #include +#include "oox/core/filterbase.hxx" #include "oox/drawingml/chart/datasourcemodel.hxx" #include "oox/helper/containerhelper.hxx" #include "oox/xls/formulaparser.hxx" @@ -64,8 +65,7 @@ void ExcelChartConverter::createDataProvider( const Reference< XChartDocument >& try { Reference< XDataReceiver > xDataRec( rxChartDoc, UNO_QUERY_THROW ); - Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY_THROW ); - Reference< XDataProvider > xDataProv( xFactory->createInstance( + Reference< XDataProvider > xDataProv( getBaseFilter().getModelFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.chart2.data.DataProvider" ) ), UNO_QUERY_THROW ); xDataRec->attachDataProvider( xDataProv ); } diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx index f097dec831d8..58049f4851d7 100755 --- a/oox/source/xls/formulabase.cxx +++ b/oox/source/xls/formulabase.cxx @@ -1025,7 +1025,7 @@ struct OpCodeProviderImpl : public ApiOpCodes explicit OpCodeProviderImpl( const FunctionInfoVector& rFuncInfos, - const Reference< XMultiServiceFactory >& rxFactory ); + const Reference< XMultiServiceFactory >& rxModelFactory ); private: typedef ::std::map< OUString, ApiToken > ApiTokenMap; @@ -1047,11 +1047,11 @@ private: // ---------------------------------------------------------------------------- OpCodeProviderImpl::OpCodeProviderImpl( const FunctionInfoVector& rFuncInfos, - const Reference< XMultiServiceFactory >& rxFactory ) + const Reference< XMultiServiceFactory >& rxModelFactory ) { - if( rxFactory.is() ) try + if( rxModelFactory.is() ) try { - Reference< XFormulaOpCodeMapper > xMapper( rxFactory->createInstance( + Reference< XFormulaOpCodeMapper > xMapper( rxModelFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaOpCodeMapper" ) ), UNO_QUERY_THROW ); // op-codes provided as attributes @@ -1297,10 +1297,10 @@ bool OpCodeProviderImpl::initFuncOpCodes( const ApiTokenMap& rIntFuncTokenMap, c // ---------------------------------------------------------------------------- -OpCodeProvider::OpCodeProvider( const Reference< XMultiServiceFactory >& rxFactory, +OpCodeProvider::OpCodeProvider( const Reference< XMultiServiceFactory >& rxModelFactory, FilterType eFilter, BiffType eBiff, bool bImportFilter ) : FunctionProvider( eFilter, eBiff, bImportFilter ), - mxOpCodeImpl( new OpCodeProviderImpl( getFuncs(), rxFactory ) ) + mxOpCodeImpl( new OpCodeProviderImpl( getFuncs(), rxModelFactory ) ) { } @@ -1335,12 +1335,12 @@ Sequence< FormulaOpCodeMapEntry > OpCodeProvider::getOoxParserMap() const // API formula parser wrapper ================================================= ApiParserWrapper::ApiParserWrapper( - const Reference< XMultiServiceFactory >& rxFactory, const OpCodeProvider& rOpCodeProv ) : + const Reference< XMultiServiceFactory >& rxModelFactory, const OpCodeProvider& rOpCodeProv ) : OpCodeProvider( rOpCodeProv ) { - if( rxFactory.is() ) try + if( rxModelFactory.is() ) try { - mxParser.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaParser" ) ), UNO_QUERY_THROW ); + mxParser.set( rxModelFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaParser" ) ), UNO_QUERY_THROW ); } catch( Exception& ) { @@ -1483,7 +1483,7 @@ TokenToRangeListState lclProcessClose( sal_Int32& ornParenLevel ) // ---------------------------------------------------------------------------- FormulaProcessorBase::FormulaProcessorBase( const WorkbookHelper& rHelper ) : - OpCodeProvider( rHelper.getDocumentFactory(), rHelper.getFilterType(), rHelper.getBiff(), rHelper.getBaseFilter().isImportFilter() ), + OpCodeProvider( rHelper.getBaseFilter().getModelFactory(), rHelper.getFilterType(), rHelper.getBiff(), rHelper.getBaseFilter().isImportFilter() ), ApiOpCodes( getOpCodes() ), WorkbookHelper( rHelper ) { diff --git a/oox/source/xls/formulaparser.cxx b/oox/source/xls/formulaparser.cxx index 26bf66986638..d7eb91a9c05c 100644 --- a/oox/source/xls/formulaparser.cxx +++ b/oox/source/xls/formulaparser.cxx @@ -1313,7 +1313,7 @@ private: OoxFormulaParserImpl::OoxFormulaParserImpl( const FormulaParser& rParent ) : FormulaParserImpl( rParent ), - maApiParser( rParent.getDocumentFactory(), rParent ), + maApiParser( rParent.getBaseFilter().getModelFactory(), rParent ), mnAddDataPos( 0 ), mbNeedExtRefs( true ) { diff --git a/oox/source/xls/numberformatsbuffer.cxx b/oox/source/xls/numberformatsbuffer.cxx index c77381b2a1c8..782c138d43e2 100644 --- a/oox/source/xls/numberformatsbuffer.cxx +++ b/oox/source/xls/numberformatsbuffer.cxx @@ -1950,7 +1950,7 @@ NumberFormatsBuffer::NumberFormatsBuffer( const WorkbookHelper& rHelper ) : // get the current locale try { - Reference< XMultiServiceFactory > xConfigProv( getGlobalFactory()->createInstance( + Reference< XMultiServiceFactory > xConfigProv( getBaseFilter().getServiceFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.configuration.ConfigurationProvider" ) ), UNO_QUERY_THROW ); // try user-defined locale setting diff --git a/oox/source/xls/ooxformulaparser.cxx b/oox/source/xls/ooxformulaparser.cxx index efa69abcb750..a8860a8f2131 100644 --- a/oox/source/xls/ooxformulaparser.cxx +++ b/oox/source/xls/ooxformulaparser.cxx @@ -47,7 +47,7 @@ using ::rtl::OUString; class OOXMLFormulaParserImpl : private FormulaFinalizer { public: - explicit OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxFactory ); + explicit OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxModelFactory ); Sequence< FormulaToken > parseFormula( const OUString& rFormula, const CellAddress& rReferencePos ); @@ -60,9 +60,9 @@ private: // ---------------------------------------------------------------------------- -OOXMLFormulaParserImpl::OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxFactory ) : - FormulaFinalizer( OpCodeProvider( rxFactory, FILTER_OOXML, BIFF_UNKNOWN, true ) ), - maApiParser( rxFactory, *this ) +OOXMLFormulaParserImpl::OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxModelFactory ) : + FormulaFinalizer( OpCodeProvider( rxModelFactory, FILTER_OOXML, BIFF_UNKNOWN, true ) ), + maApiParser( rxModelFactory, *this ) { } @@ -115,7 +115,7 @@ const FunctionInfo* OOXMLFormulaParserImpl::resolveBadFuncName( const OUString& class OOXMLFormulaPrinterImpl : public OpCodeProvider { public: - explicit OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxFactory ); + explicit OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxModelFactory ); private: ApiParserWrapper maApiParser; @@ -123,9 +123,9 @@ private: // ---------------------------------------------------------------------------- -OOXMLFormulaPrinterImpl::OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxFactory ) : - OpCodeProvider( rxFactory, FILTER_OOXML, BIFF_UNKNOWN, false ), - maApiParser( rxFactory, *this ) +OOXMLFormulaPrinterImpl::OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxModelFactory ) : + OpCodeProvider( rxModelFactory, FILTER_OOXML, BIFF_UNKNOWN, false ), + maApiParser( rxModelFactory, *this ) { } @@ -202,8 +202,8 @@ Sequence< FormulaToken > SAL_CALL OOXMLFormulaParser::parseFormula( { if( !mxParserImpl ) { - Reference< XMultiServiceFactory > xFactory( mxComponent, UNO_QUERY_THROW ); - mxParserImpl.reset( new OOXMLFormulaParserImpl( xFactory ) ); + Reference< XMultiServiceFactory > xModelFactory( mxComponent, UNO_QUERY_THROW ); + mxParserImpl.reset( new OOXMLFormulaParserImpl( xModelFactory ) ); } return mxParserImpl->parseFormula( rFormula, rReferencePos ); } diff --git a/oox/source/xls/pagesettings.cxx b/oox/source/xls/pagesettings.cxx index 188bf78544ec..5c1770bd6463 100644 --- a/oox/source/xls/pagesettings.cxx +++ b/oox/source/xls/pagesettings.cxx @@ -903,8 +903,7 @@ Reference< XTextContent > HeaderFooterParser::createField( const OUString& rServ Reference< XTextContent > xContent; try { - Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY_THROW ); - xContent.set( xFactory->createInstance( rServiceName ), UNO_QUERY_THROW ); + xContent.set( getBaseFilter().getModelFactory()->createInstance( rServiceName ), UNO_QUERY_THROW ); } catch( Exception& ) { diff --git a/oox/source/xls/pivotcachebuffer.cxx b/oox/source/xls/pivotcachebuffer.cxx index e8ca3539e167..5e5e5efef546 100644 --- a/oox/source/xls/pivotcachebuffer.cxx +++ b/oox/source/xls/pivotcachebuffer.cxx @@ -737,7 +737,7 @@ void PivotCacheField::importPCDFRangePr( BiffInputStream& rStrm ) void PivotCacheField::importPCDFDiscretePr( BiffInputStream& rStrm ) { - sal_Int32 nCount = static_cast< sal_Int32 >( rStrm.getLength() / 2 ); + sal_Int32 nCount = static_cast< sal_Int32 >( rStrm.size() / 2 ); for( sal_Int32 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex ) maDiscreteItems.push_back( rStrm.readuInt16() ); } diff --git a/oox/source/xls/viewsettings.cxx b/oox/source/xls/viewsettings.cxx index c9658dd41cf9..e23273b42b82 100644 --- a/oox/source/xls/viewsettings.cxx +++ b/oox/source/xls/viewsettings.cxx @@ -734,7 +734,7 @@ void ViewSettings::finalizeImport() sal_Int16 nShowMode = getWorkbookSettings().getApiShowObjectMode(); // view settings for all sheets - Reference< XNameContainer > xSheetsNC = ContainerHelper::createNameContainer( getGlobalFactory() ); + Reference< XNameContainer > xSheetsNC = ContainerHelper::createNameContainer( getBaseFilter().getComponentContext() ); if( !xSheetsNC.is() ) return; for( SheetPropertiesMap::const_iterator aIt = maSheetProps.begin(), aEnd = maSheetProps.end(); aIt != aEnd; ++aIt ) ContainerHelper::insertByName( xSheetsNC, rWorksheets.getCalcSheetName( aIt->first ), aIt->second ); @@ -746,7 +746,7 @@ void ViewSettings::finalizeImport() if( !rxActiveSheetView ) rxActiveSheetView.reset( new SheetViewModel ); - Reference< XIndexContainer > xContainer = ContainerHelper::createIndexContainer( getGlobalFactory() ); + Reference< XIndexContainer > xContainer = ContainerHelper::createIndexContainer( getBaseFilter().getComponentContext() ); if( xContainer.is() ) try { PropertyMap aPropMap; diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx index 69daca13812e..843bfd69fdfe 100644 --- a/oox/source/xls/workbookfragment.cxx +++ b/oox/source/xls/workbookfragment.cxx @@ -289,7 +289,7 @@ void WorkbookFragment::finalizeImport() { Reference< XInputStream > xInStrm = getBaseFilter().openInputStream( aVbaFragmentPath ); if( xInStrm.is() ) - setVbaProjectStorage( StorageRef( new ::oox::ole::OleStorage( getGlobalFactory(), xInStrm, false ) ) ); + setVbaProjectStorage( StorageRef( new ::oox::ole::OleStorage( getBaseFilter().getComponentContext(), xInStrm, false ) ) ); } // final conversions, e.g. calculation settings and view settings diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx index 8cd2748101d7..6adb7957d4b8 100644 --- a/oox/source/xls/workbookhelper.cxx +++ b/oox/source/xls/workbookhelper.cxx @@ -595,11 +595,6 @@ FilterBase& WorkbookHelper::getBaseFilter() const return mrBookData.getBaseFilter(); } -Reference< XMultiServiceFactory > WorkbookHelper::getGlobalFactory() const -{ - return mrBookData.getBaseFilter().getServiceFactory(); -} - FilterType WorkbookHelper::getFilterType() const { return mrBookData.getFilterType(); @@ -666,11 +661,6 @@ Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const return mrBookData.getDocument(); } -Reference< XMultiServiceFactory > WorkbookHelper::getDocumentFactory() const -{ - return mrBookData.getBaseFilter().getModelFactory(); -} - Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int16 nSheet ) const { Reference< XSpreadsheet > xSheet; diff --git a/oox/source/xls/workbooksettings.cxx b/oox/source/xls/workbooksettings.cxx index 6889d42ed2f6..264555971ba0 100644 --- a/oox/source/xls/workbooksettings.cxx +++ b/oox/source/xls/workbooksettings.cxx @@ -299,7 +299,7 @@ void WorkbookSettings::finalizeImport() { getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "ReadOnly" ) ] <<= true; - Reference< XPropertySet > xDocumentSettings( getDocumentFactory()->createInstance( + Reference< XPropertySet > xDocumentSettings( getBaseFilter().getModelFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.document.Settings" ) ), UNO_QUERY_THROW ); PropertySet aSettingsProp( xDocumentSettings ); if( maFileSharing.mbRecommendReadOnly ) diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index 124fdacd4431..00f65f90294f 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -681,7 +681,7 @@ Reference< XSheetCellRanges > WorksheetData::getCellRangeList( const ApiCellRang Reference< XSheetCellRanges > xRanges; if( mxSheet.is() && !rRanges.empty() ) try { - xRanges.set( getDocumentFactory()->createInstance( maSheetCellRanges ), UNO_QUERY_THROW ); + xRanges.set( getBaseFilter().getModelFactory()->createInstance( maSheetCellRanges ), UNO_QUERY_THROW ); Reference< XSheetCellRangeContainer > xRangeCont( xRanges, UNO_QUERY_THROW ); xRangeCont->addRangeAddresses( ContainerHelper::vectorToSequence( rRanges ), sal_False ); } @@ -1359,7 +1359,7 @@ void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString if( xText.is() ) { // create a URL field object and set its properties - Reference< XTextContent > xUrlField( getDocumentFactory()->createInstance( maUrlTextField ), UNO_QUERY ); + Reference< XTextContent > xUrlField( getBaseFilter().getModelFactory()->createInstance( maUrlTextField ), UNO_QUERY ); OSL_ENSURE( xUrlField.is(), "WorksheetData::insertHyperlink - cannot create text field" ); if( xUrlField.is() ) { -- cgit From aec1b58b2f959770f072778ec187ae89f6053b76 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Thu, 10 Feb 2011 17:12:02 +0100 Subject: dr78: #164376# oox import performance: step 1 - encapsulate all code related to cell contents and cell formatting import into class SheetDataBuffer (including shared formulas, array formulas, table operations), remove FormulaContext concept to gain full control over formula import --- oox/source/dump/xlsbdumper.ini | 1 + oox/source/xls/chartsheetfragment.cxx | 10 +- oox/source/xls/condformatbuffer.cxx | 46 +- oox/source/xls/defnamesbuffer.cxx | 182 +++---- oox/source/xls/excelchartconverter.cxx | 7 +- oox/source/xls/excelfilter.cxx | 51 +- oox/source/xls/excelhandlers.cxx | 27 +- oox/source/xls/externallinkbuffer.cxx | 11 +- oox/source/xls/formulabase.cxx | 52 +- oox/source/xls/formulaparser.cxx | 277 +++++----- oox/source/xls/makefile.mk | 2 +- oox/source/xls/pivotcachebuffer.cxx | 20 +- oox/source/xls/pivotcachefragment.cxx | 23 +- oox/source/xls/sharedformulabuffer.cxx | 212 -------- oox/source/xls/sheetdatabuffer.cxx | 689 ++++++++++++++++++++++++ oox/source/xls/sheetdatacontext.cxx | 424 +++++++-------- oox/source/xls/workbookfragment.cxx | 80 ++- oox/source/xls/workbookhelper.cxx | 235 ++++----- oox/source/xls/worksheetfragment.cxx | 49 +- oox/source/xls/worksheethelper.cxx | 930 ++++++--------------------------- 20 files changed, 1563 insertions(+), 1765 deletions(-) delete mode 100644 oox/source/xls/sharedformulabuffer.cxx create mode 100755 oox/source/xls/sheetdatabuffer.cxx (limited to 'oox/source') diff --git a/oox/source/dump/xlsbdumper.ini b/oox/source/dump/xlsbdumper.ini index 3490111c4ba5..16b97172d5c8 100644 --- a/oox/source/dump/xlsbdumper.ini +++ b/oox/source/dump/xlsbdumper.ini @@ -278,6 +278,7 @@ end # ARRAY ---------------------------------------------------------------------- flagslist=ARRAY-FLAGS + ignore=0xFE 0x01=recalc-always end diff --git a/oox/source/xls/chartsheetfragment.cxx b/oox/source/xls/chartsheetfragment.cxx index c67768ef2f22..c7a74c155a3c 100644 --- a/oox/source/xls/chartsheetfragment.cxx +++ b/oox/source/xls/chartsheetfragment.cxx @@ -45,9 +45,8 @@ using ::rtl::OUString; // ============================================================================ -ChartsheetFragment::ChartsheetFragment( const WorkbookHelper& rHelper, - const OUString& rFragmentPath, const ISegmentProgressBarRef& rxProgressBar, sal_Int16 nSheet ) : - WorksheetFragmentBase( rHelper, rFragmentPath, rxProgressBar, SHEETTYPE_CHARTSHEET, nSheet ) +ChartsheetFragment::ChartsheetFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) : + WorksheetFragmentBase( rHelper, rFragmentPath ) { } @@ -179,9 +178,8 @@ void ChartsheetFragment::importDrawing( SequenceInputStream& rStrm ) // ============================================================================ -BiffChartsheetFragment::BiffChartsheetFragment( const BiffWorkbookFragmentBase& rParent, - const ISegmentProgressBarRef& rxProgressBar, sal_Int16 nSheet ) : - BiffWorksheetFragmentBase( rParent, rxProgressBar, SHEETTYPE_CHARTSHEET, nSheet ) +BiffChartsheetFragment::BiffChartsheetFragment( const WorksheetHelper& rHelper, const BiffWorkbookFragmentBase& rParent ) : + BiffWorksheetFragmentBase( rHelper, rParent ) { } diff --git a/oox/source/xls/condformatbuffer.cxx b/oox/source/xls/condformatbuffer.cxx index 51d9170e1794..1914ed233f46 100644 --- a/oox/source/xls/condformatbuffer.cxx +++ b/oox/source/xls/condformatbuffer.cxx @@ -193,10 +193,9 @@ void CondFormatRule::importCfRule( const AttributeList& rAttribs ) void CondFormatRule::appendFormula( const OUString& rFormula ) { - TokensFormulaContext aContext( true, false ); - aContext.setBaseAddress( mrCondFormat.getRanges().getBaseAddress() ); - getFormulaParser().importFormula( aContext, rFormula ); - maModel.maFormulas.push_back( aContext ); + CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress(); + ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, rFormula ); + maModel.maFormulas.push_back( aTokens ); } void CondFormatRule::importCfRule( SequenceInputStream& rStrm ) @@ -216,25 +215,24 @@ void CondFormatRule::importCfRule( SequenceInputStream& rStrm ) OSL_ENSURE( (nFmla1Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" ); if( rStrm.getRemaining() >= 8 ) { - TokensFormulaContext aContext( true, false ); - aContext.setBaseAddress( mrCondFormat.getRanges().getBaseAddress() ); - getFormulaParser().importFormula( aContext, rStrm ); - maModel.maFormulas.push_back( aContext ); + CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress(); + ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm ); + maModel.maFormulas.push_back( aTokens ); // second formula OSL_ENSURE( (nFmla2Size >= 0) || (nFmla3Size == 0), "CondFormatRule::importCfRule - missing second formula" ); OSL_ENSURE( (nFmla2Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" ); if( rStrm.getRemaining() >= 8 ) { - getFormulaParser().importFormula( aContext, rStrm ); - maModel.maFormulas.push_back( aContext ); + aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm ); + maModel.maFormulas.push_back( aTokens ); // third formula OSL_ENSURE( (nFmla3Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" ); if( rStrm.getRemaining() >= 8 ) { - getFormulaParser().importFormula( aContext, rStrm ); - maModel.maFormulas.push_back( aContext ); + aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm ); + maModel.maFormulas.push_back( aTokens ); } } } @@ -419,21 +417,20 @@ void CondFormatRule::importCfRule( BiffInputStream& rStrm, sal_Int32 nPriority ) OSL_ENSURE( (nFmla1Size > 0) || (nFmla2Size == 0), "CondFormatRule::importCfRule - missing first formula" ); if( nFmla1Size > 0 ) { - TokensFormulaContext aContext( true, false ); - aContext.setBaseAddress( mrCondFormat.getRanges().getBaseAddress() ); - getFormulaParser().importFormula( aContext, rStrm, &nFmla1Size ); - maModel.maFormulas.push_back( aContext ); + CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress(); + ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm, &nFmla1Size ); + maModel.maFormulas.push_back( aTokens ); if( nFmla2Size > 0 ) { - getFormulaParser().importFormula( aContext, rStrm, &nFmla2Size ); - maModel.maFormulas.push_back( aContext ); + aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm, &nFmla2Size ); + maModel.maFormulas.push_back( aTokens ); } } } void CondFormatRule::finalizeImport( const Reference< XSheetConditionalEntries >& rxEntries ) { - ConditionOperator eOperator = ::com::sun::star::sheet::ConditionOperator_NONE; + ConditionOperator eOperator = ConditionOperator_NONE; /* Replacement formula for unsupported rule types (text comparison rules, time period rules, cell type rules). The replacement formulas below may @@ -460,7 +457,7 @@ void CondFormatRule::finalizeImport( const Reference< XSheetConditionalEntries > eOperator = CondFormatBuffer::convertToApiOperator( maModel.mnOperator ); break; case XML_expression: - eOperator = ::com::sun::star::sheet::ConditionOperator_FORMULA; + eOperator = ConditionOperator_FORMULA; break; case XML_containsText: OSL_ENSURE( maModel.mnOperator == XML_containsText, "CondFormatRule::finalizeImport - unexpected operator" ); @@ -591,17 +588,17 @@ void CondFormatRule::finalizeImport( const Reference< XSheetConditionalEntries > // set the replacement formula maModel.maFormulas.clear(); appendFormula( aReplaceFormula ); - eOperator = ::com::sun::star::sheet::ConditionOperator_FORMULA; + eOperator = ConditionOperator_FORMULA; } - if( rxEntries.is() && (eOperator != ::com::sun::star::sheet::ConditionOperator_NONE) && !maModel.maFormulas.empty() ) + if( rxEntries.is() && (eOperator != ConditionOperator_NONE) && !maModel.maFormulas.empty() ) { ::std::vector< PropertyValue > aProps; // create condition properties lclAppendProperty( aProps, CREATE_OUSTRING( "Operator" ), eOperator ); - lclAppendProperty( aProps, CREATE_OUSTRING( "Formula1" ), maModel.maFormulas[ 0 ].getTokens() ); + lclAppendProperty( aProps, CREATE_OUSTRING( "Formula1" ), maModel.maFormulas[ 0 ] ); if( maModel.maFormulas.size() >= 2 ) - lclAppendProperty( aProps, CREATE_OUSTRING( "Formula2" ), maModel.maFormulas[ 1 ].getTokens() ); + lclAppendProperty( aProps, CREATE_OUSTRING( "Formula2" ), maModel.maFormulas[ 1 ] ); // style name for the formatting attributes OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId ); @@ -744,7 +741,6 @@ void CondFormatBuffer::finalizeImport() ConditionOperator CondFormatBuffer::convertToApiOperator( sal_Int32 nToken ) { - using namespace ::com::sun::star::sheet; switch( nToken ) { case XML_between: return ConditionOperator_BETWEEN; diff --git a/oox/source/xls/defnamesbuffer.cxx b/oox/source/xls/defnamesbuffer.cxx index 1fda43065fde..335aae5273af 100644 --- a/oox/source/xls/defnamesbuffer.cxx +++ b/oox/source/xls/defnamesbuffer.cxx @@ -189,32 +189,32 @@ void lclConvertRefFlags( sal_Int32& ornFlags, sal_Int32& ornAbsPos, sal_Int32& o } } -void lclConvertSingleRefFlags( SingleReference& orApiRef, const CellAddress& rBaseAddress, bool bColRel, bool bRowRel ) +void lclConvertSingleRefFlags( SingleReference& orApiRef, const CellAddress& rBaseAddr, bool bColRel, bool bRowRel ) { using namespace ::com::sun::star::sheet::ReferenceFlags; lclConvertRefFlags( orApiRef.Flags, orApiRef.Column, orApiRef.RelativeColumn, - rBaseAddress.Column, COLUMN_RELATIVE, bColRel ); + rBaseAddr.Column, COLUMN_RELATIVE, bColRel ); lclConvertRefFlags( orApiRef.Flags, orApiRef.Row, orApiRef.RelativeRow, - rBaseAddress.Row, ROW_RELATIVE, bRowRel ); + rBaseAddr.Row, ROW_RELATIVE, bRowRel ); } -Any lclConvertReference( const Any& rRefAny, const CellAddress& rBaseAddress, sal_uInt16 nRelFlags ) +Any lclConvertReference( const Any& rRefAny, const CellAddress& rBaseAddr, sal_uInt16 nRelFlags ) { if( rRefAny.has< SingleReference >() && !getFlag( nRelFlags, BIFF_REFFLAG_COL2REL ) && !getFlag( nRelFlags, BIFF_REFFLAG_ROW2REL ) ) { SingleReference aApiRef; rRefAny >>= aApiRef; - lclConvertSingleRefFlags( aApiRef, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) ); + lclConvertSingleRefFlags( aApiRef, rBaseAddr, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) ); return Any( aApiRef ); } if( rRefAny.has< ComplexReference >() ) { ComplexReference aApiRef; rRefAny >>= aApiRef; - lclConvertSingleRefFlags( aApiRef.Reference1, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) ); - lclConvertSingleRefFlags( aApiRef.Reference2, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL2REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW2REL ) ); + lclConvertSingleRefFlags( aApiRef.Reference1, rBaseAddr, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) ); + lclConvertSingleRefFlags( aApiRef.Reference2, rBaseAddr, getFlag( nRelFlags, BIFF_REFFLAG_COL2REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW2REL ) ); return Any( aApiRef ); } return Any(); @@ -248,7 +248,7 @@ const OUString& DefinedNameBase::getUpcaseModelName() const return maUpModelName; } -Any DefinedNameBase::getReference( const CellAddress& rBaseAddress ) const +Any DefinedNameBase::getReference( const CellAddress& rBaseAddr ) const { if( maRefAny.hasValue() && (maModel.maName.getLength() >= 2) && (maModel.maName[ 0 ] == '\x01') ) { @@ -260,7 +260,7 @@ Any DefinedNameBase::getReference( const CellAddress& rBaseAddress ) const { ExternalReference aApiExtRef; maRefAny >>= aApiExtRef; - Any aRefAny = lclConvertReference( aApiExtRef.Reference, rBaseAddress, nRelFlags ); + Any aRefAny = lclConvertReference( aApiExtRef.Reference, rBaseAddr, nRelFlags ); if( aRefAny.hasValue() ) { aApiExtRef.Reference <<= aRefAny; @@ -269,37 +269,30 @@ Any DefinedNameBase::getReference( const CellAddress& rBaseAddress ) const } else { - return lclConvertReference( maRefAny, rBaseAddress, nRelFlags ); + return lclConvertReference( maRefAny, rBaseAddr, nRelFlags ); } } } return Any(); } -void DefinedNameBase::importOoxFormula( FormulaContext& rContext, sal_Int16 nBaseSheet ) +ApiTokenSequence DefinedNameBase::importOoxFormula( const CellAddress& rBaseAddr ) { - if( maModel.maFormula.getLength() > 0 ) - { - rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) ); - getFormulaParser().importFormula( rContext, maModel.maFormula ); - } - else - getFormulaParser().convertErrorToFormula( rContext, BIFF_ERR_NAME ); + return (maModel.maFormula.getLength() > 0) ? + getFormulaParser().importFormula( rBaseAddr, maModel.maFormula ) : + getFormulaParser().convertErrorToFormula( BIFF_ERR_NAME ); } -void DefinedNameBase::importBiff12Formula( FormulaContext& rContext, sal_Int16 nBaseSheet, SequenceInputStream& rStrm ) +ApiTokenSequence DefinedNameBase::importBiff12Formula( const CellAddress& rBaseAddr, SequenceInputStream& rStrm ) { - rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) ); - getFormulaParser().importFormula( rContext, rStrm ); + return getFormulaParser().importFormula( rBaseAddr, FORMULATYPE_DEFINEDNAME, rStrm ); } -void DefinedNameBase::importBiffFormula( FormulaContext& rContext, sal_Int16 nBaseSheet, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) +ApiTokenSequence DefinedNameBase::importBiffFormula( const CellAddress& rBaseAddr, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) { - rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) ); - if( !pnFmlaSize || (*pnFmlaSize > 0) ) - getFormulaParser().importFormula( rContext, rStrm, pnFmlaSize ); - else - getFormulaParser().convertErrorToFormula( rContext, BIFF_ERR_NAME ); + return (!pnFmlaSize || (*pnFmlaSize > 0)) ? + getFormulaParser().importFormula( rBaseAddr, FORMULATYPE_DEFINEDNAME, rStrm, pnFmlaSize ) : + getFormulaParser().convertErrorToFormula( BIFF_ERR_NAME ); } void DefinedNameBase::extractReference( const ApiTokenSequence& rTokens ) @@ -467,9 +460,9 @@ void DefinedName::importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcShee these names contain a simple cell reference or range reference. Other regular defined names and external names rely on existence of this reference. */ - TokensFormulaContext aContext( true, true ); - importBiffFormula( aContext, mnCalcSheet, rStrm, &mnFmlaSize ); - extractReference( aContext.getTokens() ); + CellAddress aBaseAddr( mnCalcSheet, 0, 0 ); + ApiTokenSequence aTokens = importBiffFormula( aBaseAddr, rStrm, &mnFmlaSize ); + extractReference( aTokens ); } else { @@ -523,69 +516,84 @@ void DefinedName::createNameObject() void DefinedName::convertFormula() { Reference< XFormulaTokens > xTokens( mxNamedRange, UNO_QUERY ); - if( xTokens.is() ) + if( !xTokens.is() ) + return; + + // convert and set formula of the defined name + ApiTokenSequence aTokens; + CellAddress aBaseAddr( mnCalcSheet, 0, 0 ); + switch( getFilterType() ) { - // convert and set formula of the defined name - switch( getFilterType() ) + case FILTER_OOXML: { - case FILTER_OOXML: + if( mxFormula.get() ) { - SimpleFormulaContext aContext( xTokens, true, false ); - implImportOoxFormula( aContext ); + SequenceInputStream aStrm( *mxFormula ); + aTokens = importBiff12Formula( aBaseAddr, aStrm ); } - break; - case FILTER_BIFF: + else + aTokens = importOoxFormula( aBaseAddr ); + } + break; + case FILTER_BIFF: + { + OSL_ENSURE( mxBiffStrm.get(), "DefinedName::convertFormula - missing BIFF stream" ); + if( mxBiffStrm.get() ) { - SimpleFormulaContext aContext( xTokens, true, getBiff() <= BIFF4 ); - implImportBiffFormula( aContext ); + BiffInputStream& rStrm = mxBiffStrm->getStream(); + BiffInputStreamPosGuard aStrmGuard( rStrm ); + if( mxBiffStrm->restorePosition() ) + aTokens = importBiffFormula( aBaseAddr, rStrm, &mnFmlaSize ); } - break; - case FILTER_UNKNOWN: break; } + break; + case FILTER_UNKNOWN: + break; + } + xTokens->setTokens( aTokens ); - // set built-in names (print ranges, repeated titles, filter ranges) - if( !isGlobalName() ) switch( mcBuiltinId ) + // set built-in names (print ranges, repeated titles, filter ranges) + if( !isGlobalName() ) switch( mcBuiltinId ) + { + case BIFF_DEFNAME_PRINTAREA: { - case BIFF_DEFNAME_PRINTAREA: - { - Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); - ApiCellRangeList aPrintRanges; - getFormulaParser().extractCellRangeList( aPrintRanges, xTokens->getTokens(), false, mnCalcSheet ); - if( xPrintAreas.is() && !aPrintRanges.empty() ) - xPrintAreas->setPrintAreas( ContainerHelper::vectorToSequence( aPrintRanges ) ); - } - break; - case BIFF_DEFNAME_PRINTTITLES: + Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); + ApiCellRangeList aPrintRanges; + getFormulaParser().extractCellRangeList( aPrintRanges, xTokens->getTokens(), false, mnCalcSheet ); + if( xPrintAreas.is() && !aPrintRanges.empty() ) + xPrintAreas->setPrintAreas( ContainerHelper::vectorToSequence( aPrintRanges ) ); + } + break; + case BIFF_DEFNAME_PRINTTITLES: + { + Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); + ApiCellRangeList aTitleRanges; + getFormulaParser().extractCellRangeList( aTitleRanges, xTokens->getTokens(), false, mnCalcSheet ); + if( xPrintAreas.is() && !aTitleRanges.empty() ) { - Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); - ApiCellRangeList aTitleRanges; - getFormulaParser().extractCellRangeList( aTitleRanges, xTokens->getTokens(), false, mnCalcSheet ); - if( xPrintAreas.is() && !aTitleRanges.empty() ) + bool bHasRowTitles = false; + bool bHasColTitles = false; + const CellAddress& rMaxPos = getAddressConverter().getMaxAddress(); + for( ApiCellRangeList::const_iterator aIt = aTitleRanges.begin(), aEnd = aTitleRanges.end(); (aIt != aEnd) && (!bHasRowTitles || !bHasColTitles); ++aIt ) { - bool bHasRowTitles = false; - bool bHasColTitles = false; - const CellAddress& rMaxPos = getAddressConverter().getMaxAddress(); - for( ApiCellRangeList::const_iterator aIt = aTitleRanges.begin(), aEnd = aTitleRanges.end(); (aIt != aEnd) && (!bHasRowTitles || !bHasColTitles); ++aIt ) + bool bFullRow = (aIt->StartColumn == 0) && (aIt->EndColumn >= rMaxPos.Column); + bool bFullCol = (aIt->StartRow == 0) && (aIt->EndRow >= rMaxPos.Row); + if( !bHasRowTitles && bFullRow && !bFullCol ) { - bool bFullRow = (aIt->StartColumn == 0) && (aIt->EndColumn >= rMaxPos.Column); - bool bFullCol = (aIt->StartRow == 0) && (aIt->EndRow >= rMaxPos.Row); - if( !bHasRowTitles && bFullRow && !bFullCol ) - { - xPrintAreas->setTitleRows( *aIt ); - xPrintAreas->setPrintTitleRows( sal_True ); - bHasRowTitles = true; - } - else if( !bHasColTitles && bFullCol && !bFullRow ) - { - xPrintAreas->setTitleColumns( *aIt ); - xPrintAreas->setPrintTitleColumns( sal_True ); - bHasColTitles = true; - } + xPrintAreas->setTitleRows( *aIt ); + xPrintAreas->setPrintTitleRows( sal_True ); + bHasRowTitles = true; + } + else if( !bHasColTitles && bFullCol && !bFullRow ) + { + xPrintAreas->setTitleColumns( *aIt ); + xPrintAreas->setPrintTitleColumns( sal_True ); + bHasColTitles = true; } } } - break; } + break; } } @@ -597,26 +605,6 @@ bool DefinedName::getAbsoluteRange( CellRangeAddress& orRange ) const return xTokens.is() && getFormulaParser().extractCellRange( orRange, xTokens->getTokens(), false ); } -void DefinedName::implImportOoxFormula( FormulaContext& rContext ) -{ - if( mxFormula.get() ) - { - SequenceInputStream aStrm( *mxFormula ); - importBiff12Formula( rContext, mnCalcSheet, aStrm ); - } - else - importOoxFormula( rContext, mnCalcSheet ); -} - -void DefinedName::implImportBiffFormula( FormulaContext& rContext ) -{ - OSL_ENSURE( mxBiffStrm.get(), "DefinedName::implImportBiffFormula - missing BIFF stream" ); - BiffInputStream& rStrm = mxBiffStrm->getStream(); - BiffInputStreamPosGuard aStrmGuard( rStrm ); - if( mxBiffStrm->restorePosition() ) - importBiffFormula( rContext, mnCalcSheet, rStrm, &mnFmlaSize ); -} - // ============================================================================ DefinedNamesBuffer::DefinedNamesBuffer( const WorkbookHelper& rHelper ) : diff --git a/oox/source/xls/excelchartconverter.cxx b/oox/source/xls/excelchartconverter.cxx index 702a12fbde50..e2538cbc3ebc 100644 --- a/oox/source/xls/excelchartconverter.cxx +++ b/oox/source/xls/excelchartconverter.cxx @@ -85,13 +85,12 @@ Reference< XDataSequence > ExcelChartConverter::createDataSequence( { // parse the formula string, create a token sequence FormulaParser& rParser = getFormulaParser(); - TokensFormulaContext aContext( true, true ); - aContext.setBaseAddress( CellAddress( getCurrentSheetIndex(), 0, 0 ) ); - rParser.importFormula( aContext, rDataSeq.maFormula ); + CellAddress aBaseAddr( getCurrentSheetIndex(), 0, 0 ); + ApiTokenSequence aTokens = rParser.importFormula( aBaseAddr, rDataSeq.maFormula ); // create a range list from the token sequence ApiCellRangeList aRanges; - rParser.extractCellRangeList( aRanges, aContext.getTokens(), false ); + rParser.extractCellRangeList( aRanges, aTokens, false ); aRangeRep = rParser.generateApiRangeListString( aRanges ); } else if( !rDataSeq.maData.empty() ) diff --git a/oox/source/xls/excelfilter.cxx b/oox/source/xls/excelfilter.cxx index aeac1494c338..eb5183a4dd80 100644 --- a/oox/source/xls/excelfilter.cxx +++ b/oox/source/xls/excelfilter.cxx @@ -56,29 +56,29 @@ using ::oox::drawingml::table::TableStyleListPtr; // ============================================================================ ExcelFilterBase::ExcelFilterBase() : - mpData( 0 ) + mpBookGlob( 0 ) { } ExcelFilterBase::~ExcelFilterBase() { - OSL_ENSURE( !mpData, "ExcelFilterBase::~ExcelFilterBase - workbook data not cleared" ); + OSL_ENSURE( !mpBookGlob, "ExcelFilterBase::~ExcelFilterBase - workbook data not cleared" ); } -void ExcelFilterBase::registerWorkbookData( WorkbookData& rData ) +void ExcelFilterBase::registerWorkbookGlobals( WorkbookGlobals& rBookGlob ) { - mpData = &rData; + mpBookGlob = &rBookGlob; } -WorkbookData& ExcelFilterBase::getWorkbookData() const +WorkbookGlobals& ExcelFilterBase::getWorkbookGlobals() const { - OSL_ENSURE( mpData, "ExcelFilterBase::getWorkbookData - missing workbook data" ); - return *mpData; + OSL_ENSURE( mpBookGlob, "ExcelFilterBase::getWorkbookGlobals - missing workbook data" ); + return *mpBookGlob; } -void ExcelFilterBase::unregisterWorkbookData() +void ExcelFilterBase::unregisterWorkbookGlobals() { - mpData = 0; + mpBookGlob = 0; } // ============================================================================ @@ -125,8 +125,11 @@ bool ExcelFilter::importDocument() throw() if( aWorkbookPath.getLength() == 0 ) return false; - WorkbookHelperRoot aHelper( *this ); - return aHelper.isValid() && importFragment( new WorkbookFragment( aHelper, aWorkbookPath ) ); + /* Construct the WorkbookGlobals object referred to by every instance of + the class WorkbookHelper, and execute the import filter by constructing + an instance of WorkbookFragment and loading the file. */ + WorkbookGlobalsRef xBookGlob = WorkbookHelper::constructGlobals( *this ); + return xBookGlob.get() && importFragment( new WorkbookFragment( *xBookGlob, aWorkbookPath ) ); } bool ExcelFilter::exportDocument() throw() @@ -136,7 +139,7 @@ bool ExcelFilter::exportDocument() throw() const ::oox::drawingml::Theme* ExcelFilter::getCurrentTheme() const { - return &WorkbookHelper( getWorkbookData() ).getTheme(); + return &WorkbookHelper( getWorkbookGlobals() ).getTheme(); } ::oox::vml::Drawing* ExcelFilter::getVmlDrawing() @@ -151,12 +154,12 @@ const TableStyleListPtr ExcelFilter::getTableStyles() ::oox::drawingml::chart::ChartConverter& ExcelFilter::getChartConverter() { - return WorkbookHelper( getWorkbookData() ).getChartConverter(); + return WorkbookHelper( getWorkbookGlobals() ).getChartConverter(); } GraphicHelper* ExcelFilter::implCreateGraphicHelper() const { - return new ExcelGraphicHelper( getWorkbookData() ); + return new ExcelGraphicHelper( getWorkbookGlobals() ); } ::oox::ole::VbaProject* ExcelFilter::implCreateVbaProject() const @@ -225,8 +228,11 @@ bool ExcelBiffFilter::importDocument() throw() if( eBiff == BIFF_UNKNOWN ) return false; - WorkbookHelperRoot aHelper( *this, eBiff ); - return aHelper.isValid() && BiffWorkbookFragment( aHelper, aWorkbookName ).importFragment(); + /* Construct the WorkbookGlobals object referred to by every instance of + the class WorkbookHelper, and execute the import filter by constructing + an instance of BiffWorkbookFragment and loading the file. */ + WorkbookGlobalsRef xBookGlob = WorkbookHelper::constructGlobals( *this, eBiff ); + return xBookGlob.get() && BiffWorkbookFragment( *xBookGlob, aWorkbookName ).importFragment(); } bool ExcelBiffFilter::exportDocument() throw() @@ -236,7 +242,7 @@ bool ExcelBiffFilter::exportDocument() throw() GraphicHelper* ExcelBiffFilter::implCreateGraphicHelper() const { - return new ExcelGraphicHelper( getWorkbookData() ); + return new ExcelGraphicHelper( getWorkbookGlobals() ); } ::oox::ole::VbaProject* ExcelBiffFilter::implCreateVbaProject() const @@ -289,11 +295,16 @@ bool ExcelVbaProjectFilter::importDocument() throw() if( !xVbaPrjStrg || !xVbaPrjStrg->isStorage() ) return false; - WorkbookHelperRoot aHelper( *this, eBiff ); + /* Construct the WorkbookGlobals object referred to by every instance of + the class WorkbookHelper. */ + WorkbookGlobalsRef xBookGlob = WorkbookHelper::constructGlobals( *this, eBiff ); + if( !xBookGlob.get() ) + return false; + // set palette colors passed in service constructor Any aPalette = getArgument( CREATE_OUSTRING( "ColorPalette" ) ); - aHelper.getStyles().importPalette( aPalette ); - // import the VBA project + WorkbookHelper( *xBookGlob ).getStyles().importPalette( aPalette ); + // import the VBA project (getVbaProject() implemented in base class) getVbaProject().importVbaProject( *xVbaPrjStrg, getGraphicHelper() ); return true; } diff --git a/oox/source/xls/excelhandlers.cxx b/oox/source/xls/excelhandlers.cxx index ba2fdd3a03d0..15f9d8297032 100644 --- a/oox/source/xls/excelhandlers.cxx +++ b/oox/source/xls/excelhandlers.cxx @@ -51,17 +51,10 @@ WorkbookFragmentBase::WorkbookFragmentBase( // ============================================================================ -WorksheetFragmentBase::WorksheetFragmentBase( const WorkbookHelper& rHelper, - const OUString& rFragmentPath, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : - FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ), - WorksheetHelperRoot( rHelper, rxProgressBar, eSheetType, nSheet ) -{ -} - WorksheetFragmentBase::WorksheetFragmentBase( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) : FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ), - WorksheetHelperRoot( rHelper ) + WorksheetHelper( rHelper ) { } @@ -81,14 +74,8 @@ BiffWorkbookContextBase::BiffWorkbookContextBase( const WorkbookHelper& rHelper // ---------------------------------------------------------------------------- -BiffWorksheetContextBase::BiffWorksheetContextBase( const WorkbookHelper& rHelper, - const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : - WorksheetHelperRoot( rHelper, rxProgressBar, eSheetType, nSheet ) -{ -} - BiffWorksheetContextBase::BiffWorksheetContextBase( const WorksheetHelper& rHelper ) : - WorksheetHelperRoot( rHelper ) + WorksheetHelper( rHelper ) { } @@ -202,18 +189,16 @@ BiffWorkbookFragmentBase::BiffWorkbookFragmentBase( const WorkbookHelper& rHelpe // ---------------------------------------------------------------------------- -BiffWorksheetFragmentBase::BiffWorksheetFragmentBase( const BiffWorkbookFragmentBase& rParent, - const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : +BiffWorksheetFragmentBase::BiffWorksheetFragmentBase( const WorksheetHelper& rHelper, const BiffWorkbookFragmentBase& rParent ) : BiffFragmentHandler( rParent ), - WorksheetHelperRoot( rParent, rxProgressBar, eSheetType, nSheet ) + WorksheetHelper( rHelper ) { } // ---------------------------------------------------------------------------- -BiffSkipWorksheetFragment::BiffSkipWorksheetFragment( const BiffWorkbookFragmentBase& rParent, - const ISegmentProgressBarRef& rxProgressBar, sal_Int16 nSheet ) : - BiffWorksheetFragmentBase( rParent, rxProgressBar, SHEETTYPE_EMPTYSHEET, nSheet ) +BiffSkipWorksheetFragment::BiffSkipWorksheetFragment( const WorksheetHelper& rHelper, const BiffWorkbookFragmentBase& rParent ) : + BiffWorksheetFragmentBase( rHelper, rParent ) { } diff --git a/oox/source/xls/externallinkbuffer.cxx b/oox/source/xls/externallinkbuffer.cxx index 683ac3582071..fe527f35f634 100644 --- a/oox/source/xls/externallinkbuffer.cxx +++ b/oox/source/xls/externallinkbuffer.cxx @@ -242,9 +242,9 @@ void ExternalName::importExternalName( BiffInputStream& rStrm ) // cell references to other internal sheets are stored in hidden external names if( bHiddenRef && (getBiff() == BIFF4) && isWorkbookFile() ) { - TokensFormulaContext aContext( true, true ); - importBiffFormula( aContext, mrParentLink.getCalcSheetIndex(), rStrm ); - extractReference( aContext.getTokens() ); + CellAddress aBaseAddr( mrParentLink.getCalcSheetIndex(), 0, 0 ); + ApiTokenSequence aTokens = importBiffFormula( aBaseAddr, rStrm ); + extractReference( aTokens ); } break; @@ -252,9 +252,8 @@ void ExternalName::importExternalName( BiffInputStream& rStrm ) // cell references to other documents are stored in hidden external names if( bHiddenRef ) { - TokensFormulaContext aContext( true, true ); - importBiffFormula( aContext, 0, rStrm ); - extractExternalReference( aContext.getTokens() ); + ApiTokenSequence aTokens = importBiffFormula( CellAddress(), rStrm ); + extractExternalReference( aTokens ); } break; diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx index 58049f4851d7..25398f9aa133 100755 --- a/oox/source/xls/formulabase.cxx +++ b/oox/source/xls/formulabase.cxx @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include "oox/core/filterbase.hxx" @@ -1366,51 +1365,6 @@ ApiTokenSequence ApiParserWrapper::parseFormula( const OUString& rFormula, const return aTokenSeq; } -// formula contexts =========================================================== - -FormulaContext::FormulaContext( bool bRelativeAsOffset, bool b2dRefsAs3dRefs, bool bAllowNulChars ) : - maBaseAddress( 0, 0, 0 ), - mbRelativeAsOffset( bRelativeAsOffset ), - mb2dRefsAs3dRefs( b2dRefsAs3dRefs ), - mbAllowNulChars( bAllowNulChars ) -{ -} - -FormulaContext::~FormulaContext() -{ -} - -void FormulaContext::setSharedFormula( const CellAddress& ) -{ -} - -// ---------------------------------------------------------------------------- - -TokensFormulaContext::TokensFormulaContext( bool bRelativeAsOffset, bool b2dRefsAs3dRefs, bool bAllowNulChars ) : - FormulaContext( bRelativeAsOffset, b2dRefsAs3dRefs, bAllowNulChars ) -{ -} - -void TokensFormulaContext::setTokens( const ApiTokenSequence& rTokens ) -{ - maTokens = rTokens; -} - -// ---------------------------------------------------------------------------- - -SimpleFormulaContext::SimpleFormulaContext( const Reference< XFormulaTokens >& rxTokens, - bool bRelativeAsOffset, bool b2dRefsAs3dRefs, bool bAllowNulChars ) : - FormulaContext( bRelativeAsOffset, b2dRefsAs3dRefs, bAllowNulChars ), - mxTokens( rxTokens ) -{ - OSL_ENSURE( mxTokens.is(), "SimpleFormulaContext::SimpleFormulaContext - missing XFormulaTokens interface" ); -} - -void SimpleFormulaContext::setTokens( const ApiTokenSequence& rTokens ) -{ - mxTokens->setTokens( rTokens ); -} - // formula parser/printer base class for filters ============================== namespace { @@ -1708,6 +1662,12 @@ bool FormulaProcessorBase::extractString( OUString& orString, const ApiTokenSequ return aTokenIt.is() && (aTokenIt->OpCode == OPCODE_PUSH) && (aTokenIt->Data >>= orString) && !(++aTokenIt).is(); } +bool FormulaProcessorBase::extractSpecialTokenInfo( ApiSpecialTokenInfo& orTokenInfo, const ApiTokenSequence& rTokens ) const +{ + ApiTokenIterator aTokenIt( rTokens, OPCODE_SPACES, true ); + return aTokenIt.is() && (aTokenIt->OpCode == OPCODE_BAD) && (aTokenIt->Data >>= orTokenInfo); +} + void FormulaProcessorBase::convertStringToStringList( ApiTokenSequence& orTokens, sal_Unicode cStringSep, bool bTrimLeadingSpaces ) const { diff --git a/oox/source/xls/formulaparser.cxx b/oox/source/xls/formulaparser.cxx index d7eb91a9c05c..674f9a8e6320 100644 --- a/oox/source/xls/formulaparser.cxx +++ b/oox/source/xls/formulaparser.cxx @@ -440,27 +440,23 @@ class FormulaParserImpl : public FormulaFinalizer, public WorkbookHelper public: explicit FormulaParserImpl( const FormulaParser& rParent ); - /** Converts an XML formula string. */ - virtual void importOoxFormula( - FormulaContext& rContext, + /** Converts an OOXML formula string. */ + virtual ApiTokenSequence importOoxFormula( + const CellAddress& rBaseAddress, const OUString& rFormulaString ); /** Imports and converts a BIFF12 token array from the passed stream. */ - virtual void importBiff12Formula( - FormulaContext& rContext, + virtual ApiTokenSequence importBiff12Formula( + const CellAddress& rBaseAddress, + FormulaType eType, SequenceInputStream& rStrm ); /** Imports and converts a BIFF2-BIFF8 token array from the passed stream. */ - virtual void importBiffFormula( - FormulaContext& rContext, + virtual ApiTokenSequence importBiffFormula( + const CellAddress& rBaseAddress, + FormulaType eType, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ); - /** Finalizes the passed token array after import (e.g. adjusts function - parameters) and sets the formula using the passed context. */ - void setFormula( - FormulaContext& rContext, - const ApiTokenSequence& rTokens ); - /** Tries to resolve the passed ref-id to an OLE target URL. */ OUString resolveOleTarget( sal_Int32 nRefId, bool bUseRefSheets ) const; @@ -468,18 +464,10 @@ protected: typedef ::std::pair< sal_Int32, bool > WhiteSpace; typedef ::std::vector< WhiteSpace > WhiteSpaceVec; - /** Sets the current formula context used for import. */ - inline FormulaContext& getFormulaContext() const { return *mpContext; } - - /** Sets the current formula context used for import. */ - void initializeImport( FormulaContext& rContext ); - /** Finalizes the passed token array after import. */ - void finalizeImport( const ApiTokenSequence& rTokens ); + /** Initializes the formula parser before importing a formula. */ + void initializeImport( const CellAddress& rBaseAddress, FormulaType eType ); /** Finalizes the internal token storage after import. */ - void finalizeImport(); - - /** Inserts a shared formula using the current formula context and passed base address. */ - void setSharedFormula( const BinAddress& rBaseAddr ); + ApiTokenSequence finalizeImport(); // token array ------------------------------------------------------------ @@ -542,6 +530,7 @@ protected: bool pushExternalFuncOperand( const FunctionInfo& rFuncInfo ); bool pushDdeLinkOperand( const OUString& rDdeServer, const OUString& rDdeTopic, const OUString& rDdeItem ); bool pushExternalNameOperand( const ExternalNameRef& rxExtName, const ExternalLink& rExtLink ); + bool pushSpecialTokenOperand( const BinAddress& rBaseAddr, bool bTable ); bool pushUnaryPreOperator( sal_Int32 nOpCode ); bool pushUnaryPostOperator( sal_Int32 nOpCode ); @@ -575,6 +564,12 @@ protected: const sal_Int32 mnMaxXlsCol; /// Maximum column index in imported document. const sal_Int32 mnMaxXlsRow; /// Maximum row index in imported document. + CellAddress maBaseAddr; /// Base address for relative references. + bool mbRelativeAsOffset; /// True = relative row/column index is (signed) offset, false = explicit index. + bool mb2dRefsAs3dRefs; /// True = convert all 2D references to 3D references in sheet specified by base address. + bool mbSpecialTokens; /// True = special handling for tExp and tTbl tokens, false = exit with error. + bool mbAllowNulChars; /// True = keep NUL characters in string tokens. + private: typedef ::std::vector< size_t > SizeTypeVector; @@ -584,7 +579,6 @@ private: WhiteSpaceVec maLeadingSpaces; /// List of whitespaces before next token. WhiteSpaceVec maOpeningSpaces; /// List of whitespaces before opening parenthesis. WhiteSpaceVec maClosingSpaces; /// List of whitespaces before closing parenthesis. - FormulaContext* mpContext; /// Current formula context. }; // ---------------------------------------------------------------------------- @@ -596,7 +590,9 @@ FormulaParserImpl::FormulaParserImpl( const FormulaParser& rParent ) : mnMaxApiRow( rParent.getAddressConverter().getMaxApiAddress().Row ), mnMaxXlsCol( rParent.getAddressConverter().getMaxXlsAddress().Column ), mnMaxXlsRow( rParent.getAddressConverter().getMaxXlsAddress().Row ), - mpContext( 0 ) + mbRelativeAsOffset( false ), + mb2dRefsAs3dRefs( false ), + mbAllowNulChars( false ) { // reserve enough space to make resize(), push_back() etc. cheap maTokenStorage.reserve( 0x2000 ); @@ -607,25 +603,22 @@ FormulaParserImpl::FormulaParserImpl( const FormulaParser& rParent ) : maClosingSpaces.reserve( 256 ); } -void FormulaParserImpl::importOoxFormula( FormulaContext&, const OUString& ) +ApiTokenSequence FormulaParserImpl::importOoxFormula( const CellAddress&, const OUString& ) { OSL_ENSURE( false, "FormulaParserImpl::importOoxFormula - not implemented" ); + return ApiTokenSequence(); } -void FormulaParserImpl::importBiff12Formula( FormulaContext&, SequenceInputStream& ) +ApiTokenSequence FormulaParserImpl::importBiff12Formula( const CellAddress&, FormulaType, SequenceInputStream& ) { OSL_ENSURE( false, "FormulaParserImpl::importBiff12Formula - not implemented" ); + return ApiTokenSequence(); } -void FormulaParserImpl::importBiffFormula( FormulaContext&, BiffInputStream&, const sal_uInt16* ) +ApiTokenSequence FormulaParserImpl::importBiffFormula( const CellAddress&, FormulaType, BiffInputStream&, const sal_uInt16* ) { OSL_ENSURE( false, "FormulaParserImpl::importBiffFormula - not implemented" ); -} - -void FormulaParserImpl::setFormula( FormulaContext& rContext, const ApiTokenSequence& rTokens ) -{ - initializeImport( rContext ); - finalizeImport( rTokens ); + return ApiTokenSequence(); } OUString FormulaParserImpl::resolveOleTarget( sal_Int32 nRefId, bool bUseRefSheets ) const @@ -637,22 +630,41 @@ OUString FormulaParserImpl::resolveOleTarget( sal_Int32 nRefId, bool bUseRefShee return OUString(); } -void FormulaParserImpl::initializeImport( FormulaContext& rContext ) +void FormulaParserImpl::initializeImport( const CellAddress& rBaseAddr, FormulaType eType ) { + maBaseAddr = rBaseAddr; + mbRelativeAsOffset = mb2dRefsAs3dRefs = mbSpecialTokens = mbAllowNulChars = false; + switch( eType ) + { + case FORMULATYPE_CELL: + mbSpecialTokens = true; + break; + case FORMULATYPE_ARRAY: + break; + case FORMULATYPE_SHAREDFORMULA: + mbRelativeAsOffset = true; + break; + case FORMULATYPE_CONDFORMAT: + mbRelativeAsOffset = true; + break; + case FORMULATYPE_VALIDATION: + mbRelativeAsOffset = true; + // enable NUL characters in BIFF import, string list is single tStr token with NUL separators + mbAllowNulChars = getFilterType() == FILTER_BIFF; + break; + case FORMULATYPE_DEFINEDNAME: + mbRelativeAsOffset = true; + // BIFF2-BIFF4: convert 2D referebces to absolute 3D references + mb2dRefsAs3dRefs = (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4); + break; + } + maTokenStorage.clear(); maTokenIndexes.clear(); maOperandSizeStack.clear(); - mpContext = &rContext; } -void FormulaParserImpl::finalizeImport( const ApiTokenSequence& rTokens ) -{ - ApiTokenSequence aFinalTokens = finalizeTokenArray( rTokens ); - if( aFinalTokens.hasElements() ) - mpContext->setTokens( aFinalTokens ); -} - -void FormulaParserImpl::finalizeImport() +ApiTokenSequence FormulaParserImpl::finalizeImport() { ApiTokenSequence aTokens( static_cast< sal_Int32 >( maTokenIndexes.size() ) ); if( aTokens.hasElements() ) @@ -661,14 +673,7 @@ void FormulaParserImpl::finalizeImport() for( SizeTypeVector::const_iterator aIt = maTokenIndexes.begin(), aEnd = maTokenIndexes.end(); aIt != aEnd; ++aIt, ++pToken ) *pToken = maTokenStorage[ *aIt ]; } - finalizeImport( aTokens ); -} - -void FormulaParserImpl::setSharedFormula( const BinAddress& rBaseAddr ) -{ - CellAddress aApiBaseAddr; - if( getAddressConverter().convertToCellAddress( aApiBaseAddr, rBaseAddr, mpContext->getBaseAddress().Sheet, false ) ) - mpContext->setSharedFormula( aApiBaseAddr ); + return finalizeTokenArray( aTokens ); } // token array ---------------------------------------------------------------- @@ -1018,7 +1023,7 @@ bool FormulaParserImpl::pushNlrOperand( const BinSingleRef2d& rRef ) bool FormulaParserImpl::pushEmbeddedRefOperand( const DefinedNameBase& rName, bool bPushBadToken ) { - Any aRefAny = rName.getReference( mpContext->getBaseAddress() ); + Any aRefAny = rName.getReference( maBaseAddr ); if( aRefAny.hasValue() ) return pushAnyOperand( aRefAny, OPCODE_PUSH ); if( bPushBadToken && (rName.getModelName().getLength() > 0) && (rName.getModelName()[ 0 ] >= ' ') ) @@ -1088,6 +1093,13 @@ bool FormulaParserImpl::pushExternalNameOperand( const ExternalNameRef& rxExtNam return pushBiffErrorOperand( BIFF_ERR_NAME ); } +bool FormulaParserImpl::pushSpecialTokenOperand( const BinAddress& rBaseAddr, bool bTable ) +{ + CellAddress aBaseAddr( maBaseAddr.Sheet, rBaseAddr.mnCol, rBaseAddr.mnRow ); + ApiSpecialTokenInfo aTokenInfo( aBaseAddr, bTable ); + return mbSpecialTokens && (getFormulaSize() == 0) && pushValueOperand( aTokenInfo, OPCODE_BAD ); +} + bool FormulaParserImpl::pushUnaryPreOperator( sal_Int32 nOpCode ) { return pushUnaryPreOperatorToken( nOpCode, &maLeadingSpaces ) && resetSpaces(); @@ -1122,15 +1134,15 @@ bool FormulaParserImpl::pushFunctionOperator( const FunctionInfo& rFuncInfo, siz void FormulaParserImpl::initReference2d( SingleReference& orApiRef ) const { - if( mpContext->is2dRefsAs3dRefs() ) + if( mb2dRefsAs3dRefs ) { - initReference3d( orApiRef, mpContext->getBaseAddress().Sheet, false ); + initReference3d( orApiRef, maBaseAddr.Sheet, false ); } else { orApiRef.Flags = SHEET_RELATIVE; // #i10184# absolute sheet index needed for relative references in shared formulas - orApiRef.Sheet = mpContext->getBaseAddress().Sheet; + orApiRef.Sheet = maBaseAddr.Sheet; orApiRef.RelativeSheet = 0; } } @@ -1175,9 +1187,9 @@ void FormulaParserImpl::convertReference( SingleReference& orApiRef, const BinSi if( !bRelativeAsOffset ) { if( rRef.mbColRel ) - orApiRef.RelativeColumn -= mpContext->getBaseAddress().Column; + orApiRef.RelativeColumn -= maBaseAddr.Column; if( rRef.mbRowRel ) - orApiRef.RelativeRow -= mpContext->getBaseAddress().Row; + orApiRef.RelativeRow -= maBaseAddr.Row; } } } @@ -1264,12 +1276,13 @@ class OoxFormulaParserImpl : public FormulaParserImpl public: explicit OoxFormulaParserImpl( const FormulaParser& rParent ); - virtual void importOoxFormula( - FormulaContext& rContext, + virtual ApiTokenSequence importOoxFormula( + const CellAddress& rBaseAddr, const OUString& rFormulaString ); - virtual void importBiff12Formula( - FormulaContext& rContext, + virtual ApiTokenSequence importBiff12Formula( + const CellAddress& rBaseAddr, + FormulaType eType, SequenceInputStream& rStrm ); private: @@ -1319,20 +1332,19 @@ OoxFormulaParserImpl::OoxFormulaParserImpl( const FormulaParser& rParent ) : { } -void OoxFormulaParserImpl::importOoxFormula( FormulaContext& rContext, const OUString& rFormulaString ) +ApiTokenSequence OoxFormulaParserImpl::importOoxFormula( const CellAddress& rBaseAddr, const OUString& rFormulaString ) { if( mbNeedExtRefs ) { maApiParser.getParserProperties().setProperty( PROP_ExternalLinks, getExternalLinks().getLinkInfos() ); mbNeedExtRefs = false; } - initializeImport( rContext ); - finalizeImport( maApiParser.parseFormula( rFormulaString, rContext.getBaseAddress() ) ); + return finalizeTokenArray( maApiParser.parseFormula( rFormulaString, rBaseAddr ) ); } -void OoxFormulaParserImpl::importBiff12Formula( FormulaContext& rContext, SequenceInputStream& rStrm ) +ApiTokenSequence OoxFormulaParserImpl::importBiff12Formula( const CellAddress& rBaseAddr, FormulaType eType, SequenceInputStream& rStrm ) { - initializeImport( rContext ); + initializeImport( rBaseAddr, eType ); sal_Int32 nFmlaSize = rStrm.readInt32(); sal_Int64 nFmlaPos = rStrm.tell(); @@ -1345,7 +1357,7 @@ void OoxFormulaParserImpl::importBiff12Formula( FormulaContext& rContext, Sequen rStrm.seek( nFmlaPos ); bool bOk = (nFmlaSize >= 0) && (nAddDataSize >= 0); - bool bRelativeAsOffset = getFormulaContext().isRelativeAsOffset(); + bool bRelativeAsOffset = mbRelativeAsOffset; while( bOk && !rStrm.isEof() && (rStrm.tell() < nFmlaEndPos) ) { @@ -1422,12 +1434,16 @@ void OoxFormulaParserImpl::importBiff12Formula( FormulaContext& rContext, Sequen } // build and finalize the token sequence + ApiTokenSequence aFinalTokens; if( bOk && (rStrm.tell() == nFmlaEndPos) && (mnAddDataPos == nAddDataEndPos) ) - finalizeImport(); + aFinalTokens = finalizeImport(); // seek behind token array if( (nFmlaSize >= 0) && (nAddDataSize >= 0) ) rStrm.seek( nAddDataEndPos ); + + // return the final token sequence + return aFinalTokens; } // import token contents and create API formula token ------------------------- @@ -1571,7 +1587,7 @@ bool OoxFormulaParserImpl::importTableToken( SequenceInputStream& rStrm ) } else if( bThisRow ) { - nStartRow = nEndRow = getFormulaContext().getBaseAddress().Row - xTable->getRange().StartRow; + nStartRow = nEndRow = maBaseAddr.Row - xTable->getRange().StartRow; bFixedHeight = true; } else @@ -1750,9 +1766,7 @@ bool OoxFormulaParserImpl::importExpToken( SequenceInputStream& rStrm ) swapStreamPosition( rStrm ); rStrm >> aBaseAddr.mnCol; swapStreamPosition( rStrm ); - setSharedFormula( aBaseAddr ); - // formula has been set, exit parser by returning false - return false; + return pushSpecialTokenOperand( aBaseAddr, false ); } LinkSheetRange OoxFormulaParserImpl::readSheetRange( SequenceInputStream& rStrm ) @@ -1867,8 +1881,9 @@ class BiffFormulaParserImpl : public FormulaParserImpl public: explicit BiffFormulaParserImpl( const FormulaParser& rParent ); - virtual void importBiffFormula( - FormulaContext& rContext, + virtual ApiTokenSequence importBiffFormula( + const CellAddress& rBaseAddr, + FormulaType eType, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ); private: @@ -1904,7 +1919,8 @@ private: bool importFuncVarToken2( BiffInputStream& rStrm ); bool importFuncVarToken4( BiffInputStream& rStrm ); bool importFuncCEToken( BiffInputStream& rStrm ); - bool importExpToken5( BiffInputStream& rStrm ); + bool importExpToken( BiffInputStream& rStrm ); + bool importTblToken( BiffInputStream& rStrm ); bool importNlrAddrToken( BiffInputStream& rStrm, bool bRow ); bool importNlrRangeToken( BiffInputStream& rStrm ); @@ -1953,7 +1969,6 @@ private: ImportTokenFunc mpImportFuncToken; /// Pointer to tFunc import function (function with fixed parameter count). ImportTokenFunc mpImportFuncVarToken; /// Pointer to tFuncVar import function (function with variable parameter count). ImportTokenFunc mpImportFuncCEToken; /// Pointer to tFuncCE import function (command macro call). - ImportTokenFunc mpImportExpToken; /// Pointer to tExp import function (array/shared formula). sal_Int64 mnAddDataPos; /// Current stream position for additional data (tArray, tMemArea, tNlr). sal_Int32 mnCurrRefId; /// Current ref-id from tSheet token (BIFF2-BIFF4 only). sal_uInt16 mnAttrDataSize; /// Size of one tAttr data element. @@ -1987,7 +2002,6 @@ BiffFormulaParserImpl::BiffFormulaParserImpl( const FormulaParser& rParent ) : mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken2; mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken2; mpImportFuncCEToken = &BiffFormulaParserImpl::importFuncCEToken; - mpImportExpToken = &BiffFormulaParserImpl::importTokenNotAvailable; mnAttrDataSize = 1; mnArraySize = 6; mnNameSize = 5; @@ -2009,7 +2023,6 @@ BiffFormulaParserImpl::BiffFormulaParserImpl( const FormulaParser& rParent ) : mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken2; mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken2; mpImportFuncCEToken = &BiffFormulaParserImpl::importFuncCEToken; - mpImportExpToken = &BiffFormulaParserImpl::importTokenNotAvailable; mnAttrDataSize = 2; mnArraySize = 7; mnNameSize = 8; @@ -2031,7 +2044,6 @@ BiffFormulaParserImpl::BiffFormulaParserImpl( const FormulaParser& rParent ) : mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken4; mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken4; mpImportFuncCEToken = &BiffFormulaParserImpl::importTokenNotAvailable; - mpImportExpToken = &BiffFormulaParserImpl::importTokenNotAvailable; mnAttrDataSize = 2; mnArraySize = 7; mnNameSize = 8; @@ -2053,7 +2065,6 @@ BiffFormulaParserImpl::BiffFormulaParserImpl( const FormulaParser& rParent ) : mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken4; mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken4; mpImportFuncCEToken = &BiffFormulaParserImpl::importTokenNotAvailable; - mpImportExpToken = &BiffFormulaParserImpl::importExpToken5; mnAttrDataSize = 2; mnArraySize = 7; mnNameSize = 12; @@ -2075,7 +2086,6 @@ BiffFormulaParserImpl::BiffFormulaParserImpl( const FormulaParser& rParent ) : mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken4; mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken4; mpImportFuncCEToken = &BiffFormulaParserImpl::importTokenNotAvailable; - mpImportExpToken = &BiffFormulaParserImpl::importExpToken5; mnAttrDataSize = 2; mnArraySize = 7; mnNameSize = 2; @@ -2087,15 +2097,14 @@ BiffFormulaParserImpl::BiffFormulaParserImpl( const FormulaParser& rParent ) : } } -void BiffFormulaParserImpl::importBiffFormula( FormulaContext& rContext, - BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) +ApiTokenSequence BiffFormulaParserImpl::importBiffFormula( const CellAddress& rBaseAddr, + FormulaType eType, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) { - initializeImport( rContext ); + initializeImport( rBaseAddr, eType ); mnCurrRefId = 0; sal_uInt16 nFmlaSize = lclReadFmlaSize( rStrm, getBiff(), pnFmlaSize ); sal_Int64 nEndPos = mnAddDataPos = rStrm.tell() + nFmlaSize; - bool bRelativeAsOffset = getFormulaContext().isRelativeAsOffset(); bool bOk = true; while( bOk && !rStrm.isEof() && (rStrm.tell() < nEndPos) ) @@ -2113,8 +2122,8 @@ void BiffFormulaParserImpl::importBiffFormula( FormulaContext& rContext, // base tokens switch( nBaseId ) { - case BIFF_TOKID_EXP: bOk = (this->*mpImportExpToken)( rStrm ); break; - case BIFF_TOKID_TBL: bOk = false; /* multiple op. will be set externally */ break; + case BIFF_TOKID_EXP: bOk = importExpToken( rStrm ); break; + case BIFF_TOKID_TBL: bOk = importTblToken( rStrm ); break; case BIFF_TOKID_ADD: bOk = pushBinaryOperator( OPCODE_ADD ); break; case BIFF_TOKID_SUB: bOk = pushBinaryOperator( OPCODE_SUB ); break; case BIFF_TOKID_MUL: bOk = pushBinaryOperator( OPCODE_MULT ); break; @@ -2170,10 +2179,10 @@ void BiffFormulaParserImpl::importBiffFormula( FormulaContext& rContext, case BIFF_TOKID_MEMNOMEMN: bOk = importMemFuncToken( rStrm ); break; case BIFF_TOKID_FUNCCE: bOk = (this->*mpImportFuncCEToken)( rStrm ); break; case BIFF_TOKID_NAMEX: bOk = (this->*mpImportNameXToken)( rStrm ); break; - case BIFF_TOKID_REF3D: bOk = (this->*mpImportRef3dToken)( rStrm, false, bRelativeAsOffset ); break; - case BIFF_TOKID_AREA3D: bOk = (this->*mpImportArea3dToken)( rStrm, false, bRelativeAsOffset ); break; - case BIFF_TOKID_REFERR3D: bOk = (this->*mpImportRef3dToken)( rStrm, true, bRelativeAsOffset ); break; - case BIFF_TOKID_AREAERR3D: bOk = (this->*mpImportArea3dToken)( rStrm, true, bRelativeAsOffset ); break; + case BIFF_TOKID_REF3D: bOk = (this->*mpImportRef3dToken)( rStrm, false, mbRelativeAsOffset ); break; + case BIFF_TOKID_AREA3D: bOk = (this->*mpImportArea3dToken)( rStrm, false, mbRelativeAsOffset ); break; + case BIFF_TOKID_REFERR3D: bOk = (this->*mpImportRef3dToken)( rStrm, true, mbRelativeAsOffset ); break; + case BIFF_TOKID_AREAERR3D: bOk = (this->*mpImportArea3dToken)( rStrm, true, mbRelativeAsOffset ); break; default: bOk = false; } } @@ -2181,11 +2190,15 @@ void BiffFormulaParserImpl::importBiffFormula( FormulaContext& rContext, } // build and finalize the token sequence + ApiTokenSequence aFinalTokens; if( bOk && (rStrm.tell() == nEndPos) ) - finalizeImport(); + aFinalTokens = finalizeImport(); // seek behind additional token data of tArray, tMemArea, tNlr tokens rStrm.seek( mnAddDataPos ); + + // return the final token sequence + return aFinalTokens; } // import token contents and create API formula token ------------------------- @@ -2204,13 +2217,13 @@ bool BiffFormulaParserImpl::importRefTokenNotAvailable( BiffInputStream&, bool, bool BiffFormulaParserImpl::importStrToken2( BiffInputStream& rStrm ) { - return pushValueOperand( rStrm.readByteStringUC( false, getTextEncoding(), getFormulaContext().isNulCharsAllowed() ) ); + return pushValueOperand( rStrm.readByteStringUC( false, getTextEncoding(), mbAllowNulChars ) ); } bool BiffFormulaParserImpl::importStrToken8( BiffInputStream& rStrm ) { // read flags field for empty strings also - return pushValueOperand( rStrm.readUniStringBody( rStrm.readuInt8(), getFormulaContext().isNulCharsAllowed() ) ); + return pushValueOperand( rStrm.readUniStringBody( rStrm.readuInt8(), mbAllowNulChars ) ); } bool BiffFormulaParserImpl::importAttrToken( BiffInputStream& rStrm ) @@ -2340,7 +2353,6 @@ bool BiffFormulaParserImpl::importArrayToken( BiffInputStream& rStrm ) size_t nOpSize = popOperandSize(); size_t nOldArraySize = getFormulaSize(); bool bBiff8 = getBiff() == BIFF8; - bool bNulChars = getFormulaContext().isNulCharsAllowed(); // read array size swapStreamPosition( rStrm ); @@ -2369,8 +2381,8 @@ bool BiffFormulaParserImpl::importArrayToken( BiffInputStream& rStrm ) break; case BIFF_DATATYPE_STRING: appendRawToken( OPCODE_PUSH ) <<= bBiff8 ? - rStrm.readUniString( bNulChars ) : - rStrm.readByteStringUC( false, getTextEncoding(), bNulChars ); + rStrm.readUniString( mbAllowNulChars ) : + rStrm.readByteStringUC( false, getTextEncoding(), mbAllowNulChars ); break; case BIFF_DATATYPE_BOOL: appendRawToken( OPCODE_PUSH ) <<= static_cast< double >( (rStrm.readuInt8() == BIFF_TOK_BOOL_FALSE) ? 0.0 : 1.0 ); @@ -2519,13 +2531,18 @@ bool BiffFormulaParserImpl::importFuncCEToken( BiffInputStream& rStrm ) return pushBiffFunction( nCmdId, nParamCount ); } -bool BiffFormulaParserImpl::importExpToken5( BiffInputStream& rStrm ) +bool BiffFormulaParserImpl::importExpToken( BiffInputStream& rStrm ) { BinAddress aBaseAddr; aBaseAddr.read( rStrm ); - setSharedFormula( aBaseAddr ); - // formula has been set, exit parser by returning false - return false; + return pushSpecialTokenOperand( aBaseAddr, false ); +} + +bool BiffFormulaParserImpl::importTblToken( BiffInputStream& rStrm ) +{ + BinAddress aBaseAddr; + aBaseAddr.read( rStrm ); + return pushSpecialTokenOperand( aBaseAddr, true ); } bool BiffFormulaParserImpl::importNlrAddrToken( BiffInputStream& rStrm, bool bRow ) @@ -2795,22 +2812,35 @@ FormulaParser::~FormulaParser() { } -void FormulaParser::importFormula( FormulaContext& rContext, const OUString& rFormulaString ) const +ApiTokenSequence FormulaParser::importFormula( const CellAddress& rBaseAddress, const OUString& rFormulaString ) const { - mxImpl->importOoxFormula( rContext, rFormulaString ); + return mxImpl->importOoxFormula( rBaseAddress, rFormulaString ); } -void FormulaParser::importFormula( FormulaContext& rContext, SequenceInputStream& rStrm ) const +ApiTokenSequence FormulaParser::importFormula( const CellAddress& rBaseAddress, FormulaType eType, SequenceInputStream& rStrm ) const { - mxImpl->importBiff12Formula( rContext, rStrm ); + return mxImpl->importBiff12Formula( rBaseAddress, eType, rStrm ); } -void FormulaParser::importFormula( FormulaContext& rContext, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) const +ApiTokenSequence FormulaParser::importFormula( const CellAddress& rBaseAddress, FormulaType eType, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) const { - mxImpl->importBiffFormula( rContext, rStrm, pnFmlaSize ); + return mxImpl->importBiffFormula( rBaseAddress, eType, rStrm, pnFmlaSize ); } -void FormulaParser::convertErrorToFormula( FormulaContext& rContext, sal_uInt8 nErrorCode ) const +ApiTokenSequence FormulaParser::convertBoolToFormula( bool bValue ) const +{ + if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiffFuncId( bValue ? BIFF_FUNC_TRUE : BIFF_FUNC_FALSE ) ) + { + ApiTokenSequence aTokens( 3 ); + aTokens[ 0 ].OpCode = pFuncInfo->mnApiOpCode; + aTokens[ 1 ].OpCode = OPCODE_OPEN; + aTokens[ 2 ].OpCode = OPCODE_CLOSE; + return aTokens; + } + return ApiTokenSequence(); +} + +ApiTokenSequence FormulaParser::convertErrorToFormula( sal_uInt8 nErrorCode ) const { ApiTokenSequence aTokens( 3 ); // HACK: enclose all error codes into an 1x1 matrix @@ -2818,26 +2848,24 @@ void FormulaParser::convertErrorToFormula( FormulaContext& rContext, sal_uInt8 n aTokens[ 1 ].OpCode = OPCODE_PUSH; aTokens[ 1 ].Data <<= BiffHelper::calcDoubleFromError( nErrorCode ); aTokens[ 2 ].OpCode = OPCODE_ARRAY_CLOSE; - mxImpl->setFormula( rContext, aTokens ); + return aTokens; } -void FormulaParser::convertNameToFormula( FormulaContext& rContext, sal_Int32 nTokenIndex ) const +ApiTokenSequence FormulaParser::convertNameToFormula( sal_Int32 nTokenIndex ) const { - if( nTokenIndex >= 0 ) - { - ApiTokenSequence aTokens( 1 ); - aTokens[ 0 ].OpCode = OPCODE_NAME; - aTokens[ 0 ].Data <<= nTokenIndex; - mxImpl->setFormula( rContext, aTokens ); - } - else - convertErrorToFormula( rContext, BIFF_ERR_REF ); + if( nTokenIndex < 0 ) + return convertErrorToFormula( BIFF_ERR_REF ); + + ApiTokenSequence aTokens( 1 ); + aTokens[ 0 ].OpCode = OPCODE_NAME; + aTokens[ 0 ].Data <<= nTokenIndex; + return aTokens; } -void FormulaParser::convertNumberToHyperlink( FormulaContext& rContext, const OUString& rUrl, double fValue ) const +ApiTokenSequence FormulaParser::convertNumberToHyperlink( const OUString& rUrl, double fValue ) const { OSL_ENSURE( rUrl.getLength() > 0, "FormulaParser::convertNumberToHyperlink - missing URL" ); - if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiff12FuncId( BIFF_FUNC_HYPERLINK ) ) + if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiffFuncId( BIFF_FUNC_HYPERLINK ) ) { ApiTokenSequence aTokens( 6 ); aTokens[ 0 ].OpCode = pFuncInfo->mnApiOpCode; @@ -2848,8 +2876,9 @@ void FormulaParser::convertNumberToHyperlink( FormulaContext& rContext, const OU aTokens[ 4 ].OpCode = OPCODE_PUSH; aTokens[ 4 ].Data <<= fValue; aTokens[ 5 ].OpCode = OPCODE_CLOSE; - mxImpl->setFormula( rContext, aTokens ); + return aTokens; } + return ApiTokenSequence(); } OUString FormulaParser::importOleTargetLink( const OUString& rFormulaString ) diff --git a/oox/source/xls/makefile.mk b/oox/source/xls/makefile.mk index e337afe786a8..bcd539a70705 100755 --- a/oox/source/xls/makefile.mk +++ b/oox/source/xls/makefile.mk @@ -81,9 +81,9 @@ SLOFILES = \ $(SLO)$/richstringcontext.obj \ $(SLO)$/scenariobuffer.obj \ $(SLO)$/scenariocontext.obj \ - $(SLO)$/sharedformulabuffer.obj \ $(SLO)$/sharedstringsbuffer.obj \ $(SLO)$/sharedstringsfragment.obj \ + $(SLO)$/sheetdatabuffer.obj \ $(SLO)$/sheetdatacontext.obj \ $(SLO)$/stylesbuffer.obj \ $(SLO)$/stylesfragment.obj \ diff --git a/oox/source/xls/pivotcachebuffer.cxx b/oox/source/xls/pivotcachebuffer.cxx index 5e5e5efef546..88935a679c83 100644 --- a/oox/source/xls/pivotcachebuffer.cxx +++ b/oox/source/xls/pivotcachebuffer.cxx @@ -44,6 +44,7 @@ #include "oox/xls/defnamesbuffer.hxx" #include "oox/xls/excelhandlers.hxx" #include "oox/xls/pivotcachefragment.hxx" +#include "oox/xls/sheetdatabuffer.hxx" #include "oox/xls/tablebuffer.hxx" #include "oox/xls/unitconverter.hxx" #include "oox/xls/worksheetbuffer.hxx" @@ -936,7 +937,8 @@ OUString PivotCacheField::createParentGroupField( const Reference< XDataPilotFie void PivotCacheField::writeSourceHeaderCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const { - rSheetHelper.setStringCell( rSheetHelper.getCell( CellAddress( rSheetHelper.getSheetIndex(), nCol, nRow ) ), maFieldModel.maName ); + CellAddress aCellAddr( rSheetHelper.getSheetIndex(), nCol, nRow ); + rSheetHelper.getSheetData().setStringCell( rSheetHelper.getCell( aCellAddr ), aCellAddr, maFieldModel.maName ); } void PivotCacheField::writeSourceDataCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const @@ -982,15 +984,17 @@ void PivotCacheField::writeItemToSourceDataCell( WorksheetHelper& rSheetHelper, { if( rItem.getType() != XML_m ) { - Reference< XCell > xCell = rSheetHelper.getCell( CellAddress( rSheetHelper.getSheetIndex(), nCol, nRow ) ); + CellAddress aCellAddr( rSheetHelper.getSheetIndex(), nCol, nRow ); + SheetDataBuffer& rSheetData = rSheetHelper.getSheetData(); + Reference< XCell > xCell = rSheetHelper.getCell( aCellAddr ); if( xCell.is() ) switch( rItem.getType() ) { - case XML_s: rSheetHelper.setStringCell( xCell, rItem.getValue().get< OUString >() ); break; - case XML_n: xCell->setValue( rItem.getValue().get< double >() ); break; - case XML_i: xCell->setValue( rItem.getValue().get< sal_Int16 >() ); break; - case XML_d: rSheetHelper.setDateTimeCell( xCell, rItem.getValue().get< DateTime >() ); break; - case XML_b: rSheetHelper.setBooleanCell( xCell, rItem.getValue().get< bool >() ); break; - case XML_e: rSheetHelper.setErrorCell( xCell, static_cast< sal_uInt8 >( rItem.getValue().get< sal_Int32 >() ) ); break; + case XML_s: rSheetData.setStringCell( xCell, aCellAddr, rItem.getValue().get< OUString >() ); break; + case XML_n: rSheetData.setValueCell( xCell, aCellAddr, rItem.getValue().get< double >() ); break; + case XML_i: rSheetData.setValueCell( xCell, aCellAddr, rItem.getValue().get< sal_Int16 >() ); break; + case XML_d: rSheetData.setDateTimeCell( xCell, aCellAddr, rItem.getValue().get< DateTime >() ); break; + case XML_b: rSheetData.setBooleanCell( xCell, aCellAddr, rItem.getValue().get< bool >() ); break; + case XML_e: rSheetData.setErrorCell( xCell, aCellAddr, static_cast< sal_uInt8 >( rItem.getValue().get< sal_Int32 >() ) ); break; default: OSL_ENSURE( false, "PivotCacheField::writeItemToSourceDataCell - unexpected item data type" ); } } diff --git a/oox/source/xls/pivotcachefragment.cxx b/oox/source/xls/pivotcachefragment.cxx index d49077af4f91..b28d3b64e8e3 100644 --- a/oox/source/xls/pivotcachefragment.cxx +++ b/oox/source/xls/pivotcachefragment.cxx @@ -208,15 +208,20 @@ void PivotCacheDefinitionFragment::finalizeImport() { OUString aRecFragmentPath = getRelations().getFragmentPathFromRelId( mrPivotCache.getRecordsRelId() ); if( aRecFragmentPath.getLength() > 0 ) - importOoxFragment( new PivotCacheRecordsFragment( *this, aRecFragmentPath, mrPivotCache ) ); + { + sal_Int16 nSheet = mrPivotCache.getSourceRange().Sheet; + WorksheetGlobalsRef xSheetGlob = WorksheetHelper::constructGlobals( *this, ISegmentProgressBarRef(), SHEETTYPE_WORKSHEET, nSheet ); + if( xSheetGlob.get() ) + importOoxFragment( new PivotCacheRecordsFragment( *xSheetGlob, aRecFragmentPath, mrPivotCache ) ); + } } } // ============================================================================ -PivotCacheRecordsFragment::PivotCacheRecordsFragment( const WorkbookHelper& rHelper, +PivotCacheRecordsFragment::PivotCacheRecordsFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath, const PivotCache& rPivotCache ) : - WorksheetFragmentBase( rHelper, rFragmentPath, ISegmentProgressBarRef(), SHEETTYPE_WORKSHEET, rPivotCache.getSourceRange().Sheet ), + WorksheetFragmentBase( rHelper, rFragmentPath ), mrPivotCache( rPivotCache ), mnCol( 0 ), mnRow( 0 ), @@ -373,10 +378,14 @@ bool BiffPivotCacheFragment::importFragment() { /* Last call of lclSeekToPCDField() failed and kept stream position unchanged. Stream should point to source data table now. */ - BiffPivotCacheRecordsContext aContext( *this, mrPivotCache ); - if( aContext.isValidSheet() ) + sal_Int16 nSheet = mrPivotCache.getSourceRange().Sheet; + WorksheetGlobalsRef xSheetGlob = WorksheetHelper::constructGlobals( *this, ISegmentProgressBarRef(), SHEETTYPE_WORKSHEET, nSheet ); + if( xSheetGlob.get() ) + { + BiffPivotCacheRecordsContext aContext( *xSheetGlob, mrPivotCache ); while( rStrm.startNextRecord() && (rStrm.getRecId() != BIFF_ID_EOF) ) aContext.importRecord( rStrm ); + } } } @@ -385,8 +394,8 @@ bool BiffPivotCacheFragment::importFragment() // ============================================================================ -BiffPivotCacheRecordsContext::BiffPivotCacheRecordsContext( const WorkbookHelper& rHelper, const PivotCache& rPivotCache ) : - BiffWorksheetContextBase( rHelper, ISegmentProgressBarRef(), SHEETTYPE_WORKSHEET, rPivotCache.getSourceRange().Sheet ), +BiffPivotCacheRecordsContext::BiffPivotCacheRecordsContext( const WorksheetHelper& rHelper, const PivotCache& rPivotCache ) : + BiffWorksheetContextBase( rHelper ), mrPivotCache( rPivotCache ), mnColIdx( 0 ), mnRow( 0 ), diff --git a/oox/source/xls/sharedformulabuffer.cxx b/oox/source/xls/sharedformulabuffer.cxx deleted file mode 100644 index efdfe801f784..000000000000 --- a/oox/source/xls/sharedformulabuffer.cxx +++ /dev/null @@ -1,212 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include "oox/xls/sharedformulabuffer.hxx" - -#include -#include -#include "oox/helper/propertyset.hxx" -#include "oox/xls/addressconverter.hxx" -#include "oox/xls/biffinputstream.hxx" -#include "oox/xls/formulaparser.hxx" - -namespace oox { -namespace xls { - -// ============================================================================ - -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::sheet; -using namespace ::com::sun::star::table; - -using ::rtl::OUString; -using ::rtl::OUStringBuffer; - -// ============================================================================ - -namespace { - -bool operator==( const CellAddress& rAddr1, const CellAddress& rAddr2 ) -{ - return - (rAddr1.Sheet == rAddr2.Sheet) && - (rAddr1.Column == rAddr2.Column) && - (rAddr1.Row == rAddr2.Row); -} - -bool lclContains( const CellRangeAddress& rRange, const CellAddress& rAddr ) -{ - return - (rRange.Sheet == rAddr.Sheet) && - (rRange.StartColumn <= rAddr.Column) && (rAddr.Column <= rRange.EndColumn) && - (rRange.StartRow <= rAddr.Row) && (rAddr.Row <= rRange.EndRow); -} - -} // namespace - -// ============================================================================ - -ExtCellFormulaContext::ExtCellFormulaContext( const WorksheetHelper& rHelper, - const Reference< XFormulaTokens >& rxTokens, const CellAddress& rCellPos ) : - SimpleFormulaContext( rxTokens, false, false ), - WorksheetHelper( rHelper ) -{ - setBaseAddress( rCellPos ); -} - -void ExtCellFormulaContext::setSharedFormula( const CellAddress& rBaseAddr ) -{ - getSharedFormulas().setSharedFormulaCell( *this, rBaseAddr ); -} - -// ============================================================================ - -SharedFormulaBuffer::SharedFormulaBuffer( const WorksheetHelper& rHelper ) : - WorksheetHelper( rHelper ) -{ -} - -void SharedFormulaBuffer::importSharedFmla( const OUString& rFormula, const OUString& rSharedRange, sal_Int32 nSharedId, const CellAddress& rBaseAddr ) -{ - CellRangeAddress aFmlaRange; - if( getAddressConverter().convertToCellRange( aFmlaRange, rSharedRange, getSheetIndex(), true, true ) ) - { - // create the defined name representing the shared formula - OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SharedFormulaBuffer::importSharedFmla - invalid range for shared formula" ); - BinAddress aMapKey( nSharedId, 0 ); - Reference< XNamedRange > xNamedRange = createDefinedName( aMapKey ); - // convert the formula definition - Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY ); - if( xTokens.is() ) - { - SimpleFormulaContext aContext( xTokens, true, false ); - aContext.setBaseAddress( rBaseAddr ); - getFormulaParser().importFormula( aContext, rFormula ); - updateCachedCell( rBaseAddr, aMapKey ); - } - } -} - -void SharedFormulaBuffer::importSharedFmla( SequenceInputStream& rStrm, const CellAddress& rBaseAddr ) -{ - BinRange aRange; - rStrm >> aRange; - CellRangeAddress aFmlaRange; - if( getAddressConverter().convertToCellRange( aFmlaRange, aRange, getSheetIndex(), true, true ) ) - { - // create the defined name representing the shared formula - OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SharedFormulaBuffer::importSharedFmla - invalid range for shared formula" ); - BinAddress aMapKey( rBaseAddr ); - Reference< XNamedRange > xNamedRange = createDefinedName( aMapKey ); - // load the formula definition - Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY ); - if( xTokens.is() ) - { - SimpleFormulaContext aContext( xTokens, true, false ); - aContext.setBaseAddress( rBaseAddr ); - getFormulaParser().importFormula( aContext, rStrm ); - updateCachedCell( rBaseAddr, aMapKey ); - } - } -} - -void SharedFormulaBuffer::importSharedFmla( BiffInputStream& rStrm, const CellAddress& rBaseAddr ) -{ - BinRange aRange; - aRange.read( rStrm, false ); // always 8bit column indexes - CellRangeAddress aFmlaRange; - if( getAddressConverter().convertToCellRange( aFmlaRange, aRange, getSheetIndex(), true, true ) ) - { - // create the defined name representing the shared formula - OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SharedFormulaBuffer::importSharedFmla - invalid range for shared formula" ); - BinAddress aMapKey( rBaseAddr ); - Reference< XNamedRange > xNamedRange = createDefinedName( aMapKey ); - // load the formula definition - Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY ); - if( xTokens.is() ) - { - rStrm.skip( 2 ); // flags - SimpleFormulaContext aContext( xTokens, true, false ); - aContext.setBaseAddress( rBaseAddr ); - getFormulaParser().importFormula( aContext, rStrm ); - updateCachedCell( rBaseAddr, aMapKey ); - } - } -} - -void SharedFormulaBuffer::setSharedFormulaCell( ExtCellFormulaContext& rContext, const CellAddress& rBaseAddr ) -{ - if( !implSetSharedFormulaCell( rContext, BinAddress( rBaseAddr ) ) ) - if( rContext.getBaseAddress() == rBaseAddr ) - mxLastContext.reset( new ExtCellFormulaContext( rContext ) ); -} - -void SharedFormulaBuffer::setSharedFormulaCell( ExtCellFormulaContext& rContext, sal_Int32 nSharedId ) -{ - implSetSharedFormulaCell( rContext, BinAddress( nSharedId, 0 ) ); -} - -Reference< XNamedRange > SharedFormulaBuffer::createDefinedName( const BinAddress& rMapKey ) -{ - OSL_ENSURE( maIndexMap.count( rMapKey ) == 0, "SharedFormulaBuffer::createDefinedName - shared formula exists already" ); - // create the defined name representing the shared formula - OUString aName = OUStringBuffer().appendAscii( "__shared_" ). - append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) ). - append( sal_Unicode( '_' ) ).append( rMapKey.mnRow ). - append( sal_Unicode( '_' ) ).append( rMapKey.mnCol ).makeStringAndClear(); - Reference< XNamedRange > xNamedRange = createNamedRangeObject( aName ); - PropertySet aNameProps( xNamedRange ); - aNameProps.setProperty( PROP_IsSharedFormula, true ); - sal_Int32 nTokenIndex = -1; - if( aNameProps.getProperty( nTokenIndex, PROP_TokenIndex ) && (nTokenIndex >= 0) ) - maIndexMap[ rMapKey ] = nTokenIndex; - return xNamedRange; -} - -bool SharedFormulaBuffer::implSetSharedFormulaCell( ExtCellFormulaContext& rContext, const BinAddress& rMapKey ) -{ - TokenIndexMap::const_iterator aIt = maIndexMap.find( rMapKey ); - sal_Int32 nTokenIndex = (aIt == maIndexMap.end()) ? -1 : aIt->second; - if( nTokenIndex >= 0 ) - { - getFormulaParser().convertNameToFormula( rContext, nTokenIndex ); - return true; - } - return false; -} - -void SharedFormulaBuffer::updateCachedCell( const CellAddress& rBaseAddr, const BinAddress& rMapKey ) -{ - if( mxLastContext.get() && (mxLastContext->getBaseAddress() == rBaseAddr) ) - implSetSharedFormulaCell( *mxLastContext, rMapKey ); - mxLastContext.reset(); -} - -// ============================================================================ - -} // namespace xls -} // namespace oox diff --git a/oox/source/xls/sheetdatabuffer.cxx b/oox/source/xls/sheetdatabuffer.cxx new file mode 100755 index 000000000000..e63e9fbb61b5 --- /dev/null +++ b/oox/source/xls/sheetdatabuffer.cxx @@ -0,0 +1,689 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/xls/sheetdatabuffer.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "oox/helper/containerhelper.hxx" +#include "oox/helper/propertymap.hxx" +#include "oox/helper/propertyset.hxx" +#include "oox/token/tokens.hxx" +#include "oox/xls/addressconverter.hxx" +#include "oox/xls/biffinputstream.hxx" +#include "oox/xls/formulaparser.hxx" +#include "oox/xls/sharedstringsbuffer.hxx" +#include "oox/xls/unitconverter.hxx" + +namespace oox { +namespace xls { + +// ============================================================================ + +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::sheet; +using namespace ::com::sun::star::table; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + +// ============================================================================ + +namespace { + +bool lclContains( const CellRangeAddress& rRange, const CellAddress& rAddr ) +{ + return + (rRange.Sheet == rAddr.Sheet) && + (rRange.StartColumn <= rAddr.Column) && (rAddr.Column <= rRange.EndColumn) && + (rRange.StartRow <= rAddr.Row) && (rAddr.Row <= rRange.EndRow); +} + +} // namespace + +// ============================================================================ + +SheetDataBuffer::SheetDataBuffer( const WorksheetHelper& rHelper ) : + WorksheetHelper( rHelper ), + mbPendingSharedFmla( false ) +{ +} + +void SheetDataBuffer::importSharedFmla( const OUString& rFormula, const OUString& rSharedRange, sal_Int32 nSharedId, const CellAddress& rBaseAddr ) +{ + CellRangeAddress aFmlaRange; + if( getAddressConverter().convertToCellRange( aFmlaRange, rSharedRange, getSheetIndex(), true, true ) ) try + { + // get or create the defined name representing the shared formula + OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SheetDataBuffer::importSharedFmla - invalid range for shared formula" ); + Reference< XNamedRange > xNamedRange = createSharedFormulaName( BinAddress( nSharedId, 0 ) ); + Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY_THROW ); + // convert the formula definition + ApiTokenSequence aTokens = getFormulaParser().importFormula( rBaseAddr, rFormula ); + xTokens->setTokens( aTokens ); + // retry to insert a pending shared formula cell + retryPendingSharedFormulaCell(); + } + catch( Exception& ) + { + } +} + +void SheetDataBuffer::importSharedFmla( SequenceInputStream& rStrm, const CellAddress& rBaseAddr ) +{ + BinRange aRange; + rStrm >> aRange; + CellRangeAddress aFmlaRange; + if( getAddressConverter().convertToCellRange( aFmlaRange, aRange, getSheetIndex(), true, true ) ) try + { + // get or create the defined name representing the shared formula + OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SheetDataBuffer::importSharedFmla - invalid range for shared formula" ); + Reference< XNamedRange > xNamedRange = createSharedFormulaName( BinAddress( rBaseAddr ) ); + Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY_THROW ); + // load the formula definition + ApiTokenSequence aTokens = getFormulaParser().importFormula( rBaseAddr, FORMULATYPE_SHAREDFORMULA, rStrm ); + xTokens->setTokens( aTokens ); + // retry to insert a pending shared formula cell + retryPendingSharedFormulaCell(); + } + catch( Exception& ) + { + } +} + +void SheetDataBuffer::importSharedFmla( BiffInputStream& rStrm, const CellAddress& rBaseAddr ) +{ + BinRange aRange; + aRange.read( rStrm, false ); // always 8bit column indexes + CellRangeAddress aFmlaRange; + if( getAddressConverter().convertToCellRange( aFmlaRange, aRange, getSheetIndex(), true, true ) ) try + { + // get or create the defined name representing the shared formula + OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SheetDataBuffer::importSharedFmla - invalid range for shared formula" ); + Reference< XNamedRange > xNamedRange = createSharedFormulaName( BinAddress( rBaseAddr ) ); + Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY_THROW ); + // load the formula definition + rStrm.skip( 2 ); // flags + ApiTokenSequence aTokens = getFormulaParser().importFormula( rBaseAddr, FORMULATYPE_SHAREDFORMULA, rStrm ); + xTokens->setTokens( aTokens ); + // retry to insert a pending shared formula cell + retryPendingSharedFormulaCell(); + } + catch( Exception& ) + { + } +} + +void SheetDataBuffer::setValueCell( const Reference< XCell >& rxCell, const CellAddress& /*rCellAddr*/, double fValue ) +{ + OSL_ENSURE( rxCell.is(), "SheetDataBuffer::setDateTimeCell - missing cell interface" ); + if( rxCell.is() ) + rxCell->setValue( fValue ); +} + +void SheetDataBuffer::setStringCell( const Reference< XCell >& rxCell, const CellAddress& /*rCellAddr*/, const OUString& rText ) +{ + Reference< XText > xText( rxCell, UNO_QUERY ); + OSL_ENSURE( xText.is(), "SheetDataBuffer::setStringCell - missing text interface" ); + if( xText.is() ) + xText->setString( rText ); +} + +void SheetDataBuffer::setStringCell( const Reference< XCell >& rxCell, const CellAddress& /*rCellAddr*/, const RichString& rString, sal_Int32 nXfId ) +{ + Reference< XText > xText( rxCell, UNO_QUERY ); + OSL_ENSURE( xText.is(), "SheetDataBuffer::setStringCell - missing text interface" ); + rString.convert( xText, nXfId ); +} + +void SheetDataBuffer::setStringCell( const Reference< XCell >& rxCell, const CellAddress& /*rCellAddr*/, sal_Int32 nStringId, sal_Int32 nXfId ) +{ + Reference< XText > xText( rxCell, UNO_QUERY ); + OSL_ENSURE( xText.is(), "SheetDataBuffer::setStringCell - missing text interface" ); + getSharedStrings().convertString( xText, nStringId, nXfId ); +} + +void SheetDataBuffer::setDateTimeCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, const DateTime& rDateTime ) +{ + // write serial date/time value into the cell + double fSerial = getUnitConverter().calcSerialFromDateTime( rDateTime ); + setValueCell( rxCell, rCellAddr, fSerial ); + // set appropriate number format + using namespace ::com::sun::star::util::NumberFormat; + sal_Int16 nStdFmt = (fSerial < 1.0) ? TIME : (((rDateTime.Hours > 0) || (rDateTime.Minutes > 0) || (rDateTime.Seconds > 0)) ? DATETIME : DATE); + setStandardNumFmt( rCellAddr, nStdFmt ); +} + +void SheetDataBuffer::setBooleanCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, bool bValue ) +{ + setFormulaCell( rxCell, rCellAddr, getFormulaParser().convertBoolToFormula( bValue ) ); +} + +void SheetDataBuffer::setErrorCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, const OUString& rErrorCode ) +{ + setErrorCell( rxCell, rCellAddr, getUnitConverter().calcBiffErrorCode( rErrorCode ) ); +} + +void SheetDataBuffer::setErrorCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, sal_uInt8 nErrorCode ) +{ + setFormulaCell( rxCell, rCellAddr, getFormulaParser().convertErrorToFormula( nErrorCode ) ); +} + +void SheetDataBuffer::setFormulaCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, const ApiTokenSequence& rTokens ) +{ + mbPendingSharedFmla = false; + ApiTokenSequence aTokens; + + /* Detect special token passed as placeholder for array formulas, shared + formulas, and table operations. In BIFF, these formulas are represented + by a single tExp resp. tTbl token. If the formula parser finds these + tokens, it puts a single OPCODE_BAD token with the base address and + formula type into the token sequence. This information will be + extracted here, and in case of a shared formula, the shared formula + buffer will generate the resulting formula token array. */ + ApiSpecialTokenInfo aTokenInfo; + if( rTokens.hasElements() && getFormulaParser().extractSpecialTokenInfo( aTokenInfo, rTokens ) ) + { + /* The second member of the token info is set to true, if the formula + represents a table operation, which will be skipped. In BIFF12 it + is not possible to distinguish array and shared formulas + (BIFF5/BIFF8 provide this information with a special flag in the + FORMULA record). */ + if( !aTokenInfo.Second ) + { + /* Construct the token array representing the shared formula. If + the returned sequence is empty, the definition of the shared + formula has not been loaded yet, or the cell is part of an + array formula. In this case, the cell will be remembered. After + reading the formula definition it will be retried to insert the + formula via retryPendingSharedFormulaCell(). */ + aTokens = resolveSharedFormula( aTokenInfo.First ); + if( !aTokens.hasElements() ) + { + maSharedFmlaAddr = rCellAddr; + maSharedBaseAddr = aTokenInfo.First; + mbPendingSharedFmla = true; + } + } + } + else + { + // simple formula, use the passed token array + aTokens = rTokens; + } + + if( aTokens.hasElements() ) + { + Reference< XFormulaTokens > xTokens( rxCell, UNO_QUERY ); + OSL_ENSURE( xTokens.is(), "SheetDataBuffer::setFormulaCell - missing formula interface" ); + if( xTokens.is() ) + xTokens->setTokens( aTokens ); + } +} + +void SheetDataBuffer::setFormulaCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, sal_Int32 nSharedId ) +{ + setFormulaCell( rxCell, rCellAddr, resolveSharedFormula( nSharedId ) ); +} + +void SheetDataBuffer::setArrayFormula( const CellRangeAddress& rRange, const ApiTokenSequence& rTokens ) +{ + try + { + Reference< XArrayFormulaTokens > xTokens( getCellRange( rRange ), UNO_QUERY_THROW ); + xTokens->setArrayTokens( rTokens ); + } + catch( Exception& ) + { + } +} + +void SheetDataBuffer::setTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel ) +{ + OSL_ENSURE( getAddressConverter().checkCellRange( rRange, true, false ), "SheetDataBuffer::setTableOperation - invalid range" ); + sal_Int16 nSheet = getSheetIndex(); + bool bOk = false; + if( !rModel.mbRef1Deleted && (rModel.maRef1.getLength() > 0) && (rRange.StartColumn > 0) && (rRange.StartRow > 0) ) + { + CellRangeAddress aOpRange = rRange; + CellAddress aRef1, aRef2; + if( getAddressConverter().convertToCellAddress( aRef1, rModel.maRef1, nSheet, true ) ) try + { + if( rModel.mb2dTable ) + { + if( !rModel.mbRef2Deleted && getAddressConverter().convertToCellAddress( aRef2, rModel.maRef2, nSheet, true ) ) + { + // API call expects input values inside operation range + --aOpRange.StartColumn; + --aOpRange.StartRow; + // formula range is top-left cell of operation range + CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn, aOpRange.StartRow, aOpRange.StartColumn, aOpRange.StartRow ); + // set multiple operation + Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW ); + xMultOp->setTableOperation( aFormulaRange, TableOperationMode_BOTH, aRef2, aRef1 ); + bOk = true; + } + } + else if( rModel.mbRowTable ) + { + // formula range is column to the left of operation range + CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn - 1, aOpRange.StartRow, aOpRange.StartColumn - 1, aOpRange.EndRow ); + // API call expects input values (top row) inside operation range + --aOpRange.StartRow; + // set multiple operation + Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW ); + xMultOp->setTableOperation( aFormulaRange, TableOperationMode_ROW, aRef1, aRef1 ); + bOk = true; + } + else + { + // formula range is row above operation range + CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn, aOpRange.StartRow - 1, aOpRange.EndColumn, aOpRange.StartRow - 1 ); + // API call expects input values (left column) inside operation range + --aOpRange.StartColumn; + // set multiple operation + Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW ); + xMultOp->setTableOperation( aFormulaRange, TableOperationMode_COLUMN, aRef1, aRef1 ); + bOk = true; + } + } + catch( Exception& ) + { + } + } + + // on error: fill cell range with error codes + if( !bOk ) + for( CellAddress aPos( nSheet, rRange.StartColumn, rRange.StartRow ); aPos.Row <= rRange.EndRow; ++aPos.Row ) + for( aPos.Column = rRange.StartColumn; aPos.Column <= rRange.EndColumn; ++aPos.Column ) + setErrorCell( getCell( aPos ), aPos, BIFF_ERR_REF ); +} + +void SheetDataBuffer::setRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId, bool bCustomFormat ) +{ + // set row formatting + if( bCustomFormat ) + { + // try to expand cached row range, if formatting is equal + if( (maXfIdRowRange.mnLastRow < 0) || !maXfIdRowRange.tryExpand( nFirstRow, nLastRow, nXfId ) ) + { + writeXfIdRowRangeProperties( maXfIdRowRange ); + maXfIdRowRange.set( nFirstRow, nLastRow, nXfId ); + } + } + else if( maXfIdRowRange.mnLastRow >= 0 ) + { + // finish last cached row range + writeXfIdRowRangeProperties( maXfIdRowRange ); + maXfIdRowRange.set( -1, -1, -1 ); + } +} + +void SheetDataBuffer::setCellFormat( const CellModel& rModel ) +{ + if( rModel.mxCell.is() && ((rModel.mnXfId >= 0) || (rModel.mnNumFmtId >= 0)) ) + { + // try to merge existing ranges and to write some formatting properties + if( !maXfIdRanges.empty() ) + { + // get row index of last inserted cell + sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow; + // row changed - try to merge ranges of last row with existing ranges + if( rModel.maAddress.Row != nLastRow ) + { + mergeXfIdRanges(); + // write format properties of all ranges above last row and remove them + XfIdRangeMap::iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); + while( aIt != aEnd ) + { + // check that range cannot be merged with current row, and that range is not in cached row range + if( (aIt->second.maRange.EndRow < nLastRow) && !maXfIdRowRange.intersects( aIt->second.maRange ) ) + { + writeXfIdRangeProperties( aIt->second ); + maXfIdRanges.erase( aIt++ ); + } + else + ++aIt; + } + } + } + + // try to expand last existing range, or create new range entry + if( maXfIdRanges.empty() || !maXfIdRanges.rbegin()->second.tryExpand( rModel ) ) + maXfIdRanges[ BinAddress( rModel.maAddress ) ].set( rModel ); + + // update merged ranges for 'center across selection' and 'fill' + if( const Xf* pXf = getStyles().getCellXf( rModel.mnXfId ).get() ) + { + sal_Int32 nHorAlign = pXf->getAlignment().getModel().mnHorAlign; + if( (nHorAlign == XML_centerContinuous) || (nHorAlign == XML_fill) ) + { + /* start new merged range, if cell is not empty (#108781#), + or try to expand last range with empty cell */ + if( rModel.mnCellType != XML_TOKEN_INVALID ) + maCenterFillRanges.push_back( MergedRange( rModel.maAddress, nHorAlign ) ); + else if( !maCenterFillRanges.empty() ) + maCenterFillRanges.rbegin()->tryExpand( rModel.maAddress, nHorAlign ); + } + } + } +} + +void SheetDataBuffer::setMergedRange( const CellRangeAddress& rRange ) +{ + maMergedRanges.push_back( MergedRange( rRange ) ); +} + +void SheetDataBuffer::setStandardNumFmt( const CellAddress& rCellAddr, sal_Int16 nStdNumFmt ) +{ + try + { + Reference< XNumberFormatsSupplier > xNumFmtsSupp( getDocument(), UNO_QUERY_THROW ); + Reference< XNumberFormatTypes > xNumFmtTypes( xNumFmtsSupp->getNumberFormats(), UNO_QUERY_THROW ); + sal_Int32 nIndex = xNumFmtTypes->getStandardFormat( nStdNumFmt, Locale() ); + PropertySet aPropSet( getCell( rCellAddr ) ); + aPropSet.setProperty( PROP_NumberFormat, nIndex ); + } + catch( Exception& ) + { + } +} + +void SheetDataBuffer::finalizeImport() +{ + // write default formatting of remaining row range + writeXfIdRowRangeProperties( maXfIdRowRange ); + + // try to merge remaining inserted ranges + mergeXfIdRanges(); + // write all formatting + for( XfIdRangeMap::const_iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); aIt != aEnd; ++aIt ) + writeXfIdRangeProperties( aIt->second ); + + // merge all cached merged ranges and update right/bottom cell borders + MergedRangeList::const_iterator aIt, aEnd; + for( aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt ) + finalizeMergedRange( aIt->maRange ); + for( aIt = maCenterFillRanges.begin(), aEnd = maCenterFillRanges.end(); aIt != aEnd; ++aIt ) + finalizeMergedRange( aIt->maRange ); +} + +// private -------------------------------------------------------------------- + +SheetDataBuffer::XfIdRowRange::XfIdRowRange() : + mnFirstRow( -1 ), + mnLastRow( -1 ), + mnXfId( -1 ) +{ +} + +bool SheetDataBuffer::XfIdRowRange::intersects( const CellRangeAddress& rRange ) const +{ + return (rRange.StartRow <= mnLastRow) && (mnFirstRow <= rRange.EndRow); +} + +void SheetDataBuffer::XfIdRowRange::set( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) +{ + mnFirstRow = nFirstRow; + mnLastRow = nLastRow; + mnXfId = nXfId; +} + +bool SheetDataBuffer::XfIdRowRange::tryExpand( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) +{ + if( mnXfId == nXfId ) + { + if( mnLastRow + 1 == nFirstRow ) + { + mnLastRow = nLastRow; + return true; + } + if( mnFirstRow == nLastRow + 1 ) + { + mnFirstRow = nFirstRow; + return true; + } + } + return false; +} + +void SheetDataBuffer::XfIdRange::set( const CellModel& rModel ) +{ + maRange.Sheet = rModel.maAddress.Sheet; + maRange.StartColumn = maRange.EndColumn = rModel.maAddress.Column; + maRange.StartRow = maRange.EndRow = rModel.maAddress.Row; + mnXfId = rModel.mnXfId; + mnNumFmtId = rModel.mnNumFmtId; +} + +bool SheetDataBuffer::XfIdRange::tryExpand( const CellModel& rModel ) +{ + if( (mnXfId == rModel.mnXfId) && (mnNumFmtId == rModel.mnNumFmtId) && + (maRange.StartRow == rModel.maAddress.Row) && + (maRange.EndRow == rModel.maAddress.Row) && + (maRange.EndColumn + 1 == rModel.maAddress.Column) ) + { + ++maRange.EndColumn; + return true; + } + return false; +} + +bool SheetDataBuffer::XfIdRange::tryMerge( const XfIdRange& rXfIdRange ) +{ + if( (mnXfId == rXfIdRange.mnXfId) && + (mnNumFmtId == rXfIdRange.mnNumFmtId) && + (maRange.EndRow + 1 == rXfIdRange.maRange.StartRow) && + (maRange.StartColumn == rXfIdRange.maRange.StartColumn) && + (maRange.EndColumn == rXfIdRange.maRange.EndColumn) ) + { + maRange.EndRow = rXfIdRange.maRange.EndRow; + return true; + } + return false; +} + + +SheetDataBuffer::MergedRange::MergedRange( const CellRangeAddress& rRange ) : + maRange( rRange ), + mnHorAlign( XML_TOKEN_INVALID ) +{ +} + +SheetDataBuffer::MergedRange::MergedRange( const CellAddress& rAddress, sal_Int32 nHorAlign ) : + maRange( rAddress.Sheet, rAddress.Column, rAddress.Row, rAddress.Column, rAddress.Row ), + mnHorAlign( nHorAlign ) +{ +} + +bool SheetDataBuffer::MergedRange::tryExpand( const CellAddress& rAddress, sal_Int32 nHorAlign ) +{ + if( (mnHorAlign == nHorAlign) && (maRange.StartRow == rAddress.Row) && + (maRange.EndRow == rAddress.Row) && (maRange.EndColumn + 1 == rAddress.Column) ) + { + ++maRange.EndColumn; + return true; + } + return false; +} + +Reference< XNamedRange > SheetDataBuffer::createSharedFormulaName( const BinAddress& rMapKey ) +{ + // create the defined name that will represent the shared formula + OUString aName = OUStringBuffer().appendAscii( RTL_CONSTASCII_STRINGPARAM( "__shared_" ) ). + append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) ). + append( sal_Unicode( '_' ) ).append( rMapKey.mnRow ). + append( sal_Unicode( '_' ) ).append( rMapKey.mnCol ).makeStringAndClear(); + Reference< XNamedRange > xNamedRange = createNamedRangeObject( aName ); + PropertySet aNameProps( xNamedRange ); + aNameProps.setProperty( PROP_IsSharedFormula, true ); + + // get and store the token index of the defined name + OSL_ENSURE( maTokenIndexes.count( rMapKey ) == 0, "SheetDataBuffer::createSharedFormulaName - key exists already" ); + sal_Int32 nTokenIndex = 0; + if( aNameProps.getProperty( nTokenIndex, PROP_TokenIndex ) ) + maTokenIndexes[ rMapKey ] = nTokenIndex; + + return xNamedRange; +} + +ApiTokenSequence SheetDataBuffer::resolveSharedFormula( sal_Int32 nSharedId ) const +{ + sal_Int32 nTokenIndex = ContainerHelper::getMapElement( maTokenIndexes, BinAddress( nSharedId, 0 ), -1 ); + return (nTokenIndex >= 0) ? getFormulaParser().convertNameToFormula( nTokenIndex ) : ApiTokenSequence(); +} + +ApiTokenSequence SheetDataBuffer::resolveSharedFormula( const CellAddress& rBaseAddr ) const +{ + sal_Int32 nTokenIndex = ContainerHelper::getMapElement( maTokenIndexes, BinAddress( rBaseAddr ), -1 ); + return (nTokenIndex >= 0) ? getFormulaParser().convertNameToFormula( nTokenIndex ) : ApiTokenSequence(); +} + +void SheetDataBuffer::retryPendingSharedFormulaCell() +{ + if( mbPendingSharedFmla ) + { + ApiTokenSequence aTokens = resolveSharedFormula( maSharedBaseAddr ); + setFormulaCell( getCell( maSharedFmlaAddr ), maSharedFmlaAddr, aTokens ); + mbPendingSharedFmla = false; + } +} + +void SheetDataBuffer::writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const +{ + if( (rXfIdRowRange.mnLastRow >= 0) && (rXfIdRowRange.mnXfId >= 0) ) + { + AddressConverter& rAddrConv = getAddressConverter(); + CellRangeAddress aRange( getSheetIndex(), 0, rXfIdRowRange.mnFirstRow, rAddrConv.getMaxApiAddress().Column, rXfIdRowRange.mnLastRow ); + if( rAddrConv.validateCellRange( aRange, true, false ) ) + { + PropertySet aPropSet( getCellRange( aRange ) ); + getStyles().writeCellXfToPropertySet( aPropSet, rXfIdRowRange.mnXfId ); + } + } +} + +void SheetDataBuffer::writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const +{ + StylesBuffer& rStyles = getStyles(); + PropertyMap aPropMap; + if( rXfIdRange.mnXfId >= 0 ) + rStyles.writeCellXfToPropertyMap( aPropMap, rXfIdRange.mnXfId ); + if( rXfIdRange.mnNumFmtId >= 0 ) + rStyles.writeNumFmtToPropertyMap( aPropMap, rXfIdRange.mnNumFmtId ); + PropertySet aPropSet( getCellRange( rXfIdRange.maRange ) ); + aPropSet.setProperties( aPropMap ); +} + +void SheetDataBuffer::mergeXfIdRanges() +{ + if( !maXfIdRanges.empty() ) + { + // get row index of last range + sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow; + // process all ranges located in the same row of the last range + XfIdRangeMap::iterator aMergeIt = maXfIdRanges.end(); + while( (aMergeIt != maXfIdRanges.begin()) && ((--aMergeIt)->second.maRange.StartRow == nLastRow) ) + { + const XfIdRange& rMergeXfIdRange = aMergeIt->second; + // try to find a range that can be merged with rMergeRange + bool bFound = false; + for( XfIdRangeMap::iterator aIt = maXfIdRanges.begin(); !bFound && (aIt != aMergeIt); ++aIt ) + if( (bFound = aIt->second.tryMerge( rMergeXfIdRange )) == true ) + maXfIdRanges.erase( aMergeIt++ ); + } + } +} + +void SheetDataBuffer::finalizeMergedRange( const CellRangeAddress& rRange ) +{ + bool bMultiCol = rRange.StartColumn < rRange.EndColumn; + bool bMultiRow = rRange.StartRow < rRange.EndRow; + + if( bMultiCol || bMultiRow ) try + { + // merge the cell range + Reference< XMergeable > xMerge( getCellRange( rRange ), UNO_QUERY_THROW ); + xMerge->merge( sal_True ); + + // if merging this range worked (no overlapping merged ranges), update cell borders + Reference< XCell > xTopLeft( getCell( CellAddress( getSheetIndex(), rRange.StartColumn, rRange.StartRow ) ), UNO_SET_THROW ); + PropertySet aTopLeftProp( xTopLeft ); + + // copy right border of top-right cell to right border of top-left cell + if( bMultiCol ) + { + PropertySet aTopRightProp( getCell( CellAddress( getSheetIndex(), rRange.EndColumn, rRange.StartRow ) ) ); + BorderLine aLine; + if( aTopRightProp.getProperty( aLine, PROP_RightBorder ) ) + aTopLeftProp.setProperty( PROP_RightBorder, aLine ); + } + + // copy bottom border of bottom-left cell to bottom border of top-left cell + if( bMultiRow ) + { + PropertySet aBottomLeftProp( getCell( CellAddress( getSheetIndex(), rRange.StartColumn, rRange.EndRow ) ) ); + BorderLine aLine; + if( aBottomLeftProp.getProperty( aLine, PROP_BottomBorder ) ) + aTopLeftProp.setProperty( PROP_BottomBorder, aLine ); + } + + // #i93609# merged range in a single row: test if manual row height is needed + if( !bMultiRow ) + { + bool bTextWrap = aTopLeftProp.getBoolProperty( PROP_IsTextWrapped ); + if( !bTextWrap && (xTopLeft->getType() == CellContentType_TEXT) ) + { + Reference< XText > xText( xTopLeft, UNO_QUERY ); + bTextWrap = xText.is() && (xText->getString().indexOf( '\x0A' ) >= 0); + } + if( bTextWrap ) + setManualRowHeight( rRange.StartRow ); + } + } + catch( Exception& ) + { + } +} + +// ============================================================================ + +} // namespace xls +} // namespace oox diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx index 2d678aec72ca..f387257eaaf0 100644 --- a/oox/source/xls/sheetdatacontext.cxx +++ b/oox/source/xls/sheetdatacontext.cxx @@ -27,8 +27,6 @@ #include "oox/xls/sheetdatacontext.hxx" -#include -#include #include #include #include @@ -39,7 +37,7 @@ #include "oox/xls/biffinputstream.hxx" #include "oox/xls/formulaparser.hxx" #include "oox/xls/richstringcontext.hxx" -#include "oox/xls/sharedformulabuffer.hxx" +#include "oox/xls/sheetdatabuffer.hxx" #include "oox/xls/unitconverter.hxx" namespace oox { @@ -100,61 +98,13 @@ const sal_uInt32 BIFF_ROW_SHOWPHONETIC = 0x40000000; const sal_Int32 BIFF2_CELL_USEIXFE = 63; -// ---------------------------------------------------------------------------- - -/** Formula context for cell formulas. */ -class CellFormulaContext : public SimpleFormulaContext -{ -public: - explicit CellFormulaContext( - const Reference< XFormulaTokens >& rxTokens, - const CellAddress& rCellPos ); -}; - -CellFormulaContext::CellFormulaContext( const Reference< XFormulaTokens >& rxTokens, const CellAddress& rCellPos ) : - SimpleFormulaContext( rxTokens, false, false ) -{ - setBaseAddress( rCellPos ); -} - -// ---------------------------------------------------------------------------- - -/** Uses the XArrayFormulaTokens interface to set a token sequence. */ -class ArrayFormulaContext : public FormulaContext -{ -public: - explicit ArrayFormulaContext( - const Reference< XArrayFormulaTokens >& rxTokens, - const CellRangeAddress& rArrayRange ); - - virtual void setTokens( const ApiTokenSequence& rTokens ); - -private: - Reference< XArrayFormulaTokens > mxTokens; -}; - -ArrayFormulaContext::ArrayFormulaContext( - const Reference< XArrayFormulaTokens >& rxTokens, const CellRangeAddress& rArrayRange ) : - FormulaContext( false, false ), - mxTokens( rxTokens ) -{ - OSL_ENSURE( mxTokens.is(), "ArrayFormulaContext::ArrayFormulaContext - missing XArrayFormulaTokens interface" ); - setBaseAddress( CellAddress( rArrayRange.Sheet, rArrayRange.StartColumn, rArrayRange.StartRow ) ); -} - -void ArrayFormulaContext::setTokens( const ApiTokenSequence& rTokens ) -{ - mxTokens->setArrayTokens( rTokens ); -} - -// ---------------------------------------------------------------------------- - } // namespace // ============================================================================ SheetDataContext::SheetDataContext( WorksheetFragmentBase& rFragment ) : - WorksheetContextBase( rFragment ) + WorksheetContextBase( rFragment ), + mrSheetData( getSheetData() ) { } @@ -177,10 +127,10 @@ ContextHandlerRef SheetDataContext::onCreateContext( sal_Int32 nElement, const A mxInlineStr.reset( new RichString( *this ) ); return new RichStringContext( *this, mxInlineStr ); case XLS_TOKEN( v ): - return this; + return this; // characters contain cell value case XLS_TOKEN( f ): importFormula( rAttribs ); - return this; + return this; // characters contain formula string } break; } @@ -192,94 +142,112 @@ void SheetDataContext::onCharacters( const OUString& rChars ) switch( getCurrentElement() ) { case XLS_TOKEN( v ): - maCurrCell.maValueStr = rChars; - maCurrCell.mbHasValueStr = true; + maCurrCell.maValue = rChars; break; - case XLS_TOKEN( f ): - if( maCurrCell.mxCell.is() ) try - { - switch( maCurrCell.mnFormulaType ) - { - case XML_normal: - if( rChars.getLength() > 0 ) - { - Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY_THROW ); - CellFormulaContext aContext( xTokens, maCurrCell.maAddress ); - getFormulaParser().importFormula( aContext, rChars ); - } - break; - - case XML_array: - if( (maCurrCell.maFormulaRef.getLength() > 0) && (rChars.getLength() > 0) ) - { - CellRangeAddress aArrayRange; - Reference< XArrayFormulaTokens > xTokens( getCellRange( maCurrCell.maFormulaRef, &aArrayRange ), UNO_QUERY_THROW ); - ArrayFormulaContext aContext( xTokens, aArrayRange ); - getFormulaParser().importFormula( aContext, rChars ); - } - break; - - case XML_shared: - if( maCurrCell.mnSharedId >= 0 ) - { - if( rChars.getLength() > 0 ) - getSharedFormulas().importSharedFmla( rChars, maCurrCell.maFormulaRef, maCurrCell.mnSharedId, maCurrCell.maAddress ); - Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY_THROW ); - ExtCellFormulaContext aContext( *this, xTokens, maCurrCell.maAddress ); - getSharedFormulas().setSharedFormulaCell( aContext, maCurrCell.mnSharedId ); - } - break; - - case XML_dataTable: - if( maCurrCell.maFormulaRef.getLength() > 0 ) - { - CellRangeAddress aTableRange; - if( getAddressConverter().convertToCellRange( aTableRange, maCurrCell.maFormulaRef, getSheetIndex(), true, true ) ) - setTableOperation( aTableRange, maTableData ); - } - break; - - default: - OSL_ENSURE( false, "SheetDataContext::onCharacters - unknown formula type" ); - } - } - catch( Exception& ) - { - } + maCurrCell.maFormula = rChars; break; } } void SheetDataContext::onEndElement() { - if( isCurrentElement( XLS_TOKEN( c ) ) && maCurrCell.mxCell.is() ) + switch( getCurrentElement() ) { - if( maCurrCell.mxCell->getType() == CellContentType_EMPTY ) - { - if( maCurrCell.mbHasValueStr ) - { - // implemented in WorksheetHelper class - setCell( maCurrCell ); - } - else if( (maCurrCell.mnCellType == XML_inlineStr) && mxInlineStr.get() ) - { - // convert font settings - mxInlineStr->finalizeImport(); - // write string to cell - Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY ); - if( xText.is() ) - mxInlineStr->convert( xText, maCurrCell.mnXfId ); - } - else + case XLS_TOKEN( c ): + if( maCurrCell.mxCell.is() ) { - // empty cell, update cell type - maCurrCell.mnCellType = XML_TOKEN_INVALID; - } - } + // try to create a formula cell + if( maCurrCell.mxCell->getType() == CellContentType_EMPTY ) + { + switch( maCurrCell.mnFormulaType ) + { + case XML_normal: + if( maCurrCell.maFormula.getLength() > 0 ) + { + ApiTokenSequence aTokens = getFormulaParser().importFormula( maCurrCell.maAddress, maCurrCell.maFormula ); + mrSheetData.setFormulaCell( maCurrCell.mxCell, maCurrCell.maAddress, aTokens ); + } + break; + + case XML_array: + if( (maCurrCell.maFormula.getLength() > 0) && (maCurrCell.maFormulaRef.getLength() > 0) ) + { + CellRangeAddress aArrayRange; + if( getAddressConverter().convertToCellRange( aArrayRange, maCurrCell.maFormulaRef, getSheetIndex(), true, true ) ) + { + CellAddress aBaseAddr( aArrayRange.Sheet, aArrayRange.StartColumn, aArrayRange.StartRow ); + ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, maCurrCell.maFormula ); + mrSheetData.setArrayFormula( aArrayRange, aTokens ); + } + } + break; + + case XML_shared: + if( maCurrCell.mnSharedId >= 0 ) + { + if( maCurrCell.maFormula.getLength() > 0 ) + mrSheetData.importSharedFmla( maCurrCell.maFormula, maCurrCell.maFormulaRef, maCurrCell.mnSharedId, maCurrCell.maAddress ); + mrSheetData.setFormulaCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.mnSharedId ); + } + break; + + case XML_dataTable: + if( maCurrCell.maFormulaRef.getLength() > 0 ) + { + CellRangeAddress aTableRange; + if( getAddressConverter().convertToCellRange( aTableRange, maCurrCell.maFormulaRef, getSheetIndex(), true, true ) ) + mrSheetData.setTableOperation( aTableRange, maTableData ); + } + break; + + default: + OSL_ENSURE( maCurrCell.mnFormulaType == XML_TOKEN_INVALID, "SheetDataContext::onCharacters - unknown formula type" ); + } + } + + // no formula created: try to set the cell value + if( maCurrCell.mxCell->getType() == CellContentType_EMPTY ) + { + if( maCurrCell.maValue.getLength() > 0 ) + { + switch( maCurrCell.mnCellType ) + { + case XML_n: + mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.maValue.toDouble() ); + break; + case XML_b: + mrSheetData.setBooleanCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.maValue.toDouble() != 0.0 ); + // #108770# set 'Standard' number format for all Boolean cells + maCurrCell.mnNumFmtId = 0; + break; + case XML_e: + mrSheetData.setErrorCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.maValue ); + break; + case XML_str: + mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.maValue ); + break; + case XML_s: + mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.maValue.toInt32(), maCurrCell.mnXfId ); + break; + } + } + else if( (maCurrCell.mnCellType == XML_inlineStr) && mxInlineStr.get() ) + { + mxInlineStr->finalizeImport(); + mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, *mxInlineStr, maCurrCell.mnXfId ); + } + else + { + // empty cell, update cell type + maCurrCell.mnCellType = XML_TOKEN_INVALID; + } + } - // store the cell formatting data - setCellFormat( maCurrCell ); + // store the cell formatting data + mrSheetData.setCellFormat( maCurrCell ); + } + break; } } @@ -288,10 +256,7 @@ ContextHandlerRef SheetDataContext::onCreateRecordContext( sal_Int32 nRecId, Seq switch( getCurrentElement() ) { case BIFF12_ID_SHEETDATA: - switch( nRecId ) - { - case BIFF12_ID_ROW: importRow( rStrm ); return this; - } + if( nRecId == BIFF12_ID_ROW ) { importRow( rStrm ); return this; } break; case BIFF12_ID_ROW: @@ -409,19 +374,19 @@ void SheetDataContext::importCellBool( SequenceInputStream& rStrm, CellType eCel } else { - setBooleanCell( maCurrCell.mxCell, bValue ); + mrSheetData.setBooleanCell( maCurrCell.mxCell, maCurrCell.maAddress, bValue ); // #108770# set 'Standard' number format for all Boolean cells maCurrCell.mnNumFmtId = 0; } } - setCellFormat( maCurrCell ); + mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellBlank( SequenceInputStream& rStrm, CellType eCellType ) { OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellBlank - no formula cells supported" ); importCellHeader( rStrm, eCellType ); - setCellFormat( maCurrCell ); + mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellDouble( SequenceInputStream& rStrm, CellType eCellType ) @@ -434,9 +399,9 @@ void SheetDataContext::importCellDouble( SequenceInputStream& rStrm, CellType eC if( eCellType == CELLTYPE_FORMULA ) importCellFormula( rStrm ); else - maCurrCell.mxCell->setValue( fValue ); + mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, fValue ); } - setCellFormat( maCurrCell ); + mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellError( SequenceInputStream& rStrm, CellType eCellType ) @@ -449,9 +414,9 @@ void SheetDataContext::importCellError( SequenceInputStream& rStrm, CellType eCe if( eCellType == CELLTYPE_FORMULA ) importCellFormula( rStrm ); else - setErrorCell( maCurrCell.mxCell, nErrorCode ); + mrSheetData.setErrorCell( maCurrCell.mxCell, maCurrCell.maAddress, nErrorCode ); } - setCellFormat( maCurrCell ); + mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellRk( SequenceInputStream& rStrm, CellType eCellType ) @@ -460,8 +425,8 @@ void SheetDataContext::importCellRk( SequenceInputStream& rStrm, CellType eCellT importCellHeader( rStrm, eCellType ); maCurrCell.mnCellType = XML_n; if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) - maCurrCell.mxCell->setValue( BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); - setCellFormat( maCurrCell ); + mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); + mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellRString( SequenceInputStream& rStrm, CellType eCellType ) @@ -469,15 +434,14 @@ void SheetDataContext::importCellRString( SequenceInputStream& rStrm, CellType e OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRString - no formula cells supported" ); importCellHeader( rStrm, eCellType ); maCurrCell.mnCellType = XML_inlineStr; - Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY ); - if( xText.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) + if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) { RichString aString( *this ); aString.importString( rStrm, true ); aString.finalizeImport(); - aString.convert( xText, maCurrCell.mnXfId ); + mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, aString, maCurrCell.mnXfId ); } - setCellFormat( maCurrCell ); + mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellSi( SequenceInputStream& rStrm, CellType eCellType ) @@ -486,8 +450,8 @@ void SheetDataContext::importCellSi( SequenceInputStream& rStrm, CellType eCellT importCellHeader( rStrm, eCellType ); maCurrCell.mnCellType = XML_s; if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) - setSharedStringCell( maCurrCell.mxCell, rStrm.readInt32(), maCurrCell.mnXfId ); - setCellFormat( maCurrCell ); + mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, rStrm.readInt32(), maCurrCell.mnXfId ); + mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellString( SequenceInputStream& rStrm, CellType eCellType ) @@ -495,7 +459,7 @@ void SheetDataContext::importCellString( SequenceInputStream& rStrm, CellType eC importCellHeader( rStrm, eCellType ); maCurrCell.mnCellType = XML_inlineStr; Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY ); - if( xText.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) + if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) { RichString aString( *this ); aString.importString( rStrm, false ); @@ -503,20 +467,16 @@ void SheetDataContext::importCellString( SequenceInputStream& rStrm, CellType eC if( eCellType == CELLTYPE_FORMULA ) importCellFormula( rStrm ); else - aString.convert( xText, maCurrCell.mnXfId ); + mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, aString, maCurrCell.mnXfId ); } - setCellFormat( maCurrCell ); + mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellFormula( SequenceInputStream& rStrm ) { rStrm.skip( 2 ); - Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY ); - if( xTokens.is() ) - { - ExtCellFormulaContext aContext( *this, xTokens, maCurrCell.maAddress ); - getFormulaParser().importFormula( aContext, rStrm ); - } + ApiTokenSequence aTokens = getFormulaParser().importFormula( maCurrCell.maAddress, FORMULATYPE_CELL, rStrm ); + mrSheetData.setFormulaCell( maCurrCell.mxCell, maCurrCell.maAddress, aTokens ); } void SheetDataContext::importRow( SequenceInputStream& rStrm ) @@ -548,19 +508,18 @@ void SheetDataContext::importArray( SequenceInputStream& rStrm ) BinRange aRange; rStrm >> aRange; CellRangeAddress aArrayRange; - Reference< XCellRange > xRange = getCellRange( aRange, &aArrayRange ); - Reference< XArrayFormulaTokens > xTokens( xRange, UNO_QUERY ); - if( xRange.is() && xTokens.is() ) + if( getAddressConverter().convertToCellRange( aArrayRange, aRange, getSheetIndex(), true, true ) ) { rStrm.skip( 1 ); - ArrayFormulaContext aContext( xTokens, aArrayRange ); - getFormulaParser().importFormula( aContext, rStrm ); + CellAddress aBaseAddr( aArrayRange.Sheet, aArrayRange.StartColumn, aArrayRange.StartRow ); + ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_ARRAY, rStrm ); + mrSheetData.setArrayFormula( aArrayRange, aTokens ); } } void SheetDataContext::importSharedFmla( SequenceInputStream& rStrm ) { - getSharedFormulas().importSharedFmla( rStrm, maCurrCell.maAddress ); + mrSheetData.importSharedFmla( rStrm, maCurrCell.maAddress ); } void SheetDataContext::importDataTable( SequenceInputStream& rStrm ) @@ -580,7 +539,7 @@ void SheetDataContext::importDataTable( SequenceInputStream& rStrm ) aModel.mb2dTable = getFlag( nFlags, BIFF12_DATATABLE_2D ); aModel.mbRef1Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF1DEL ); aModel.mbRef2Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF2DEL ); - setTableOperation( aTableRange, aModel ); + mrSheetData.setTableOperation( aTableRange, aModel ); } } @@ -588,25 +547,27 @@ void SheetDataContext::importDataTable( SequenceInputStream& rStrm ) BiffSheetDataContext::BiffSheetDataContext( const WorksheetHelper& rHelper ) : BiffWorksheetContextBase( rHelper ), + mrSheetData( getSheetData() ), mnBiff2XfId( 0 ) { switch( getBiff() ) { case BIFF2: - mnFormulaIgnoreSize = 9; // double formula result, 1 byte flags - mnArrayIgnoreSize = 1; // recalc-always flag + mnFormulaSkipSize = 9; // double formula result, 1 byte flags + mnArraySkipSize = 1; // recalc-always flag break; case BIFF3: case BIFF4: - mnFormulaIgnoreSize = 10; // double formula result, 2 byte flags - mnArrayIgnoreSize = 2; // 2 byte flags + mnFormulaSkipSize = 10; // double formula result, 2 byte flags + mnArraySkipSize = 2; // 2 byte flags break; case BIFF5: case BIFF8: - mnFormulaIgnoreSize = 14; // double formula result, 2 byte flags, 4 bytes nothing - mnArrayIgnoreSize = 6; // 2 byte flags, 4 bytes nothing + mnFormulaSkipSize = 14; // double formula result, 2 byte flags, 4 bytes nothing + mnArraySkipSize = 6; // 2 byte flags, 4 bytes nothing + break; + case BIFF_UNKNOWN: break; - case BIFF_UNKNOWN: break; } } @@ -687,7 +648,8 @@ void BiffSheetDataContext::importRecord( BiffInputStream& rStrm ) } break; - case BIFF_UNKNOWN: break; + case BIFF_UNKNOWN: + break; } } } @@ -752,7 +714,7 @@ void BiffSheetDataContext::importCellHeader( BiffInputStream& rStrm, bool bBiff2 void BiffSheetDataContext::importBlank( BiffInputStream& rStrm ) { importCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BLANK ); - setCellFormat( maCurrCell ); + mrSheetData.setCellFormat( maCurrCell ); } void BiffSheetDataContext::importBoolErr( BiffInputStream& rStrm ) @@ -766,87 +728,77 @@ void BiffSheetDataContext::importBoolErr( BiffInputStream& rStrm ) { case BIFF_BOOLERR_BOOL: maCurrCell.mnCellType = XML_b; - setBooleanCell( maCurrCell.mxCell, nValue != 0 ); + mrSheetData.setBooleanCell( maCurrCell.mxCell, maCurrCell.maAddress, nValue != 0 ); // #108770# set 'Standard' number format for all Boolean cells maCurrCell.mnNumFmtId = 0; break; case BIFF_BOOLERR_ERROR: maCurrCell.mnCellType = XML_e; - setErrorCell( maCurrCell.mxCell, nValue ); + mrSheetData.setErrorCell( maCurrCell.mxCell, maCurrCell.maAddress, nValue ); break; default: OSL_ENSURE( false, "BiffSheetDataContext::importBoolErr - unknown cell type" ); } } - setCellFormat( maCurrCell ); + mrSheetData.setCellFormat( maCurrCell ); } void BiffSheetDataContext::importFormula( BiffInputStream& rStrm ) { importCellHeader( rStrm, getBiff() == BIFF2 ); maCurrCell.mnCellType = XML_n; - Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY ); - if( xTokens.is() ) - { - rStrm.skip( mnFormulaIgnoreSize ); - ExtCellFormulaContext aContext( *this, xTokens, maCurrCell.maAddress ); - getFormulaParser().importFormula( aContext, rStrm ); - } - setCellFormat( maCurrCell ); + rStrm.skip( mnFormulaSkipSize ); + ApiTokenSequence aTokens = getFormulaParser().importFormula( maCurrCell.maAddress, FORMULATYPE_CELL, rStrm ); + mrSheetData.setFormulaCell( maCurrCell.mxCell, maCurrCell.maAddress, aTokens ); + mrSheetData.setCellFormat( maCurrCell ); } void BiffSheetDataContext::importInteger( BiffInputStream& rStrm ) { importCellHeader( rStrm, true ); maCurrCell.mnCellType = XML_n; - if( maCurrCell.mxCell.is() ) - maCurrCell.mxCell->setValue( rStrm.readuInt16() ); - setCellFormat( maCurrCell ); + mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, rStrm.readuInt16() ); + mrSheetData.setCellFormat( maCurrCell ); } void BiffSheetDataContext::importLabel( BiffInputStream& rStrm ) { + /* the deep secrets of BIFF type and record identifier... + record id BIFF -> XF type String type + 0x0004 2-7 -> 3 byte 8-bit length, byte string + 0x0004 8 -> 3 byte 16-bit length, unicode string + 0x0204 2-7 -> 2 byte 16-bit length, byte string + 0x0204 8 -> 2 byte 16-bit length, unicode string + */ bool bBiff2Xf = rStrm.getRecId() == BIFF2_ID_LABEL; importCellHeader( rStrm, bBiff2Xf ); maCurrCell.mnCellType = XML_inlineStr; - Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY ); - if( xText.is() ) + RichString aString( *this ); + if( getBiff() == BIFF8 ) { - /* the deep secrets of BIFF type and record identifier... - record id BIFF -> XF type String type - 0x0004 2-7 -> 3 byte 8-bit length, byte string - 0x0004 8 -> 3 byte 16-bit length, unicode string - 0x0204 2-7 -> 2 byte 16-bit length, byte string - 0x0204 8 -> 2 byte 16-bit length, unicode string */ - - RichString aString( *this ); - if( getBiff() == BIFF8 ) - { - aString.importUniString( rStrm ); - } - else - { - // #i63105# use text encoding from FONT record - rtl_TextEncoding eTextEnc = getTextEncoding(); - if( const Font* pFont = getStyles().getFontFromCellXf( maCurrCell.mnXfId ).get() ) - eTextEnc = pFont->getFontEncoding(); - BiffStringFlags nFlags = bBiff2Xf ? BIFF_STR_8BITLENGTH : BIFF_STR_DEFAULT; - setFlag( nFlags, BIFF_STR_EXTRAFONTS, rStrm.getRecId() == BIFF_ID_RSTRING ); - aString.importByteString( rStrm, eTextEnc, nFlags ); - } - aString.finalizeImport(); - aString.convert( xText, maCurrCell.mnXfId ); + aString.importUniString( rStrm ); + } + else + { + // #i63105# use text encoding from FONT record + rtl_TextEncoding eTextEnc = getTextEncoding(); + if( const Font* pFont = getStyles().getFontFromCellXf( maCurrCell.mnXfId ).get() ) + eTextEnc = pFont->getFontEncoding(); + BiffStringFlags nFlags = bBiff2Xf ? BIFF_STR_8BITLENGTH : BIFF_STR_DEFAULT; + setFlag( nFlags, BIFF_STR_EXTRAFONTS, rStrm.getRecId() == BIFF_ID_RSTRING ); + aString.importByteString( rStrm, eTextEnc, nFlags ); } - setCellFormat( maCurrCell ); + aString.finalizeImport(); + mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, aString, maCurrCell.mnXfId ); + mrSheetData.setCellFormat( maCurrCell ); } void BiffSheetDataContext::importLabelSst( BiffInputStream& rStrm ) { importCellHeader( rStrm, false ); maCurrCell.mnCellType = XML_s; - if( maCurrCell.mxCell.is() ) - setSharedStringCell( maCurrCell.mxCell, rStrm.readInt32(), maCurrCell.mnXfId ); - setCellFormat( maCurrCell ); + mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, rStrm.readInt32(), maCurrCell.mnXfId ); + mrSheetData.setCellFormat( maCurrCell ); } void BiffSheetDataContext::importMultBlank( BiffInputStream& rStrm ) @@ -856,7 +808,7 @@ void BiffSheetDataContext::importMultBlank( BiffInputStream& rStrm ) { setCurrCell( aAddr ); importXfId( rStrm, false ); - setCellFormat( maCurrCell ); + mrSheetData.setCellFormat( maCurrCell ); } } @@ -869,9 +821,8 @@ void BiffSheetDataContext::importMultRk( BiffInputStream& rStrm ) maCurrCell.mnCellType = XML_n; importXfId( rStrm, false ); sal_Int32 nRkValue = rStrm.readInt32(); - if( maCurrCell.mxCell.is() ) - maCurrCell.mxCell->setValue( BiffHelper::calcDoubleFromRk( nRkValue ) ); - setCellFormat( maCurrCell ); + mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, BiffHelper::calcDoubleFromRk( nRkValue ) ); + mrSheetData.setCellFormat( maCurrCell ); } } @@ -879,18 +830,16 @@ void BiffSheetDataContext::importNumber( BiffInputStream& rStrm ) { importCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_NUMBER ); maCurrCell.mnCellType = XML_n; - if( maCurrCell.mxCell.is() ) - maCurrCell.mxCell->setValue( rStrm.readDouble() ); - setCellFormat( maCurrCell ); + mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, rStrm.readDouble() ); + mrSheetData.setCellFormat( maCurrCell ); } void BiffSheetDataContext::importRk( BiffInputStream& rStrm ) { importCellHeader( rStrm, false ); maCurrCell.mnCellType = XML_n; - if( maCurrCell.mxCell.is() ) - maCurrCell.mxCell->setValue( BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); - setCellFormat( maCurrCell ); + mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); + mrSheetData.setCellFormat( maCurrCell ); } void BiffSheetDataContext::importRow( BiffInputStream& rStrm ) @@ -939,19 +888,18 @@ void BiffSheetDataContext::importArray( BiffInputStream& rStrm ) BinRange aRange; aRange.read( rStrm, false ); // columns always 8-bit CellRangeAddress aArrayRange; - Reference< XCellRange > xRange = getCellRange( aRange, &aArrayRange ); - Reference< XArrayFormulaTokens > xTokens( xRange, UNO_QUERY ); - if( xRange.is() && xTokens.is() ) + if( getAddressConverter().convertToCellRange( aArrayRange, aRange, getSheetIndex(), true, true ) ) { - rStrm.skip( mnArrayIgnoreSize ); - ArrayFormulaContext aContext( xTokens, aArrayRange ); - getFormulaParser().importFormula( aContext, rStrm ); + rStrm.skip( mnArraySkipSize ); + CellAddress aBaseAddr( aArrayRange.Sheet, aArrayRange.StartColumn, aArrayRange.StartRow ); + ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_ARRAY, rStrm ); + mrSheetData.setArrayFormula( aArrayRange, aTokens ); } } void BiffSheetDataContext::importSharedFmla( BiffInputStream& rStrm ) { - getSharedFormulas().importSharedFmla( rStrm, maCurrCell.maAddress ); + mrSheetData.importSharedFmla( rStrm, maCurrCell.maAddress ); } void BiffSheetDataContext::importDataTable( BiffInputStream& rStrm ) @@ -991,7 +939,7 @@ void BiffSheetDataContext::importDataTable( BiffInputStream& rStrm ) } aModel.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false ); aModel.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false ); - setTableOperation( aTableRange, aModel ); + mrSheetData.setTableOperation( aTableRange, aModel ); } } diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx index 843bfd69fdfe..13382787e958 100644 --- a/oox/source/xls/workbookfragment.cxx +++ b/oox/source/xls/workbookfragment.cxx @@ -222,8 +222,10 @@ void WorkbookFragment::finalizeImport() /* Create fragments for all sheets, before importing them. Needed to do some preprocessing in the fragment constructors, e.g. loading the table fragments for all sheets that are needed before the cell formulas are - loaded. */ - typedef ::std::vector< FragmentHandlerRef > SheetFragmentVector; + loaded. Additionally, the instances of the WorkbookGlobals structures + have to be stored for every sheet. */ + typedef ::std::pair< WorksheetGlobalsRef, FragmentHandlerRef > SheetFragmentHandler; + typedef ::std::vector< SheetFragmentHandler > SheetFragmentVector; SheetFragmentVector aSheetFragments; WorksheetBuffer& rWorksheets = getWorksheets(); sal_Int32 nWorksheetCount = rWorksheets.getWorksheetCount(); @@ -238,34 +240,49 @@ void WorkbookFragment::finalizeImport() OSL_ENSURE( aFragmentPath.getLength() > 0, "WorkbookFragment::finalizeImport - cannot access sheet fragment" ); if( aFragmentPath.getLength() > 0 ) { - ::rtl::Reference< WorksheetFragmentBase > xFragment; double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); ISegmentProgressBarRef xSheetSegment = getProgressBar().createSegment( fSegmentLength ); - // create the fragment according to the sheet type + // get the sheet type according to the relations type + WorksheetType eSheetType = SHEETTYPE_EMPTYSHEET; if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "worksheet" ) ) - { - xFragment.set( new WorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_WORKSHEET, nCalcSheet ) ); - } + eSheetType = SHEETTYPE_WORKSHEET; else if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "chartsheet" ) ) - { - xFragment.set( new ChartsheetFragment( *this, aFragmentPath, xSheetSegment, nCalcSheet ) ); - } + eSheetType = SHEETTYPE_CHARTSHEET; else if( (pRelation->maType == CREATE_MSOFFICE_RELATION_TYPE( "xlMacrosheet" )) || (pRelation->maType == CREATE_MSOFFICE_RELATION_TYPE( "xlIntlMacrosheet" )) ) - { - xFragment.set( new WorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_MACROSHEET, nCalcSheet ) ); - } + eSheetType = SHEETTYPE_MACROSHEET; else if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "dialogsheet" ) ) + eSheetType = SHEETTYPE_DIALOGSHEET; + OSL_ENSURE( eSheetType != SHEETTYPE_EMPTYSHEET, "WorkbookFragment::finalizeImport - unknown sheet type" ); + if( eSheetType != SHEETTYPE_EMPTYSHEET ) { - xFragment.set( new WorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_DIALOGSHEET, nCalcSheet ) ); + // create the WorksheetGlobals object + WorksheetGlobalsRef xSheetGlob = WorksheetHelper::constructGlobals( *this, xSheetSegment, eSheetType, nCalcSheet ); + OSL_ENSURE( xSheetGlob.get(), "WorkbookFragment::finalizeImport - missing sheet in document" ); + if( xSheetGlob.get() ) + { + // create the sheet fragment handler + ::rtl::Reference< WorksheetFragmentBase > xFragment; + switch( eSheetType ) + { + case SHEETTYPE_WORKSHEET: + case SHEETTYPE_MACROSHEET: + case SHEETTYPE_DIALOGSHEET: + xFragment.set( new WorksheetFragment( *xSheetGlob, aFragmentPath ) ); + break; + case SHEETTYPE_CHARTSHEET: + xFragment.set( new ChartsheetFragment( *xSheetGlob, aFragmentPath ) ); + break; + default: + OSL_ENSURE( false, "WorkbookFragment::finalizeImport - unexpected sheet type" ); + } + + // insert the fragment into the map + if( xFragment.is() ) + aSheetFragments.push_back( SheetFragmentHandler( xSheetGlob, xFragment.get() ) ); + } } - - // insert the fragment into the map - OSL_ENSURE( xFragment.is(), "WorkbookFragment::finalizeImport - unknown sheet type" ); - OSL_ENSURE( !xFragment.is() || xFragment->isValidSheet(), "WorkbookFragment::finalizeImport - missing sheet in document" ); - if( xFragment.is() && xFragment->isValidSheet() ) - aSheetFragments.push_back( xFragment.get() ); } } } @@ -278,9 +295,10 @@ void WorkbookFragment::finalizeImport() for( SheetFragmentVector::iterator aIt = aSheetFragments.begin(), aEnd = aSheetFragments.end(); aIt != aEnd; ++aIt ) { // import the sheet fragment - importOoxFragment( *aIt ); - // delete fragment object, will free all allocated sheet buffers - aIt->clear(); + importOoxFragment( aIt->second ); + // delete fragment object and WorkbookGlobals object, will free all allocated sheet buffers + aIt->second.clear(); + aIt->first.reset(); } // open the VBA project storage @@ -715,26 +733,32 @@ bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBa break; } - // create the worksheet fragment + // create the WorksheetGlobals object ISegmentProgressBarRef xSheetProgress = rProgressBar.createSegment( rProgressBar.getFreeLength() ); + WorksheetGlobalsRef xSheetGlob = WorksheetHelper::constructGlobals( *this, xSheetProgress, eSheetType, nCalcSheet ); + OSL_ENSURE( xSheetGlob.get(), "BiffWorkbookFragment::importSheetFragment - missing sheet in document" ); + if( !xSheetGlob.get() ) + return false; + + // create the worksheet fragment ::boost::shared_ptr< BiffWorksheetFragmentBase > xFragment; switch( eSheetType ) { case SHEETTYPE_WORKSHEET: case SHEETTYPE_MACROSHEET: case SHEETTYPE_DIALOGSHEET: - xFragment.reset( new BiffWorksheetFragment( *this, xSheetProgress, eSheetType, nCalcSheet ) ); + xFragment.reset( new BiffWorksheetFragment( *xSheetGlob, *this ) ); break; case SHEETTYPE_CHARTSHEET: - xFragment.reset( new BiffChartsheetFragment( *this, xSheetProgress, nCalcSheet ) ); + xFragment.reset( new BiffChartsheetFragment( *xSheetGlob, *this ) ); break; case SHEETTYPE_MODULESHEET: case SHEETTYPE_EMPTYSHEET: - xFragment.reset( new BiffSkipWorksheetFragment( *this, xSheetProgress, nCalcSheet ) ); + xFragment.reset( new BiffSkipWorksheetFragment( *xSheetGlob, *this ) ); break; } // load the sheet fragment records - return xFragment->isValidSheet() && xFragment->importFragment(); + return xFragment.get() && xFragment->importFragment(); } // ============================================================================ diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx index 6adb7957d4b8..a06001ca3971 100644 --- a/oox/source/xls/workbookhelper.cxx +++ b/oox/source/xls/workbookhelper.cxx @@ -98,12 +98,12 @@ bool IgnoreCaseCompare::operator()( const OUString& rName1, const OUString& rNam // ============================================================================ -class WorkbookData +class WorkbookGlobals { public: - explicit WorkbookData( ExcelFilter& rFilter ); - explicit WorkbookData( ExcelBiffFilter& rFilter, BiffType eBiff ); - ~WorkbookData(); + explicit WorkbookGlobals( ExcelFilter& rFilter ); + explicit WorkbookGlobals( ExcelBiffFilter& rFilter, BiffType eBiff ); + ~WorkbookGlobals(); /** Returns true, if this helper refers to a valid document. */ inline bool isValid() const { return mxDoc.is(); } @@ -118,14 +118,15 @@ public: inline FilterType getFilterType() const { return meFilterType; } /** Returns true, if the file is a multi-sheet document, or false if single-sheet. */ inline bool isWorkbookFile() const { return mbWorkbook; } - /** Returns the index of the current sheet in the Calc document. */ - inline sal_Int16 getCurrentSheetIndex() const { return mnCurrSheet; } - /** Sets the index of the current sheet in the Calc document. */ - inline void setCurrentSheetIndex( sal_Int16 nSheet ) { mnCurrSheet = nSheet; } /** Returns the VBA project storage. */ inline StorageRef getVbaProjectStorage() const { return mxVbaPrjStrg; } - /** Sets the VBA project storage. */ + /** Returns the index of the current Calc sheet, if filter currently processes a sheet. */ + inline sal_Int16 getCurrentSheetIndex() const { return mnCurrSheet; } + + /** Sets the VBA project storage used to import VBA source code and forms. */ inline void setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) { mxVbaPrjStrg = rxVbaPrjStrg; } + /** Sets the index of the current Calc sheet, if filter currently processes a sheet. */ + inline void setCurrentSheetIndex( sal_Int16 nSheet ) { mnCurrSheet = nSheet; } // document model --------------------------------------------------------- @@ -286,7 +287,7 @@ private: // ---------------------------------------------------------------------------- -WorkbookData::WorkbookData( ExcelFilter& rFilter ) : +WorkbookGlobals::WorkbookGlobals( ExcelFilter& rFilter ) : mrBaseFilter( rFilter ), mrExcelBase( rFilter ), meFilterType( FILTER_OOXML ), @@ -295,11 +296,11 @@ WorkbookData::WorkbookData( ExcelFilter& rFilter ) : meBiff( BIFF_UNKNOWN ) { // register at the filter, needed for virtual callbacks (even during construction) - mrExcelBase.registerWorkbookData( *this ); + mrExcelBase.registerWorkbookGlobals( *this ); initialize( true ); } -WorkbookData::WorkbookData( ExcelBiffFilter& rFilter, BiffType eBiff ) : +WorkbookGlobals::WorkbookGlobals( ExcelBiffFilter& rFilter, BiffType eBiff ) : mrBaseFilter( rFilter ), mrExcelBase( rFilter ), meFilterType( FILTER_BIFF ), @@ -308,19 +309,19 @@ WorkbookData::WorkbookData( ExcelBiffFilter& rFilter, BiffType eBiff ) : meBiff( eBiff ) { // register at the filter, needed for virtual callbacks (even during construction) - mrExcelBase.registerWorkbookData( *this ); + mrExcelBase.registerWorkbookGlobals( *this ); initialize( eBiff >= BIFF5 ); } -WorkbookData::~WorkbookData() +WorkbookGlobals::~WorkbookGlobals() { finalize(); - mrExcelBase.unregisterWorkbookData(); + mrExcelBase.unregisterWorkbookGlobals(); } // document model ------------------------------------------------------------- -Reference< XNameContainer > WorkbookData::getStyleFamily( bool bPageStyles ) const +Reference< XNameContainer > WorkbookGlobals::getStyleFamily( bool bPageStyles ) const { Reference< XNameContainer > xStylesNC; try @@ -332,11 +333,11 @@ Reference< XNameContainer > WorkbookData::getStyleFamily( bool bPageStyles ) con catch( Exception& ) { } - OSL_ENSURE( xStylesNC.is(), "WorkbookData::getStyleFamily - cannot access style family" ); + OSL_ENSURE( xStylesNC.is(), "WorkbookGlobals::getStyleFamily - cannot access style family" ); return xStylesNC; } -Reference< XStyle > WorkbookData::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const +Reference< XStyle > WorkbookGlobals::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const { Reference< XStyle > xStyle; try @@ -347,11 +348,11 @@ Reference< XStyle > WorkbookData::getStyleObject( const OUString& rStyleName, bo catch( Exception& ) { } - OSL_ENSURE( xStyle.is(), "WorkbookData::getStyleObject - cannot access style object" ); + OSL_ENSURE( xStyle.is(), "WorkbookGlobals::getStyleObject - cannot access style object" ); return xStyle; } -Reference< XNamedRange > WorkbookData::createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const +Reference< XNamedRange > WorkbookGlobals::createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const { // create the name and insert it into the Calc document Reference< XNamedRange > xNamedRange; @@ -369,11 +370,11 @@ Reference< XNamedRange > WorkbookData::createNamedRangeObject( OUString& orName, catch( Exception& ) { } - OSL_ENSURE( xNamedRange.is(), "WorkbookData::createNamedRangeObject - cannot create defined name" ); + OSL_ENSURE( xNamedRange.is(), "WorkbookGlobals::createNamedRangeObject - cannot create defined name" ); return xNamedRange; } -Reference< XDatabaseRange > WorkbookData::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const +Reference< XDatabaseRange > WorkbookGlobals::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const { // validate cell range CellRangeAddress aDestRange = rRangeAddr; @@ -395,11 +396,11 @@ Reference< XDatabaseRange > WorkbookData::createDatabaseRangeObject( OUString& o catch( Exception& ) { } - OSL_ENSURE( xDatabaseRange.is(), "WorkbookData::createDatabaseRangeObject - cannot create database range" ); + OSL_ENSURE( xDatabaseRange.is(), "WorkbookGlobals::createDatabaseRangeObject - cannot create database range" ); return xDatabaseRange; } -Reference< XStyle > WorkbookData::createStyleObject( OUString& orStyleName, bool bPageStyle ) const +Reference< XStyle > WorkbookGlobals::createStyleObject( OUString& orStyleName, bool bPageStyle ) const { Reference< XStyle > xStyle; try @@ -411,63 +412,62 @@ Reference< XStyle > WorkbookData::createStyleObject( OUString& orStyleName, bool catch( Exception& ) { } - OSL_ENSURE( xStyle.is(), "WorkbookData::createStyleObject - cannot create style" ); + OSL_ENSURE( xStyle.is(), "WorkbookGlobals::createStyleObject - cannot create style" ); return xStyle; } // BIFF specific -------------------------------------------------------------- -void WorkbookData::setTextEncoding( rtl_TextEncoding eTextEnc ) +void WorkbookGlobals::setTextEncoding( rtl_TextEncoding eTextEnc ) { if( eTextEnc != RTL_TEXTENCODING_DONTKNOW ) meTextEnc = eTextEnc; } -void WorkbookData::setCodePage( sal_uInt16 nCodePage ) +void WorkbookGlobals::setCodePage( sal_uInt16 nCodePage ) { setTextEncoding( BiffHelper::calcTextEncodingFromCodePage( nCodePage ) ); mbHasCodePage = true; } -void WorkbookData::setAppFontEncoding( rtl_TextEncoding eAppFontEnc ) +void WorkbookGlobals::setAppFontEncoding( rtl_TextEncoding eAppFontEnc ) { if( !mbHasCodePage ) setTextEncoding( eAppFontEnc ); } -void WorkbookData::setIsWorkbookFile() +void WorkbookGlobals::setIsWorkbookFile() { - OSL_ENSURE( meBiff == BIFF4, "WorkbookData::setIsWorkbookFile - invalid call" ); + OSL_ENSURE( meBiff == BIFF4, "WorkbookGlobals::setIsWorkbookFile - invalid call" ); mbWorkbook = true; } -void WorkbookData::createBuffersPerSheet( sal_Int16 nSheet ) +void WorkbookGlobals::createBuffersPerSheet( sal_Int16 nSheet ) { - // set mnCurrSheet to enable usage of WorkbookHelper::getCurrentSheetIndex() - mnCurrSheet = nSheet; switch( meBiff ) { case BIFF2: case BIFF3: - OSL_ENSURE( mnCurrSheet == 0, "WorkbookData::createBuffersPerSheet - unexpected sheet index" ); - mxDefNames->setLocalCalcSheet( mnCurrSheet ); + OSL_ENSURE( nSheet == 0, "WorkbookGlobals::createBuffersPerSheet - unexpected sheet index" ); + mxDefNames->setLocalCalcSheet( nSheet ); break; case BIFF4: - OSL_ENSURE( mbWorkbook || (mnCurrSheet == 0), "WorkbookData::createBuffersPerSheet - unexpected sheet index" ); + OSL_ENSURE( mbWorkbook || (nSheet == 0), "WorkbookGlobals::createBuffersPerSheet - unexpected sheet index" ); // #i11183# sheets in BIFF4W files have own styles and names - if( mbWorkbook && (mnCurrSheet > 0) ) + if( nSheet > 0 ) { mxStyles.reset( new StylesBuffer( *this ) ); mxDefNames.reset( new DefinedNamesBuffer( *this ) ); mxExtLinks.reset( new ExternalLinkBuffer( *this ) ); } - mxDefNames->setLocalCalcSheet( mnCurrSheet ); + mxDefNames->setLocalCalcSheet( nSheet ); break; case BIFF5: // BIFF5 stores external references per sheet - mxExtLinks.reset( new ExternalLinkBuffer( *this ) ); + if( nSheet > 0 ) + mxExtLinks.reset( new ExternalLinkBuffer( *this ) ); break; case BIFF8: @@ -476,12 +476,11 @@ void WorkbookData::createBuffersPerSheet( sal_Int16 nSheet ) case BIFF_UNKNOWN: break; } - mnCurrSheet = -1; } // private -------------------------------------------------------------------- -void WorkbookData::initialize( bool bWorkbookFile ) +void WorkbookGlobals::initialize( bool bWorkbookFile ) { maCellStyles = CREATE_OUSTRING( "CellStyles" ); maPageStyles = CREATE_OUSTRING( "PageStyles" ); @@ -494,7 +493,7 @@ void WorkbookData::initialize( bool bWorkbookFile ) // the spreadsheet document mxDoc.set( mrBaseFilter.getModel(), UNO_QUERY ); - OSL_ENSURE( mxDoc.is(), "WorkbookData::initialize - no spreadsheet document" ); + OSL_ENSURE( mxDoc.is(), "WorkbookGlobals::initialize - no spreadsheet document" ); mxWorkbookSettings.reset( new WorkbookSettings( *this ) ); mxViewSettings.reset( new ViewSettings( *this ) ); @@ -557,7 +556,7 @@ void WorkbookData::initialize( bool bWorkbookFile ) } } -void WorkbookData::finalize() +void WorkbookGlobals::finalize() { // set some document properties needed after import if( mrBaseFilter.isImportFilter() ) @@ -588,57 +587,73 @@ WorkbookHelper::~WorkbookHelper() { } +/*static*/ WorkbookGlobalsRef WorkbookHelper::constructGlobals( ExcelFilter& rFilter ) +{ + WorkbookGlobalsRef xBookGlob( new WorkbookGlobals( rFilter ) ); + if( !xBookGlob->isValid() ) + xBookGlob.reset(); + return xBookGlob; +} + +/*static*/ WorkbookGlobalsRef WorkbookHelper::constructGlobals( ExcelBiffFilter& rFilter, BiffType eBiff ) +{ + WorkbookGlobalsRef xBookGlob( new WorkbookGlobals( rFilter, eBiff ) ); + if( !xBookGlob->isValid() ) + xBookGlob.reset(); + return xBookGlob; +} + // filter --------------------------------------------------------------------- FilterBase& WorkbookHelper::getBaseFilter() const { - return mrBookData.getBaseFilter(); + return mrBookGlob.getBaseFilter(); } FilterType WorkbookHelper::getFilterType() const { - return mrBookData.getFilterType(); + return mrBookGlob.getFilterType(); } SegmentProgressBar& WorkbookHelper::getProgressBar() const { - return mrBookData.getProgressBar(); + return mrBookGlob.getProgressBar(); } bool WorkbookHelper::isWorkbookFile() const { - return mrBookData.isWorkbookFile(); + return mrBookGlob.isWorkbookFile(); } sal_Int16 WorkbookHelper::getCurrentSheetIndex() const { - return mrBookData.getCurrentSheetIndex(); + return mrBookGlob.getCurrentSheetIndex(); } -void WorkbookHelper::setCurrentSheetIndex( sal_Int16 nSheet ) +void WorkbookHelper::setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) { - mrBookData.setCurrentSheetIndex( nSheet ); + mrBookGlob.setVbaProjectStorage( rxVbaPrjStrg ); } -void WorkbookHelper::setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) +void WorkbookHelper::setCurrentSheetIndex( sal_Int16 nSheet ) { - mrBookData.setVbaProjectStorage( rxVbaPrjStrg ); + mrBookGlob.setCurrentSheetIndex( nSheet ); } void WorkbookHelper::finalizeWorkbookImport() { // workbook settings, document and sheet view settings - mrBookData.getWorkbookSettings().finalizeImport(); - mrBookData.getViewSettings().finalizeImport(); + mrBookGlob.getWorkbookSettings().finalizeImport(); + mrBookGlob.getViewSettings().finalizeImport(); /* Insert all pivot tables. Must be done after loading all sheets, because data pilots expect existing source data on creation. */ - mrBookData.getPivotTables().finalizeImport(); + mrBookGlob.getPivotTables().finalizeImport(); /* Insert scenarios after all sheet processing is done, because new hidden sheets are created for scenarios which would confuse code that relies on certain sheet indexes. Must be done after pivot tables too. */ - mrBookData.getScenarios().finalizeImport(); + mrBookGlob.getScenarios().finalizeImport(); /* Set 'Default' page style to automatic page numbering (default is manual number 1). Otherwise hidden sheets (e.g. for scenarios) which have @@ -649,7 +664,7 @@ void WorkbookHelper::finalizeWorkbookImport() /* Import the VBA project (after finalizing workbook settings which contains the workbook code name). */ - StorageRef xVbaPrjStrg = mrBookData.getVbaProjectStorage(); + StorageRef xVbaPrjStrg = mrBookGlob.getVbaProjectStorage(); if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() ) getBaseFilter().getVbaProject().importVbaProject( *xVbaPrjStrg, getBaseFilter().getGraphicHelper() ); } @@ -658,7 +673,7 @@ void WorkbookHelper::finalizeWorkbookImport() Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const { - return mrBookData.getDocument(); + return mrBookGlob.getDocument(); } Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int16 nSheet ) const @@ -719,129 +734,129 @@ Reference< XCellRange > WorkbookHelper::getCellRangeFromDoc( const CellRangeAddr Reference< XNameContainer > WorkbookHelper::getStyleFamily( bool bPageStyles ) const { - return mrBookData.getStyleFamily( bPageStyles ); + return mrBookGlob.getStyleFamily( bPageStyles ); } Reference< XStyle > WorkbookHelper::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const { - return mrBookData.getStyleObject( rStyleName, bPageStyle ); + return mrBookGlob.getStyleObject( rStyleName, bPageStyle ); } Reference< XNamedRange > WorkbookHelper::createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const { - return mrBookData.createNamedRangeObject( orName, nNameFlags ); + return mrBookGlob.createNamedRangeObject( orName, nNameFlags ); } Reference< XDatabaseRange > WorkbookHelper::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const { - return mrBookData.createDatabaseRangeObject( orName, rRangeAddr ); + return mrBookGlob.createDatabaseRangeObject( orName, rRangeAddr ); } Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle ) const { - return mrBookData.createStyleObject( orStyleName, bPageStyle ); + return mrBookGlob.createStyleObject( orStyleName, bPageStyle ); } // buffers -------------------------------------------------------------------- WorkbookSettings& WorkbookHelper::getWorkbookSettings() const { - return mrBookData.getWorkbookSettings(); + return mrBookGlob.getWorkbookSettings(); } ViewSettings& WorkbookHelper::getViewSettings() const { - return mrBookData.getViewSettings(); + return mrBookGlob.getViewSettings(); } WorksheetBuffer& WorkbookHelper::getWorksheets() const { - return mrBookData.getWorksheets(); + return mrBookGlob.getWorksheets(); } ThemeBuffer& WorkbookHelper::getTheme() const { - return mrBookData.getTheme(); + return mrBookGlob.getTheme(); } StylesBuffer& WorkbookHelper::getStyles() const { - return mrBookData.getStyles(); + return mrBookGlob.getStyles(); } SharedStringsBuffer& WorkbookHelper::getSharedStrings() const { - return mrBookData.getSharedStrings(); + return mrBookGlob.getSharedStrings(); } ExternalLinkBuffer& WorkbookHelper::getExternalLinks() const { - return mrBookData.getExternalLinks(); + return mrBookGlob.getExternalLinks(); } DefinedNamesBuffer& WorkbookHelper::getDefinedNames() const { - return mrBookData.getDefinedNames(); + return mrBookGlob.getDefinedNames(); } TableBuffer& WorkbookHelper::getTables() const { - return mrBookData.getTables(); + return mrBookGlob.getTables(); } ScenarioBuffer& WorkbookHelper::getScenarios() const { - return mrBookData.getScenarios(); + return mrBookGlob.getScenarios(); } ConnectionsBuffer& WorkbookHelper::getConnections() const { - return mrBookData.getConnections(); + return mrBookGlob.getConnections(); } PivotCacheBuffer& WorkbookHelper::getPivotCaches() const { - return mrBookData.getPivotCaches(); + return mrBookGlob.getPivotCaches(); } PivotTableBuffer& WorkbookHelper::getPivotTables() const { - return mrBookData.getPivotTables(); + return mrBookGlob.getPivotTables(); } // converters ----------------------------------------------------------------- FormulaParser& WorkbookHelper::getFormulaParser() const { - return mrBookData.getFormulaParser(); + return mrBookGlob.getFormulaParser(); } UnitConverter& WorkbookHelper::getUnitConverter() const { - return mrBookData.getUnitConverter(); + return mrBookGlob.getUnitConverter(); } AddressConverter& WorkbookHelper::getAddressConverter() const { - return mrBookData.getAddressConverter(); + return mrBookGlob.getAddressConverter(); } ExcelChartConverter& WorkbookHelper::getChartConverter() const { - return mrBookData.getChartConverter(); + return mrBookGlob.getChartConverter(); } PageSettingsConverter& WorkbookHelper::getPageSettingsConverter() const { - return mrBookData.getPageSettingsConverter(); + return mrBookGlob.getPageSettingsConverter(); } // OOXML/BIFF12 specific ------------------------------------------------------ XmlFilterBase& WorkbookHelper::getOoxFilter() const { - OSL_ENSURE( mrBookData.getFilterType() == FILTER_OOXML, "WorkbookHelper::getOoxFilter - invalid call" ); - return mrBookData.getOoxFilter(); + OSL_ENSURE( mrBookGlob.getFilterType() == FILTER_OOXML, "WorkbookHelper::getOoxFilter - invalid call" ); + return mrBookGlob.getOoxFilter(); } bool WorkbookHelper::importOoxFragment( const ::rtl::Reference< FragmentHandler >& rxHandler ) @@ -853,82 +868,48 @@ bool WorkbookHelper::importOoxFragment( const ::rtl::Reference< FragmentHandler BinaryFilterBase& WorkbookHelper::getBiffFilter() const { - OSL_ENSURE( mrBookData.getFilterType() == FILTER_BIFF, "WorkbookHelper::getBiffFilter - invalid call" ); - return mrBookData.getBiffFilter(); + OSL_ENSURE( mrBookGlob.getFilterType() == FILTER_BIFF, "WorkbookHelper::getBiffFilter - invalid call" ); + return mrBookGlob.getBiffFilter(); } BiffType WorkbookHelper::getBiff() const { - return mrBookData.getBiff(); + return mrBookGlob.getBiff(); } rtl_TextEncoding WorkbookHelper::getTextEncoding() const { - return mrBookData.getTextEncoding(); + return mrBookGlob.getTextEncoding(); } void WorkbookHelper::setTextEncoding( rtl_TextEncoding eTextEnc ) { - mrBookData.setTextEncoding( eTextEnc ); + mrBookGlob.setTextEncoding( eTextEnc ); } void WorkbookHelper::setCodePage( sal_uInt16 nCodePage ) { - mrBookData.setCodePage( nCodePage ); + mrBookGlob.setCodePage( nCodePage ); } void WorkbookHelper::setAppFontEncoding( rtl_TextEncoding eAppFontEnc ) { - mrBookData.setAppFontEncoding( eAppFontEnc ); + mrBookGlob.setAppFontEncoding( eAppFontEnc ); } void WorkbookHelper::setIsWorkbookFile() { - mrBookData.setIsWorkbookFile(); + mrBookGlob.setIsWorkbookFile(); } void WorkbookHelper::createBuffersPerSheet( sal_Int16 nSheet ) { - mrBookData.createBuffersPerSheet( nSheet ); + mrBookGlob.createBuffersPerSheet( nSheet ); } BiffCodecHelper& WorkbookHelper::getCodecHelper() const { - return mrBookData.getCodecHelper(); -} - -// ============================================================================ - -namespace prv { - -WorkbookDataOwner::WorkbookDataOwner( WorkbookDataRef xBookData ) : - mxBookData( xBookData ) -{ -} - -WorkbookDataOwner::~WorkbookDataOwner() -{ -} - -} // namespace prv - -// ---------------------------------------------------------------------------- - -WorkbookHelperRoot::WorkbookHelperRoot( ExcelFilter& rFilter ) : - prv::WorkbookDataOwner( prv::WorkbookDataRef( new WorkbookData( rFilter ) ) ), - WorkbookHelper( *mxBookData ) -{ -} - -WorkbookHelperRoot::WorkbookHelperRoot( ExcelBiffFilter& rFilter, BiffType eBiff ) : - prv::WorkbookDataOwner( prv::WorkbookDataRef( new WorkbookData( rFilter, eBiff ) ) ), - WorkbookHelper( *mxBookData ) -{ -} - -bool WorkbookHelperRoot::isValid() const -{ - return mxBookData->isValid(); + return mrBookGlob.getCodecHelper(); } // ============================================================================ diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx index 77f0c1072706..387aef608339 100644 --- a/oox/source/xls/worksheetfragment.cxx +++ b/oox/source/xls/worksheetfragment.cxx @@ -44,6 +44,7 @@ #include "oox/xls/querytablefragment.hxx" #include "oox/xls/scenariobuffer.hxx" #include "oox/xls/scenariocontext.hxx" +#include "oox/xls/sheetdatabuffer.hxx" #include "oox/xls/sheetdatacontext.hxx" #include "oox/xls/tablefragment.hxx" #include "oox/xls/viewsettings.hxx" @@ -124,32 +125,18 @@ ContextHandlerRef DataValidationsContext::onCreateContext( sal_Int32 nElement, c return 0; } -namespace { - -ApiTokenSequence lclImportDataValFormula( FormulaParser& rParser, const OUString& rFormula, const CellAddress& rBaseAddress ) -{ - TokensFormulaContext aContext( true, false ); - aContext.setBaseAddress( rBaseAddress ); - rParser.importFormula( aContext, rFormula ); - return aContext.getTokens(); -} - -} // namespace - void DataValidationsContext::onCharacters( const OUString& rChars ) { if( mxValModel.get() ) switch( getCurrentElement() ) { case XLS_TOKEN( formula1 ): - mxValModel->maTokens1 = lclImportDataValFormula( - getFormulaParser(), rChars, mxValModel->maRanges.getBaseAddress() ); + mxValModel->maTokens1 = getFormulaParser().importFormula( mxValModel->maRanges.getBaseAddress(), rChars ); // process string list of a list validation (convert to list of string tokens) if( mxValModel->mnType == XML_list ) getFormulaParser().convertStringToStringList( mxValModel->maTokens1, ',', true ); break; case XLS_TOKEN( formula2 ): - mxValModel->maTokens2 = lclImportDataValFormula( - getFormulaParser(), rChars, mxValModel->maRanges.getBaseAddress() ); + mxValModel->maTokens2 = getFormulaParser().importFormula( mxValModel->maRanges.getBaseAddress(), rChars ); break; } } @@ -213,12 +200,9 @@ void DataValidationsContext::importDataValidation( SequenceInputStream& rStrm ) // condition formula(s) FormulaParser& rParser = getFormulaParser(); - TokensFormulaContext aContext( true, false ); - aContext.setBaseAddress( aModel.maRanges.getBaseAddress() ); - rParser.importFormula( aContext, rStrm ); - aModel.maTokens1 = aContext.getTokens(); - rParser.importFormula( aContext, rStrm ); - aModel.maTokens2 = aContext.getTokens(); + CellAddress aBaseAddr = aModel.maRanges.getBaseAddress(); + aModel.maTokens1 = rParser.importFormula( aBaseAddr, FORMULATYPE_VALIDATION, rStrm ); + aModel.maTokens2 = rParser.importFormula( aBaseAddr, FORMULATYPE_VALIDATION, rStrm ); // process string list of a list validation (convert to list of string tokens) if( (aModel.mnType == XML_list) && getFlag( nFlags, BIFF_DATAVAL_STRINGLIST ) ) rParser.convertStringToStringList( aModel.maTokens1, ',', true ); @@ -229,9 +213,8 @@ void DataValidationsContext::importDataValidation( SequenceInputStream& rStrm ) // ============================================================================ -WorksheetFragment::WorksheetFragment( const WorkbookHelper& rHelper, - const OUString& rFragmentPath, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : - WorksheetFragmentBase( rHelper, rFragmentPath, rxProgressBar, eSheetType, nSheet ) +WorksheetFragment::WorksheetFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) : + WorksheetFragmentBase( rHelper, rFragmentPath ) { // import data tables related to this worksheet RelationsRef xTableRels = getRelations().getRelationsFromType( CREATE_OFFICEDOC_RELATION_TYPE( "table" ) ); @@ -558,7 +541,7 @@ void WorksheetFragment::importMergeCell( const AttributeList& rAttribs ) { CellRangeAddress aRange; if( getAddressConverter().convertToCellRange( aRange, rAttribs.getString( XML_ref, OUString() ), getSheetIndex(), true, true ) ) - setMergedRange( aRange ); + getSheetData().setMergedRange( aRange ); } void WorksheetFragment::importHyperlink( const AttributeList& rAttribs ) @@ -682,7 +665,7 @@ void WorksheetFragment::importMergeCell( SequenceInputStream& rStrm ) rStrm >> aBinRange; CellRangeAddress aRange; if( getAddressConverter().convertToCellRange( aRange, aBinRange, getSheetIndex(), true, true ) ) - setMergedRange( aRange ); + getSheetData().setMergedRange( aRange ); } void WorksheetFragment::importHyperlink( SequenceInputStream& rStrm ) @@ -753,9 +736,8 @@ void WorksheetFragment::importEmbeddedOleData( StreamDataSequence& orEmbeddedDat // ============================================================================ -BiffWorksheetFragment::BiffWorksheetFragment( const BiffWorkbookFragmentBase& rParent, - const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : - BiffWorksheetFragmentBase( rParent, rxProgressBar, eSheetType, nSheet ) +BiffWorksheetFragment::BiffWorksheetFragment( const WorksheetHelper& rHelper, const BiffWorkbookFragmentBase& rParent ) : + BiffWorksheetFragmentBase( rHelper, rParent ) { } @@ -1047,10 +1029,7 @@ ApiTokenSequence lclReadDataValFormula( BiffInputStream& rStrm, FormulaParser& r { sal_uInt16 nFmlaSize = rStrm.readuInt16(); rStrm.skip( 2 ); - // enable NUL characters, string list is single tStr token with NUL separators - TokensFormulaContext aContext( true, false, true ); - rParser.importFormula( aContext, rStrm, &nFmlaSize ); - return aContext.getTokens(); + return rParser.importFormula( CellAddress(), FORMULATYPE_VALIDATION, rStrm, &nFmlaSize ); } } // namespace @@ -1169,7 +1148,7 @@ void BiffWorksheetFragment::importMergedCells( BiffInputStream& rStrm ) ApiCellRangeList aRanges; getAddressConverter().convertToCellRangeList( aRanges, aBiffRanges, getSheetIndex(), true ); for( ApiCellRangeList::const_iterator aIt = aRanges.begin(), aEnd = aRanges.end(); aIt != aEnd; ++aIt ) - setMergedRange( *aIt ); + getSheetData().setMergedRange( *aIt ); } void BiffWorksheetFragment::importNote( BiffInputStream& rStrm ) diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index 00f65f90294f..778adcff24ab 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -50,10 +49,6 @@ #include #include #include -#include -#include -#include -#include #include #include "oox/core/filterbase.hxx" #include "oox/helper/containerhelper.hxx" @@ -67,8 +62,8 @@ #include "oox/xls/formulaparser.hxx" #include "oox/xls/pagesettings.hxx" #include "oox/xls/querytablebuffer.hxx" -#include "oox/xls/sharedformulabuffer.hxx" #include "oox/xls/sharedstringsbuffer.hxx" +#include "oox/xls/sheetdatabuffer.hxx" #include "oox/xls/stylesbuffer.hxx" #include "oox/xls/unitconverter.hxx" #include "oox/xls/viewsettings.hxx" @@ -192,10 +187,10 @@ void ValueRangeSet::intersect( ValueRangeVector& orRanges, sal_Int32 nFirst, sal void CellModel::reset() { mxCell.clear(); - maValueStr = maFormulaRef = OUString(); + maValue = maFormula = maFormulaRef = OUString(); mnCellType = mnFormulaType = XML_TOKEN_INVALID; mnSharedId = mnXfId = mnNumFmtId = -1; - mbHasValueStr = mbShowPhonetic = false; + mbShowPhonetic = false; } // ---------------------------------------------------------------------------- @@ -324,10 +319,10 @@ void ValidationModel::setBiffErrorStyle( sal_uInt8 nErrorStyle ) // ============================================================================ // ============================================================================ -class WorksheetData : public WorkbookHelper +class WorksheetGlobals : public WorkbookHelper { public: - explicit WorksheetData( + explicit WorksheetGlobals( const WorkbookHelper& rHelper, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, @@ -336,16 +331,12 @@ public: /** Returns true, if this helper refers to an existing Calc sheet. */ inline bool isValidSheet() const { return mxSheet.is(); } - /** Returns a cell formula simulating the passed boolean value. */ - const OUString& getBooleanFormula( bool bValue ) const; - /** Returns the type of this sheet. */ inline WorksheetType getSheetType() const { return meSheetType; } /** Returns the index of the current sheet. */ inline sal_Int16 getSheetIndex() const { return maUsedArea.Sheet; } /** Returns the XSpreadsheet interface of the current sheet. */ - inline const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet >& - getSheet() const { return mxSheet; } + inline const Reference< XSpreadsheet >& getSheet() const { return mxSheet; } /** Returns the XCell interface for the passed cell address. */ Reference< XCell > getCell( const CellAddress& rAddress ) const; @@ -379,10 +370,8 @@ public: /** Returns the cell range address that contains the passed rectangle in 1/100 mm. */ CellRangeAddress getCellRangeFromRectangle( const Rectangle& rRect ) const; - /** Returns the worksheet settings object. */ - inline WorksheetSettings& getWorksheetSettings() { return maSheetSett; } - /** Returns the buffer containing all shared formulas in this sheet. */ - inline SharedFormulaBuffer& getSharedFormulas() { return maSharedFmlas; } + /** Returns the buffer for cell contents and cell formatting. */ + inline SheetDataBuffer& getSheetData() { return maSheetData; } /** Returns the conditional formattings in this sheet. */ inline CondFormatBuffer& getCondFormats() { return maCondFormats; } /** Returns the buffer for all cell comments in this sheet. */ @@ -391,6 +380,8 @@ public: inline AutoFilterBuffer& getAutoFilters() { return maAutoFilters; } /** Returns the buffer for all web query tables in this sheet. */ inline QueryTableBuffer& getQueryTables() { return maQueryTables; } + /** Returns the worksheet settings object. */ + inline WorksheetSettings& getWorksheetSettings() { return maSheetSett; } /** Returns the page/print settings for this sheet. */ inline PageSettings& getPageSettings() { return maPageSett; } /** Returns the view settings for this sheet. */ @@ -402,10 +393,6 @@ public: /** Changes the current sheet type. */ inline void setSheetType( WorksheetType eSheetType ) { meSheetType = eSheetType; } - /** Stores the cell format at the passed address. */ - void setCellFormat( const CellModel& rModel ); - /** Merges the cells in the passed cell range. */ - void setMergedRange( const CellRangeAddress& rRange ); /** Sets a column or row page break described in the passed struct. */ void setPageBreak( const PageBreakModel& rModel, bool bRowBreak ); /** Inserts the hyperlink URL into the spreadsheet. */ @@ -434,6 +421,8 @@ public: @descr Column default formatting is converted directly, other settings are cached and converted in the finalizeImport() call. */ void setColumnModel( const ColumnModel& rModel ); + /** Converts column default cell formatting. */ + void convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const; /** Sets default height and hidden state for all unused rows in the sheet. */ void setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom ); @@ -441,11 +430,8 @@ public: @descr Row default formatting is converted directly, other settings are cached and converted in the finalizeImport() call. */ void setRowModel( const RowModel& rModel ); - - /** Converts column default cell formatting. */ - void convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const; - /** Converts row default cell formatting. */ - void convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) const; + /** Specifies that the passed row needs to set its height manually. */ + void setManualRowHeight( sal_Int32 nRow ); /** Initial conversion before importing the worksheet. */ void initializeWorksheetImport(); @@ -459,52 +445,6 @@ private: typedef ::std::list< HyperlinkModel > HyperlinkModelList; typedef ::std::list< ValidationModel > ValidationModelList; - struct XfIdRowRange - { - sal_Int32 mnFirstRow; /// Index of first row. - sal_Int32 mnLastRow; /// Index of last row. - sal_Int32 mnXfId; /// XF identifier for the row range. - - explicit XfIdRowRange(); - bool intersects( const CellRangeAddress& rRange ) const; - void set( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ); - bool tryExpand( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ); - }; - - struct XfIdRange - { - CellRangeAddress maRange; /// The formatted cell range. - sal_Int32 mnXfId; /// XF identifier for the range. - sal_Int32 mnNumFmtId; /// Number format id overriding the XF. - - void set( const CellModel& rModel ); - bool tryExpand( const CellModel& rModel ); - bool tryMerge( const XfIdRange& rXfIdRange ); - }; - - struct MergedRange - { - CellRangeAddress maRange; /// The formatted cell range. - sal_Int32 mnHorAlign; /// Horizontal alignment in the range. - - explicit MergedRange( const CellRangeAddress& rRange ); - explicit MergedRange( const CellAddress& rAddress, sal_Int32 nHorAlign ); - bool tryExpand( const CellAddress& rAddress, sal_Int32 nHorAlign ); - }; - - typedef ::std::pair< sal_Int32, sal_Int32 > RowColKey; - typedef ::std::map< RowColKey, XfIdRange > XfIdRangeMap; - typedef ::std::list< MergedRange > MergedRangeList; - - /** Writes all cell formatting attributes to the passed row range. */ - void writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const; - /** Writes all cell formatting attributes to the passed cell range. */ - void writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const; - /** Tries to merge the ranges last inserted in maXfIdRanges with existing ranges. */ - void mergeXfIdRanges(); - /** Finalizes the remaining ranges in maXfIdRanges. */ - void finalizeXfIdRanges(); - /** Inserts all imported hyperlinks into their cell ranges. */ void finalizeHyperlinkRanges() const; /** Generates the final URL for the passed hyperlink. */ @@ -515,11 +455,6 @@ private: /** Inserts all imported data validations into their cell ranges. */ void finalizeValidationRanges() const; - /** Merges all cached merged ranges and updates right/bottom cell borders. */ - void finalizeMergedRanges(); - /** Merges the passed merged range and updates right/bottom cell borders. */ - void finalizeMergedRange( const CellRangeAddress& rRange ); - /** Converts column properties for all columns in the sheet. */ void convertColumns(); /** Converts column properties. */ @@ -542,8 +477,6 @@ private: typedef ::std::auto_ptr< VmlDrawing > VmlDrawingPtr; typedef ::std::auto_ptr< BiffSheetDrawing > BiffSheetDrawingPtr; - const OUString maTrueFormula; /// Replacement formula for TRUE boolean cells. - const OUString maFalseFormula; /// Replacement formula for FALSE boolean cells. const OUString maSheetCellRanges; /// Service name for a SheetCellRanges object. const OUString maUrlTextField; /// Service name for a URL text field. const CellAddress& mrMaxApiPos; /// Reference to maximum Calc cell address from address converter. @@ -554,17 +487,13 @@ private: RowModelMap maRowModels; /// Rows sorted by row index. HyperlinkModelList maHyperlinks; /// Cell ranges containing hyperlinks. ValidationModelList maValidations; /// Cell ranges containing data validation settings. - XfIdRowRange maXfIdRowRange; /// Cached XF identifier for a range of rows. - XfIdRangeMap maXfIdRanges; /// Collected XF identifiers for cell ranges. - MergedRangeList maMergedRanges; /// Merged cell ranges. - MergedRangeList maCenterFillRanges; /// Merged cell ranges from 'center across' or 'fill' alignment. ValueRangeSet maManualRowHeights; /// Rows that need manual height independent from own settings. - WorksheetSettings maSheetSett; /// Global settings for this sheet. - SharedFormulaBuffer maSharedFmlas; /// Buffer for shared formulas in this sheet. + SheetDataBuffer maSheetData; /// Buffer for cell contents and cell formatting. CondFormatBuffer maCondFormats; /// Buffer for conditional formattings. CommentsBuffer maComments; /// Buffer for all cell comments in this sheet. AutoFilterBuffer maAutoFilters; /// Sheet auto filters (not associated to a table). QueryTableBuffer maQueryTables; /// Buffer for all web query tables in this sheet. + WorksheetSettings maSheetSett; /// Global settings for this sheet. PageSettings maPageSett; /// Page/print settings for this sheet. SheetViewSettings maSheetViewSett; /// View settings for this sheet. VmlDrawingPtr mxVmlDrawing; /// Collection of all VML shapes. @@ -583,20 +512,18 @@ private: // ---------------------------------------------------------------------------- -WorksheetData::WorksheetData( const WorkbookHelper& rHelper, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : +WorksheetGlobals::WorksheetGlobals( const WorkbookHelper& rHelper, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : WorkbookHelper( rHelper ), - maTrueFormula( CREATE_OUSTRING( "=TRUE()" ) ), - maFalseFormula( CREATE_OUSTRING( "=FALSE()" ) ), maSheetCellRanges( CREATE_OUSTRING( "com.sun.star.sheet.SheetCellRanges" ) ), maUrlTextField( CREATE_OUSTRING( "com.sun.star.text.TextField.URL" ) ), mrMaxApiPos( rHelper.getAddressConverter().getMaxApiAddress() ), maUsedArea( nSheet, SAL_MAX_INT32, SAL_MAX_INT32, -1, -1 ), - maSheetSett( *this ), - maSharedFmlas( *this ), + maSheetData( *this ), maCondFormats( *this ), maComments( *this ), maAutoFilters( *this ), maQueryTables( *this ), + maSheetSett( *this ), maPageSett( *this ), maSheetViewSett( *this ), mxProgressBar( rxProgressBar ), @@ -645,12 +572,7 @@ WorksheetData::WorksheetData( const WorkbookHelper& rHelper, const ISegmentProgr } } -const OUString& WorksheetData::getBooleanFormula( bool bValue ) const -{ - return bValue ? maTrueFormula : maFalseFormula; -} - -Reference< XCell > WorksheetData::getCell( const CellAddress& rAddress ) const +Reference< XCell > WorksheetGlobals::getCell( const CellAddress& rAddress ) const { Reference< XCell > xCell; if( mxSheet.is() ) try @@ -663,7 +585,7 @@ Reference< XCell > WorksheetData::getCell( const CellAddress& rAddress ) const return xCell; } -Reference< XCellRange > WorksheetData::getCellRange( const CellRangeAddress& rRange ) const +Reference< XCellRange > WorksheetGlobals::getCellRange( const CellRangeAddress& rRange ) const { Reference< XCellRange > xRange; if( mxSheet.is() ) try @@ -676,7 +598,7 @@ Reference< XCellRange > WorksheetData::getCellRange( const CellRangeAddress& rRa return xRange; } -Reference< XSheetCellRanges > WorksheetData::getCellRangeList( const ApiCellRangeList& rRanges ) const +Reference< XSheetCellRanges > WorksheetGlobals::getCellRangeList( const ApiCellRangeList& rRanges ) const { Reference< XSheetCellRanges > xRanges; if( mxSheet.is() && !rRanges.empty() ) try @@ -691,7 +613,7 @@ Reference< XSheetCellRanges > WorksheetData::getCellRangeList( const ApiCellRang return xRanges; } -Reference< XCellRange > WorksheetData::getColumn( sal_Int32 nCol ) const +Reference< XCellRange > WorksheetGlobals::getColumn( sal_Int32 nCol ) const { Reference< XCellRange > xColumn; try @@ -706,7 +628,7 @@ Reference< XCellRange > WorksheetData::getColumn( sal_Int32 nCol ) const return xColumn; } -Reference< XCellRange > WorksheetData::getRow( sal_Int32 nRow ) const +Reference< XCellRange > WorksheetGlobals::getRow( sal_Int32 nRow ) const { Reference< XCellRange > xRow; try @@ -721,7 +643,7 @@ Reference< XCellRange > WorksheetData::getRow( sal_Int32 nRow ) const return xRow; } -Reference< XTableColumns > WorksheetData::getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const +Reference< XTableColumns > WorksheetGlobals::getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const { Reference< XTableColumns > xColumns; nLastCol = ::std::min( nLastCol, mrMaxApiPos.Column ); @@ -734,7 +656,7 @@ Reference< XTableColumns > WorksheetData::getColumns( sal_Int32 nFirstCol, sal_I return xColumns; } -Reference< XTableRows > WorksheetData::getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const +Reference< XTableRows > WorksheetGlobals::getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const { Reference< XTableRows > xRows; nLastRow = ::std::min( nLastRow, mrMaxApiPos.Row ); @@ -747,7 +669,7 @@ Reference< XTableRows > WorksheetData::getRows( sal_Int32 nFirstRow, sal_Int32 n return xRows; } -Reference< XDrawPage > WorksheetData::getDrawPage() const +Reference< XDrawPage > WorksheetGlobals::getDrawPage() const { Reference< XDrawPage > xDrawPage; try @@ -760,13 +682,13 @@ Reference< XDrawPage > WorksheetData::getDrawPage() const return xDrawPage; } -const Size& WorksheetData::getDrawPageSize() const +const Size& WorksheetGlobals::getDrawPageSize() const { - OSL_ENSURE( (maDrawPageSize.Width > 0) && (maDrawPageSize.Height > 0), "WorksheetData::getDrawPageSize - called too early, size invalid" ); + OSL_ENSURE( (maDrawPageSize.Width > 0) && (maDrawPageSize.Height > 0), "WorksheetGlobals::getDrawPageSize - called too early, size invalid" ); return maDrawPageSize; } -Point WorksheetData::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const +Point WorksheetGlobals::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const { Point aPoint; PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) ); @@ -774,7 +696,7 @@ Point WorksheetData::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const return aPoint; } -Size WorksheetData::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const +Size WorksheetGlobals::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const { Size aSize; PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) ); @@ -851,7 +773,7 @@ bool lclUpdateInterval( sal_Int32& rnBegAddr, sal_Int32& rnMidAddr, sal_Int32& r } // namespace -CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition ) const +CellAddress WorksheetGlobals::getCellAddressFromPosition( const Point& rPosition ) const { // starting cell address and its position in drawing layer (top-left edge) sal_Int32 nBegCol = 0; @@ -887,7 +809,7 @@ CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition ) return CellAddress( getSheetIndex(), nMidCol, nMidRow ); } -CellRangeAddress WorksheetData::getCellRangeFromRectangle( const Rectangle& rRect ) const +CellRangeAddress WorksheetGlobals::getCellRangeFromRectangle( const Rectangle& rRect ) const { CellAddress aStartAddr = getCellAddressFromPosition( Point( rRect.X, rRect.Y ) ); Point aBotRight( rRect.X + rRect.Width, rRect.Y + rRect.Height ); @@ -907,62 +829,7 @@ CellRangeAddress WorksheetData::getCellRangeFromRectangle( const Rectangle& rRec return CellRangeAddress( getSheetIndex(), aStartAddr.Column, aStartAddr.Row, aEndAddr.Column, aEndAddr.Row ); } -void WorksheetData::setCellFormat( const CellModel& rModel ) -{ - if( rModel.mxCell.is() && ((rModel.mnXfId >= 0) || (rModel.mnNumFmtId >= 0)) ) - { - // try to merge existing ranges and to write some formatting properties - if( !maXfIdRanges.empty() ) - { - // get row index of last inserted cell - sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow; - // row changed - try to merge ranges of last row with existing ranges - if( rModel.maAddress.Row != nLastRow ) - { - mergeXfIdRanges(); - // write format properties of all ranges above last row and remove them - XfIdRangeMap::iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); - while( aIt != aEnd ) - { - // check that range cannot be merged with current row, and that range is not in cached row range - if( (aIt->second.maRange.EndRow < nLastRow) && !maXfIdRowRange.intersects( aIt->second.maRange ) ) - { - writeXfIdRangeProperties( aIt->second ); - maXfIdRanges.erase( aIt++ ); - } - else - ++aIt; - } - } - } - - // try to expand last existing range, or create new range entry - if( maXfIdRanges.empty() || !maXfIdRanges.rbegin()->second.tryExpand( rModel ) ) - maXfIdRanges[ RowColKey( rModel.maAddress.Row, rModel.maAddress.Column ) ].set( rModel ); - - // update merged ranges for 'center across selection' and 'fill' - if( const Xf* pXf = getStyles().getCellXf( rModel.mnXfId ).get() ) - { - sal_Int32 nHorAlign = pXf->getAlignment().getModel().mnHorAlign; - if( (nHorAlign == XML_centerContinuous) || (nHorAlign == XML_fill) ) - { - /* start new merged range, if cell is not empty (#108781#), - or try to expand last range with empty cell */ - if( rModel.mnCellType != XML_TOKEN_INVALID ) - maCenterFillRanges.push_back( MergedRange( rModel.maAddress, nHorAlign ) ); - else if( !maCenterFillRanges.empty() ) - maCenterFillRanges.rbegin()->tryExpand( rModel.maAddress, nHorAlign ); - } - } - } -} - -void WorksheetData::setMergedRange( const CellRangeAddress& rRange ) -{ - maMergedRanges.push_back( MergedRange( rRange ) ); -} - -void WorksheetData::setPageBreak( const PageBreakModel& rModel, bool bRowBreak ) +void WorksheetGlobals::setPageBreak( const PageBreakModel& rModel, bool bRowBreak ) { if( rModel.mbManual && (rModel.mnColRow > 0) ) { @@ -971,27 +838,27 @@ void WorksheetData::setPageBreak( const PageBreakModel& rModel, bool bRowBreak ) } } -void WorksheetData::setHyperlink( const HyperlinkModel& rModel ) +void WorksheetGlobals::setHyperlink( const HyperlinkModel& rModel ) { maHyperlinks.push_back( rModel ); } -void WorksheetData::setValidation( const ValidationModel& rModel ) +void WorksheetGlobals::setValidation( const ValidationModel& rModel ) { maValidations.push_back( rModel ); } -void WorksheetData::setDrawingPath( const OUString& rDrawingPath ) +void WorksheetGlobals::setDrawingPath( const OUString& rDrawingPath ) { maDrawingPath = rDrawingPath; } -void WorksheetData::setVmlDrawingPath( const OUString& rVmlDrawingPath ) +void WorksheetGlobals::setVmlDrawingPath( const OUString& rVmlDrawingPath ) { maVmlDrawingPath = rVmlDrawingPath; } -void WorksheetData::extendUsedArea( const CellAddress& rAddress ) +void WorksheetGlobals::extendUsedArea( const CellAddress& rAddress ) { maUsedArea.StartColumn = ::std::min( maUsedArea.StartColumn, rAddress.Column ); maUsedArea.StartRow = ::std::min( maUsedArea.StartRow, rAddress.Row ); @@ -999,13 +866,13 @@ void WorksheetData::extendUsedArea( const CellAddress& rAddress ) maUsedArea.EndRow = ::std::max( maUsedArea.EndRow, rAddress.Row ); } -void WorksheetData::extendUsedArea( const CellRangeAddress& rRange ) +void WorksheetGlobals::extendUsedArea( const CellRangeAddress& rRange ) { extendUsedArea( CellAddress( rRange.Sheet, rRange.StartColumn, rRange.StartRow ) ); extendUsedArea( CellAddress( rRange.Sheet, rRange.EndColumn, rRange.EndRow ) ); } -void WorksheetData::extendShapeBoundingBox( const Rectangle& rShapeRect ) +void WorksheetGlobals::extendShapeBoundingBox( const Rectangle& rShapeRect ) { if( (maShapeBoundingBox.Width == 0) && (maShapeBoundingBox.Height == 0) ) { @@ -1023,7 +890,7 @@ void WorksheetData::extendShapeBoundingBox( const Rectangle& rShapeRect ) } } -void WorksheetData::setBaseColumnWidth( sal_Int32 nWidth ) +void WorksheetGlobals::setBaseColumnWidth( sal_Int32 nWidth ) { // do not modify width, if setDefaultColumnWidth() has been used if( !mbHasDefWidth && (nWidth > 0) ) @@ -1035,7 +902,7 @@ void WorksheetData::setBaseColumnWidth( sal_Int32 nWidth ) } } -void WorksheetData::setDefaultColumnWidth( double fWidth ) +void WorksheetGlobals::setDefaultColumnWidth( double fWidth ) { // overrides a width set with setBaseColumnWidth() if( fWidth > 0.0 ) @@ -1045,7 +912,7 @@ void WorksheetData::setDefaultColumnWidth( double fWidth ) } } -void WorksheetData::setColumnModel( const ColumnModel& rModel ) +void WorksheetGlobals::setColumnModel( const ColumnModel& rModel ) { // convert 1-based OOXML column indexes to 0-based API column indexes sal_Int32 nFirstCol = rModel.mnFirstCol - 1; @@ -1060,7 +927,17 @@ void WorksheetData::setColumnModel( const ColumnModel& rModel ) } } -void WorksheetData::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom ) +void WorksheetGlobals::convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const +{ + CellRangeAddress aRange( getSheetIndex(), nFirstCol, 0, nLastCol, mrMaxApiPos.Row ); + if( getAddressConverter().validateCellRange( aRange, true, false ) ) + { + PropertySet aPropSet( getCellRange( aRange ) ); + getStyles().writeCellXfToPropertySet( aPropSet, nXfId ); + } +} + +void WorksheetGlobals::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom ) { maDefRowModel.mfHeight = fHeight; maDefRowModel.mbCustomHeight = bCustomHeight; @@ -1069,7 +946,7 @@ void WorksheetData::setDefaultRowSettings( double fHeight, bool bCustomHeight, b maDefRowModel.mbThickBottom = bThickBottom; } -void WorksheetData::setRowModel( const RowModel& rModel ) +void WorksheetGlobals::setRowModel( const RowModel& rModel ) { // convert 1-based OOXML row indexes to 0-based API row indexes sal_Int32 nFirstRow = rModel.mnFirstRow - 1; @@ -1077,22 +954,7 @@ void WorksheetData::setRowModel( const RowModel& rModel ) if( (0 <= nFirstRow) && (nFirstRow <= mrMaxApiPos.Row) ) { // set row formatting - if( rModel.mbCustomFormat ) - { - // try to expand cached row range, if formatting is equal - if( (maXfIdRowRange.mnLastRow < 0) || !maXfIdRowRange.tryExpand( nFirstRow, nLastRow, rModel.mnXfId ) ) - { - writeXfIdRowRangeProperties( maXfIdRowRange ); - maXfIdRowRange.set( nFirstRow, nLastRow, rModel.mnXfId ); - } - } - else if( maXfIdRowRange.mnLastRow >= 0 ) - { - // finish last cached row range - writeXfIdRowRangeProperties( maXfIdRowRange ); - maXfIdRowRange.set( -1, -1, -1 ); - } - + maSheetData.setRowFormat( nFirstRow, nLastRow, rModel.mnXfId, rModel.mbCustomFormat ); // expand last entry or add new entry if( maRowModels.empty() || !maRowModels.rbegin()->second.tryExpand( rModel ) ) maRowModels[ nFirstRow ] = rModel; @@ -1100,52 +962,35 @@ void WorksheetData::setRowModel( const RowModel& rModel ) lclUpdateProgressBar( mxRowProgress, maUsedArea, nLastRow ); } -void WorksheetData::convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const +void WorksheetGlobals::setManualRowHeight( sal_Int32 nRow ) { - CellRangeAddress aRange( getSheetIndex(), nFirstCol, 0, nLastCol, mrMaxApiPos.Row ); - if( getAddressConverter().validateCellRange( aRange, true, false ) ) - { - PropertySet aPropSet( getCellRange( aRange ) ); - getStyles().writeCellXfToPropertySet( aPropSet, nXfId ); - } + maManualRowHeights.insert( nRow ); } -void WorksheetData::convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) const -{ - CellRangeAddress aRange( getSheetIndex(), 0, nFirstRow, mrMaxApiPos.Column, nLastRow ); - if( getAddressConverter().validateCellRange( aRange, true, false ) ) - { - PropertySet aPropSet( getCellRange( aRange ) ); - getStyles().writeCellXfToPropertySet( aPropSet, nXfId ); - } -} - -void WorksheetData::initializeWorksheetImport() +void WorksheetGlobals::initializeWorksheetImport() { // set default cell style for unused cells PropertySet aPropSet( mxSheet ); aPropSet.setProperty( PROP_CellStyle, getStyles().getDefaultStyleName() ); - /* Remember current sheet index in global data, needed by some global + /* Remember the current sheet index in global data, needed by global objects, e.g. the chart converter. */ setCurrentSheetIndex( getSheetIndex() ); } -void WorksheetData::finalizeWorksheetImport() +void WorksheetGlobals::finalizeWorksheetImport() { lclUpdateProgressBar( mxRowProgress, 1.0 ); - finalizeXfIdRanges(); + maSheetData.finalizeImport(); lclUpdateProgressBar( mxFinalProgress, 0.25 ); finalizeHyperlinkRanges(); finalizeValidationRanges(); - finalizeMergedRanges(); maAutoFilters.finalizeImport( getSheetIndex() ); - maSheetSett.finalizeImport(); maCondFormats.finalizeImport(); maQueryTables.finalizeImport(); + maSheetSett.finalizeImport(); maPageSett.finalizeImport(); maSheetViewSett.finalizeImport(); - maSheetSett.finalizeImport(); lclUpdateProgressBar( mxFinalProgress, 0.5 ); convertColumns(); @@ -1154,159 +999,13 @@ void WorksheetData::finalizeWorksheetImport() finalizeDrawings(); lclUpdateProgressBar( mxFinalProgress, 1.0 ); - // reset current sheet index in global data + // forget current sheet index in global data setCurrentSheetIndex( -1 ); } // private -------------------------------------------------------------------- -WorksheetData::XfIdRowRange::XfIdRowRange() : - mnFirstRow( -1 ), - mnLastRow( -1 ), - mnXfId( -1 ) -{ -} - -bool WorksheetData::XfIdRowRange::intersects( const CellRangeAddress& rRange ) const -{ - return (rRange.StartRow <= mnLastRow) && (mnFirstRow <= rRange.EndRow); -} - -void WorksheetData::XfIdRowRange::set( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) -{ - mnFirstRow = nFirstRow; - mnLastRow = nLastRow; - mnXfId = nXfId; -} - -bool WorksheetData::XfIdRowRange::tryExpand( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) -{ - if( mnXfId == nXfId ) - { - if( mnLastRow + 1 == nFirstRow ) - { - mnLastRow = nLastRow; - return true; - } - if( mnFirstRow == nLastRow + 1 ) - { - mnFirstRow = nFirstRow; - return true; - } - } - return false; -} - -void WorksheetData::XfIdRange::set( const CellModel& rModel ) -{ - maRange.Sheet = rModel.maAddress.Sheet; - maRange.StartColumn = maRange.EndColumn = rModel.maAddress.Column; - maRange.StartRow = maRange.EndRow = rModel.maAddress.Row; - mnXfId = rModel.mnXfId; - mnNumFmtId = rModel.mnNumFmtId; -} - -bool WorksheetData::XfIdRange::tryExpand( const CellModel& rModel ) -{ - if( (mnXfId == rModel.mnXfId) && (mnNumFmtId == rModel.mnNumFmtId) && - (maRange.StartRow == rModel.maAddress.Row) && - (maRange.EndRow == rModel.maAddress.Row) && - (maRange.EndColumn + 1 == rModel.maAddress.Column) ) - { - ++maRange.EndColumn; - return true; - } - return false; -} - -bool WorksheetData::XfIdRange::tryMerge( const XfIdRange& rXfIdRange ) -{ - if( (mnXfId == rXfIdRange.mnXfId) && - (mnNumFmtId == rXfIdRange.mnNumFmtId) && - (maRange.EndRow + 1 == rXfIdRange.maRange.StartRow) && - (maRange.StartColumn == rXfIdRange.maRange.StartColumn) && - (maRange.EndColumn == rXfIdRange.maRange.EndColumn) ) - { - maRange.EndRow = rXfIdRange.maRange.EndRow; - return true; - } - return false; -} - - -WorksheetData::MergedRange::MergedRange( const CellRangeAddress& rRange ) : - maRange( rRange ), - mnHorAlign( XML_TOKEN_INVALID ) -{ -} - -WorksheetData::MergedRange::MergedRange( const CellAddress& rAddress, sal_Int32 nHorAlign ) : - maRange( rAddress.Sheet, rAddress.Column, rAddress.Row, rAddress.Column, rAddress.Row ), - mnHorAlign( nHorAlign ) -{ -} - -bool WorksheetData::MergedRange::tryExpand( const CellAddress& rAddress, sal_Int32 nHorAlign ) -{ - if( (mnHorAlign == nHorAlign) && (maRange.StartRow == rAddress.Row) && - (maRange.EndRow == rAddress.Row) && (maRange.EndColumn + 1 == rAddress.Column) ) - { - ++maRange.EndColumn; - return true; - } - return false; -} - -void WorksheetData::writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const -{ - if( (rXfIdRowRange.mnLastRow >= 0) && (rXfIdRowRange.mnXfId >= 0) ) - convertRowFormat( rXfIdRowRange.mnFirstRow, rXfIdRowRange.mnLastRow, rXfIdRowRange.mnXfId ); -} - -void WorksheetData::writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const -{ - StylesBuffer& rStyles = getStyles(); - PropertyMap aPropMap; - if( rXfIdRange.mnXfId >= 0 ) - rStyles.writeCellXfToPropertyMap( aPropMap, rXfIdRange.mnXfId ); - if( rXfIdRange.mnNumFmtId >= 0 ) - rStyles.writeNumFmtToPropertyMap( aPropMap, rXfIdRange.mnNumFmtId ); - PropertySet aPropSet( getCellRange( rXfIdRange.maRange ) ); - aPropSet.setProperties( aPropMap ); -} - -void WorksheetData::mergeXfIdRanges() -{ - if( !maXfIdRanges.empty() ) - { - // get row index of last range - sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow; - // process all ranges located in the same row of the last range - XfIdRangeMap::iterator aMergeIt = maXfIdRanges.end(); - while( (aMergeIt != maXfIdRanges.begin()) && ((--aMergeIt)->second.maRange.StartRow == nLastRow) ) - { - const XfIdRange& rMergeXfIdRange = aMergeIt->second; - // try to find a range that can be merged with rMergeRange - bool bFound = false; - for( XfIdRangeMap::iterator aIt = maXfIdRanges.begin(); !bFound && (aIt != aMergeIt); ++aIt ) - if( (bFound = aIt->second.tryMerge( rMergeXfIdRange )) == true ) - maXfIdRanges.erase( aMergeIt++ ); - } - } -} - -void WorksheetData::finalizeXfIdRanges() -{ - // write default formatting of remaining row range - writeXfIdRowRangeProperties( maXfIdRowRange ); - // try to merge remaining inserted ranges - mergeXfIdRanges(); - // write all formatting - for( XfIdRangeMap::const_iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); aIt != aEnd; ++aIt ) - writeXfIdRangeProperties( aIt->second ); -} - -void WorksheetData::finalizeHyperlinkRanges() const +void WorksheetGlobals::finalizeHyperlinkRanges() const { for( HyperlinkModelList::const_iterator aIt = maHyperlinks.begin(), aEnd = maHyperlinks.end(); aIt != aEnd; ++aIt ) { @@ -1319,7 +1018,7 @@ void WorksheetData::finalizeHyperlinkRanges() const } } -OUString WorksheetData::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const +OUString WorksheetGlobals::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const { OUStringBuffer aUrlBuffer; if( rHyperlink.maTarget.getLength() > 0 ) @@ -1347,20 +1046,20 @@ OUString WorksheetData::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) cons return aUrl; } -void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const +void WorksheetGlobals::insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const { Reference< XCell > xCell = getCell( rAddress ); if( xCell.is() ) switch( xCell->getType() ) { // #i54261# restrict creation of URL field to text cells - case ::com::sun::star::table::CellContentType_TEXT: + case CellContentType_TEXT: { Reference< XText > xText( xCell, UNO_QUERY ); if( xText.is() ) { // create a URL field object and set its properties Reference< XTextContent > xUrlField( getBaseFilter().getModelFactory()->createInstance( maUrlTextField ), UNO_QUERY ); - OSL_ENSURE( xUrlField.is(), "WorksheetData::insertHyperlink - cannot create text field" ); + OSL_ENSURE( xUrlField.is(), "WorksheetGlobals::insertHyperlink - cannot create text field" ); if( xUrlField.is() ) { // properties of the URL field @@ -1376,7 +1075,7 @@ void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString } catch( const Exception& ) { - OSL_ENSURE( false, "WorksheetData::insertHyperlink - cannot insert text field" ); + OSL_ENSURE( false, "WorksheetGlobals::insertHyperlink - cannot insert text field" ); } } } @@ -1386,15 +1085,13 @@ void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString // fix for #i31050# disabled, HYPERLINK is not able to return numeric value (#i91351#) #if 0 // #i31050# replace number with HYPERLINK function - case ::com::sun::star::table::CellContentType_VALUE: + case CellContentType_VALUE: { Reference< XFormulaTokens > xTokens( xCell, UNO_QUERY ); - OSL_ENSURE( xTokens.is(), "WorksheetHelper::insertHyperlink - missing formula interface" ); - if( xTokens.is() ) - { - SimpleFormulaContext aContext( xTokens, false, false ); - getFormulaParser().convertNumberToHyperlink( aContext, rUrl, xCell->getValue() ); - } + ApiTokenSequence aTokens = getFormulaParser().convertNumberToHyperlink( rUrl, xCell->getValue() ); + OSL_ENSURE( xTokens.is(), "WorksheetHelper::insertHyperlink - missing formula token interface" ); + if( xTokens.is() && aTokens.hasElements() ) + xTokens->setTokens( aTokens ); } break; #endif @@ -1403,7 +1100,7 @@ void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString } } -void WorksheetData::finalizeValidationRanges() const +void WorksheetGlobals::finalizeValidationRanges() const { for( ValidationModelList::const_iterator aIt = maValidations.begin(), aEnd = maValidations.end(); aIt != aEnd; ++aIt ) { @@ -1413,37 +1110,36 @@ void WorksheetData::finalizeValidationRanges() const if( xValidation.is() ) { PropertySet aValProps( xValidation ); - namespace csss = ::com::sun::star::sheet; // convert validation type to API enum - ValidationType eType = csss::ValidationType_ANY; + ValidationType eType = ValidationType_ANY; switch( aIt->mnType ) { - case XML_custom: eType = csss::ValidationType_CUSTOM; break; - case XML_date: eType = csss::ValidationType_DATE; break; - case XML_decimal: eType = csss::ValidationType_DECIMAL; break; - case XML_list: eType = csss::ValidationType_LIST; break; - case XML_none: eType = csss::ValidationType_ANY; break; - case XML_textLength: eType = csss::ValidationType_TEXT_LEN; break; - case XML_time: eType = csss::ValidationType_TIME; break; - case XML_whole: eType = csss::ValidationType_WHOLE; break; - default: OSL_ENSURE( false, "WorksheetData::finalizeValidationRanges - unknown validation type" ); + case XML_custom: eType = ValidationType_CUSTOM; break; + case XML_date: eType = ValidationType_DATE; break; + case XML_decimal: eType = ValidationType_DECIMAL; break; + case XML_list: eType = ValidationType_LIST; break; + case XML_none: eType = ValidationType_ANY; break; + case XML_textLength: eType = ValidationType_TEXT_LEN; break; + case XML_time: eType = ValidationType_TIME; break; + case XML_whole: eType = ValidationType_WHOLE; break; + default: OSL_ENSURE( false, "WorksheetGlobals::finalizeValidationRanges - unknown validation type" ); } aValProps.setProperty( PROP_Type, eType ); // convert error alert style to API enum - ValidationAlertStyle eAlertStyle = csss::ValidationAlertStyle_STOP; + ValidationAlertStyle eAlertStyle = ValidationAlertStyle_STOP; switch( aIt->mnErrorStyle ) { - case XML_information: eAlertStyle = csss::ValidationAlertStyle_INFO; break; - case XML_stop: eAlertStyle = csss::ValidationAlertStyle_STOP; break; - case XML_warning: eAlertStyle = csss::ValidationAlertStyle_WARNING; break; - default: OSL_ENSURE( false, "WorksheetData::finalizeValidationRanges - unknown error style" ); + case XML_information: eAlertStyle = ValidationAlertStyle_INFO; break; + case XML_stop: eAlertStyle = ValidationAlertStyle_STOP; break; + case XML_warning: eAlertStyle = ValidationAlertStyle_WARNING; break; + default: OSL_ENSURE( false, "WorksheetGlobals::finalizeValidationRanges - unknown error style" ); } aValProps.setProperty( PROP_ErrorAlertStyle, eAlertStyle ); // convert dropdown style to API visibility constants - sal_Int16 nVisibility = aIt->mbNoDropDown ? csss::TableValidationVisibility::INVISIBLE : csss::TableValidationVisibility::UNSORTED; + sal_Int16 nVisibility = aIt->mbNoDropDown ? TableValidationVisibility::INVISIBLE : TableValidationVisibility::UNSORTED; aValProps.setProperty( PROP_ShowList, nVisibility ); // messages @@ -1478,67 +1174,7 @@ void WorksheetData::finalizeValidationRanges() const } } -void WorksheetData::finalizeMergedRanges() -{ - MergedRangeList::const_iterator aIt, aEnd; - for( aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt ) - finalizeMergedRange( aIt->maRange ); - for( aIt = maCenterFillRanges.begin(), aEnd = maCenterFillRanges.end(); aIt != aEnd; ++aIt ) - finalizeMergedRange( aIt->maRange ); -} - -void WorksheetData::finalizeMergedRange( const CellRangeAddress& rRange ) -{ - bool bMultiCol = rRange.StartColumn < rRange.EndColumn; - bool bMultiRow = rRange.StartRow < rRange.EndRow; - - if( bMultiCol || bMultiRow ) try - { - // merge the cell range - Reference< XMergeable > xMerge( getCellRange( rRange ), UNO_QUERY_THROW ); - xMerge->merge( sal_True ); - - // if merging this range worked (no overlapping merged ranges), update cell borders - Reference< XCell > xTopLeft( getCell( CellAddress( getSheetIndex(), rRange.StartColumn, rRange.StartRow ) ), UNO_SET_THROW ); - PropertySet aTopLeftProp( xTopLeft ); - - // copy right border of top-right cell to right border of top-left cell - if( bMultiCol ) - { - PropertySet aTopRightProp( getCell( CellAddress( getSheetIndex(), rRange.EndColumn, rRange.StartRow ) ) ); - BorderLine aLine; - if( aTopRightProp.getProperty( aLine, PROP_RightBorder ) ) - aTopLeftProp.setProperty( PROP_RightBorder, aLine ); - } - - // copy bottom border of bottom-left cell to bottom border of top-left cell - if( bMultiRow ) - { - PropertySet aBottomLeftProp( getCell( CellAddress( getSheetIndex(), rRange.StartColumn, rRange.EndRow ) ) ); - BorderLine aLine; - if( aBottomLeftProp.getProperty( aLine, PROP_BottomBorder ) ) - aTopLeftProp.setProperty( PROP_BottomBorder, aLine ); - } - - // #i93609# merged range in a single row: test if manual row height is needed - if( !bMultiRow ) - { - bool bTextWrap = aTopLeftProp.getBoolProperty( PROP_IsTextWrapped ); - if( !bTextWrap && (xTopLeft->getType() == ::com::sun::star::table::CellContentType_TEXT) ) - { - Reference< XText > xText( xTopLeft, UNO_QUERY ); - bTextWrap = xText.is() && (xText->getString().indexOf( '\x0A' ) >= 0); - } - if( bTextWrap ) - maManualRowHeights.insert( rRange.StartRow ); - } - } - catch( Exception& ) - { - } -} - -void WorksheetData::convertColumns() +void WorksheetGlobals::convertColumns() { sal_Int32 nNextCol = 0; sal_Int32 nMaxCol = mrMaxApiPos.Column; @@ -1567,7 +1203,7 @@ void WorksheetData::convertColumns() convertOutlines( aColLevels, nMaxCol + 1, 0, false, false ); } -void WorksheetData::convertColumns( OutlineLevelVec& orColLevels, +void WorksheetGlobals::convertColumns( OutlineLevelVec& orColLevels, sal_Int32 nFirstCol, sal_Int32 nLastCol, const ColumnModel& rModel ) { PropertySet aPropSet( getColumns( nFirstCol, nLastCol ) ); @@ -1588,7 +1224,7 @@ void WorksheetData::convertColumns( OutlineLevelVec& orColLevels, convertOutlines( orColLevels, nFirstCol, rModel.mnLevel, rModel.mbCollapsed, false ); } -void WorksheetData::convertRows() +void WorksheetGlobals::convertRows() { sal_Int32 nNextRow = 0; sal_Int32 nMaxRow = mrMaxApiPos.Row; @@ -1617,7 +1253,7 @@ void WorksheetData::convertRows() convertOutlines( aRowLevels, nMaxRow + 1, 0, false, true ); } -void WorksheetData::convertRows( OutlineLevelVec& orRowLevels, +void WorksheetGlobals::convertRows( OutlineLevelVec& orRowLevels, sal_Int32 nFirstRow, sal_Int32 nLastRow, const RowModel& rModel, double fDefHeight ) { // row height: convert points to row height in 1/100 mm @@ -1648,13 +1284,13 @@ void WorksheetData::convertRows( OutlineLevelVec& orRowLevels, convertOutlines( orRowLevels, nFirstRow, rModel.mnLevel, rModel.mbCollapsed, true ); } -void WorksheetData::convertOutlines( OutlineLevelVec& orLevels, +void WorksheetGlobals::convertOutlines( OutlineLevelVec& orLevels, sal_Int32 nColRow, sal_Int32 nLevel, bool bCollapsed, bool bRows ) { /* It is ensured from caller functions, that this function is called without any gaps between the processed column or row ranges. */ - OSL_ENSURE( nLevel >= 0, "WorksheetData::convertOutlines - negative outline level" ); + OSL_ENSURE( nLevel >= 0, "WorksheetGlobals::convertOutlines - negative outline level" ); nLevel = ::std::max< sal_Int32 >( nLevel, 0 ); sal_Int32 nSize = orLevels.size(); @@ -1677,7 +1313,7 @@ void WorksheetData::convertOutlines( OutlineLevelVec& orLevels, } } -void WorksheetData::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapse, bool bRows ) +void WorksheetGlobals::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapse, bool bRows ) { try { @@ -1685,14 +1321,14 @@ void WorksheetData::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastC if( bRows ) { CellRangeAddress aRange( getSheetIndex(), 0, nFirstColRow, 0, nLastColRow ); - xOutline->group( aRange, ::com::sun::star::table::TableOrientation_ROWS ); + xOutline->group( aRange, TableOrientation_ROWS ); if( bCollapse ) xOutline->hideDetail( aRange ); } else { CellRangeAddress aRange( getSheetIndex(), nFirstColRow, 0, nLastColRow, 0 ); - xOutline->group( aRange, ::com::sun::star::table::TableOrientation_COLUMNS ); + xOutline->group( aRange, TableOrientation_COLUMNS ); if( bCollapse ) xOutline->hideDetail( aRange ); } @@ -1702,7 +1338,7 @@ void WorksheetData::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastC } } -void WorksheetData::finalizeDrawings() +void WorksheetGlobals::finalizeDrawings() { // calculate the current drawing page size (after rows/columns are imported) PropertySet aRangeProp( getCellRange( CellRangeAddress( getSheetIndex(), 0, 0, mrMaxApiPos.Column, mrMaxApiPos.Row ) ) ); @@ -1752,46 +1388,55 @@ void WorksheetData::finalizeDrawings() if( maSheetViewSett.isSheetRightToLeft() ) { PropertySet aPropSet( mxSheet ); - aPropSet.setProperty( PROP_TableLayout, ::com::sun::star::text::WritingMode2::RL_TB ); + aPropSet.setProperty( PROP_TableLayout, WritingMode2::RL_TB ); } } // ============================================================================ // ============================================================================ -WorksheetHelper::WorksheetHelper( WorksheetData& rSheetData ) : - WorkbookHelper( rSheetData ), - mrSheetData( rSheetData ) +WorksheetHelper::WorksheetHelper( WorksheetGlobals& rSheetGlob ) : + WorkbookHelper( rSheetGlob ), + mrSheetGlob( rSheetGlob ) { } +/*static*/ WorksheetGlobalsRef WorksheetHelper::constructGlobals( const WorkbookHelper& rHelper, + const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) +{ + WorksheetGlobalsRef xSheetGlob( new WorksheetGlobals( rHelper, rxProgressBar, eSheetType, nSheet ) ); + if( !xSheetGlob->isValidSheet() ) + xSheetGlob.reset(); + return xSheetGlob; +} + WorksheetType WorksheetHelper::getSheetType() const { - return mrSheetData.getSheetType(); + return mrSheetGlob.getSheetType(); } sal_Int16 WorksheetHelper::getSheetIndex() const { - return mrSheetData.getSheetIndex(); + return mrSheetGlob.getSheetIndex(); } const Reference< XSpreadsheet >& WorksheetHelper::getSheet() const { - return mrSheetData.getSheet(); + return mrSheetGlob.getSheet(); } Reference< XCell > WorksheetHelper::getCell( const CellAddress& rAddress ) const { - return mrSheetData.getCell( rAddress ); + return mrSheetGlob.getCell( rAddress ); } Reference< XCell > WorksheetHelper::getCell( const OUString& rAddressStr, CellAddress* opAddress ) const { CellAddress aAddress; - if( getAddressConverter().convertToCellAddress( aAddress, rAddressStr, mrSheetData.getSheetIndex(), true ) ) + if( getAddressConverter().convertToCellAddress( aAddress, rAddressStr, mrSheetGlob.getSheetIndex(), true ) ) { if( opAddress ) *opAddress = aAddress; - return mrSheetData.getCell( aAddress ); + return mrSheetGlob.getCell( aAddress ); } return Reference< XCell >(); } @@ -1799,62 +1444,22 @@ Reference< XCell > WorksheetHelper::getCell( const OUString& rAddressStr, CellAd Reference< XCell > WorksheetHelper::getCell( const BinAddress& rBinAddress, CellAddress* opAddress ) const { CellAddress aAddress; - if( getAddressConverter().convertToCellAddress( aAddress, rBinAddress, mrSheetData.getSheetIndex(), true ) ) + if( getAddressConverter().convertToCellAddress( aAddress, rBinAddress, mrSheetGlob.getSheetIndex(), true ) ) { if( opAddress ) *opAddress = aAddress; - return mrSheetData.getCell( aAddress ); + return mrSheetGlob.getCell( aAddress ); } return Reference< XCell >(); } Reference< XCellRange > WorksheetHelper::getCellRange( const CellRangeAddress& rRange ) const { - return mrSheetData.getCellRange( rRange ); -} - -Reference< XCellRange > WorksheetHelper::getCellRange( const OUString& rRangeStr, CellRangeAddress* opRange ) const -{ - CellRangeAddress aRange; - if( getAddressConverter().convertToCellRange( aRange, rRangeStr, mrSheetData.getSheetIndex(), true, true ) ) - { - if( opRange ) *opRange = aRange; - return mrSheetData.getCellRange( aRange ); - } - return Reference< XCellRange >(); -} - -Reference< XCellRange > WorksheetHelper::getCellRange( const BinRange& rBinRange, CellRangeAddress* opRange ) const -{ - CellRangeAddress aRange; - if( getAddressConverter().convertToCellRange( aRange, rBinRange, mrSheetData.getSheetIndex(), true, true ) ) - { - if( opRange ) *opRange = aRange; - return mrSheetData.getCellRange( aRange ); - } - return Reference< XCellRange >(); + return mrSheetGlob.getCellRange( rRange ); } Reference< XSheetCellRanges > WorksheetHelper::getCellRangeList( const ApiCellRangeList& rRanges ) const { - return mrSheetData.getCellRangeList( rRanges ); -} - -Reference< XSheetCellRanges > WorksheetHelper::getCellRangeList( - const OUString& rRangesStr, ApiCellRangeList* opRanges ) const -{ - ApiCellRangeList aRanges; - getAddressConverter().convertToCellRangeList( aRanges, rRangesStr, mrSheetData.getSheetIndex(), true ); - if( opRanges ) *opRanges = aRanges; - return mrSheetData.getCellRangeList( aRanges ); -} - -Reference< XSheetCellRanges > WorksheetHelper::getCellRangeList( - const BinRangeList& rBinRanges, ApiCellRangeList* opRanges ) const -{ - ApiCellRangeList aRanges; - getAddressConverter().convertToCellRangeList( aRanges, rBinRanges, mrSheetData.getSheetIndex(), true ); - if( opRanges ) *opRanges = aRanges; - return mrSheetData.getCellRangeList( aRanges ); + return mrSheetGlob.getCellRangeList( rRanges ); } CellAddress WorksheetHelper::getCellAddress( const Reference< XCell >& rxCell ) @@ -1879,272 +1484,112 @@ CellRangeAddress WorksheetHelper::getRangeAddress( const Reference< XCellRange > Reference< XCellRange > WorksheetHelper::getColumn( sal_Int32 nCol ) const { - return mrSheetData.getColumn( nCol ); + return mrSheetGlob.getColumn( nCol ); } Reference< XCellRange > WorksheetHelper::getRow( sal_Int32 nRow ) const { - return mrSheetData.getRow( nRow ); + return mrSheetGlob.getRow( nRow ); } Reference< XTableColumns > WorksheetHelper::getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const { - return mrSheetData.getColumns( nFirstCol, nLastCol ); + return mrSheetGlob.getColumns( nFirstCol, nLastCol ); } Reference< XTableRows > WorksheetHelper::getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const { - return mrSheetData.getRows( nFirstRow, nLastRow ); + return mrSheetGlob.getRows( nFirstRow, nLastRow ); } Reference< XDrawPage > WorksheetHelper::getDrawPage() const { - return mrSheetData.getDrawPage(); + return mrSheetGlob.getDrawPage(); } Point WorksheetHelper::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const { - return mrSheetData.getCellPosition( nCol, nRow ); + return mrSheetGlob.getCellPosition( nCol, nRow ); } Size WorksheetHelper::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const { - return mrSheetData.getCellSize( nCol, nRow ); + return mrSheetGlob.getCellSize( nCol, nRow ); } Size WorksheetHelper::getDrawPageSize() const { - return mrSheetData.getDrawPageSize(); + return mrSheetGlob.getDrawPageSize(); } -WorksheetSettings& WorksheetHelper::getWorksheetSettings() const +SheetDataBuffer& WorksheetHelper::getSheetData() const { - return mrSheetData.getWorksheetSettings(); -} - -SharedFormulaBuffer& WorksheetHelper::getSharedFormulas() const -{ - return mrSheetData.getSharedFormulas(); + return mrSheetGlob.getSheetData(); } CondFormatBuffer& WorksheetHelper::getCondFormats() const { - return mrSheetData.getCondFormats(); + return mrSheetGlob.getCondFormats(); } CommentsBuffer& WorksheetHelper::getComments() const { - return mrSheetData.getComments(); + return mrSheetGlob.getComments(); } AutoFilterBuffer& WorksheetHelper::getAutoFilters() const { - return mrSheetData.getAutoFilters(); + return mrSheetGlob.getAutoFilters(); } QueryTableBuffer& WorksheetHelper::getQueryTables() const { - return mrSheetData.getQueryTables(); + return mrSheetGlob.getQueryTables(); +} + +WorksheetSettings& WorksheetHelper::getWorksheetSettings() const +{ + return mrSheetGlob.getWorksheetSettings(); } PageSettings& WorksheetHelper::getPageSettings() const { - return mrSheetData.getPageSettings(); + return mrSheetGlob.getPageSettings(); } SheetViewSettings& WorksheetHelper::getSheetViewSettings() const { - return mrSheetData.getSheetViewSettings(); + return mrSheetGlob.getSheetViewSettings(); } VmlDrawing& WorksheetHelper::getVmlDrawing() const { - return mrSheetData.getVmlDrawing(); + return mrSheetGlob.getVmlDrawing(); } BiffSheetDrawing& WorksheetHelper::getBiffDrawing() const { - return mrSheetData.getBiffDrawing(); -} - -void WorksheetHelper::setStringCell( const Reference< XCell >& rxCell, const OUString& rText ) const -{ - OSL_ENSURE( rxCell.is(), "WorksheetHelper::setStringCell - missing cell interface" ); - Reference< XText > xText( rxCell, UNO_QUERY ); - if( xText.is() ) - xText->setString( rText ); -} - -void WorksheetHelper::setSharedStringCell( const Reference< XCell >& rxCell, sal_Int32 nStringId, sal_Int32 nXfId ) const -{ - OSL_ENSURE( rxCell.is(), "WorksheetHelper::setSharedStringCell - missing cell interface" ); - getSharedStrings().convertString( Reference< XText >( rxCell, UNO_QUERY ), nStringId, nXfId ); -} - -void WorksheetHelper::setDateTimeCell( const Reference< XCell >& rxCell, const DateTime& rDateTime ) const -{ - OSL_ENSURE( rxCell.is(), "WorksheetHelper::setDateTimeCell - missing cell interface" ); - // write serial date/time value into the cell - double fSerial = getUnitConverter().calcSerialFromDateTime( rDateTime ); - rxCell->setValue( fSerial ); - // set appropriate number format - using namespace ::com::sun::star::util::NumberFormat; - sal_Int16 nStdFmt = (fSerial < 1.0) ? TIME : (((rDateTime.Hours > 0) || (rDateTime.Minutes > 0) || (rDateTime.Seconds > 0)) ? DATETIME : DATE); - setStandardNumFmt( rxCell, nStdFmt ); -} - -void WorksheetHelper::setBooleanCell( const Reference< XCell >& rxCell, bool bValue ) const -{ - OSL_ENSURE( rxCell.is(), "WorksheetHelper::setBooleanCell - missing cell interface" ); - rxCell->setFormula( mrSheetData.getBooleanFormula( bValue ) ); -} - -void WorksheetHelper::setErrorCell( const Reference< XCell >& rxCell, const OUString& rErrorCode ) const -{ - setErrorCell( rxCell, getUnitConverter().calcBiffErrorCode( rErrorCode ) ); -} - -void WorksheetHelper::setErrorCell( const Reference< XCell >& rxCell, sal_uInt8 nErrorCode ) const -{ - Reference< XFormulaTokens > xTokens( rxCell, UNO_QUERY ); - OSL_ENSURE( xTokens.is(), "WorksheetHelper::setErrorCell - missing formula interface" ); - if( xTokens.is() ) - { - SimpleFormulaContext aContext( xTokens, false, false ); - getFormulaParser().convertErrorToFormula( aContext, nErrorCode ); - } -} - -void WorksheetHelper::setCell( CellModel& orModel ) const -{ - OSL_ENSURE( orModel.mxCell.is(), "WorksheetHelper::setCell - missing cell interface" ); - if( orModel.mbHasValueStr ) switch( orModel.mnCellType ) - { - case XML_b: - setBooleanCell( orModel.mxCell, orModel.maValueStr.toDouble() != 0.0 ); - // #108770# set 'Standard' number format for all Boolean cells - orModel.mnNumFmtId = 0; - break; - case XML_n: - orModel.mxCell->setValue( orModel.maValueStr.toDouble() ); - break; - case XML_e: - setErrorCell( orModel.mxCell, orModel.maValueStr ); - break; - case XML_str: - setStringCell( orModel.mxCell, orModel.maValueStr ); - break; - case XML_s: - setSharedStringCell( orModel.mxCell, orModel.maValueStr.toInt32(), orModel.mnXfId ); - break; - } -} - -void WorksheetHelper::setStandardNumFmt( const Reference< XCell >& rxCell, sal_Int16 nStdNumFmt ) const -{ - try - { - Reference< XNumberFormatsSupplier > xNumFmtsSupp( getDocument(), UNO_QUERY_THROW ); - Reference< XNumberFormatTypes > xNumFmtTypes( xNumFmtsSupp->getNumberFormats(), UNO_QUERY_THROW ); - sal_Int32 nIndex = xNumFmtTypes->getStandardFormat( nStdNumFmt, Locale() ); - PropertySet aPropSet( rxCell ); - aPropSet.setProperty( PROP_NumberFormat, nIndex ); - } - catch( Exception& ) - { - } + return mrSheetGlob.getBiffDrawing(); } void WorksheetHelper::setSheetType( WorksheetType eSheetType ) { - mrSheetData.setSheetType( eSheetType ); -} - -void WorksheetHelper::setCellFormat( const CellModel& rModel ) -{ - mrSheetData.setCellFormat( rModel ); -} - -void WorksheetHelper::setMergedRange( const CellRangeAddress& rRange ) -{ - mrSheetData.setMergedRange( rRange ); + mrSheetGlob.setSheetType( eSheetType ); } void WorksheetHelper::setPageBreak( const PageBreakModel& rModel, bool bRowBreak ) { - mrSheetData.setPageBreak( rModel, bRowBreak ); + mrSheetGlob.setPageBreak( rModel, bRowBreak ); } void WorksheetHelper::setHyperlink( const HyperlinkModel& rModel ) { - mrSheetData.setHyperlink( rModel ); + mrSheetGlob.setHyperlink( rModel ); } void WorksheetHelper::setValidation( const ValidationModel& rModel ) { - mrSheetData.setValidation( rModel ); -} - -void WorksheetHelper::setTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel ) const -{ - OSL_ENSURE( getAddressConverter().checkCellRange( rRange, true, false ), "WorksheetHelper::setTableOperation - invalid range" ); - bool bOk = false; - if( !rModel.mbRef1Deleted && (rModel.maRef1.getLength() > 0) && (rRange.StartColumn > 0) && (rRange.StartRow > 0) ) - { - CellRangeAddress aOpRange = rRange; - CellAddress aRef1, aRef2; - if( getAddressConverter().convertToCellAddress( aRef1, rModel.maRef1, mrSheetData.getSheetIndex(), true ) ) try - { - if( rModel.mb2dTable ) - { - if( !rModel.mbRef2Deleted && getAddressConverter().convertToCellAddress( aRef2, rModel.maRef2, mrSheetData.getSheetIndex(), true ) ) - { - // API call expects input values inside operation range - --aOpRange.StartColumn; - --aOpRange.StartRow; - // formula range is top-left cell of operation range - CellRangeAddress aFormulaRange( mrSheetData.getSheetIndex(), aOpRange.StartColumn, aOpRange.StartRow, aOpRange.StartColumn, aOpRange.StartRow ); - // set multiple operation - Reference< XMultipleOperation > xMultOp( mrSheetData.getCellRange( aOpRange ), UNO_QUERY_THROW ); - xMultOp->setTableOperation( aFormulaRange, ::com::sun::star::sheet::TableOperationMode_BOTH, aRef2, aRef1 ); - bOk = true; - } - } - else if( rModel.mbRowTable ) - { - // formula range is column to the left of operation range - CellRangeAddress aFormulaRange( mrSheetData.getSheetIndex(), aOpRange.StartColumn - 1, aOpRange.StartRow, aOpRange.StartColumn - 1, aOpRange.EndRow ); - // API call expects input values (top row) inside operation range - --aOpRange.StartRow; - // set multiple operation - Reference< XMultipleOperation > xMultOp( mrSheetData.getCellRange( aOpRange ), UNO_QUERY_THROW ); - xMultOp->setTableOperation( aFormulaRange, ::com::sun::star::sheet::TableOperationMode_ROW, aRef1, aRef1 ); - bOk = true; - } - else - { - // formula range is row above operation range - CellRangeAddress aFormulaRange( mrSheetData.getSheetIndex(), aOpRange.StartColumn, aOpRange.StartRow - 1, aOpRange.EndColumn, aOpRange.StartRow - 1 ); - // API call expects input values (left column) inside operation range - --aOpRange.StartColumn; - // set multiple operation - Reference< XMultipleOperation > xMultOp( mrSheetData.getCellRange( aOpRange ), UNO_QUERY_THROW ); - xMultOp->setTableOperation( aFormulaRange, ::com::sun::star::sheet::TableOperationMode_COLUMN, aRef1, aRef1 ); - bOk = true; - } - } - catch( Exception& ) - { - } - } - - // on error: fill cell range with error codes - if( !bOk ) - { - for( CellAddress aPos( mrSheetData.getSheetIndex(), rRange.StartColumn, rRange.StartRow ); aPos.Row <= rRange.EndRow; ++aPos.Row ) - for( aPos.Column = rRange.StartColumn; aPos.Column <= rRange.EndColumn; ++aPos.Column ) - setErrorCell( mrSheetData.getCell( aPos ), BIFF_ERR_REF ); - } + mrSheetGlob.setValidation( rModel ); } void WorksheetHelper::setLabelRanges( const ApiCellRangeList& rColRanges, const ApiCellRangeList& rRowRanges ) @@ -2201,107 +1646,72 @@ void WorksheetHelper::setLabelRanges( const ApiCellRangeList& rColRanges, const void WorksheetHelper::setDrawingPath( const OUString& rDrawingPath ) { - mrSheetData.setDrawingPath( rDrawingPath ); + mrSheetGlob.setDrawingPath( rDrawingPath ); } void WorksheetHelper::setVmlDrawingPath( const OUString& rVmlDrawingPath ) { - mrSheetData.setVmlDrawingPath( rVmlDrawingPath ); + mrSheetGlob.setVmlDrawingPath( rVmlDrawingPath ); } void WorksheetHelper::extendUsedArea( const CellAddress& rAddress ) { - mrSheetData.extendUsedArea( rAddress ); + mrSheetGlob.extendUsedArea( rAddress ); } void WorksheetHelper::extendUsedArea( const CellRangeAddress& rRange ) { - mrSheetData.extendUsedArea( rRange ); + mrSheetGlob.extendUsedArea( rRange ); } void WorksheetHelper::extendShapeBoundingBox( const Rectangle& rShapeRect ) { - mrSheetData.extendShapeBoundingBox( rShapeRect ); + mrSheetGlob.extendShapeBoundingBox( rShapeRect ); } void WorksheetHelper::setBaseColumnWidth( sal_Int32 nWidth ) { - mrSheetData.setBaseColumnWidth( nWidth ); + mrSheetGlob.setBaseColumnWidth( nWidth ); } void WorksheetHelper::setDefaultColumnWidth( double fWidth ) { - mrSheetData.setDefaultColumnWidth( fWidth ); + mrSheetGlob.setDefaultColumnWidth( fWidth ); } void WorksheetHelper::setDefaultColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) { - mrSheetData.convertColumnFormat( nFirstCol, nLastCol, nXfId ); + mrSheetGlob.convertColumnFormat( nFirstCol, nLastCol, nXfId ); } void WorksheetHelper::setColumnModel( const ColumnModel& rModel ) { - mrSheetData.setColumnModel( rModel ); + mrSheetGlob.setColumnModel( rModel ); } void WorksheetHelper::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom ) { - mrSheetData.setDefaultRowSettings( fHeight, bCustomHeight, bHidden, bThickTop, bThickBottom ); + mrSheetGlob.setDefaultRowSettings( fHeight, bCustomHeight, bHidden, bThickTop, bThickBottom ); } void WorksheetHelper::setRowModel( const RowModel& rModel ) { - mrSheetData.setRowModel( rModel ); -} - -void WorksheetHelper::initializeWorksheetImport() -{ - mrSheetData.initializeWorksheetImport(); -} - -void WorksheetHelper::finalizeWorksheetImport() -{ - mrSheetData.finalizeWorksheetImport(); -} - -// ============================================================================ - -namespace prv { - -WorksheetDataOwner::WorksheetDataOwner( WorksheetDataRef xSheetData ) : - mxSheetData( xSheetData ) -{ -} - -WorksheetDataOwner::~WorksheetDataOwner() -{ + mrSheetGlob.setRowModel( rModel ); } -} // namespace prv - -// ---------------------------------------------------------------------------- - -WorksheetHelperRoot::WorksheetHelperRoot( const WorkbookHelper& rHelper, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : - prv::WorksheetDataOwner( prv::WorksheetDataRef( new WorksheetData( rHelper, rxProgressBar, eSheetType, nSheet ) ) ), - WorksheetHelper( *mxSheetData ) +void WorksheetHelper::setManualRowHeight( sal_Int32 nRow ) { + mrSheetGlob.setManualRowHeight( nRow ); } -WorksheetHelperRoot::WorksheetHelperRoot( const WorksheetHelper& rHelper ) : - prv::WorksheetDataOwner( prv::WorksheetDataRef() ), - WorksheetHelper( rHelper ) -{ -} - -WorksheetHelperRoot::WorksheetHelperRoot( const WorksheetHelperRoot& rHelper ) : - prv::WorksheetDataOwner( rHelper.mxSheetData ), - WorksheetHelper( rHelper ) +void WorksheetHelper::initializeWorksheetImport() { + mrSheetGlob.initializeWorksheetImport(); } -bool WorksheetHelperRoot::isValidSheet() const +void WorksheetHelper::finalizeWorksheetImport() { - return mxSheetData->isValidSheet(); + mrSheetGlob.finalizeWorksheetImport(); } // ============================================================================ -- cgit From f042519085109581abcdff4403e7e6d9999d4980 Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Fri, 11 Feb 2011 16:11:43 +0100 Subject: dr78: #164376# oox import performance: step 2 - move every access to XCell interface into SheetDataBuffer class, delay creation of array formulas and table operations, let XCellRangeData::setDataArray() accept formula token sequences in addition to plain values --- oox/source/xls/defnamesbuffer.cxx | 22 +- oox/source/xls/externallinkbuffer.cxx | 5 +- oox/source/xls/pivotcachebuffer.cxx | 18 +- oox/source/xls/sheetdatabuffer.cxx | 410 +++++++++--------- oox/source/xls/sheetdatacontext.cxx | 789 +++++++++++++++++----------------- oox/source/xls/worksheethelper.cxx | 43 -- 6 files changed, 629 insertions(+), 658 deletions(-) (limited to 'oox/source') diff --git a/oox/source/xls/defnamesbuffer.cxx b/oox/source/xls/defnamesbuffer.cxx index 335aae5273af..e69cc44c8a1d 100644 --- a/oox/source/xls/defnamesbuffer.cxx +++ b/oox/source/xls/defnamesbuffer.cxx @@ -276,22 +276,22 @@ Any DefinedNameBase::getReference( const CellAddress& rBaseAddr ) const return Any(); } -ApiTokenSequence DefinedNameBase::importOoxFormula( const CellAddress& rBaseAddr ) +ApiTokenSequence DefinedNameBase::importOoxFormula( sal_Int16 nBaseSheet ) { return (maModel.maFormula.getLength() > 0) ? - getFormulaParser().importFormula( rBaseAddr, maModel.maFormula ) : + getFormulaParser().importFormula( CellAddress( nBaseSheet, 0, 0 ), maModel.maFormula ) : getFormulaParser().convertErrorToFormula( BIFF_ERR_NAME ); } -ApiTokenSequence DefinedNameBase::importBiff12Formula( const CellAddress& rBaseAddr, SequenceInputStream& rStrm ) +ApiTokenSequence DefinedNameBase::importBiff12Formula( sal_Int16 nBaseSheet, SequenceInputStream& rStrm ) { - return getFormulaParser().importFormula( rBaseAddr, FORMULATYPE_DEFINEDNAME, rStrm ); + return getFormulaParser().importFormula( CellAddress( nBaseSheet, 0, 0 ), FORMULATYPE_DEFINEDNAME, rStrm ); } -ApiTokenSequence DefinedNameBase::importBiffFormula( const CellAddress& rBaseAddr, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) +ApiTokenSequence DefinedNameBase::importBiffFormula( sal_Int16 nBaseSheet, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) { return (!pnFmlaSize || (*pnFmlaSize > 0)) ? - getFormulaParser().importFormula( rBaseAddr, FORMULATYPE_DEFINEDNAME, rStrm, pnFmlaSize ) : + getFormulaParser().importFormula( CellAddress( nBaseSheet, 0, 0 ), FORMULATYPE_DEFINEDNAME, rStrm, pnFmlaSize ) : getFormulaParser().convertErrorToFormula( BIFF_ERR_NAME ); } @@ -460,8 +460,7 @@ void DefinedName::importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcShee these names contain a simple cell reference or range reference. Other regular defined names and external names rely on existence of this reference. */ - CellAddress aBaseAddr( mnCalcSheet, 0, 0 ); - ApiTokenSequence aTokens = importBiffFormula( aBaseAddr, rStrm, &mnFmlaSize ); + ApiTokenSequence aTokens = importBiffFormula( mnCalcSheet, rStrm, &mnFmlaSize ); extractReference( aTokens ); } else @@ -521,7 +520,6 @@ void DefinedName::convertFormula() // convert and set formula of the defined name ApiTokenSequence aTokens; - CellAddress aBaseAddr( mnCalcSheet, 0, 0 ); switch( getFilterType() ) { case FILTER_OOXML: @@ -529,10 +527,10 @@ void DefinedName::convertFormula() if( mxFormula.get() ) { SequenceInputStream aStrm( *mxFormula ); - aTokens = importBiff12Formula( aBaseAddr, aStrm ); + aTokens = importBiff12Formula( mnCalcSheet, aStrm ); } else - aTokens = importOoxFormula( aBaseAddr ); + aTokens = importOoxFormula( mnCalcSheet ); } break; case FILTER_BIFF: @@ -543,7 +541,7 @@ void DefinedName::convertFormula() BiffInputStream& rStrm = mxBiffStrm->getStream(); BiffInputStreamPosGuard aStrmGuard( rStrm ); if( mxBiffStrm->restorePosition() ) - aTokens = importBiffFormula( aBaseAddr, rStrm, &mnFmlaSize ); + aTokens = importBiffFormula( mnCalcSheet, rStrm, &mnFmlaSize ); } } break; diff --git a/oox/source/xls/externallinkbuffer.cxx b/oox/source/xls/externallinkbuffer.cxx index fe527f35f634..aa4d7a068530 100644 --- a/oox/source/xls/externallinkbuffer.cxx +++ b/oox/source/xls/externallinkbuffer.cxx @@ -242,8 +242,7 @@ void ExternalName::importExternalName( BiffInputStream& rStrm ) // cell references to other internal sheets are stored in hidden external names if( bHiddenRef && (getBiff() == BIFF4) && isWorkbookFile() ) { - CellAddress aBaseAddr( mrParentLink.getCalcSheetIndex(), 0, 0 ); - ApiTokenSequence aTokens = importBiffFormula( aBaseAddr, rStrm ); + ApiTokenSequence aTokens = importBiffFormula( mrParentLink.getCalcSheetIndex(), rStrm ); extractReference( aTokens ); } break; @@ -252,7 +251,7 @@ void ExternalName::importExternalName( BiffInputStream& rStrm ) // cell references to other documents are stored in hidden external names if( bHiddenRef ) { - ApiTokenSequence aTokens = importBiffFormula( CellAddress(), rStrm ); + ApiTokenSequence aTokens = importBiffFormula( 0, rStrm ); extractExternalReference( aTokens ); } break; diff --git a/oox/source/xls/pivotcachebuffer.cxx b/oox/source/xls/pivotcachebuffer.cxx index 88935a679c83..2c4d55b089f1 100644 --- a/oox/source/xls/pivotcachebuffer.cxx +++ b/oox/source/xls/pivotcachebuffer.cxx @@ -34,7 +34,6 @@ #include #include #include -#include #include #include "oox/core/filterbase.hxx" #include "oox/helper/attributelist.hxx" @@ -938,7 +937,7 @@ OUString PivotCacheField::createParentGroupField( const Reference< XDataPilotFie void PivotCacheField::writeSourceHeaderCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const { CellAddress aCellAddr( rSheetHelper.getSheetIndex(), nCol, nRow ); - rSheetHelper.getSheetData().setStringCell( rSheetHelper.getCell( aCellAddr ), aCellAddr, maFieldModel.maName ); + rSheetHelper.getSheetData().setStringCell( aCellAddr, maFieldModel.maName ); } void PivotCacheField::writeSourceDataCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const @@ -986,15 +985,14 @@ void PivotCacheField::writeItemToSourceDataCell( WorksheetHelper& rSheetHelper, { CellAddress aCellAddr( rSheetHelper.getSheetIndex(), nCol, nRow ); SheetDataBuffer& rSheetData = rSheetHelper.getSheetData(); - Reference< XCell > xCell = rSheetHelper.getCell( aCellAddr ); - if( xCell.is() ) switch( rItem.getType() ) + switch( rItem.getType() ) { - case XML_s: rSheetData.setStringCell( xCell, aCellAddr, rItem.getValue().get< OUString >() ); break; - case XML_n: rSheetData.setValueCell( xCell, aCellAddr, rItem.getValue().get< double >() ); break; - case XML_i: rSheetData.setValueCell( xCell, aCellAddr, rItem.getValue().get< sal_Int16 >() ); break; - case XML_d: rSheetData.setDateTimeCell( xCell, aCellAddr, rItem.getValue().get< DateTime >() ); break; - case XML_b: rSheetData.setBooleanCell( xCell, aCellAddr, rItem.getValue().get< bool >() ); break; - case XML_e: rSheetData.setErrorCell( xCell, aCellAddr, static_cast< sal_uInt8 >( rItem.getValue().get< sal_Int32 >() ) ); break; + case XML_s: rSheetData.setStringCell( aCellAddr, rItem.getValue().get< OUString >() ); break; + case XML_n: rSheetData.setValueCell( aCellAddr, rItem.getValue().get< double >() ); break; + case XML_i: rSheetData.setValueCell( aCellAddr, rItem.getValue().get< sal_Int16 >() ); break; + case XML_d: rSheetData.setDateTimeCell( aCellAddr, rItem.getValue().get< DateTime >() ); break; + case XML_b: rSheetData.setBooleanCell( aCellAddr, rItem.getValue().get< bool >() ); break; + case XML_e: rSheetData.setErrorCell( aCellAddr, static_cast< sal_uInt8 >( rItem.getValue().get< sal_Int32 >() ) ); break; default: OSL_ENSURE( false, "PivotCacheField::writeItemToSourceDataCell - unexpected item data type" ); } } diff --git a/oox/source/xls/sheetdatabuffer.cxx b/oox/source/xls/sheetdatabuffer.cxx index e63e9fbb61b5..0cfe741cb135 100755 --- a/oox/source/xls/sheetdatabuffer.cxx +++ b/oox/source/xls/sheetdatabuffer.cxx @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -66,147 +67,116 @@ using ::rtl::OUStringBuffer; // ============================================================================ -namespace { - -bool lclContains( const CellRangeAddress& rRange, const CellAddress& rAddr ) +CellModel::CellModel() : + mnCellType( XML_TOKEN_INVALID ), + mnXfId( -1 ), + mbShowPhonetic( false ) { - return - (rRange.Sheet == rAddr.Sheet) && - (rRange.StartColumn <= rAddr.Column) && (rAddr.Column <= rRange.EndColumn) && - (rRange.StartRow <= rAddr.Row) && (rAddr.Row <= rRange.EndRow); } -} // namespace +// ---------------------------------------------------------------------------- -// ============================================================================ +CellFormulaModel::CellFormulaModel() : + mnFormulaType( XML_TOKEN_INVALID ), + mnSharedId( -1 ) +{ +} -SheetDataBuffer::SheetDataBuffer( const WorksheetHelper& rHelper ) : - WorksheetHelper( rHelper ), - mbPendingSharedFmla( false ) +bool CellFormulaModel::isValidArrayRef( const CellAddress& rCellAddr ) { + return + (maFormulaRef.Sheet == rCellAddr.Sheet) && + (maFormulaRef.StartColumn == rCellAddr.Column) && + (maFormulaRef.StartRow == rCellAddr.Row); } -void SheetDataBuffer::importSharedFmla( const OUString& rFormula, const OUString& rSharedRange, sal_Int32 nSharedId, const CellAddress& rBaseAddr ) +bool CellFormulaModel::isValidSharedRef( const CellAddress& rCellAddr ) { - CellRangeAddress aFmlaRange; - if( getAddressConverter().convertToCellRange( aFmlaRange, rSharedRange, getSheetIndex(), true, true ) ) try - { - // get or create the defined name representing the shared formula - OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SheetDataBuffer::importSharedFmla - invalid range for shared formula" ); - Reference< XNamedRange > xNamedRange = createSharedFormulaName( BinAddress( nSharedId, 0 ) ); - Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY_THROW ); - // convert the formula definition - ApiTokenSequence aTokens = getFormulaParser().importFormula( rBaseAddr, rFormula ); - xTokens->setTokens( aTokens ); - // retry to insert a pending shared formula cell - retryPendingSharedFormulaCell(); - } - catch( Exception& ) - { - } + return + (maFormulaRef.Sheet == rCellAddr.Sheet) && + (maFormulaRef.StartColumn <= rCellAddr.Column) && (rCellAddr.Column <= maFormulaRef.EndColumn) && + (maFormulaRef.StartRow <= rCellAddr.Row) && (rCellAddr.Row <= maFormulaRef.EndRow); } -void SheetDataBuffer::importSharedFmla( SequenceInputStream& rStrm, const CellAddress& rBaseAddr ) +// ---------------------------------------------------------------------------- + +DataTableModel::DataTableModel() : + mb2dTable( false ), + mbRowTable( false ), + mbRef1Deleted( false ), + mbRef2Deleted( false ) { - BinRange aRange; - rStrm >> aRange; - CellRangeAddress aFmlaRange; - if( getAddressConverter().convertToCellRange( aFmlaRange, aRange, getSheetIndex(), true, true ) ) try - { - // get or create the defined name representing the shared formula - OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SheetDataBuffer::importSharedFmla - invalid range for shared formula" ); - Reference< XNamedRange > xNamedRange = createSharedFormulaName( BinAddress( rBaseAddr ) ); - Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY_THROW ); - // load the formula definition - ApiTokenSequence aTokens = getFormulaParser().importFormula( rBaseAddr, FORMULATYPE_SHAREDFORMULA, rStrm ); - xTokens->setTokens( aTokens ); - // retry to insert a pending shared formula cell - retryPendingSharedFormulaCell(); - } - catch( Exception& ) - { - } } -void SheetDataBuffer::importSharedFmla( BiffInputStream& rStrm, const CellAddress& rBaseAddr ) +// ============================================================================ + +SheetDataBuffer::SheetDataBuffer( const WorksheetHelper& rHelper ) : + WorksheetHelper( rHelper ), + mbPendingSharedFmla( false ) { - BinRange aRange; - aRange.read( rStrm, false ); // always 8bit column indexes - CellRangeAddress aFmlaRange; - if( getAddressConverter().convertToCellRange( aFmlaRange, aRange, getSheetIndex(), true, true ) ) try - { - // get or create the defined name representing the shared formula - OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SheetDataBuffer::importSharedFmla - invalid range for shared formula" ); - Reference< XNamedRange > xNamedRange = createSharedFormulaName( BinAddress( rBaseAddr ) ); - Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY_THROW ); - // load the formula definition - rStrm.skip( 2 ); // flags - ApiTokenSequence aTokens = getFormulaParser().importFormula( rBaseAddr, FORMULATYPE_SHAREDFORMULA, rStrm ); - xTokens->setTokens( aTokens ); - // retry to insert a pending shared formula cell - retryPendingSharedFormulaCell(); - } - catch( Exception& ) - { - } } -void SheetDataBuffer::setValueCell( const Reference< XCell >& rxCell, const CellAddress& /*rCellAddr*/, double fValue ) +void SheetDataBuffer::setValueCell( const CellAddress& rCellAddr, double fValue ) { - OSL_ENSURE( rxCell.is(), "SheetDataBuffer::setDateTimeCell - missing cell interface" ); - if( rxCell.is() ) - rxCell->setValue( fValue ); + Reference< XCell > xCell = getCell( rCellAddr ); + OSL_ENSURE( xCell.is(), "SheetDataBuffer::setValueCell - missing cell interface" ); + if( xCell.is() ) + xCell->setValue( fValue ); } -void SheetDataBuffer::setStringCell( const Reference< XCell >& rxCell, const CellAddress& /*rCellAddr*/, const OUString& rText ) +void SheetDataBuffer::setStringCell( const CellAddress& rCellAddr, const OUString& rText ) { - Reference< XText > xText( rxCell, UNO_QUERY ); + Reference< XText > xText( getCell( rCellAddr ), UNO_QUERY ); OSL_ENSURE( xText.is(), "SheetDataBuffer::setStringCell - missing text interface" ); if( xText.is() ) xText->setString( rText ); } -void SheetDataBuffer::setStringCell( const Reference< XCell >& rxCell, const CellAddress& /*rCellAddr*/, const RichString& rString, sal_Int32 nXfId ) +void SheetDataBuffer::setStringCell( const CellAddress& rCellAddr, const RichString& rString, sal_Int32 nXfId ) { - Reference< XText > xText( rxCell, UNO_QUERY ); + Reference< XText > xText( getCell( rCellAddr ), UNO_QUERY ); OSL_ENSURE( xText.is(), "SheetDataBuffer::setStringCell - missing text interface" ); rString.convert( xText, nXfId ); + (void)rString; + (void)nXfId; } -void SheetDataBuffer::setStringCell( const Reference< XCell >& rxCell, const CellAddress& /*rCellAddr*/, sal_Int32 nStringId, sal_Int32 nXfId ) +void SheetDataBuffer::setStringCell( const CellAddress& rCellAddr, sal_Int32 nStringId, sal_Int32 nXfId ) { - Reference< XText > xText( rxCell, UNO_QUERY ); + Reference< XText > xText( getCell( rCellAddr ), UNO_QUERY ); OSL_ENSURE( xText.is(), "SheetDataBuffer::setStringCell - missing text interface" ); getSharedStrings().convertString( xText, nStringId, nXfId ); + (void)nStringId; + (void)nXfId; } -void SheetDataBuffer::setDateTimeCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, const DateTime& rDateTime ) +void SheetDataBuffer::setDateTimeCell( const CellAddress& rCellAddr, const DateTime& rDateTime ) { // write serial date/time value into the cell double fSerial = getUnitConverter().calcSerialFromDateTime( rDateTime ); - setValueCell( rxCell, rCellAddr, fSerial ); + setValueCell( rCellAddr, fSerial ); // set appropriate number format using namespace ::com::sun::star::util::NumberFormat; sal_Int16 nStdFmt = (fSerial < 1.0) ? TIME : (((rDateTime.Hours > 0) || (rDateTime.Minutes > 0) || (rDateTime.Seconds > 0)) ? DATETIME : DATE); setStandardNumFmt( rCellAddr, nStdFmt ); } -void SheetDataBuffer::setBooleanCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, bool bValue ) +void SheetDataBuffer::setBooleanCell( const CellAddress& rCellAddr, bool bValue ) { - setFormulaCell( rxCell, rCellAddr, getFormulaParser().convertBoolToFormula( bValue ) ); + setFormulaCell( rCellAddr, getFormulaParser().convertBoolToFormula( bValue ) ); } -void SheetDataBuffer::setErrorCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, const OUString& rErrorCode ) +void SheetDataBuffer::setErrorCell( const CellAddress& rCellAddr, const OUString& rErrorCode ) { - setErrorCell( rxCell, rCellAddr, getUnitConverter().calcBiffErrorCode( rErrorCode ) ); + setErrorCell( rCellAddr, getUnitConverter().calcBiffErrorCode( rErrorCode ) ); } -void SheetDataBuffer::setErrorCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, sal_uInt8 nErrorCode ) +void SheetDataBuffer::setErrorCell( const CellAddress& rCellAddr, sal_uInt8 nErrorCode ) { - setFormulaCell( rxCell, rCellAddr, getFormulaParser().convertErrorToFormula( nErrorCode ) ); + setFormulaCell( rCellAddr, getFormulaParser().convertErrorToFormula( nErrorCode ) ); } -void SheetDataBuffer::setFormulaCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, const ApiTokenSequence& rTokens ) +void SheetDataBuffer::setFormulaCell( const CellAddress& rCellAddr, const ApiTokenSequence& rTokens ) { mbPendingSharedFmla = false; ApiTokenSequence aTokens; @@ -234,11 +204,12 @@ void SheetDataBuffer::setFormulaCell( const Reference< XCell >& rxCell, const Ce array formula. In this case, the cell will be remembered. After reading the formula definition it will be retried to insert the formula via retryPendingSharedFormulaCell(). */ - aTokens = resolveSharedFormula( aTokenInfo.First ); + BinAddress aBaseAddr( aTokenInfo.First ); + aTokens = resolveSharedFormula( aBaseAddr ); if( !aTokens.hasElements() ) { maSharedFmlaAddr = rCellAddr; - maSharedBaseAddr = aTokenInfo.First; + maSharedBaseAddr = aBaseAddr; mbPendingSharedFmla = true; } } @@ -251,89 +222,42 @@ void SheetDataBuffer::setFormulaCell( const Reference< XCell >& rxCell, const Ce if( aTokens.hasElements() ) { - Reference< XFormulaTokens > xTokens( rxCell, UNO_QUERY ); + Reference< XFormulaTokens > xTokens( getCell( rCellAddr ), UNO_QUERY ); OSL_ENSURE( xTokens.is(), "SheetDataBuffer::setFormulaCell - missing formula interface" ); if( xTokens.is() ) xTokens->setTokens( aTokens ); } } -void SheetDataBuffer::setFormulaCell( const Reference< XCell >& rxCell, const CellAddress& rCellAddr, sal_Int32 nSharedId ) +void SheetDataBuffer::setFormulaCell( const CellAddress& rCellAddr, sal_Int32 nSharedId ) { - setFormulaCell( rxCell, rCellAddr, resolveSharedFormula( nSharedId ) ); + setFormulaCell( rCellAddr, resolveSharedFormula( BinAddress( nSharedId, 0 ) ) ); } -void SheetDataBuffer::setArrayFormula( const CellRangeAddress& rRange, const ApiTokenSequence& rTokens ) +void SheetDataBuffer::createArrayFormula( const CellRangeAddress& rRange, const ApiTokenSequence& rTokens ) { - try - { - Reference< XArrayFormulaTokens > xTokens( getCellRange( rRange ), UNO_QUERY_THROW ); - xTokens->setArrayTokens( rTokens ); - } - catch( Exception& ) - { - } + /* Array formulas will be inserted later in finalizeImport(). This is + needed to not disturb collecting all the cells, which will be put into + the sheet in large blocks to increase performance. */ + maArrayFormulas.push_back( ArrayFormula( rRange, rTokens ) ); } -void SheetDataBuffer::setTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel ) +void SheetDataBuffer::createTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel ) { - OSL_ENSURE( getAddressConverter().checkCellRange( rRange, true, false ), "SheetDataBuffer::setTableOperation - invalid range" ); - sal_Int16 nSheet = getSheetIndex(); - bool bOk = false; - if( !rModel.mbRef1Deleted && (rModel.maRef1.getLength() > 0) && (rRange.StartColumn > 0) && (rRange.StartRow > 0) ) - { - CellRangeAddress aOpRange = rRange; - CellAddress aRef1, aRef2; - if( getAddressConverter().convertToCellAddress( aRef1, rModel.maRef1, nSheet, true ) ) try - { - if( rModel.mb2dTable ) - { - if( !rModel.mbRef2Deleted && getAddressConverter().convertToCellAddress( aRef2, rModel.maRef2, nSheet, true ) ) - { - // API call expects input values inside operation range - --aOpRange.StartColumn; - --aOpRange.StartRow; - // formula range is top-left cell of operation range - CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn, aOpRange.StartRow, aOpRange.StartColumn, aOpRange.StartRow ); - // set multiple operation - Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW ); - xMultOp->setTableOperation( aFormulaRange, TableOperationMode_BOTH, aRef2, aRef1 ); - bOk = true; - } - } - else if( rModel.mbRowTable ) - { - // formula range is column to the left of operation range - CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn - 1, aOpRange.StartRow, aOpRange.StartColumn - 1, aOpRange.EndRow ); - // API call expects input values (top row) inside operation range - --aOpRange.StartRow; - // set multiple operation - Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW ); - xMultOp->setTableOperation( aFormulaRange, TableOperationMode_ROW, aRef1, aRef1 ); - bOk = true; - } - else - { - // formula range is row above operation range - CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn, aOpRange.StartRow - 1, aOpRange.EndColumn, aOpRange.StartRow - 1 ); - // API call expects input values (left column) inside operation range - --aOpRange.StartColumn; - // set multiple operation - Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW ); - xMultOp->setTableOperation( aFormulaRange, TableOperationMode_COLUMN, aRef1, aRef1 ); - bOk = true; - } - } - catch( Exception& ) - { - } - } + /* Table operations will be inserted later in finalizeImport(). This is + needed to not disturb collecting all the cells, which will be put into + the sheet in large blocks to increase performance. */ + maTableOperations.push_back( TableOperation( rRange, rModel ) ); +} + +void SheetDataBuffer::createSharedFormula( sal_Int32 nSharedId, const ApiTokenSequence& rTokens ) +{ + createSharedFormula( BinAddress( nSharedId, 0 ), rTokens ); +} - // on error: fill cell range with error codes - if( !bOk ) - for( CellAddress aPos( nSheet, rRange.StartColumn, rRange.StartRow ); aPos.Row <= rRange.EndRow; ++aPos.Row ) - for( aPos.Column = rRange.StartColumn; aPos.Column <= rRange.EndColumn; ++aPos.Column ) - setErrorCell( getCell( aPos ), aPos, BIFF_ERR_REF ); +void SheetDataBuffer::createSharedFormula( const CellAddress& rCellAddr, const ApiTokenSequence& rTokens ) +{ + createSharedFormula( BinAddress( rCellAddr ), rTokens ); } void SheetDataBuffer::setRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId, bool bCustomFormat ) @@ -356,9 +280,9 @@ void SheetDataBuffer::setRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal } } -void SheetDataBuffer::setCellFormat( const CellModel& rModel ) +void SheetDataBuffer::setCellFormat( const CellModel& rModel, sal_Int32 nNumFmtId ) { - if( rModel.mxCell.is() && ((rModel.mnXfId >= 0) || (rModel.mnNumFmtId >= 0)) ) + if( (rModel.mnXfId >= 0) || (nNumFmtId >= 0) ) { // try to merge existing ranges and to write some formatting properties if( !maXfIdRanges.empty() ) @@ -366,7 +290,7 @@ void SheetDataBuffer::setCellFormat( const CellModel& rModel ) // get row index of last inserted cell sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow; // row changed - try to merge ranges of last row with existing ranges - if( rModel.maAddress.Row != nLastRow ) + if( rModel.maCellAddr.Row != nLastRow ) { mergeXfIdRanges(); // write format properties of all ranges above last row and remove them @@ -386,8 +310,8 @@ void SheetDataBuffer::setCellFormat( const CellModel& rModel ) } // try to expand last existing range, or create new range entry - if( maXfIdRanges.empty() || !maXfIdRanges.rbegin()->second.tryExpand( rModel ) ) - maXfIdRanges[ BinAddress( rModel.maAddress ) ].set( rModel ); + if( maXfIdRanges.empty() || !maXfIdRanges.rbegin()->second.tryExpand( rModel, nNumFmtId ) ) + maXfIdRanges[ BinAddress( rModel.maCellAddr ) ].set( rModel, nNumFmtId ); // update merged ranges for 'center across selection' and 'fill' if( const Xf* pXf = getStyles().getCellXf( rModel.mnXfId ).get() ) @@ -398,9 +322,9 @@ void SheetDataBuffer::setCellFormat( const CellModel& rModel ) /* start new merged range, if cell is not empty (#108781#), or try to expand last range with empty cell */ if( rModel.mnCellType != XML_TOKEN_INVALID ) - maCenterFillRanges.push_back( MergedRange( rModel.maAddress, nHorAlign ) ); + maCenterFillRanges.push_back( MergedRange( rModel.maCellAddr, nHorAlign ) ); else if( !maCenterFillRanges.empty() ) - maCenterFillRanges.rbegin()->tryExpand( rModel.maAddress, nHorAlign ); + maCenterFillRanges.rbegin()->tryExpand( rModel.maCellAddr, nHorAlign ); } } } @@ -428,6 +352,14 @@ void SheetDataBuffer::setStandardNumFmt( const CellAddress& rCellAddr, sal_Int16 void SheetDataBuffer::finalizeImport() { + // create all array formulas + for( ArrayFormulaList::iterator aIt = maArrayFormulas.begin(), aEnd = maArrayFormulas.end(); aIt != aEnd; ++aIt ) + finalizeArrayFormula( aIt->first, aIt->second ); + + // create all table operations + for( TableOperationList::iterator aIt = maTableOperations.begin(), aEnd = maTableOperations.end(); aIt != aEnd; ++aIt ) + finalizeTableOperation( aIt->first, aIt->second ); + // write default formatting of remaining row range writeXfIdRowRangeProperties( maXfIdRowRange ); @@ -438,10 +370,9 @@ void SheetDataBuffer::finalizeImport() writeXfIdRangeProperties( aIt->second ); // merge all cached merged ranges and update right/bottom cell borders - MergedRangeList::const_iterator aIt, aEnd; - for( aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt ) + for( MergedRangeList::iterator aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt ) finalizeMergedRange( aIt->maRange ); - for( aIt = maCenterFillRanges.begin(), aEnd = maCenterFillRanges.end(); aIt != aEnd; ++aIt ) + for( MergedRangeList::iterator aIt = maCenterFillRanges.begin(), aEnd = maCenterFillRanges.end(); aIt != aEnd; ++aIt ) finalizeMergedRange( aIt->maRange ); } @@ -484,21 +415,21 @@ bool SheetDataBuffer::XfIdRowRange::tryExpand( sal_Int32 nFirstRow, sal_Int32 nL return false; } -void SheetDataBuffer::XfIdRange::set( const CellModel& rModel ) +void SheetDataBuffer::XfIdRange::set( const CellModel& rModel, sal_Int32 nNumFmtId ) { - maRange.Sheet = rModel.maAddress.Sheet; - maRange.StartColumn = maRange.EndColumn = rModel.maAddress.Column; - maRange.StartRow = maRange.EndRow = rModel.maAddress.Row; + maRange.Sheet = rModel.maCellAddr.Sheet; + maRange.StartColumn = maRange.EndColumn = rModel.maCellAddr.Column; + maRange.StartRow = maRange.EndRow = rModel.maCellAddr.Row; mnXfId = rModel.mnXfId; - mnNumFmtId = rModel.mnNumFmtId; + mnNumFmtId = nNumFmtId; } -bool SheetDataBuffer::XfIdRange::tryExpand( const CellModel& rModel ) +bool SheetDataBuffer::XfIdRange::tryExpand( const CellModel& rModel, sal_Int32 nNumFmtId ) { - if( (mnXfId == rModel.mnXfId) && (mnNumFmtId == rModel.mnNumFmtId) && - (maRange.StartRow == rModel.maAddress.Row) && - (maRange.EndRow == rModel.maAddress.Row) && - (maRange.EndColumn + 1 == rModel.maAddress.Column) ) + if( (mnXfId == rModel.mnXfId) && (mnNumFmtId == nNumFmtId) && + (maRange.StartRow == rModel.maCellAddr.Row) && + (maRange.EndRow == rModel.maCellAddr.Row) && + (maRange.EndColumn + 1 == rModel.maCellAddr.Column) ) { ++maRange.EndColumn; return true; @@ -544,7 +475,83 @@ bool SheetDataBuffer::MergedRange::tryExpand( const CellAddress& rAddress, sal_I return false; } -Reference< XNamedRange > SheetDataBuffer::createSharedFormulaName( const BinAddress& rMapKey ) +void SheetDataBuffer::finalizeArrayFormula( const CellRangeAddress& rRange, const ApiTokenSequence& rTokens ) +{ + Reference< XArrayFormulaTokens > xTokens( getCellRange( rRange ), UNO_QUERY ); + OSL_ENSURE( xTokens.is(), "SheetDataBuffer::finalizeArrayFormula - missing formula token interface" ); + if( xTokens.is() ) + xTokens->setArrayTokens( rTokens ); +} + +void SheetDataBuffer::finalizeTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel ) +{ + sal_Int16 nSheet = getSheetIndex(); + bool bOk = false; + if( !rModel.mbRef1Deleted && (rModel.maRef1.getLength() > 0) && (rRange.StartColumn > 0) && (rRange.StartRow > 0) ) + { + CellRangeAddress aOpRange = rRange; + CellAddress aRef1; + if( getAddressConverter().convertToCellAddress( aRef1, rModel.maRef1, nSheet, true ) ) try + { + if( rModel.mb2dTable ) + { + CellAddress aRef2; + if( !rModel.mbRef2Deleted && getAddressConverter().convertToCellAddress( aRef2, rModel.maRef2, nSheet, true ) ) + { + // API call expects input values inside operation range + --aOpRange.StartColumn; + --aOpRange.StartRow; + // formula range is top-left cell of operation range + CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn, aOpRange.StartRow, aOpRange.StartColumn, aOpRange.StartRow ); + // set multiple operation + Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW ); + xMultOp->setTableOperation( aFormulaRange, TableOperationMode_BOTH, aRef2, aRef1 ); + bOk = true; + } + } + else if( rModel.mbRowTable ) + { + // formula range is column to the left of operation range + CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn - 1, aOpRange.StartRow, aOpRange.StartColumn - 1, aOpRange.EndRow ); + // API call expects input values (top row) inside operation range + --aOpRange.StartRow; + // set multiple operation + Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW ); + xMultOp->setTableOperation( aFormulaRange, TableOperationMode_ROW, aRef1, aRef1 ); + bOk = true; + } + else + { + // formula range is row above operation range + CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn, aOpRange.StartRow - 1, aOpRange.EndColumn, aOpRange.StartRow - 1 ); + // API call expects input values (left column) inside operation range + --aOpRange.StartColumn; + // set multiple operation + Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW ); + xMultOp->setTableOperation( aFormulaRange, TableOperationMode_COLUMN, aRef1, aRef1 ); + bOk = true; + } + } + catch( Exception& ) + { + } + } + + // on error: fill cell range with #REF! error codes + if( !bOk ) try + { + Reference< XCellRangeData > xCellRangeData( getCellRange( rRange ), UNO_QUERY_THROW ); + size_t nWidth = static_cast< size_t >( rRange.EndColumn - rRange.StartColumn + 1 ); + size_t nHeight = static_cast< size_t >( rRange.EndRow - rRange.StartRow + 1 ); + Matrix< Any > aErrorCells( nWidth, nHeight, Any( getFormulaParser().convertErrorToFormula( BIFF_ERR_REF ) ) ); + xCellRangeData->setDataArray( ContainerHelper::matrixToSequenceSequence( aErrorCells ) ); + } + catch( Exception& ) + { + } +} + +void SheetDataBuffer::createSharedFormula( const BinAddress& rMapKey, const ApiTokenSequence& rTokens ) { // create the defined name that will represent the shared formula OUString aName = OUStringBuffer().appendAscii( RTL_CONSTASCII_STRINGPARAM( "__shared_" ) ). @@ -552,40 +559,39 @@ Reference< XNamedRange > SheetDataBuffer::createSharedFormulaName( const BinAddr append( sal_Unicode( '_' ) ).append( rMapKey.mnRow ). append( sal_Unicode( '_' ) ).append( rMapKey.mnCol ).makeStringAndClear(); Reference< XNamedRange > xNamedRange = createNamedRangeObject( aName ); + OSL_ENSURE( xNamedRange.is(), "SheetDataBuffer::createSharedFormula - cannot create shared formula" ); PropertySet aNameProps( xNamedRange ); aNameProps.setProperty( PROP_IsSharedFormula, true ); // get and store the token index of the defined name - OSL_ENSURE( maTokenIndexes.count( rMapKey ) == 0, "SheetDataBuffer::createSharedFormulaName - key exists already" ); + OSL_ENSURE( maSharedFormulas.count( rMapKey ) == 0, "SheetDataBuffer::createSharedFormula - shared formula exists already" ); sal_Int32 nTokenIndex = 0; - if( aNameProps.getProperty( nTokenIndex, PROP_TokenIndex ) ) - maTokenIndexes[ rMapKey ] = nTokenIndex; - - return xNamedRange; -} - -ApiTokenSequence SheetDataBuffer::resolveSharedFormula( sal_Int32 nSharedId ) const -{ - sal_Int32 nTokenIndex = ContainerHelper::getMapElement( maTokenIndexes, BinAddress( nSharedId, 0 ), -1 ); - return (nTokenIndex >= 0) ? getFormulaParser().convertNameToFormula( nTokenIndex ) : ApiTokenSequence(); + if( aNameProps.getProperty( nTokenIndex, PROP_TokenIndex ) && (nTokenIndex >= 0) ) try + { + // store the token index in the map + maSharedFormulas[ rMapKey ] = nTokenIndex; + // set the formula definition + Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY_THROW ); + xTokens->setTokens( rTokens ); + // retry to insert a pending shared formula cell + if( mbPendingSharedFmla ) + { + ApiTokenSequence aTokens = resolveSharedFormula( maSharedBaseAddr ); + setFormulaCell( maSharedFmlaAddr, aTokens ); + } + } + catch( Exception& ) + { + } + mbPendingSharedFmla = false; } -ApiTokenSequence SheetDataBuffer::resolveSharedFormula( const CellAddress& rBaseAddr ) const +ApiTokenSequence SheetDataBuffer::resolveSharedFormula( const BinAddress& rMapKey ) const { - sal_Int32 nTokenIndex = ContainerHelper::getMapElement( maTokenIndexes, BinAddress( rBaseAddr ), -1 ); + sal_Int32 nTokenIndex = ContainerHelper::getMapElement( maSharedFormulas, rMapKey, -1 ); return (nTokenIndex >= 0) ? getFormulaParser().convertNameToFormula( nTokenIndex ) : ApiTokenSequence(); } -void SheetDataBuffer::retryPendingSharedFormulaCell() -{ - if( mbPendingSharedFmla ) - { - ApiTokenSequence aTokens = resolveSharedFormula( maSharedBaseAddr ); - setFormulaCell( getCell( maSharedFmlaAddr ), maSharedFmlaAddr, aTokens ); - mbPendingSharedFmla = false; - } -} - void SheetDataBuffer::writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const { if( (rXfIdRowRange.mnLastRow >= 0) && (rXfIdRowRange.mnXfId >= 0) ) diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx index f387257eaaf0..63db3286cff6 100644 --- a/oox/source/xls/sheetdatacontext.cxx +++ b/oox/source/xls/sheetdatacontext.cxx @@ -37,7 +37,6 @@ #include "oox/xls/biffinputstream.hxx" #include "oox/xls/formulaparser.hxx" #include "oox/xls/richstringcontext.hxx" -#include "oox/xls/sheetdatabuffer.hxx" #include "oox/xls/unitconverter.hxx" namespace oox { @@ -102,9 +101,25 @@ const sal_Int32 BIFF2_CELL_USEIXFE = 63; // ============================================================================ +SheetDataContextBase::SheetDataContextBase( const WorksheetHelper& rHelper ) : + mrAddressConv( rHelper.getAddressConverter() ), + mrFormulaParser( rHelper.getFormulaParser() ), + mrSheetData( rHelper.getSheetData() ), + mnSheet( rHelper.getSheetIndex() ) +{ +} + +SheetDataContextBase::~SheetDataContextBase() +{ +} + +// ============================================================================ + SheetDataContext::SheetDataContext( WorksheetFragmentBase& rFragment ) : WorksheetContextBase( rFragment ), - mrSheetData( getSheetData() ) + SheetDataContextBase( rFragment ), + mbHasFormula( false ), + mbValidRange( false ) { } @@ -117,11 +132,13 @@ ContextHandlerRef SheetDataContext::onCreateContext( sal_Int32 nElement, const A break; case XLS_TOKEN( row ): - if( nElement == XLS_TOKEN( c ) ) { importCell( rAttribs ); return this; } + // do not process cell elements with invalid (out-of-range) address + if( nElement == XLS_TOKEN( c ) && importCell( rAttribs ) ) + return this; break; case XLS_TOKEN( c ): - if( maCurrCell.mxCell.is() ) switch( nElement ) + switch( nElement ) { case XLS_TOKEN( is ): mxInlineStr.reset( new RichString( *this ) ); @@ -142,112 +159,84 @@ void SheetDataContext::onCharacters( const OUString& rChars ) switch( getCurrentElement() ) { case XLS_TOKEN( v ): - maCurrCell.maValue = rChars; + maCellValue = rChars; break; case XLS_TOKEN( f ): - maCurrCell.maFormula = rChars; + if( maFmlaData.mnFormulaType != XML_TOKEN_INVALID ) + maTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, rChars ); break; } } void SheetDataContext::onEndElement() { - switch( getCurrentElement() ) + if( getCurrentElement() == XLS_TOKEN( c ) ) { - case XLS_TOKEN( c ): - if( maCurrCell.mxCell.is() ) - { - // try to create a formula cell - if( maCurrCell.mxCell->getType() == CellContentType_EMPTY ) - { - switch( maCurrCell.mnFormulaType ) - { - case XML_normal: - if( maCurrCell.maFormula.getLength() > 0 ) - { - ApiTokenSequence aTokens = getFormulaParser().importFormula( maCurrCell.maAddress, maCurrCell.maFormula ); - mrSheetData.setFormulaCell( maCurrCell.mxCell, maCurrCell.maAddress, aTokens ); - } - break; - - case XML_array: - if( (maCurrCell.maFormula.getLength() > 0) && (maCurrCell.maFormulaRef.getLength() > 0) ) - { - CellRangeAddress aArrayRange; - if( getAddressConverter().convertToCellRange( aArrayRange, maCurrCell.maFormulaRef, getSheetIndex(), true, true ) ) - { - CellAddress aBaseAddr( aArrayRange.Sheet, aArrayRange.StartColumn, aArrayRange.StartRow ); - ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, maCurrCell.maFormula ); - mrSheetData.setArrayFormula( aArrayRange, aTokens ); - } - } - break; - - case XML_shared: - if( maCurrCell.mnSharedId >= 0 ) - { - if( maCurrCell.maFormula.getLength() > 0 ) - mrSheetData.importSharedFmla( maCurrCell.maFormula, maCurrCell.maFormulaRef, maCurrCell.mnSharedId, maCurrCell.maAddress ); - mrSheetData.setFormulaCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.mnSharedId ); - } - break; - - case XML_dataTable: - if( maCurrCell.maFormulaRef.getLength() > 0 ) - { - CellRangeAddress aTableRange; - if( getAddressConverter().convertToCellRange( aTableRange, maCurrCell.maFormulaRef, getSheetIndex(), true, true ) ) - mrSheetData.setTableOperation( aTableRange, maTableData ); - } - break; - - default: - OSL_ENSURE( maCurrCell.mnFormulaType == XML_TOKEN_INVALID, "SheetDataContext::onCharacters - unknown formula type" ); - } - } - - // no formula created: try to set the cell value - if( maCurrCell.mxCell->getType() == CellContentType_EMPTY ) + // try to create a formula cell + if( mbHasFormula ) switch( maFmlaData.mnFormulaType ) + { + case XML_normal: + mrSheetData.setFormulaCell( maCellData.maCellAddr, maTokens ); + break; + case XML_shared: + if( maFmlaData.mnSharedId >= 0 ) { - if( maCurrCell.maValue.getLength() > 0 ) - { - switch( maCurrCell.mnCellType ) - { - case XML_n: - mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.maValue.toDouble() ); - break; - case XML_b: - mrSheetData.setBooleanCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.maValue.toDouble() != 0.0 ); - // #108770# set 'Standard' number format for all Boolean cells - maCurrCell.mnNumFmtId = 0; - break; - case XML_e: - mrSheetData.setErrorCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.maValue ); - break; - case XML_str: - mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.maValue ); - break; - case XML_s: - mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, maCurrCell.maValue.toInt32(), maCurrCell.mnXfId ); - break; - } - } - else if( (maCurrCell.mnCellType == XML_inlineStr) && mxInlineStr.get() ) - { - mxInlineStr->finalizeImport(); - mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, *mxInlineStr, maCurrCell.mnXfId ); - } - else - { - // empty cell, update cell type - maCurrCell.mnCellType = XML_TOKEN_INVALID; - } + if( mbValidRange && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) ) + mrSheetData.createSharedFormula( maFmlaData.mnSharedId, maTokens ); + mrSheetData.setFormulaCell( maCellData.maCellAddr, maFmlaData.mnSharedId ); } + break; + case XML_array: + if( mbValidRange && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) ) + mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, maTokens ); + break; + case XML_dataTable: + if( mbValidRange ) + mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData ); + break; + default: + OSL_ENSURE( maFmlaData.mnFormulaType == XML_TOKEN_INVALID, "SheetDataContext::onEndElement - unknown formula type" ); + mbHasFormula = false; + } - // store the cell formatting data - mrSheetData.setCellFormat( maCurrCell ); + if( !mbHasFormula ) + { + // no formula created: try to set the cell value + if( maCellValue.getLength() > 0 ) switch( maCellData.mnCellType ) + { + case XML_n: + mrSheetData.setValueCell( maCellData.maCellAddr, maCellValue.toDouble() ); + break; + case XML_b: + mrSheetData.setBooleanCell( maCellData.maCellAddr, maCellValue.toDouble() != 0.0 ); + break; + case XML_e: + mrSheetData.setErrorCell( maCellData.maCellAddr, maCellValue ); + break; + case XML_str: + mrSheetData.setStringCell( maCellData.maCellAddr, maCellValue ); + break; + case XML_s: + mrSheetData.setStringCell( maCellData.maCellAddr, maCellValue.toInt32(), maCellData.mnXfId ); + break; } - break; + else if( (maCellData.mnCellType == XML_inlineStr) && mxInlineStr.get() ) + { + mxInlineStr->finalizeImport(); + mrSheetData.setStringCell( maCellData.maCellAddr, *mxInlineStr, maCellData.mnXfId ); + } + else + { + // empty cell, update cell type + maCellData.mnCellType = XML_TOKEN_INVALID; + } + } + + // #108770# set 'Standard' number format for all Boolean cells + bool bBoolCell = !mbHasFormula && (maCellData.mnCellType == XML_b); + sal_Int32 nNumFmtId = bBoolCell ? 0 : -1; + // store the cell formatting data + mrSheetData.setCellFormat( maCellData, nNumFmtId ); } } @@ -311,37 +300,73 @@ void SheetDataContext::importRow( const AttributeList& rAttribs ) setRowModel( aModel ); } -void SheetDataContext::importCell( const AttributeList& rAttribs ) +bool SheetDataContext::importCell( const AttributeList& rAttribs ) { - maCurrCell.reset(); - maCurrCell.mxCell = getCell( rAttribs.getString( XML_r, OUString() ), &maCurrCell.maAddress ); - maCurrCell.mnCellType = rAttribs.getToken( XML_t, XML_n ); - maCurrCell.mnXfId = rAttribs.getInteger( XML_s, -1 ); - maCurrCell.mbShowPhonetic = rAttribs.getBool( XML_ph, false ); - mxInlineStr.reset(); + bool bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, rAttribs.getString( XML_r, OUString() ), mnSheet, true ); + if( bValidAddr ) + { + maCellData.mnCellType = rAttribs.getToken( XML_t, XML_n ); + maCellData.mnXfId = rAttribs.getInteger( XML_s, -1 ); + maCellData.mbShowPhonetic = rAttribs.getBool( XML_ph, false ); - // update used area of the sheet - if( maCurrCell.mxCell.is() ) - extendUsedArea( maCurrCell.maAddress ); + // reset cell value, formula settings, and inline string + maCellValue = OUString(); + mxInlineStr.reset(); + mbHasFormula = false; + + // update used area of the sheet + extendUsedArea( maCellData.maCellAddr ); + } + return bValidAddr; } void SheetDataContext::importFormula( const AttributeList& rAttribs ) { - maCurrCell.maFormulaRef = rAttribs.getString( XML_ref, OUString() ); - maCurrCell.mnFormulaType = rAttribs.getToken( XML_t, XML_normal ); - maCurrCell.mnSharedId = rAttribs.getInteger( XML_si, -1 ); - maTableData.maRef1 = rAttribs.getString( XML_r1, OUString() ); - maTableData.maRef2 = rAttribs.getString( XML_r2, OUString() ); - maTableData.mb2dTable = rAttribs.getBool( XML_dt2D, false ); - maTableData.mbRowTable = rAttribs.getBool( XML_dtr, false ); - maTableData.mbRef1Deleted = rAttribs.getBool( XML_del1, false ); - maTableData.mbRef2Deleted = rAttribs.getBool( XML_del2, false ); + mbHasFormula = true; + mbValidRange = mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, rAttribs.getString( XML_ref, OUString() ), mnSheet, true, true ); + + maFmlaData.mnFormulaType = rAttribs.getToken( XML_t, XML_normal ); + maFmlaData.mnSharedId = rAttribs.getInteger( XML_si, -1 ); + + if( maFmlaData.mnFormulaType == XML_dataTable ) + { + maTableData.maRef1 = rAttribs.getString( XML_r1, OUString() ); + maTableData.maRef2 = rAttribs.getString( XML_r2, OUString() ); + maTableData.mb2dTable = rAttribs.getBool( XML_dt2D, false ); + maTableData.mbRowTable = rAttribs.getBool( XML_dtr, false ); + maTableData.mbRef1Deleted = rAttribs.getBool( XML_del1, false ); + maTableData.mbRef2Deleted = rAttribs.getBool( XML_del2, false ); + } + + // clear token array, will be regenerated from element text + maTokens = ApiTokenSequence(); } -void SheetDataContext::importCellHeader( SequenceInputStream& rStrm, CellType eCellType ) +void SheetDataContext::importRow( SequenceInputStream& rStrm ) { - maCurrCell.reset(); + RowModel aModel; + sal_uInt16 nHeight, nFlags1; + sal_uInt8 nFlags2; + rStrm >> maCurrPos.mnRow >> aModel.mnXfId >> nHeight >> nFlags1 >> nFlags2; + // row index is 0-based in BIFF12, but RowModel expects 1-based + aModel.mnFirstRow = aModel.mnLastRow = maCurrPos.mnRow + 1; + // row height is in twips in BIFF12, convert to points + aModel.mfHeight = nHeight / 20.0; + aModel.mnLevel = extractValue< sal_Int32 >( nFlags1, 8, 3 ); + aModel.mbCustomHeight = getFlag( nFlags1, BIFF12_ROW_CUSTOMHEIGHT ); + aModel.mbCustomFormat = getFlag( nFlags1, BIFF12_ROW_CUSTOMFORMAT ); + aModel.mbShowPhonetic = getFlag( nFlags2, BIFF12_ROW_SHOWPHONETIC ); + aModel.mbHidden = getFlag( nFlags1, BIFF12_ROW_HIDDEN ); + aModel.mbCollapsed = getFlag( nFlags1, BIFF12_ROW_COLLAPSED ); + aModel.mbThickTop = getFlag( nFlags1, BIFF12_ROW_THICKTOP ); + aModel.mbThickBottom = getFlag( nFlags1, BIFF12_ROW_THICKBOTTOM ); + // set row properties in the current sheet + setRowModel( aModel ); +} + +bool SheetDataContext::readCellHeader( SequenceInputStream& rStrm, CellType eCellType ) +{ switch( eCellType ) { case CELLTYPE_VALUE: @@ -352,194 +377,166 @@ void SheetDataContext::importCellHeader( SequenceInputStream& rStrm, CellType eC sal_uInt32 nXfId; rStrm >> nXfId; - maCurrCell.mxCell = getCell( maCurrPos, &maCurrCell.maAddress ); - maCurrCell.mnXfId = extractValue< sal_Int32 >( nXfId, 0, 24 ); - maCurrCell.mbShowPhonetic = getFlag( nXfId, BIFF12_CELL_SHOWPHONETIC ); + bool bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, maCurrPos, mnSheet, true ); + maCellData.mnXfId = extractValue< sal_Int32 >( nXfId, 0, 24 ); + maCellData.mbShowPhonetic = getFlag( nXfId, BIFF12_CELL_SHOWPHONETIC ); // update used area of the sheet - if( maCurrCell.mxCell.is() ) - extendUsedArea( maCurrCell.maAddress ); + if( bValidAddr ) + extendUsedArea( maCellData.maCellAddr ); + return bValidAddr; +} + +ApiTokenSequence SheetDataContext::readCellFormula( SequenceInputStream& rStrm ) +{ + rStrm.skip( 2 ); + return mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_CELL, rStrm ); +} + +bool SheetDataContext::readFormulaRef( SequenceInputStream& rStrm ) +{ + BinRange aRange; + rStrm >> aRange; + return mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, aRange, mnSheet, true, true ); } void SheetDataContext::importCellBool( SequenceInputStream& rStrm, CellType eCellType ) { - importCellHeader( rStrm, eCellType ); - maCurrCell.mnCellType = XML_b; - if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) + if( readCellHeader( rStrm, eCellType ) ) { + maCellData.mnCellType = XML_b; bool bValue = rStrm.readuInt8() != 0; if( eCellType == CELLTYPE_FORMULA ) - { - importCellFormula( rStrm ); - } + mrSheetData.setFormulaCell( maCellData.maCellAddr, readCellFormula( rStrm ) ); else - { - mrSheetData.setBooleanCell( maCurrCell.mxCell, maCurrCell.maAddress, bValue ); - // #108770# set 'Standard' number format for all Boolean cells - maCurrCell.mnNumFmtId = 0; - } + mrSheetData.setBooleanCell( maCellData.maCellAddr, bValue ); + // #108770# set 'Standard' number format for all Boolean cells + sal_Int32 nNumFmtId = (eCellType != CELLTYPE_FORMULA) ? 0 : -1; + mrSheetData.setCellFormat( maCellData, nNumFmtId ); } - mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellBlank( SequenceInputStream& rStrm, CellType eCellType ) { OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellBlank - no formula cells supported" ); - importCellHeader( rStrm, eCellType ); - mrSheetData.setCellFormat( maCurrCell ); + if( readCellHeader( rStrm, eCellType ) ) + mrSheetData.setCellFormat( maCellData ); } void SheetDataContext::importCellDouble( SequenceInputStream& rStrm, CellType eCellType ) { - importCellHeader( rStrm, eCellType ); - maCurrCell.mnCellType = XML_n; - if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) + if( readCellHeader( rStrm, eCellType ) ) { + maCellData.mnCellType = XML_n; double fValue = rStrm.readDouble(); if( eCellType == CELLTYPE_FORMULA ) - importCellFormula( rStrm ); + mrSheetData.setFormulaCell( maCellData.maCellAddr, readCellFormula( rStrm ) ); else - mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, fValue ); + mrSheetData.setValueCell( maCellData.maCellAddr, fValue ); + mrSheetData.setCellFormat( maCellData ); } - mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellError( SequenceInputStream& rStrm, CellType eCellType ) { - importCellHeader( rStrm, eCellType ); - maCurrCell.mnCellType = XML_e; - if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) + if( readCellHeader( rStrm, eCellType ) ) { + maCellData.mnCellType = XML_e; sal_uInt8 nErrorCode = rStrm.readuInt8(); if( eCellType == CELLTYPE_FORMULA ) - importCellFormula( rStrm ); + mrSheetData.setFormulaCell( maCellData.maCellAddr, readCellFormula( rStrm ) ); else - mrSheetData.setErrorCell( maCurrCell.mxCell, maCurrCell.maAddress, nErrorCode ); + mrSheetData.setErrorCell( maCellData.maCellAddr, nErrorCode ); + mrSheetData.setCellFormat( maCellData ); } - mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellRk( SequenceInputStream& rStrm, CellType eCellType ) { OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRk - no formula cells supported" ); - importCellHeader( rStrm, eCellType ); - maCurrCell.mnCellType = XML_n; - if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) - mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); - mrSheetData.setCellFormat( maCurrCell ); + if( readCellHeader( rStrm, eCellType ) ) + { + maCellData.mnCellType = XML_n; + mrSheetData.setValueCell( maCellData.maCellAddr, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); + mrSheetData.setCellFormat( maCellData ); + } } void SheetDataContext::importCellRString( SequenceInputStream& rStrm, CellType eCellType ) { OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRString - no formula cells supported" ); - importCellHeader( rStrm, eCellType ); - maCurrCell.mnCellType = XML_inlineStr; - if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) + if( readCellHeader( rStrm, eCellType ) ) { + maCellData.mnCellType = XML_inlineStr; RichString aString( *this ); aString.importString( rStrm, true ); aString.finalizeImport(); - mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, aString, maCurrCell.mnXfId ); + mrSheetData.setStringCell( maCellData.maCellAddr, aString, maCellData.mnXfId ); + mrSheetData.setCellFormat( maCellData ); } - mrSheetData.setCellFormat( maCurrCell ); } void SheetDataContext::importCellSi( SequenceInputStream& rStrm, CellType eCellType ) { OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellSi - no formula cells supported" ); - importCellHeader( rStrm, eCellType ); - maCurrCell.mnCellType = XML_s; - if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) - mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, rStrm.readInt32(), maCurrCell.mnXfId ); - mrSheetData.setCellFormat( maCurrCell ); + if( readCellHeader( rStrm, eCellType ) ) + { + maCellData.mnCellType = XML_s; + mrSheetData.setStringCell( maCellData.maCellAddr, rStrm.readInt32(), maCellData.mnXfId ); + mrSheetData.setCellFormat( maCellData ); + } } void SheetDataContext::importCellString( SequenceInputStream& rStrm, CellType eCellType ) { - importCellHeader( rStrm, eCellType ); - maCurrCell.mnCellType = XML_inlineStr; - Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY ); - if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) ) + if( readCellHeader( rStrm, eCellType ) ) { + maCellData.mnCellType = XML_inlineStr; + // always import the string, stream will point to formula afterwards, if existing RichString aString( *this ); aString.importString( rStrm, false ); aString.finalizeImport(); if( eCellType == CELLTYPE_FORMULA ) - importCellFormula( rStrm ); + mrSheetData.setFormulaCell( maCellData.maCellAddr, readCellFormula( rStrm ) ); else - mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, aString, maCurrCell.mnXfId ); + mrSheetData.setStringCell( maCellData.maCellAddr, aString, maCellData.mnXfId ); + mrSheetData.setCellFormat( maCellData ); } - mrSheetData.setCellFormat( maCurrCell ); -} - -void SheetDataContext::importCellFormula( SequenceInputStream& rStrm ) -{ - rStrm.skip( 2 ); - ApiTokenSequence aTokens = getFormulaParser().importFormula( maCurrCell.maAddress, FORMULATYPE_CELL, rStrm ); - mrSheetData.setFormulaCell( maCurrCell.mxCell, maCurrCell.maAddress, aTokens ); -} - -void SheetDataContext::importRow( SequenceInputStream& rStrm ) -{ - RowModel aModel; - - sal_uInt16 nHeight, nFlags1; - sal_uInt8 nFlags2; - rStrm >> maCurrPos.mnRow >> aModel.mnXfId >> nHeight >> nFlags1 >> nFlags2; - - // row index is 0-based in BIFF12, but RowModel expects 1-based - aModel.mnFirstRow = aModel.mnLastRow = maCurrPos.mnRow + 1; - // row height is in twips in BIFF12, convert to points - aModel.mfHeight = nHeight / 20.0; - aModel.mnLevel = extractValue< sal_Int32 >( nFlags1, 8, 3 ); - aModel.mbCustomHeight = getFlag( nFlags1, BIFF12_ROW_CUSTOMHEIGHT ); - aModel.mbCustomFormat = getFlag( nFlags1, BIFF12_ROW_CUSTOMFORMAT ); - aModel.mbShowPhonetic = getFlag( nFlags2, BIFF12_ROW_SHOWPHONETIC ); - aModel.mbHidden = getFlag( nFlags1, BIFF12_ROW_HIDDEN ); - aModel.mbCollapsed = getFlag( nFlags1, BIFF12_ROW_COLLAPSED ); - aModel.mbThickTop = getFlag( nFlags1, BIFF12_ROW_THICKTOP ); - aModel.mbThickBottom = getFlag( nFlags1, BIFF12_ROW_THICKBOTTOM ); - // set row properties in the current sheet - setRowModel( aModel ); } void SheetDataContext::importArray( SequenceInputStream& rStrm ) { - BinRange aRange; - rStrm >> aRange; - CellRangeAddress aArrayRange; - if( getAddressConverter().convertToCellRange( aArrayRange, aRange, getSheetIndex(), true, true ) ) + if( readFormulaRef( rStrm ) && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) ) { rStrm.skip( 1 ); - CellAddress aBaseAddr( aArrayRange.Sheet, aArrayRange.StartColumn, aArrayRange.StartRow ); - ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_ARRAY, rStrm ); - mrSheetData.setArrayFormula( aArrayRange, aTokens ); + ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_ARRAY, rStrm ); + mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, aTokens ); } } -void SheetDataContext::importSharedFmla( SequenceInputStream& rStrm ) -{ - mrSheetData.importSharedFmla( rStrm, maCurrCell.maAddress ); -} - void SheetDataContext::importDataTable( SequenceInputStream& rStrm ) { - BinRange aRange; - rStrm >> aRange; - CellRangeAddress aTableRange; - if( getAddressConverter().convertToCellRange( aTableRange, aRange, getSheetIndex(), true, true ) ) + if( readFormulaRef( rStrm ) ) { - DataTableModel aModel; BinAddress aRef1, aRef2; sal_uInt8 nFlags; rStrm >> aRef1 >> aRef2 >> nFlags; - aModel.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false ); - aModel.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false ); - aModel.mbRowTable = getFlag( nFlags, BIFF12_DATATABLE_ROW ); - aModel.mb2dTable = getFlag( nFlags, BIFF12_DATATABLE_2D ); - aModel.mbRef1Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF1DEL ); - aModel.mbRef2Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF2DEL ); - mrSheetData.setTableOperation( aTableRange, aModel ); + maTableData.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false ); + maTableData.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false ); + maTableData.mbRowTable = getFlag( nFlags, BIFF12_DATATABLE_ROW ); + maTableData.mb2dTable = getFlag( nFlags, BIFF12_DATATABLE_2D ); + maTableData.mbRef1Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF1DEL ); + maTableData.mbRef2Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF2DEL ); + mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData ); + } +} + +void SheetDataContext::importSharedFmla( SequenceInputStream& rStrm ) +{ + if( readFormulaRef( rStrm ) && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) ) + { + ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_SHAREDFORMULA, rStrm ); + mrSheetData.createSharedFormula( maCellData.maCellAddr, aTokens ); } } @@ -547,7 +544,7 @@ void SheetDataContext::importDataTable( SequenceInputStream& rStrm ) BiffSheetDataContext::BiffSheetDataContext( const WorksheetHelper& rHelper ) : BiffWorksheetContextBase( rHelper ), - mrSheetData( getSheetData() ), + SheetDataContextBase( rHelper ), mnBiff2XfId( 0 ) { switch( getBiff() ) @@ -656,109 +653,160 @@ void BiffSheetDataContext::importRecord( BiffInputStream& rStrm ) // private -------------------------------------------------------------------- -void BiffSheetDataContext::setCurrCell( const BinAddress& rAddr ) +void BiffSheetDataContext::importRow( BiffInputStream& rStrm ) { - maCurrCell.reset(); - maCurrCell.mxCell = getCell( rAddr, &maCurrCell.maAddress ); - // update used area of the sheet - if( maCurrCell.mxCell.is() ) - extendUsedArea( maCurrCell.maAddress ); -} - -void BiffSheetDataContext::importXfId( BiffInputStream& rStrm, bool bBiff2 ) -{ - if( bBiff2 ) - { - /* #i71453# On first call, check if the file contains XF records (by - trying to access the first XF with index 0). If there are no XFs, - the explicit formatting information contained in each cell record - will be used instead. */ - if( !mobBiff2HasXfs ) - mobBiff2HasXfs = getStyles().getCellXf( 0 ).get() != 0; - // read formatting information (includes the XF identifier) - sal_uInt8 nFlags1, nFlags2, nFlags3; - rStrm >> nFlags1 >> nFlags2 >> nFlags3; - /* If the file contains XFs, extract and set the XF identifier, - otherwise get the explicit formatting. */ - if( mobBiff2HasXfs.get() ) - { - maCurrCell.mnXfId = extractValue< sal_Int32 >( nFlags1, 0, 6 ); - /* If the identifier is equal to 63, then the real identifier is - contained in the preceding IXFE record (stored in mnBiff2XfId). */ - if( maCurrCell.mnXfId == BIFF2_CELL_USEIXFE ) - maCurrCell.mnXfId = mnBiff2XfId; - } - else + RowModel aModel; + sal_uInt16 nRow, nHeight; + rStrm >> nRow; + rStrm.skip( 4 ); + rStrm >> nHeight; + if( getBiff() == BIFF2 ) + { + rStrm.skip( 2 ); + aModel.mbCustomFormat = rStrm.readuInt8() == BIFF2_ROW_CUSTOMFORMAT; + if( aModel.mbCustomFormat ) { - /* Let the Xf class do the API conversion. Keeping the member - maCurrCell.mnXfId untouched will prevent to trigger the usual - XF formatting conversion later on. */ - PropertySet aPropSet( maCurrCell.mxCell ); - Xf::writeBiff2CellFormatToPropertySet( *this, aPropSet, nFlags1, nFlags2, nFlags3 ); + rStrm.skip( 5 ); + aModel.mnXfId = rStrm.readuInt16(); } } else { - maCurrCell.mnXfId = rStrm.readuInt16(); + rStrm.skip( 4 ); + sal_uInt32 nFlags = rStrm.readuInt32(); + aModel.mnXfId = extractValue< sal_Int32 >( nFlags, 16, 12 ); + aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 0, 3 ); + aModel.mbCustomFormat = getFlag( nFlags, BIFF_ROW_CUSTOMFORMAT ); + aModel.mbCustomHeight = getFlag( nFlags, BIFF_ROW_CUSTOMHEIGHT ); + aModel.mbShowPhonetic = getFlag( nFlags, BIFF_ROW_SHOWPHONETIC ); + aModel.mbHidden = getFlag( nFlags, BIFF_ROW_HIDDEN ); + aModel.mbCollapsed = getFlag( nFlags, BIFF_ROW_COLLAPSED ); + aModel.mbThickTop = getFlag( nFlags, BIFF_ROW_THICKTOP ); + aModel.mbThickBottom = getFlag( nFlags, BIFF_ROW_THICKBOTTOM ); } + + // row index is 0-based in BIFF, but RowModel expects 1-based + aModel.mnFirstRow = aModel.mnLastRow = nRow + 1; + // row height is in twips in BIFF, convert to points + aModel.mfHeight = (nHeight & BIFF_ROW_HEIGHTMASK) / 20.0; + // set row properties in the current sheet + setRowModel( aModel ); } -void BiffSheetDataContext::importCellHeader( BiffInputStream& rStrm, bool bBiff2 ) +bool BiffSheetDataContext::readCellXfId( const BinAddress& rAddr, BiffInputStream& rStrm, bool bBiff2 ) +{ + bool bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, rAddr, mnSheet, true ); + if( bValidAddr ) + { + // update used area of the sheet + extendUsedArea( maCellData.maCellAddr ); + + // load the XF identifier according to current BIFF version + if( bBiff2 ) + { + /* #i71453# On first call, check if the file contains XF records + (by trying to access the first XF with index 0). If there are + no XFs, the explicit formatting information contained in each + cell record will be used instead. */ + if( !mobBiff2HasXfs ) + mobBiff2HasXfs = getStyles().getCellXf( 0 ).get() != 0; + // read formatting information (includes the XF identifier) + sal_uInt8 nFlags1, nFlags2, nFlags3; + rStrm >> nFlags1 >> nFlags2 >> nFlags3; + /* If the file contains XFs, extract and set the XF identifier, + otherwise get the explicit formatting. */ + if( mobBiff2HasXfs.get() ) + { + maCellData.mnXfId = extractValue< sal_Int32 >( nFlags1, 0, 6 ); + /* If the identifier is equal to 63, then the real identifier + is contained in the preceding IXFE record (stored in the + class member mnBiff2XfId). */ + if( maCellData.mnXfId == BIFF2_CELL_USEIXFE ) + maCellData.mnXfId = mnBiff2XfId; + } + else + { + /* Let the Xf class do the API conversion. Keeping the member + maCellData.mnXfId untouched will prevent to trigger the + usual XF formatting conversion later on. */ + PropertySet aPropSet( getCell( maCellData.maCellAddr ) ); + Xf::writeBiff2CellFormatToPropertySet( *this, aPropSet, nFlags1, nFlags2, nFlags3 ); + } + } + else + { + // BIFF3-BIFF8: 16-bit XF identifier + maCellData.mnXfId = rStrm.readuInt16(); + } + } + return bValidAddr; +} + +bool BiffSheetDataContext::readCellHeader( BiffInputStream& rStrm, bool bBiff2 ) { BinAddress aAddr; rStrm >> aAddr; - setCurrCell( aAddr ); - importXfId( rStrm, bBiff2 ); + return readCellXfId( aAddr, rStrm, bBiff2 ); +} + +bool BiffSheetDataContext::readFormulaRef( BiffInputStream& rStrm ) +{ + BinRange aRange; + aRange.read( rStrm, false ); // columns always 8-bit + return mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, aRange, mnSheet, true, true ); } void BiffSheetDataContext::importBlank( BiffInputStream& rStrm ) { - importCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BLANK ); - mrSheetData.setCellFormat( maCurrCell ); + if( readCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BLANK ) ) + mrSheetData.setCellFormat( maCellData ); } void BiffSheetDataContext::importBoolErr( BiffInputStream& rStrm ) { - importCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BOOLERR ); - if( maCurrCell.mxCell.is() ) + if( readCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BOOLERR ) ) { sal_uInt8 nValue, nType; rStrm >> nValue >> nType; switch( nType ) { case BIFF_BOOLERR_BOOL: - maCurrCell.mnCellType = XML_b; - mrSheetData.setBooleanCell( maCurrCell.mxCell, maCurrCell.maAddress, nValue != 0 ); - // #108770# set 'Standard' number format for all Boolean cells - maCurrCell.mnNumFmtId = 0; + maCellData.mnCellType = XML_b; + mrSheetData.setBooleanCell( maCellData.maCellAddr, nValue != 0 ); break; case BIFF_BOOLERR_ERROR: - maCurrCell.mnCellType = XML_e; - mrSheetData.setErrorCell( maCurrCell.mxCell, maCurrCell.maAddress, nValue ); + maCellData.mnCellType = XML_e; + mrSheetData.setErrorCell( maCellData.maCellAddr, nValue ); break; default: OSL_ENSURE( false, "BiffSheetDataContext::importBoolErr - unknown cell type" ); } + // #108770# set 'Standard' number format for all Boolean cells + sal_Int32 nNumFmtId = (nType == BIFF_BOOLERR_BOOL) ? 0 : -1; + mrSheetData.setCellFormat( maCellData, nNumFmtId ); } - mrSheetData.setCellFormat( maCurrCell ); } void BiffSheetDataContext::importFormula( BiffInputStream& rStrm ) { - importCellHeader( rStrm, getBiff() == BIFF2 ); - maCurrCell.mnCellType = XML_n; - rStrm.skip( mnFormulaSkipSize ); - ApiTokenSequence aTokens = getFormulaParser().importFormula( maCurrCell.maAddress, FORMULATYPE_CELL, rStrm ); - mrSheetData.setFormulaCell( maCurrCell.mxCell, maCurrCell.maAddress, aTokens ); - mrSheetData.setCellFormat( maCurrCell ); + if( readCellHeader( rStrm, getBiff() == BIFF2 ) ) + { + maCellData.mnCellType = XML_n; + rStrm.skip( mnFormulaSkipSize ); + ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_CELL, rStrm ); + mrSheetData.setFormulaCell( maCellData.maCellAddr, aTokens ); + mrSheetData.setCellFormat( maCellData ); + } } void BiffSheetDataContext::importInteger( BiffInputStream& rStrm ) { - importCellHeader( rStrm, true ); - maCurrCell.mnCellType = XML_n; - mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, rStrm.readuInt16() ); - mrSheetData.setCellFormat( maCurrCell ); + if( readCellHeader( rStrm, true ) ) + { + maCellData.mnCellType = XML_n; + mrSheetData.setValueCell( maCellData.maCellAddr, rStrm.readuInt16() ); + mrSheetData.setCellFormat( maCellData ); + } } void BiffSheetDataContext::importLabel( BiffInputStream& rStrm ) @@ -771,143 +819,98 @@ void BiffSheetDataContext::importLabel( BiffInputStream& rStrm ) 0x0204 8 -> 2 byte 16-bit length, unicode string */ bool bBiff2Xf = rStrm.getRecId() == BIFF2_ID_LABEL; - importCellHeader( rStrm, bBiff2Xf ); - maCurrCell.mnCellType = XML_inlineStr; - RichString aString( *this ); - if( getBiff() == BIFF8 ) + if( readCellHeader( rStrm, bBiff2Xf ) ) { - aString.importUniString( rStrm ); - } - else - { - // #i63105# use text encoding from FONT record - rtl_TextEncoding eTextEnc = getTextEncoding(); - if( const Font* pFont = getStyles().getFontFromCellXf( maCurrCell.mnXfId ).get() ) - eTextEnc = pFont->getFontEncoding(); - BiffStringFlags nFlags = bBiff2Xf ? BIFF_STR_8BITLENGTH : BIFF_STR_DEFAULT; - setFlag( nFlags, BIFF_STR_EXTRAFONTS, rStrm.getRecId() == BIFF_ID_RSTRING ); - aString.importByteString( rStrm, eTextEnc, nFlags ); + maCellData.mnCellType = XML_inlineStr; + RichString aString( *this ); + if( getBiff() == BIFF8 ) + { + aString.importUniString( rStrm ); + } + else + { + // #i63105# use text encoding from FONT record + rtl_TextEncoding eTextEnc = getTextEncoding(); + if( const Font* pFont = getStyles().getFontFromCellXf( maCellData.mnXfId ).get() ) + eTextEnc = pFont->getFontEncoding(); + BiffStringFlags nFlags = bBiff2Xf ? BIFF_STR_8BITLENGTH : BIFF_STR_DEFAULT; + setFlag( nFlags, BIFF_STR_EXTRAFONTS, rStrm.getRecId() == BIFF_ID_RSTRING ); + aString.importByteString( rStrm, eTextEnc, nFlags ); + } + aString.finalizeImport(); + mrSheetData.setStringCell( maCellData.maCellAddr, aString, maCellData.mnXfId ); + mrSheetData.setCellFormat( maCellData ); } - aString.finalizeImport(); - mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, aString, maCurrCell.mnXfId ); - mrSheetData.setCellFormat( maCurrCell ); } void BiffSheetDataContext::importLabelSst( BiffInputStream& rStrm ) { - importCellHeader( rStrm, false ); - maCurrCell.mnCellType = XML_s; - mrSheetData.setStringCell( maCurrCell.mxCell, maCurrCell.maAddress, rStrm.readInt32(), maCurrCell.mnXfId ); - mrSheetData.setCellFormat( maCurrCell ); + if( readCellHeader( rStrm, false ) ) + { + maCellData.mnCellType = XML_s; + mrSheetData.setStringCell( maCellData.maCellAddr, rStrm.readInt32(), maCellData.mnXfId ); + mrSheetData.setCellFormat( maCellData ); + } } void BiffSheetDataContext::importMultBlank( BiffInputStream& rStrm ) { BinAddress aAddr; - for( rStrm >> aAddr; rStrm.getRemaining() > 2; ++aAddr.mnCol ) - { - setCurrCell( aAddr ); - importXfId( rStrm, false ); - mrSheetData.setCellFormat( maCurrCell ); - } + bool bValidAddr = true; + for( rStrm >> aAddr; bValidAddr && (rStrm.getRemaining() > 2); ++aAddr.mnCol ) + if( (bValidAddr = readCellXfId( aAddr, rStrm, false )) == true ) + mrSheetData.setCellFormat( maCellData ); } void BiffSheetDataContext::importMultRk( BiffInputStream& rStrm ) { BinAddress aAddr; - for( rStrm >> aAddr; rStrm.getRemaining() > 2; ++aAddr.mnCol ) + bool bValidAddr = true; + for( rStrm >> aAddr; bValidAddr && (rStrm.getRemaining() > 2); ++aAddr.mnCol ) { - setCurrCell( aAddr ); - maCurrCell.mnCellType = XML_n; - importXfId( rStrm, false ); - sal_Int32 nRkValue = rStrm.readInt32(); - mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, BiffHelper::calcDoubleFromRk( nRkValue ) ); - mrSheetData.setCellFormat( maCurrCell ); + if( (bValidAddr = readCellXfId( aAddr, rStrm, false )) == true ) + { + maCellData.mnCellType = XML_n; + sal_Int32 nRkValue = rStrm.readInt32(); + mrSheetData.setValueCell( maCellData.maCellAddr, BiffHelper::calcDoubleFromRk( nRkValue ) ); + mrSheetData.setCellFormat( maCellData ); + } } } void BiffSheetDataContext::importNumber( BiffInputStream& rStrm ) { - importCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_NUMBER ); - maCurrCell.mnCellType = XML_n; - mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, rStrm.readDouble() ); - mrSheetData.setCellFormat( maCurrCell ); + if( readCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_NUMBER ) ) + { + maCellData.mnCellType = XML_n; + mrSheetData.setValueCell( maCellData.maCellAddr, rStrm.readDouble() ); + mrSheetData.setCellFormat( maCellData ); + } } void BiffSheetDataContext::importRk( BiffInputStream& rStrm ) { - importCellHeader( rStrm, false ); - maCurrCell.mnCellType = XML_n; - mrSheetData.setValueCell( maCurrCell.mxCell, maCurrCell.maAddress, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); - mrSheetData.setCellFormat( maCurrCell ); -} - -void BiffSheetDataContext::importRow( BiffInputStream& rStrm ) -{ - RowModel aModel; - - sal_uInt16 nRow, nHeight; - rStrm >> nRow; - rStrm.skip( 4 ); - rStrm >> nHeight; - if( getBiff() == BIFF2 ) + if( readCellHeader( rStrm, false ) ) { - rStrm.skip( 2 ); - aModel.mbCustomFormat = rStrm.readuInt8() == BIFF2_ROW_CUSTOMFORMAT; - if( aModel.mbCustomFormat ) - { - rStrm.skip( 5 ); - aModel.mnXfId = rStrm.readuInt16(); - } - } - else - { - rStrm.skip( 4 ); - sal_uInt32 nFlags = rStrm.readuInt32(); - aModel.mnXfId = extractValue< sal_Int32 >( nFlags, 16, 12 ); - aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 0, 3 ); - aModel.mbCustomFormat = getFlag( nFlags, BIFF_ROW_CUSTOMFORMAT ); - aModel.mbCustomHeight = getFlag( nFlags, BIFF_ROW_CUSTOMHEIGHT ); - aModel.mbShowPhonetic = getFlag( nFlags, BIFF_ROW_SHOWPHONETIC ); - aModel.mbHidden = getFlag( nFlags, BIFF_ROW_HIDDEN ); - aModel.mbCollapsed = getFlag( nFlags, BIFF_ROW_COLLAPSED ); - aModel.mbThickTop = getFlag( nFlags, BIFF_ROW_THICKTOP ); - aModel.mbThickBottom = getFlag( nFlags, BIFF_ROW_THICKBOTTOM ); + maCellData.mnCellType = XML_n; + mrSheetData.setValueCell( maCellData.maCellAddr, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); + mrSheetData.setCellFormat( maCellData ); } - - // row index is 0-based in BIFF, but RowModel expects 1-based - aModel.mnFirstRow = aModel.mnLastRow = nRow + 1; - // row height is in twips in BIFF, convert to points - aModel.mfHeight = (nHeight & BIFF_ROW_HEIGHTMASK) / 20.0; - // set row properties in the current sheet - setRowModel( aModel ); } void BiffSheetDataContext::importArray( BiffInputStream& rStrm ) { - BinRange aRange; - aRange.read( rStrm, false ); // columns always 8-bit - CellRangeAddress aArrayRange; - if( getAddressConverter().convertToCellRange( aArrayRange, aRange, getSheetIndex(), true, true ) ) + if( readFormulaRef( rStrm ) && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) ) { rStrm.skip( mnArraySkipSize ); - CellAddress aBaseAddr( aArrayRange.Sheet, aArrayRange.StartColumn, aArrayRange.StartRow ); - ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_ARRAY, rStrm ); - mrSheetData.setArrayFormula( aArrayRange, aTokens ); + ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_ARRAY, rStrm ); + mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, aTokens ); } } -void BiffSheetDataContext::importSharedFmla( BiffInputStream& rStrm ) -{ - mrSheetData.importSharedFmla( rStrm, maCurrCell.maAddress ); -} - void BiffSheetDataContext::importDataTable( BiffInputStream& rStrm ) { - BinRange aRange; - aRange.read( rStrm, false ); // columns always 8-bit - CellRangeAddress aTableRange; - if( getAddressConverter().convertToCellRange( aTableRange, aRange, getSheetIndex(), true, true ) ) + if( readFormulaRef( rStrm ) ) { DataTableModel aModel; BinAddress aRef1, aRef2; @@ -939,7 +942,17 @@ void BiffSheetDataContext::importDataTable( BiffInputStream& rStrm ) } aModel.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false ); aModel.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false ); - mrSheetData.setTableOperation( aTableRange, aModel ); + mrSheetData.createTableOperation( maFmlaData.maFormulaRef, aModel ); + } +} + +void BiffSheetDataContext::importSharedFmla( BiffInputStream& rStrm ) +{ + if( readFormulaRef( rStrm ) && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) ) + { + rStrm.skip( 2 ); // flags + ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_SHAREDFORMULA, rStrm ); + mrSheetData.createSharedFormula( maCellData.maCellAddr, aTokens ); } } diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index 778adcff24ab..bba52fb0d8f2 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -184,27 +184,6 @@ void ValueRangeSet::intersect( ValueRangeVector& orRanges, sal_Int32 nFirst, sal // ============================================================================ // ============================================================================ -void CellModel::reset() -{ - mxCell.clear(); - maValue = maFormula = maFormulaRef = OUString(); - mnCellType = mnFormulaType = XML_TOKEN_INVALID; - mnSharedId = mnXfId = mnNumFmtId = -1; - mbShowPhonetic = false; -} - -// ---------------------------------------------------------------------------- - -DataTableModel::DataTableModel() : - mb2dTable( false ), - mbRowTable( false ), - mbRef1Deleted( false ), - mbRef2Deleted( false ) -{ -} - -// ---------------------------------------------------------------------------- - ColumnModel::ColumnModel() : mnFirstCol( -1 ), mnLastCol( -1 ), @@ -1430,28 +1409,6 @@ Reference< XCell > WorksheetHelper::getCell( const CellAddress& rAddress ) const return mrSheetGlob.getCell( rAddress ); } -Reference< XCell > WorksheetHelper::getCell( const OUString& rAddressStr, CellAddress* opAddress ) const -{ - CellAddress aAddress; - if( getAddressConverter().convertToCellAddress( aAddress, rAddressStr, mrSheetGlob.getSheetIndex(), true ) ) - { - if( opAddress ) *opAddress = aAddress; - return mrSheetGlob.getCell( aAddress ); - } - return Reference< XCell >(); -} - -Reference< XCell > WorksheetHelper::getCell( const BinAddress& rBinAddress, CellAddress* opAddress ) const -{ - CellAddress aAddress; - if( getAddressConverter().convertToCellAddress( aAddress, rBinAddress, mrSheetGlob.getSheetIndex(), true ) ) - { - if( opAddress ) *opAddress = aAddress; - return mrSheetGlob.getCell( aAddress ); - } - return Reference< XCell >(); -} - Reference< XCellRange > WorksheetHelper::getCellRange( const CellRangeAddress& rRange ) const { return mrSheetGlob.getCellRange( rRange ); -- cgit From 4f06bfae891d1b7b80e0e17be9623536f31ae9ac Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Fri, 25 Feb 2011 16:43:02 +0100 Subject: dr78: #164376# use XCellRangeData to increase import performance --- oox/source/helper/containerhelper.cxx | 53 ++++ oox/source/xls/autofilterbuffer.cxx | 2 +- oox/source/xls/commentsbuffer.cxx | 2 +- oox/source/xls/pivotcachebuffer.cxx | 73 +++-- oox/source/xls/pivotcachefragment.cxx | 26 +- oox/source/xls/richstring.cxx | 67 ++-- oox/source/xls/sharedstringsbuffer.cxx | 6 +- oox/source/xls/sheetdatabuffer.cxx | 552 +++++++++++++++++++++++---------- oox/source/xls/sheetdatacontext.cxx | 194 +++++++----- oox/source/xls/worksheetfragment.cxx | 42 +-- oox/source/xls/worksheethelper.cxx | 351 +++++++++++---------- 11 files changed, 874 insertions(+), 494 deletions(-) (limited to 'oox/source') diff --git a/oox/source/helper/containerhelper.cxx b/oox/source/helper/containerhelper.cxx index 4fb0d93d6224..264deb366878 100644 --- a/oox/source/helper/containerhelper.cxx +++ b/oox/source/helper/containerhelper.cxx @@ -47,6 +47,59 @@ using ::rtl::OUStringBuffer; // ============================================================================ +namespace { + +struct ValueRangeComp +{ + inline bool operator()( const ValueRange& rRange, sal_Int32 nValue ) const { return rRange.mnLast < nValue; } +}; + +} // namespace + +// ---------------------------------------------------------------------------- + +void ValueRangeSet::insert( const ValueRange& rRange ) +{ + // find the first range that contains or follows the starting point of the passed range + ValueRangeVector::iterator aBeg = maRanges.begin(); + ValueRangeVector::iterator aEnd = maRanges.end(); + ValueRangeVector::iterator aIt = ::std::lower_bound( aBeg, aEnd, rRange.mnFirst, ValueRangeComp() ); + // nothing to do if found range contains passed range + if( (aIt != aEnd) && aIt->contains( rRange ) ) return; + // check if previous range can be used to merge with the passed range + if( (aIt != aBeg) && ((aIt - 1)->mnLast + 1 == rRange.mnFirst) ) --aIt; + // check if current range (aIt) can be used to merge with passed range + if( (aIt != aEnd) && aIt->intersects( rRange ) ) + { + // set new start value to existing range + aIt->mnFirst = ::std::min( aIt->mnFirst, rRange.mnFirst ); + // search first range that cannot be merged anymore (aNext) + ValueRangeVector::iterator aNext = aIt + 1; + while( (aNext != aEnd) && aNext->intersects( rRange ) ) ++aNext; + // set new end value to existing range + aIt->mnLast = ::std::max( (aNext - 1)->mnLast, rRange.mnLast ); + // remove ranges covered by new existing range (aIt) + maRanges.erase( aIt + 1, aNext ); + } + else + { + // merging not possible: insert new range + maRanges.insert( aIt, rRange ); + } +} + +ValueRangeVector ValueRangeSet::getIntersection( const ValueRange& rRange ) const +{ + ValueRangeVector aRanges; + // find the range that contains nFirst or the first range that follows nFirst + ValueRangeVector::const_iterator aIt = ::std::lower_bound( maRanges.begin(), maRanges.end(), rRange.mnFirst, ValueRangeComp() ); + for( ValueRangeVector::const_iterator aEnd = maRanges.end(); (aIt != aEnd) && (aIt->mnFirst <= rRange.mnLast); ++aIt ) + aRanges.push_back( ValueRange( ::std::max( aIt->mnFirst, rRange.mnFirst ), ::std::min( aIt->mnLast, rRange.mnLast ) ) ); + return aRanges; +} + +// ============================================================================ + Reference< XIndexContainer > ContainerHelper::createIndexContainer( const Reference< XComponentContext >& rxContext ) { Reference< XIndexContainer > xContainer; diff --git a/oox/source/xls/autofilterbuffer.cxx b/oox/source/xls/autofilterbuffer.cxx index 7cf359f6d3c9..bfc33e82056b 100755 --- a/oox/source/xls/autofilterbuffer.cxx +++ b/oox/source/xls/autofilterbuffer.cxx @@ -842,7 +842,7 @@ bool AutoFilterBuffer::finalizeImport( const Reference< XDatabaseRange >& rxData AutoFilter* AutoFilterBuffer::getActiveAutoFilter() { // Excel expects not more than one auto filter per sheet or table - OSL_ENSURE( maAutoFilters.size() == 1, "AutoFilterBuffer::getActiveAutoFilter - too many auto filters" ); + OSL_ENSURE( maAutoFilters.size() <= 1, "AutoFilterBuffer::getActiveAutoFilter - too many auto filters" ); // stick to the last imported auto filter return maAutoFilters.empty() ? 0 : maAutoFilters.back().get(); } diff --git a/oox/source/xls/commentsbuffer.cxx b/oox/source/xls/commentsbuffer.cxx index f55dac0ca6f2..f11aa89bca53 100644 --- a/oox/source/xls/commentsbuffer.cxx +++ b/oox/source/xls/commentsbuffer.cxx @@ -170,7 +170,7 @@ void Comment::finalizeImport() // insert text and convert text formatting maModel.mxText->finalizeImport(); Reference< XText > xAnnoText( xAnnoShape, UNO_QUERY_THROW ); - maModel.mxText->convert( xAnnoText, -1, true ); + maModel.mxText->convert( xAnnoText ); } catch( Exception& ) { diff --git a/oox/source/xls/pivotcachebuffer.cxx b/oox/source/xls/pivotcachebuffer.cxx index 2c4d55b089f1..146f3b53df8a 100644 --- a/oox/source/xls/pivotcachebuffer.cxx +++ b/oox/source/xls/pivotcachebuffer.cxx @@ -936,8 +936,9 @@ OUString PivotCacheField::createParentGroupField( const Reference< XDataPilotFie void PivotCacheField::writeSourceHeaderCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const { - CellAddress aCellAddr( rSheetHelper.getSheetIndex(), nCol, nRow ); - rSheetHelper.getSheetData().setStringCell( aCellAddr, maFieldModel.maName ); + CellModel aModel; + aModel.maCellAddr = CellAddress( rSheetHelper.getSheetIndex(), nCol, nRow ); + rSheetHelper.getSheetData().setStringCell( aModel, maFieldModel.maName ); } void PivotCacheField::writeSourceDataCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const @@ -983,16 +984,17 @@ void PivotCacheField::writeItemToSourceDataCell( WorksheetHelper& rSheetHelper, { if( rItem.getType() != XML_m ) { - CellAddress aCellAddr( rSheetHelper.getSheetIndex(), nCol, nRow ); + CellModel aModel; + aModel.maCellAddr = CellAddress( rSheetHelper.getSheetIndex(), nCol, nRow ); SheetDataBuffer& rSheetData = rSheetHelper.getSheetData(); switch( rItem.getType() ) { - case XML_s: rSheetData.setStringCell( aCellAddr, rItem.getValue().get< OUString >() ); break; - case XML_n: rSheetData.setValueCell( aCellAddr, rItem.getValue().get< double >() ); break; - case XML_i: rSheetData.setValueCell( aCellAddr, rItem.getValue().get< sal_Int16 >() ); break; - case XML_d: rSheetData.setDateTimeCell( aCellAddr, rItem.getValue().get< DateTime >() ); break; - case XML_b: rSheetData.setBooleanCell( aCellAddr, rItem.getValue().get< bool >() ); break; - case XML_e: rSheetData.setErrorCell( aCellAddr, static_cast< sal_uInt8 >( rItem.getValue().get< sal_Int32 >() ) ); break; + case XML_s: rSheetData.setStringCell( aModel, rItem.getValue().get< OUString >() ); break; + case XML_n: rSheetData.setValueCell( aModel, rItem.getValue().get< double >() ); break; + case XML_i: rSheetData.setValueCell( aModel, rItem.getValue().get< sal_Int16 >() ); break; + case XML_d: rSheetData.setDateTimeCell( aModel, rItem.getValue().get< DateTime >() ); break; + case XML_b: rSheetData.setBooleanCell( aModel, rItem.getValue().get< bool >() ); break; + case XML_e: rSheetData.setErrorCell( aModel, static_cast< sal_uInt8 >( rItem.getValue().get< sal_Int32 >() ) ); break; default: OSL_ENSURE( false, "PivotCacheField::writeItemToSourceDataCell - unexpected item data type" ); } } @@ -1044,6 +1046,7 @@ PCWorksheetSourceModel::PCWorksheetSourceModel() PivotCache::PivotCache( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper ), + mnCurrRow( -1 ), mbValidSource( false ), mbDummySheet( false ) { @@ -1276,34 +1279,39 @@ void PivotCache::writeSourceHeaderCells( WorksheetHelper& rSheetHelper ) const sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn; sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column; sal_Int32 nRow = maSheetSrcModel.maRange.StartRow; + mnCurrRow = -1; + updateSourceDataRow( rSheetHelper, nRow ); for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol ) (*aIt)->writeSourceHeaderCell( rSheetHelper, nCol, nRow ); } -void PivotCache::writeSourceDataCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const +void PivotCache::writeSourceDataCell( WorksheetHelper& rSheetHelper, sal_Int32 nColIdx, sal_Int32 nRowIdx, const PivotCacheItem& rItem ) const { - OSL_ENSURE( (0 <= nCol) && (nCol <= maSheetSrcModel.maRange.EndColumn - maSheetSrcModel.maRange.StartColumn), "PivotCache::writeSourceDataCell - invalid column index" ); - OSL_ENSURE( (0 < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow - maSheetSrcModel.maRange.StartRow), "PivotCache::writeSourceDataCell - invalid row index" ); - if( const PivotCacheField* pCacheField = maDatabaseFields.get( nCol ).get() ) - pCacheField->writeSourceDataCell( rSheetHelper, maSheetSrcModel.maRange.StartColumn + nCol, maSheetSrcModel.maRange.StartRow + nRow, rItem ); + sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn + nColIdx; + OSL_ENSURE( (maSheetSrcModel.maRange.StartColumn <= nCol) && (nCol <= maSheetSrcModel.maRange.EndColumn), "PivotCache::writeSourceDataCell - invalid column index" ); + sal_Int32 nRow = maSheetSrcModel.maRange.StartRow + nRowIdx; + OSL_ENSURE( (maSheetSrcModel.maRange.StartRow < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow), "PivotCache::writeSourceDataCell - invalid row index" ); + updateSourceDataRow( rSheetHelper, nRow ); + if( const PivotCacheField* pCacheField = maDatabaseFields.get( nColIdx ).get() ) + pCacheField->writeSourceDataCell( rSheetHelper, nCol, nRow, rItem ); } -void PivotCache::importPCRecord( SequenceInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nRow ) const +void PivotCache::importPCRecord( SequenceInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nRowIdx ) const { - OSL_ENSURE( (0 < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow - maSheetSrcModel.maRange.StartRow), "PivotCache::importPCRecord - invalid row index" ); + sal_Int32 nRow = maSheetSrcModel.maRange.StartRow + nRowIdx; + OSL_ENSURE( (maSheetSrcModel.maRange.StartRow < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow), "PivotCache::importPCRecord - invalid row index" ); sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn; sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column; - nRow += maSheetSrcModel.maRange.StartRow; for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); !rStrm.isEof() && (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol ) (*aIt)->importPCRecordItem( rStrm, rSheetHelper, nCol, nRow ); } -void PivotCache::importPCItemIndexList( BiffInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nRow ) const +void PivotCache::importPCItemIndexList( BiffInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nRowIdx ) const { - OSL_ENSURE( (0 < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow - maSheetSrcModel.maRange.StartRow), "PivotCache::importPCItemIndexList - invalid row index" ); + sal_Int32 nRow = maSheetSrcModel.maRange.StartRow + nRowIdx; + OSL_ENSURE( (maSheetSrcModel.maRange.StartRow < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow), "PivotCache::importPCItemIndexList - invalid row index" ); sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn; sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column; - nRow += maSheetSrcModel.maRange.StartRow; for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); !rStrm.isEof() && (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol ) if( (*aIt)->hasSharedItems() ) (*aIt)->importPCItemIndex( rStrm, rSheetHelper, nCol, nRow ); @@ -1417,17 +1425,28 @@ void PivotCache::finalizeExternalSheetSource() void PivotCache::prepareSourceDataSheet() { + CellRangeAddress& rRange = maSheetSrcModel.maRange; // data will be inserted in top-left cell, sheet index is still set to 0 (will be set below) - maSheetSrcModel.maRange.EndColumn -= maSheetSrcModel.maRange.StartColumn; - maSheetSrcModel.maRange.StartColumn = 0; - maSheetSrcModel.maRange.EndRow -= maSheetSrcModel.maRange.StartRow; - maSheetSrcModel.maRange.StartRow = 0; + rRange.EndColumn -= rRange.StartColumn; + rRange.StartColumn = 0; + rRange.EndRow -= rRange.StartRow; + rRange.StartRow = 0; // check range location, do not allow ranges that overflow the sheet partly - if( getAddressConverter().checkCellRange( maSheetSrcModel.maRange, false, true ) ) + if( getAddressConverter().checkCellRange( rRange, false, true ) ) { + maColSpans.insert( ValueRange( rRange.StartColumn, rRange.EndColumn ) ); OUString aSheetName = CREATE_OUSTRING( "DPCache_" ) + maSheetSrcModel.maSheet; - maSheetSrcModel.maRange.Sheet = getWorksheets().insertEmptySheet( aSheetName, false ); - mbValidSource = mbDummySheet = maSheetSrcModel.maRange.Sheet >= 0; + rRange.Sheet = getWorksheets().insertEmptySheet( aSheetName, false ); + mbValidSource = mbDummySheet = rRange.Sheet >= 0; + } +} + +void PivotCache::updateSourceDataRow( WorksheetHelper& rSheetHelper, sal_Int32 nRow ) const +{ + if( mnCurrRow != nRow ) + { + rSheetHelper.getSheetData().setColSpans( nRow, maColSpans ); + mnCurrRow = nRow; } } diff --git a/oox/source/xls/pivotcachefragment.cxx b/oox/source/xls/pivotcachefragment.cxx index b28d3b64e8e3..f6948917701a 100644 --- a/oox/source/xls/pivotcachefragment.cxx +++ b/oox/source/xls/pivotcachefragment.cxx @@ -223,8 +223,8 @@ PivotCacheRecordsFragment::PivotCacheRecordsFragment( const WorksheetHelper& rHe const OUString& rFragmentPath, const PivotCache& rPivotCache ) : WorksheetFragmentBase( rHelper, rFragmentPath ), mrPivotCache( rPivotCache ), - mnCol( 0 ), - mnRow( 0 ), + mnColIdx( 0 ), + mnRowIdx( 0 ), mbInRecord( false ) { // prepare sheet: insert column header names into top row @@ -257,8 +257,8 @@ ContextHandlerRef PivotCacheRecordsFragment::onCreateContext( sal_Int32 nElement case XLS_TOKEN( x ): aItem.readIndex( rAttribs ); break; default: OSL_ENSURE( false, "PivotCacheRecordsFragment::onCreateContext - unexpected element" ); } - mrPivotCache.writeSourceDataCell( *this, mnCol, mnRow, aItem ); - ++mnCol; + mrPivotCache.writeSourceDataCell( *this, mnColIdx, mnRowIdx, aItem ); + ++mnColIdx; } break; } @@ -299,15 +299,15 @@ const RecordInfo* PivotCacheRecordsFragment::getRecordInfos() const void PivotCacheRecordsFragment::startCacheRecord() { - mnCol = 0; - ++mnRow; + mnColIdx = 0; + ++mnRowIdx; mbInRecord = true; } void PivotCacheRecordsFragment::importPCRecord( SequenceInputStream& rStrm ) { startCacheRecord(); - mrPivotCache.importPCRecord( rStrm, *this, mnRow ); + mrPivotCache.importPCRecord( rStrm, *this, mnRowIdx ); mbInRecord = false; } @@ -327,8 +327,8 @@ void PivotCacheRecordsFragment::importPCRecordItem( sal_Int32 nRecId, SequenceIn case BIFF12_ID_PCITEM_INDEX: aItem.readIndex( rStrm ); break; default: OSL_ENSURE( false, "PivotCacheRecordsFragment::importPCRecordItem - unexpected record" ); } - mrPivotCache.writeSourceDataCell( *this, mnCol, mnRow, aItem ); - ++mnCol; + mrPivotCache.writeSourceDataCell( *this, mnColIdx, mnRowIdx, aItem ); + ++mnColIdx; } } @@ -398,7 +398,7 @@ BiffPivotCacheRecordsContext::BiffPivotCacheRecordsContext( const WorksheetHelpe BiffWorksheetContextBase( rHelper ), mrPivotCache( rPivotCache ), mnColIdx( 0 ), - mnRow( 0 ), + mnRowIdx( 0 ), mbHasShared( false ), mbInRow( false ) { @@ -427,7 +427,7 @@ void BiffPivotCacheRecordsContext::importRecord( BiffInputStream& rStrm ) OSL_ENSURE( mbHasShared, "BiffPivotCacheRecordsContext::importRecord - unexpected PCITEM_INDEXLIST record" ); // PCITEM_INDEXLIST record always in front of a new data row startNextRow(); - mrPivotCache.importPCItemIndexList( rStrm, *this, mnRow ); + mrPivotCache.importPCItemIndexList( rStrm, *this, mnRowIdx ); mbInRow = !maUnsharedCols.empty(); // mbInRow remains true, if unshared items are expected return; } @@ -458,14 +458,14 @@ void BiffPivotCacheRecordsContext::importRecord( BiffInputStream& rStrm ) // write the item data to the sheet cell OSL_ENSURE( mnColIdx < maUnsharedCols.size(), "BiffPivotCacheRecordsContext::importRecord - invalid column index" ); if( mnColIdx < maUnsharedCols.size() ) - mrPivotCache.writeSourceDataCell( *this, maUnsharedCols[ mnColIdx ], mnRow, aItem ); + mrPivotCache.writeSourceDataCell( *this, maUnsharedCols[ mnColIdx ], mnRowIdx, aItem ); ++mnColIdx; } void BiffPivotCacheRecordsContext::startNextRow() { mnColIdx = 0; - ++mnRow; + ++mnRowIdx; mbInRow = true; } diff --git a/oox/source/xls/richstring.cxx b/oox/source/xls/richstring.cxx index 5f4288ed651e..859280ddd548 100644 --- a/oox/source/xls/richstring.cxx +++ b/oox/source/xls/richstring.cxx @@ -52,6 +52,11 @@ namespace { const sal_uInt8 BIFF12_STRINGFLAG_FONTS = 0x01; const sal_uInt8 BIFF12_STRINGFLAG_PHONETICS = 0x02; +inline bool lclNeedsRichTextFormat( const Font* pFont ) +{ + return pFont && pFont->needsRichTextFormat(); +} + } // namespace // ============================================================================ @@ -86,10 +91,10 @@ void RichStringPortion::finalizeImport() mxFont = getStyles().getFont( mnFontId ); } -void RichStringPortion::convert( const Reference< XText >& rxText, sal_Int32 nXfId, bool bReplaceOld ) +void RichStringPortion::convert( const Reference< XText >& rxText, const Font* pFont, bool bReplace ) { Reference< XTextRange > xRange; - if( bReplaceOld ) + if( bReplace ) xRange.set( rxText, UNO_QUERY ); else xRange = rxText->getEnd(); @@ -103,13 +108,13 @@ void RichStringPortion::convert( const Reference< XText >& rxText, sal_Int32 nXf PropertySet aPropSet( xRange ); mxFont->writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT ); } - if( const Font* pFont = getStyles().getFontFromCellXf( nXfId ).get() ) + + /* Some font attributes cannot be set to cell formattiing in Calc but + require to use rich formatting, e.g. font escapement. */ + if( lclNeedsRichTextFormat( pFont ) ) { - if( pFont->needsRichTextFormat() ) - { - PropertySet aPropSet( xRange ); - pFont->writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT ); - } + PropertySet aPropSet( xRange ); + pFont->writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT ); } } } @@ -400,7 +405,7 @@ void RichString::importString( SequenceInputStream& rStrm, bool bRich ) { FontPortionModelList aPortions; aPortions.importPortions( rStrm ); - createFontPortions( aBaseText, aPortions ); + createTextPortions( aBaseText, aPortions ); } else { @@ -434,7 +439,7 @@ void RichString::importByteString( BiffInputStream& rStrm, rtl_TextEncoding eTex { FontPortionModelList aPortions; aPortions.importPortions( rStrm, false ); - createFontPortions( aBaseText, eTextEnc, aPortions ); + createTextPortions( aBaseText, eTextEnc, aPortions ); } else { @@ -468,7 +473,7 @@ void RichString::importUniString( BiffInputStream& rStrm, BiffStringFlags nFlags { FontPortionModelList aPortions; aPortions.importPortions( rStrm, nFontCount, BIFF_FONTPORTION_16BIT ); - createFontPortions( aBaseText, aPortions ); + createTextPortions( aBaseText, aPortions ); } else { @@ -502,16 +507,34 @@ void RichString::importUniString( BiffInputStream& rStrm, BiffStringFlags nFlags void RichString::finalizeImport() { - maFontPortions.forEachMem( &RichStringPortion::finalizeImport ); + maTextPortions.forEachMem( &RichStringPortion::finalizeImport ); +} + +bool RichString::extractPlainString( OUString& orString, const Font* pFirstPortionFont ) const +{ + if( !maPhonPortions.empty() ) + return false; + if( maTextPortions.empty() ) + { + orString = OUString(); + return true; + } + if( (maTextPortions.size() == 1) && !maTextPortions.front()->hasFont() && !lclNeedsRichTextFormat( pFirstPortionFont ) ) + { + orString = maTextPortions.front()->getText(); + return true; + } + return false; } -void RichString::convert( const Reference< XText >& rxText, sal_Int32 nXfId, bool bReplaceOld ) const +void RichString::convert( const Reference< XText >& rxText, const Font* pFirstPortionFont ) const { - for( PortionVec::const_iterator aIt = maFontPortions.begin(), aEnd = maFontPortions.end(); aIt != aEnd; ++aIt ) + bool bReplace = true; + for( PortionVector::const_iterator aIt = maTextPortions.begin(), aEnd = maTextPortions.end(); aIt != aEnd; ++aIt ) { - (*aIt)->convert( rxText, nXfId, bReplaceOld ); - nXfId = -1; // use passed XF identifier for first portion only - bReplaceOld = false; // do not replace first portion text with following portions + (*aIt)->convert( rxText, pFirstPortionFont, bReplace ); + pFirstPortionFont = 0; // use passed font for first portion only + bReplace = false; // do not replace first portion text with following portions } } @@ -520,7 +543,7 @@ void RichString::convert( const Reference< XText >& rxText, sal_Int32 nXfId, boo RichStringPortionRef RichString::createPortion() { RichStringPortionRef xPortion( new RichStringPortion( *this ) ); - maFontPortions.push_back( xPortion ); + maTextPortions.push_back( xPortion ); return xPortion; } @@ -531,9 +554,9 @@ RichStringPhoneticRef RichString::createPhonetic() return xPhonetic; } -void RichString::createFontPortions( const OString& rText, rtl_TextEncoding eTextEnc, FontPortionModelList& rPortions ) +void RichString::createTextPortions( const OString& rText, rtl_TextEncoding eTextEnc, FontPortionModelList& rPortions ) { - maFontPortions.clear(); + maTextPortions.clear(); sal_Int32 nStrLen = rText.getLength(); if( nStrLen > 0 ) { @@ -562,9 +585,9 @@ void RichString::createFontPortions( const OString& rText, rtl_TextEncoding eTex } } -void RichString::createFontPortions( const OUString& rText, FontPortionModelList& rPortions ) +void RichString::createTextPortions( const OUString& rText, FontPortionModelList& rPortions ) { - maFontPortions.clear(); + maTextPortions.clear(); sal_Int32 nStrLen = rText.getLength(); if( nStrLen > 0 ) { diff --git a/oox/source/xls/sharedstringsbuffer.cxx b/oox/source/xls/sharedstringsbuffer.cxx index 59d3a905bc40..c2464e1cf36f 100644 --- a/oox/source/xls/sharedstringsbuffer.cxx +++ b/oox/source/xls/sharedstringsbuffer.cxx @@ -73,11 +73,9 @@ void SharedStringsBuffer::finalizeImport() maStrings.forEachMem( &RichString::finalizeImport ); } -void SharedStringsBuffer::convertString( const Reference< XText >& rxText, sal_Int32 nStringId, sal_Int32 nXfId ) const +RichStringRef SharedStringsBuffer::getString( sal_Int32 nStringId ) const { - if( rxText.is() ) - if( const RichString* pString = maStrings.get( nStringId ).get() ) - pString->convert( rxText, nXfId ); + return maStrings.get( nStringId ); } // ============================================================================ diff --git a/oox/source/xls/sheetdatabuffer.cxx b/oox/source/xls/sheetdatabuffer.cxx index 0cfe741cb135..8bdcccca10cf 100755 --- a/oox/source/xls/sheetdatabuffer.cxx +++ b/oox/source/xls/sheetdatabuffer.cxx @@ -110,73 +110,306 @@ DataTableModel::DataTableModel() : // ============================================================================ +namespace { + +const sal_Int32 CELLBLOCK_MAXROWS = 16; /// Number of rows in a cell block. + +} // namespace + +CellBlock::CellBlock( const WorksheetHelper& rHelper, const ValueRange& rColSpan, sal_Int32 nRow ) : + WorksheetHelper( rHelper ), + maRange( rHelper.getSheetIndex(), rColSpan.mnFirst, nRow, rColSpan.mnLast, nRow ), + mnRowLength( rColSpan.mnLast - rColSpan.mnFirst + 1 ), + mnFirstFreeIndex( 0 ) +{ + maCellArray.realloc( 1 ); + maCellArray[ 0 ].realloc( mnRowLength ); + mpCurrCellRow = maCellArray[ 0 ].getArray(); +} + +bool CellBlock::isExpandable( const ValueRange& rColSpan ) const +{ + return (maRange.StartColumn == rColSpan.mnFirst) && (maRange.EndColumn == rColSpan.mnLast); +} + +bool CellBlock::isBefore( const ValueRange& rColSpan ) const +{ + return (maRange.EndColumn < rColSpan.mnLast) || + ((maRange.EndColumn == rColSpan.mnLast) && (maRange.StartColumn != rColSpan.mnFirst)); +} + +bool CellBlock::contains( sal_Int32 nCol ) const +{ + return (maRange.StartColumn <= nCol) && (nCol <= maRange.EndColumn); +} + +void CellBlock::insertRichString( const CellAddress& rAddress, const RichStringRef& rxString, const Font* pFirstPortionFont ) +{ + maRichStrings.push_back( RichStringCell( rAddress, rxString, pFirstPortionFont ) ); +} + +void CellBlock::startNextRow() +{ + // fill last cells in current row with empty strings (placeholder for empty cells) + fillUnusedCells( mnRowLength ); + // flush if the cell block reaches maximum size + if( maCellArray.getLength() == CELLBLOCK_MAXROWS ) + { + finalizeImport(); + maRange.StartRow = ++maRange.EndRow; + maCellArray.realloc( 1 ); + mpCurrCellRow = maCellArray[ 0 ].getArray(); + } + else + { + // prepare next row + ++maRange.EndRow; + sal_Int32 nRowCount = maCellArray.getLength(); + maCellArray.realloc( nRowCount + 1 ); + maCellArray[ nRowCount ].realloc( mnRowLength ); + mpCurrCellRow = maCellArray[ nRowCount ].getArray(); + } + mnFirstFreeIndex = 0; +} + +Any& CellBlock::getCellAny( sal_Int32 nCol ) +{ + OSL_ENSURE( contains( nCol ), "CellBlock::getCellAny - invalid column" ); + // fill cells before passed column with empty strings (the placeholder for empty cells) + sal_Int32 nIndex = nCol - maRange.StartColumn; + fillUnusedCells( nIndex ); + mnFirstFreeIndex = nIndex + 1; + return mpCurrCellRow[ nIndex ]; +} + +void CellBlock::finalizeImport() +{ + // fill last cells in last row with empty strings (placeholder for empty cells) + fillUnusedCells( mnRowLength ); + // insert all buffered cells into the Calc sheet + try + { + Reference< XCellRangeData > xRangeData( getCellRange( maRange ), UNO_QUERY_THROW ); + xRangeData->setDataArray( maCellArray ); + } + catch( Exception& ) + { + } + // insert uncacheable cells separately + for( RichStringCellList::const_iterator aIt = maRichStrings.begin(), aEnd = maRichStrings.end(); aIt != aEnd; ++aIt ) + putRichString( aIt->maCellAddr, *aIt->mxString, aIt->mpFirstPortionFont ); +} + +// private -------------------------------------------------------------------- + +CellBlock::RichStringCell::RichStringCell( const CellAddress& rCellAddr, const RichStringRef& rxString, const Font* pFirstPortionFont ) : + maCellAddr( rCellAddr ), + mxString( rxString ), + mpFirstPortionFont( pFirstPortionFont ) +{ +} + +void CellBlock::fillUnusedCells( sal_Int32 nIndex ) +{ + if( mnFirstFreeIndex < nIndex ) + { + Any* pCellEnd = mpCurrCellRow + nIndex; + for( Any* pCell = mpCurrCellRow + mnFirstFreeIndex; pCell < pCellEnd; ++pCell ) + *pCell <<= OUString(); + } +} + +// ============================================================================ + +CellBlockBuffer::CellBlockBuffer( const WorksheetHelper& rHelper ) : + WorksheetHelper( rHelper ), + mnCurrRow( -1 ) +{ + maCellBlockIt = maCellBlocks.end(); +} + +void CellBlockBuffer::setColSpans( sal_Int32 nRow, const ValueRangeSet& rColSpans ) +{ + OSL_ENSURE( maColSpans.count( nRow ) == 0, "CellBlockBuffer::setColSpans - multiple column spans for the same row" ); + OSL_ENSURE( (mnCurrRow < nRow) && (maColSpans.empty() || (maColSpans.rbegin()->first < nRow)), "CellBlockBuffer::setColSpans - rows are unsorted" ); + if( (mnCurrRow < nRow) && (maColSpans.count( nRow ) == 0) ) + maColSpans[ nRow ] = rColSpans.getRanges(); +} + +CellBlock* CellBlockBuffer::getCellBlock( const CellAddress& rCellAddr ) +{ + OSL_ENSURE( rCellAddr.Row >= mnCurrRow, "CellBlockBuffer::getCellBlock - passed row out of order" ); + // prepare cell blocks, if row changes + if( rCellAddr.Row != mnCurrRow ) + { + // find colspans for the new row + ColSpanVectorMap::iterator aIt = maColSpans.find( rCellAddr.Row ); + + /* Gap between rows, or rows out of order, or no colspan + information for the new row found: flush all open cell blocks. */ + if( (aIt == maColSpans.end()) || (rCellAddr.Row != mnCurrRow + 1) ) + { + finalizeImport(); + maCellBlocks.clear(); + maCellBlockIt = maCellBlocks.end(); + } + + /* Prepare matching cell blocks, create new cell blocks, finalize + unmatching cell blocks, if colspan information is available. */ + if( aIt != maColSpans.end() ) + { + /* The colspan vector aIt points to is sorted by columns, as well + as the cell block map. In the folloing, this vector and the + list of cell blocks can be iterated simultanously. */ + CellBlockMap::iterator aMIt = maCellBlocks.begin(); + const ValueRangeVector& rColRanges = aIt->second; + for( ValueRangeVector::const_iterator aVIt = rColRanges.begin(), aVEnd = rColRanges.end(); aVIt != aVEnd; ++aVIt, ++aMIt ) + { + const ValueRange& rColSpan = *aVIt; + /* Finalize and remove all cell blocks up to end of the column + range (cell blocks are keyed by end column index). + CellBlock::isBefore() returns true, if the end index of the + passed colspan is greater than the column end index of the + cell block, or if the passed range has the same end index + but the start indexes do not match. */ + while( (aMIt != maCellBlocks.end()) && aMIt->second->isBefore( rColSpan ) ) + { + aMIt->second->finalizeImport(); + maCellBlocks.erase( aMIt++ ); + } + /* If the current cell block (aMIt) fits to the colspan, start + a new row there, otherwise create and insert a new cell block. */ + if( (aMIt != maCellBlocks.end()) && aMIt->second->isExpandable( rColSpan ) ) + aMIt->second->startNextRow(); + else + aMIt = maCellBlocks.insert( aMIt, CellBlockMap::value_type( rColSpan.mnLast, + CellBlockMap::mapped_type( new CellBlock( *this, rColSpan, rCellAddr.Row ) ) ) ); + } + // finalize and remove all remaining cell blocks + CellBlockMap::iterator aMEnd = maCellBlocks.end(); + for( CellBlockMap::iterator aMIt2 = aMIt; aMIt2 != aMEnd; ++aMIt2 ) + aMIt2->second->finalizeImport(); + maCellBlocks.erase( aMIt, aMEnd ); + + // remove cached colspan information (including current one aIt points to) + maColSpans.erase( maColSpans.begin(), ++aIt ); + } + maCellBlockIt = maCellBlocks.begin(); + mnCurrRow = rCellAddr.Row; + } + + // try to find a valid cell block (update maCellBlockIt) + if( ((maCellBlockIt != maCellBlocks.end()) && maCellBlockIt->second->contains( rCellAddr.Column )) || + (((maCellBlockIt = maCellBlocks.lower_bound( rCellAddr.Column )) != maCellBlocks.end()) && maCellBlockIt->second->contains( rCellAddr.Column )) ) + { + // maCellBlockIt points to valid cell block + return maCellBlockIt->second.get(); + } + + // no valid cell block found + return 0; +} + +void CellBlockBuffer::finalizeImport() +{ + maCellBlocks.forEachMem( &CellBlock::finalizeImport ); +} + +// ============================================================================ + SheetDataBuffer::SheetDataBuffer( const WorksheetHelper& rHelper ) : WorksheetHelper( rHelper ), + maCellBlocks( rHelper ), mbPendingSharedFmla( false ) { } -void SheetDataBuffer::setValueCell( const CellAddress& rCellAddr, double fValue ) +void SheetDataBuffer::setColSpans( sal_Int32 nRow, const ValueRangeSet& rColSpans ) { - Reference< XCell > xCell = getCell( rCellAddr ); - OSL_ENSURE( xCell.is(), "SheetDataBuffer::setValueCell - missing cell interface" ); - if( xCell.is() ) - xCell->setValue( fValue ); + maCellBlocks.setColSpans( nRow, rColSpans ); } -void SheetDataBuffer::setStringCell( const CellAddress& rCellAddr, const OUString& rText ) +void SheetDataBuffer::setBlankCell( const CellModel& rModel ) { - Reference< XText > xText( getCell( rCellAddr ), UNO_QUERY ); - OSL_ENSURE( xText.is(), "SheetDataBuffer::setStringCell - missing text interface" ); - if( xText.is() ) - xText->setString( rText ); + setCellFormat( rModel ); } -void SheetDataBuffer::setStringCell( const CellAddress& rCellAddr, const RichString& rString, sal_Int32 nXfId ) +void SheetDataBuffer::setValueCell( const CellModel& rModel, double fValue ) { - Reference< XText > xText( getCell( rCellAddr ), UNO_QUERY ); - OSL_ENSURE( xText.is(), "SheetDataBuffer::setStringCell - missing text interface" ); - rString.convert( xText, nXfId ); - (void)rString; - (void)nXfId; + if( CellBlock* pCellBlock = maCellBlocks.getCellBlock( rModel.maCellAddr ) ) + pCellBlock->getCellAny( rModel.maCellAddr.Column ) <<= fValue; + else + putValue( rModel.maCellAddr, fValue ); + setCellFormat( rModel ); } -void SheetDataBuffer::setStringCell( const CellAddress& rCellAddr, sal_Int32 nStringId, sal_Int32 nXfId ) +void SheetDataBuffer::setStringCell( const CellModel& rModel, const OUString& rText ) { - Reference< XText > xText( getCell( rCellAddr ), UNO_QUERY ); - OSL_ENSURE( xText.is(), "SheetDataBuffer::setStringCell - missing text interface" ); - getSharedStrings().convertString( xText, nStringId, nXfId ); - (void)nStringId; - (void)nXfId; + if( CellBlock* pCellBlock = maCellBlocks.getCellBlock( rModel.maCellAddr ) ) + pCellBlock->getCellAny( rModel.maCellAddr.Column ) <<= rText; + else + putString( rModel.maCellAddr, rText ); + setCellFormat( rModel ); } -void SheetDataBuffer::setDateTimeCell( const CellAddress& rCellAddr, const DateTime& rDateTime ) +void SheetDataBuffer::setStringCell( const CellModel& rModel, const RichStringRef& rxString ) +{ + OSL_ENSURE( rxString.get(), "SheetDataBuffer::setStringCell - missing rich string object" ); + const Font* pFirstPortionFont = getStyles().getFontFromCellXf( rModel.mnXfId ).get(); + OUString aText; + if( rxString->extractPlainString( aText, pFirstPortionFont ) ) + { + setStringCell( rModel, aText ); + } + else + { + if( CellBlock* pCellBlock = maCellBlocks.getCellBlock( rModel.maCellAddr ) ) + pCellBlock->insertRichString( rModel.maCellAddr, rxString, pFirstPortionFont ); + else + putRichString( rModel.maCellAddr, *rxString, pFirstPortionFont ); + setCellFormat( rModel ); + } +} + +void SheetDataBuffer::setStringCell( const CellModel& rModel, sal_Int32 nStringId ) +{ + RichStringRef xString = getSharedStrings().getString( nStringId ); + if( xString.get() ) + setStringCell( rModel, xString ); + else + setBlankCell( rModel ); +} + +void SheetDataBuffer::setDateTimeCell( const CellModel& rModel, const DateTime& rDateTime ) { // write serial date/time value into the cell double fSerial = getUnitConverter().calcSerialFromDateTime( rDateTime ); - setValueCell( rCellAddr, fSerial ); + setValueCell( rModel, fSerial ); // set appropriate number format using namespace ::com::sun::star::util::NumberFormat; sal_Int16 nStdFmt = (fSerial < 1.0) ? TIME : (((rDateTime.Hours > 0) || (rDateTime.Minutes > 0) || (rDateTime.Seconds > 0)) ? DATETIME : DATE); - setStandardNumFmt( rCellAddr, nStdFmt ); + setStandardNumFmt( rModel.maCellAddr, nStdFmt ); } -void SheetDataBuffer::setBooleanCell( const CellAddress& rCellAddr, bool bValue ) +void SheetDataBuffer::setBooleanCell( const CellModel& rModel, bool bValue ) { - setFormulaCell( rCellAddr, getFormulaParser().convertBoolToFormula( bValue ) ); + setCellFormula( rModel.maCellAddr, getFormulaParser().convertBoolToFormula( bValue ) ); + // #108770# set 'Standard' number format for all Boolean cells + setCellFormat( rModel, 0 ); } -void SheetDataBuffer::setErrorCell( const CellAddress& rCellAddr, const OUString& rErrorCode ) +void SheetDataBuffer::setErrorCell( const CellModel& rModel, const OUString& rErrorCode ) { - setErrorCell( rCellAddr, getUnitConverter().calcBiffErrorCode( rErrorCode ) ); + setErrorCell( rModel, getUnitConverter().calcBiffErrorCode( rErrorCode ) ); } -void SheetDataBuffer::setErrorCell( const CellAddress& rCellAddr, sal_uInt8 nErrorCode ) +void SheetDataBuffer::setErrorCell( const CellModel& rModel, sal_uInt8 nErrorCode ) { - setFormulaCell( rCellAddr, getFormulaParser().convertErrorToFormula( nErrorCode ) ); + setCellFormula( rModel.maCellAddr, getFormulaParser().convertErrorToFormula( nErrorCode ) ); + setCellFormat( rModel ); } -void SheetDataBuffer::setFormulaCell( const CellAddress& rCellAddr, const ApiTokenSequence& rTokens ) +void SheetDataBuffer::setFormulaCell( const CellModel& rModel, const ApiTokenSequence& rTokens ) { mbPendingSharedFmla = false; ApiTokenSequence aTokens; @@ -208,7 +441,7 @@ void SheetDataBuffer::setFormulaCell( const CellAddress& rCellAddr, const ApiTok aTokens = resolveSharedFormula( aBaseAddr ); if( !aTokens.hasElements() ) { - maSharedFmlaAddr = rCellAddr; + maSharedFmlaAddr = rModel.maCellAddr; maSharedBaseAddr = aBaseAddr; mbPendingSharedFmla = true; } @@ -220,18 +453,14 @@ void SheetDataBuffer::setFormulaCell( const CellAddress& rCellAddr, const ApiTok aTokens = rTokens; } - if( aTokens.hasElements() ) - { - Reference< XFormulaTokens > xTokens( getCell( rCellAddr ), UNO_QUERY ); - OSL_ENSURE( xTokens.is(), "SheetDataBuffer::setFormulaCell - missing formula interface" ); - if( xTokens.is() ) - xTokens->setTokens( aTokens ); - } + setCellFormula( rModel.maCellAddr, aTokens ); + setCellFormat( rModel ); } -void SheetDataBuffer::setFormulaCell( const CellAddress& rCellAddr, sal_Int32 nSharedId ) +void SheetDataBuffer::setFormulaCell( const CellModel& rModel, sal_Int32 nSharedId ) { - setFormulaCell( rCellAddr, resolveSharedFormula( BinAddress( nSharedId, 0 ) ) ); + setCellFormula( rModel.maCellAddr, resolveSharedFormula( BinAddress( nSharedId, 0 ) ) ); + setCellFormat( rModel ); } void SheetDataBuffer::createArrayFormula( const CellRangeAddress& rRange, const ApiTokenSequence& rTokens ) @@ -260,73 +489,23 @@ void SheetDataBuffer::createSharedFormula( const CellAddress& rCellAddr, const A createSharedFormula( BinAddress( rCellAddr ), rTokens ); } -void SheetDataBuffer::setRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId, bool bCustomFormat ) +void SheetDataBuffer::setRowFormat( sal_Int32 nRow, sal_Int32 nXfId, bool bCustomFormat ) { // set row formatting if( bCustomFormat ) { // try to expand cached row range, if formatting is equal - if( (maXfIdRowRange.mnLastRow < 0) || !maXfIdRowRange.tryExpand( nFirstRow, nLastRow, nXfId ) ) + if( (maXfIdRowRange.maRowRange.mnLast < 0) || !maXfIdRowRange.tryExpand( nRow, nXfId ) ) { writeXfIdRowRangeProperties( maXfIdRowRange ); - maXfIdRowRange.set( nFirstRow, nLastRow, nXfId ); + maXfIdRowRange.set( nRow, nXfId ); } } - else if( maXfIdRowRange.mnLastRow >= 0 ) + else if( maXfIdRowRange.maRowRange.mnLast >= 0 ) { // finish last cached row range writeXfIdRowRangeProperties( maXfIdRowRange ); - maXfIdRowRange.set( -1, -1, -1 ); - } -} - -void SheetDataBuffer::setCellFormat( const CellModel& rModel, sal_Int32 nNumFmtId ) -{ - if( (rModel.mnXfId >= 0) || (nNumFmtId >= 0) ) - { - // try to merge existing ranges and to write some formatting properties - if( !maXfIdRanges.empty() ) - { - // get row index of last inserted cell - sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow; - // row changed - try to merge ranges of last row with existing ranges - if( rModel.maCellAddr.Row != nLastRow ) - { - mergeXfIdRanges(); - // write format properties of all ranges above last row and remove them - XfIdRangeMap::iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); - while( aIt != aEnd ) - { - // check that range cannot be merged with current row, and that range is not in cached row range - if( (aIt->second.maRange.EndRow < nLastRow) && !maXfIdRowRange.intersects( aIt->second.maRange ) ) - { - writeXfIdRangeProperties( aIt->second ); - maXfIdRanges.erase( aIt++ ); - } - else - ++aIt; - } - } - } - - // try to expand last existing range, or create new range entry - if( maXfIdRanges.empty() || !maXfIdRanges.rbegin()->second.tryExpand( rModel, nNumFmtId ) ) - maXfIdRanges[ BinAddress( rModel.maCellAddr ) ].set( rModel, nNumFmtId ); - - // update merged ranges for 'center across selection' and 'fill' - if( const Xf* pXf = getStyles().getCellXf( rModel.mnXfId ).get() ) - { - sal_Int32 nHorAlign = pXf->getAlignment().getModel().mnHorAlign; - if( (nHorAlign == XML_centerContinuous) || (nHorAlign == XML_fill) ) - { - /* start new merged range, if cell is not empty (#108781#), - or try to expand last range with empty cell */ - if( rModel.mnCellType != XML_TOKEN_INVALID ) - maCenterFillRanges.push_back( MergedRange( rModel.maCellAddr, nHorAlign ) ); - else if( !maCenterFillRanges.empty() ) - maCenterFillRanges.rbegin()->tryExpand( rModel.maCellAddr, nHorAlign ); - } - } + maXfIdRowRange.set( -1, -1 ); } } @@ -352,6 +531,9 @@ void SheetDataBuffer::setStandardNumFmt( const CellAddress& rCellAddr, sal_Int16 void SheetDataBuffer::finalizeImport() { + // insert all cells of all open cell blocks + maCellBlocks.finalizeImport(); + // create all array formulas for( ArrayFormulaList::iterator aIt = maArrayFormulas.begin(), aEnd = maArrayFormulas.end(); aIt != aEnd; ++aIt ) finalizeArrayFormula( aIt->first, aIt->second ); @@ -379,57 +561,55 @@ void SheetDataBuffer::finalizeImport() // private -------------------------------------------------------------------- SheetDataBuffer::XfIdRowRange::XfIdRowRange() : - mnFirstRow( -1 ), - mnLastRow( -1 ), + maRowRange( -1 ), mnXfId( -1 ) { } bool SheetDataBuffer::XfIdRowRange::intersects( const CellRangeAddress& rRange ) const { - return (rRange.StartRow <= mnLastRow) && (mnFirstRow <= rRange.EndRow); + return (rRange.StartRow <= maRowRange.mnLast) && (maRowRange.mnFirst <= rRange.EndRow); } -void SheetDataBuffer::XfIdRowRange::set( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) +void SheetDataBuffer::XfIdRowRange::set( sal_Int32 nRow, sal_Int32 nXfId ) { - mnFirstRow = nFirstRow; - mnLastRow = nLastRow; + maRowRange = ValueRange( nRow ); mnXfId = nXfId; } -bool SheetDataBuffer::XfIdRowRange::tryExpand( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) +bool SheetDataBuffer::XfIdRowRange::tryExpand( sal_Int32 nRow, sal_Int32 nXfId ) { if( mnXfId == nXfId ) { - if( mnLastRow + 1 == nFirstRow ) + if( maRowRange.mnLast + 1 == nRow ) { - mnLastRow = nLastRow; + ++maRowRange.mnLast; return true; } - if( mnFirstRow == nLastRow + 1 ) + if( maRowRange.mnFirst == nRow + 1 ) { - mnFirstRow = nFirstRow; + --maRowRange.mnFirst; return true; } } return false; } -void SheetDataBuffer::XfIdRange::set( const CellModel& rModel, sal_Int32 nNumFmtId ) +void SheetDataBuffer::XfIdRange::set( const CellAddress& rCellAddr, sal_Int32 nXfId, sal_Int32 nNumFmtId ) { - maRange.Sheet = rModel.maCellAddr.Sheet; - maRange.StartColumn = maRange.EndColumn = rModel.maCellAddr.Column; - maRange.StartRow = maRange.EndRow = rModel.maCellAddr.Row; - mnXfId = rModel.mnXfId; + maRange.Sheet = rCellAddr.Sheet; + maRange.StartColumn = maRange.EndColumn = rCellAddr.Column; + maRange.StartRow = maRange.EndRow = rCellAddr.Row; + mnXfId = nXfId; mnNumFmtId = nNumFmtId; } -bool SheetDataBuffer::XfIdRange::tryExpand( const CellModel& rModel, sal_Int32 nNumFmtId ) +bool SheetDataBuffer::XfIdRange::tryExpand( const CellAddress& rCellAddr, sal_Int32 nXfId, sal_Int32 nNumFmtId ) { - if( (mnXfId == rModel.mnXfId) && (mnNumFmtId == nNumFmtId) && - (maRange.StartRow == rModel.maCellAddr.Row) && - (maRange.EndRow == rModel.maCellAddr.Row) && - (maRange.EndColumn + 1 == rModel.maCellAddr.Column) ) + if( (mnXfId == nXfId) && (mnNumFmtId == nNumFmtId) && + (maRange.StartRow == rCellAddr.Row) && + (maRange.EndRow == rCellAddr.Row) && + (maRange.EndColumn + 1 == rCellAddr.Column) ) { ++maRange.EndColumn; return true; @@ -475,7 +655,58 @@ bool SheetDataBuffer::MergedRange::tryExpand( const CellAddress& rAddress, sal_I return false; } -void SheetDataBuffer::finalizeArrayFormula( const CellRangeAddress& rRange, const ApiTokenSequence& rTokens ) +// ---------------------------------------------------------------------------- + +void SheetDataBuffer::setCellFormula( const CellAddress& rCellAddr, const ApiTokenSequence& rTokens ) +{ + if( rTokens.hasElements() ) + { + if( CellBlock* pCellBlock = maCellBlocks.getCellBlock( rCellAddr ) ) + pCellBlock->getCellAny( rCellAddr.Column ) <<= rTokens; + else + putFormulaTokens( rCellAddr, rTokens ); + } +} + +void SheetDataBuffer::createSharedFormula( const BinAddress& rMapKey, const ApiTokenSequence& rTokens ) +{ + // create the defined name that will represent the shared formula + OUString aName = OUStringBuffer().appendAscii( RTL_CONSTASCII_STRINGPARAM( "__shared_" ) ). + append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) ). + append( sal_Unicode( '_' ) ).append( rMapKey.mnRow ). + append( sal_Unicode( '_' ) ).append( rMapKey.mnCol ).makeStringAndClear(); + Reference< XNamedRange > xNamedRange = createNamedRangeObject( aName ); + OSL_ENSURE( xNamedRange.is(), "SheetDataBuffer::createSharedFormula - cannot create shared formula" ); + PropertySet aNameProps( xNamedRange ); + aNameProps.setProperty( PROP_IsSharedFormula, true ); + + // get and store the token index of the defined name + OSL_ENSURE( maSharedFormulas.count( rMapKey ) == 0, "SheetDataBuffer::createSharedFormula - shared formula exists already" ); + sal_Int32 nTokenIndex = 0; + if( aNameProps.getProperty( nTokenIndex, PROP_TokenIndex ) && (nTokenIndex >= 0) ) try + { + // store the token index in the map + maSharedFormulas[ rMapKey ] = nTokenIndex; + // set the formula definition + Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY_THROW ); + xTokens->setTokens( rTokens ); + // retry to insert a pending shared formula cell + if( mbPendingSharedFmla ) + setCellFormula( maSharedFmlaAddr, resolveSharedFormula( maSharedBaseAddr ) ); + } + catch( Exception& ) + { + } + mbPendingSharedFmla = false; +} + +ApiTokenSequence SheetDataBuffer::resolveSharedFormula( const BinAddress& rMapKey ) const +{ + sal_Int32 nTokenIndex = ContainerHelper::getMapElement( maSharedFormulas, rMapKey, -1 ); + return (nTokenIndex >= 0) ? getFormulaParser().convertNameToFormula( nTokenIndex ) : ApiTokenSequence(); +} + +void SheetDataBuffer::finalizeArrayFormula( const CellRangeAddress& rRange, const ApiTokenSequence& rTokens ) const { Reference< XArrayFormulaTokens > xTokens( getCellRange( rRange ), UNO_QUERY ); OSL_ENSURE( xTokens.is(), "SheetDataBuffer::finalizeArrayFormula - missing formula token interface" ); @@ -483,7 +714,7 @@ void SheetDataBuffer::finalizeArrayFormula( const CellRangeAddress& rRange, cons xTokens->setArrayTokens( rTokens ); } -void SheetDataBuffer::finalizeTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel ) +void SheetDataBuffer::finalizeTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel ) const { sal_Int16 nSheet = getSheetIndex(); bool bOk = false; @@ -551,53 +782,62 @@ void SheetDataBuffer::finalizeTableOperation( const CellRangeAddress& rRange, co } } -void SheetDataBuffer::createSharedFormula( const BinAddress& rMapKey, const ApiTokenSequence& rTokens ) +void SheetDataBuffer::setCellFormat( const CellModel& rModel, sal_Int32 nNumFmtId ) { - // create the defined name that will represent the shared formula - OUString aName = OUStringBuffer().appendAscii( RTL_CONSTASCII_STRINGPARAM( "__shared_" ) ). - append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) ). - append( sal_Unicode( '_' ) ).append( rMapKey.mnRow ). - append( sal_Unicode( '_' ) ).append( rMapKey.mnCol ).makeStringAndClear(); - Reference< XNamedRange > xNamedRange = createNamedRangeObject( aName ); - OSL_ENSURE( xNamedRange.is(), "SheetDataBuffer::createSharedFormula - cannot create shared formula" ); - PropertySet aNameProps( xNamedRange ); - aNameProps.setProperty( PROP_IsSharedFormula, true ); - - // get and store the token index of the defined name - OSL_ENSURE( maSharedFormulas.count( rMapKey ) == 0, "SheetDataBuffer::createSharedFormula - shared formula exists already" ); - sal_Int32 nTokenIndex = 0; - if( aNameProps.getProperty( nTokenIndex, PROP_TokenIndex ) && (nTokenIndex >= 0) ) try + if( (rModel.mnXfId >= 0) || (nNumFmtId >= 0) ) { - // store the token index in the map - maSharedFormulas[ rMapKey ] = nTokenIndex; - // set the formula definition - Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY_THROW ); - xTokens->setTokens( rTokens ); - // retry to insert a pending shared formula cell - if( mbPendingSharedFmla ) + // try to merge existing ranges and to write some formatting properties + if( !maXfIdRanges.empty() ) + { + // get row index of last inserted cell + sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow; + // row changed - try to merge ranges of last row with existing ranges + if( rModel.maCellAddr.Row != nLastRow ) + { + mergeXfIdRanges(); + // write format properties of all ranges above last row and remove them + XfIdRangeMap::iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); + while( aIt != aEnd ) + { + // check that range cannot be merged with current row, and that range is not in cached row range + if( (aIt->second.maRange.EndRow < nLastRow) && !maXfIdRowRange.intersects( aIt->second.maRange ) ) + { + writeXfIdRangeProperties( aIt->second ); + maXfIdRanges.erase( aIt++ ); + } + else + ++aIt; + } + } + } + + // try to expand last existing range, or create new range entry + if( maXfIdRanges.empty() || !maXfIdRanges.rbegin()->second.tryExpand( rModel.maCellAddr, rModel.mnXfId, nNumFmtId ) ) + maXfIdRanges[ BinAddress( rModel.maCellAddr ) ].set( rModel.maCellAddr, rModel.mnXfId, nNumFmtId ); + + // update merged ranges for 'center across selection' and 'fill' + if( const Xf* pXf = getStyles().getCellXf( rModel.mnXfId ).get() ) { - ApiTokenSequence aTokens = resolveSharedFormula( maSharedBaseAddr ); - setFormulaCell( maSharedFmlaAddr, aTokens ); + sal_Int32 nHorAlign = pXf->getAlignment().getModel().mnHorAlign; + if( (nHorAlign == XML_centerContinuous) || (nHorAlign == XML_fill) ) + { + /* start new merged range, if cell is not empty (#108781#), + or try to expand last range with empty cell */ + if( rModel.mnCellType != XML_TOKEN_INVALID ) + maCenterFillRanges.push_back( MergedRange( rModel.maCellAddr, nHorAlign ) ); + else if( !maCenterFillRanges.empty() ) + maCenterFillRanges.rbegin()->tryExpand( rModel.maCellAddr, nHorAlign ); + } } } - catch( Exception& ) - { - } - mbPendingSharedFmla = false; -} - -ApiTokenSequence SheetDataBuffer::resolveSharedFormula( const BinAddress& rMapKey ) const -{ - sal_Int32 nTokenIndex = ContainerHelper::getMapElement( maSharedFormulas, rMapKey, -1 ); - return (nTokenIndex >= 0) ? getFormulaParser().convertNameToFormula( nTokenIndex ) : ApiTokenSequence(); } void SheetDataBuffer::writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const { - if( (rXfIdRowRange.mnLastRow >= 0) && (rXfIdRowRange.mnXfId >= 0) ) + if( (rXfIdRowRange.maRowRange.mnLast >= 0) && (rXfIdRowRange.mnXfId >= 0) ) { AddressConverter& rAddrConv = getAddressConverter(); - CellRangeAddress aRange( getSheetIndex(), 0, rXfIdRowRange.mnFirstRow, rAddrConv.getMaxApiAddress().Column, rXfIdRowRange.mnLastRow ); + CellRangeAddress aRange( getSheetIndex(), 0, rXfIdRowRange.maRowRange.mnFirst, rAddrConv.getMaxApiAddress().Column, rXfIdRowRange.maRowRange.mnLast ); if( rAddrConv.validateCellRange( aRange, true, false ) ) { PropertySet aPropSet( getCellRange( aRange ) ); diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx index 63db3286cff6..00c4e21d82e7 100644 --- a/oox/source/xls/sheetdatacontext.cxx +++ b/oox/source/xls/sheetdatacontext.cxx @@ -176,23 +176,30 @@ void SheetDataContext::onEndElement() if( mbHasFormula ) switch( maFmlaData.mnFormulaType ) { case XML_normal: - mrSheetData.setFormulaCell( maCellData.maCellAddr, maTokens ); + mrSheetData.setFormulaCell( maCellData, maTokens ); break; case XML_shared: if( maFmlaData.mnSharedId >= 0 ) { if( mbValidRange && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) ) mrSheetData.createSharedFormula( maFmlaData.mnSharedId, maTokens ); - mrSheetData.setFormulaCell( maCellData.maCellAddr, maFmlaData.mnSharedId ); + mrSheetData.setFormulaCell( maCellData, maFmlaData.mnSharedId ); } + else + // no success, set plain cell value and formatting below + mbHasFormula = false; break; case XML_array: if( mbValidRange && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) ) mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, maTokens ); + // set cell formatting, but do not set result as cell value + mrSheetData.setBlankCell( maCellData ); break; case XML_dataTable: if( mbValidRange ) mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData ); + // set cell formatting, but do not set result as cell value + mrSheetData.setBlankCell( maCellData ); break; default: OSL_ENSURE( maFmlaData.mnFormulaType == XML_TOKEN_INVALID, "SheetDataContext::onEndElement - unknown formula type" ); @@ -205,38 +212,33 @@ void SheetDataContext::onEndElement() if( maCellValue.getLength() > 0 ) switch( maCellData.mnCellType ) { case XML_n: - mrSheetData.setValueCell( maCellData.maCellAddr, maCellValue.toDouble() ); + mrSheetData.setValueCell( maCellData, maCellValue.toDouble() ); break; case XML_b: - mrSheetData.setBooleanCell( maCellData.maCellAddr, maCellValue.toDouble() != 0.0 ); + mrSheetData.setBooleanCell( maCellData, maCellValue.toDouble() != 0.0 ); break; case XML_e: - mrSheetData.setErrorCell( maCellData.maCellAddr, maCellValue ); + mrSheetData.setErrorCell( maCellData, maCellValue ); break; case XML_str: - mrSheetData.setStringCell( maCellData.maCellAddr, maCellValue ); + mrSheetData.setStringCell( maCellData, maCellValue ); break; case XML_s: - mrSheetData.setStringCell( maCellData.maCellAddr, maCellValue.toInt32(), maCellData.mnXfId ); + mrSheetData.setStringCell( maCellData, maCellValue.toInt32() ); break; } else if( (maCellData.mnCellType == XML_inlineStr) && mxInlineStr.get() ) { mxInlineStr->finalizeImport(); - mrSheetData.setStringCell( maCellData.maCellAddr, *mxInlineStr, maCellData.mnXfId ); + mrSheetData.setStringCell( maCellData, mxInlineStr ); } else { // empty cell, update cell type maCellData.mnCellType = XML_TOKEN_INVALID; + mrSheetData.setBlankCell( maCellData ); } } - - // #108770# set 'Standard' number format for all Boolean cells - bool bBoolCell = !mbHasFormula && (maCellData.mnCellType == XML_b); - sal_Int32 nNumFmtId = bBoolCell ? 0 : -1; - // store the cell formatting data - mrSheetData.setCellFormat( maCellData, nNumFmtId ); } } @@ -285,7 +287,7 @@ ContextHandlerRef SheetDataContext::onCreateRecordContext( sal_Int32 nRecId, Seq void SheetDataContext::importRow( const AttributeList& rAttribs ) { RowModel aModel; - aModel.mnFirstRow = aModel.mnLastRow = rAttribs.getInteger( XML_r, -1 ); + aModel.mnRow = rAttribs.getInteger( XML_r, -1 ); aModel.mfHeight = rAttribs.getDouble( XML_ht, -1.0 ); aModel.mnXfId = rAttribs.getInteger( XML_s, -1 ); aModel.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 ); @@ -296,6 +298,23 @@ void SheetDataContext::importRow( const AttributeList& rAttribs ) aModel.mbCollapsed = rAttribs.getBool( XML_collapsed, false ); aModel.mbThickTop = rAttribs.getBool( XML_thickTop, false ); aModel.mbThickBottom = rAttribs.getBool( XML_thickBot, false ); + + // decode the column spans (space-separated list of colon-separated integer pairs) + OUString aColSpansText = rAttribs.getString( XML_spans, OUString() ); + sal_Int32 nMaxCol = mrAddressConv.getMaxApiAddress().Column; + sal_Int32 nIndex = 0; + while( nIndex >= 0 ) + { + OUString aColSpanToken = aColSpansText.getToken( 0, ' ', nIndex ); + sal_Int32 nSepPos = aColSpanToken.indexOf( ':' ); + if( (0 < nSepPos) && (nSepPos + 1 < aColSpanToken.getLength()) ) + { + // OOXML uses 1-based integer column indexes, row model expects 0-based colspans + sal_Int32 nLastCol = ::std::min( aColSpanToken.copy( nSepPos + 1 ).toInt32() - 1, nMaxCol ); + aModel.insertColSpan( ValueRange( aColSpanToken.copy( 0, nSepPos ).toInt32() - 1, nLastCol ) ); + } + } + // set row properties in the current sheet setRowModel( aModel ); } @@ -345,12 +364,14 @@ void SheetDataContext::importFormula( const AttributeList& rAttribs ) void SheetDataContext::importRow( SequenceInputStream& rStrm ) { RowModel aModel; + sal_Int32 nSpanCount; sal_uInt16 nHeight, nFlags1; sal_uInt8 nFlags2; - rStrm >> maCurrPos.mnRow >> aModel.mnXfId >> nHeight >> nFlags1 >> nFlags2; + rStrm >> maCurrPos.mnRow >> aModel.mnXfId >> nHeight >> nFlags1 >> nFlags2 >> nSpanCount; + maCurrPos.mnCol = 0; // row index is 0-based in BIFF12, but RowModel expects 1-based - aModel.mnFirstRow = aModel.mnLastRow = maCurrPos.mnRow + 1; + aModel.mnRow = maCurrPos.mnRow + 1; // row height is in twips in BIFF12, convert to points aModel.mfHeight = nHeight / 20.0; aModel.mnLevel = extractValue< sal_Int32 >( nFlags1, 8, 3 ); @@ -361,6 +382,16 @@ void SheetDataContext::importRow( SequenceInputStream& rStrm ) aModel.mbCollapsed = getFlag( nFlags1, BIFF12_ROW_COLLAPSED ); aModel.mbThickTop = getFlag( nFlags1, BIFF12_ROW_THICKTOP ); aModel.mbThickBottom = getFlag( nFlags1, BIFF12_ROW_THICKBOTTOM ); + + // read the column spans + sal_Int32 nMaxCol = mrAddressConv.getMaxApiAddress().Column; + for( sal_Int32 nSpanIdx = 0; (nSpanIdx < nSpanCount) && !rStrm.isEof(); ++nSpanIdx ) + { + sal_Int32 nFirstCol, nLastCol; + rStrm >> nFirstCol >> nLastCol; + aModel.insertColSpan( ValueRange( nFirstCol, ::std::min( nLastCol, nMaxCol ) ) ); + } + // set row properties in the current sheet setRowModel( aModel ); } @@ -407,12 +438,9 @@ void SheetDataContext::importCellBool( SequenceInputStream& rStrm, CellType eCel maCellData.mnCellType = XML_b; bool bValue = rStrm.readuInt8() != 0; if( eCellType == CELLTYPE_FORMULA ) - mrSheetData.setFormulaCell( maCellData.maCellAddr, readCellFormula( rStrm ) ); + mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) ); else - mrSheetData.setBooleanCell( maCellData.maCellAddr, bValue ); - // #108770# set 'Standard' number format for all Boolean cells - sal_Int32 nNumFmtId = (eCellType != CELLTYPE_FORMULA) ? 0 : -1; - mrSheetData.setCellFormat( maCellData, nNumFmtId ); + mrSheetData.setBooleanCell( maCellData, bValue ); } } @@ -420,7 +448,7 @@ void SheetDataContext::importCellBlank( SequenceInputStream& rStrm, CellType eCe { OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellBlank - no formula cells supported" ); if( readCellHeader( rStrm, eCellType ) ) - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setBlankCell( maCellData ); } void SheetDataContext::importCellDouble( SequenceInputStream& rStrm, CellType eCellType ) @@ -430,10 +458,9 @@ void SheetDataContext::importCellDouble( SequenceInputStream& rStrm, CellType eC maCellData.mnCellType = XML_n; double fValue = rStrm.readDouble(); if( eCellType == CELLTYPE_FORMULA ) - mrSheetData.setFormulaCell( maCellData.maCellAddr, readCellFormula( rStrm ) ); + mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) ); else - mrSheetData.setValueCell( maCellData.maCellAddr, fValue ); - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setValueCell( maCellData, fValue ); } } @@ -444,10 +471,9 @@ void SheetDataContext::importCellError( SequenceInputStream& rStrm, CellType eCe maCellData.mnCellType = XML_e; sal_uInt8 nErrorCode = rStrm.readuInt8(); if( eCellType == CELLTYPE_FORMULA ) - mrSheetData.setFormulaCell( maCellData.maCellAddr, readCellFormula( rStrm ) ); + mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) ); else - mrSheetData.setErrorCell( maCellData.maCellAddr, nErrorCode ); - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setErrorCell( maCellData, nErrorCode ); } } @@ -457,8 +483,7 @@ void SheetDataContext::importCellRk( SequenceInputStream& rStrm, CellType eCellT if( readCellHeader( rStrm, eCellType ) ) { maCellData.mnCellType = XML_n; - mrSheetData.setValueCell( maCellData.maCellAddr, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setValueCell( maCellData, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); } } @@ -468,11 +493,10 @@ void SheetDataContext::importCellRString( SequenceInputStream& rStrm, CellType e if( readCellHeader( rStrm, eCellType ) ) { maCellData.mnCellType = XML_inlineStr; - RichString aString( *this ); - aString.importString( rStrm, true ); - aString.finalizeImport(); - mrSheetData.setStringCell( maCellData.maCellAddr, aString, maCellData.mnXfId ); - mrSheetData.setCellFormat( maCellData ); + RichStringRef xString( new RichString( *this ) ); + xString->importString( rStrm, true ); + xString->finalizeImport(); + mrSheetData.setStringCell( maCellData, xString ); } } @@ -482,8 +506,7 @@ void SheetDataContext::importCellSi( SequenceInputStream& rStrm, CellType eCellT if( readCellHeader( rStrm, eCellType ) ) { maCellData.mnCellType = XML_s; - mrSheetData.setStringCell( maCellData.maCellAddr, rStrm.readInt32(), maCellData.mnXfId ); - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setStringCell( maCellData, rStrm.readInt32() ); } } @@ -493,14 +516,13 @@ void SheetDataContext::importCellString( SequenceInputStream& rStrm, CellType eC { maCellData.mnCellType = XML_inlineStr; // always import the string, stream will point to formula afterwards, if existing - RichString aString( *this ); - aString.importString( rStrm, false ); - aString.finalizeImport(); + RichStringRef xString( new RichString( *this ) ); + xString->importString( rStrm, false ); + xString->finalizeImport(); if( eCellType == CELLTYPE_FORMULA ) - mrSheetData.setFormulaCell( maCellData.maCellAddr, readCellFormula( rStrm ) ); + mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) ); else - mrSheetData.setStringCell( maCellData.maCellAddr, aString, maCellData.mnXfId ); - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setStringCell( maCellData, xString ); } } @@ -656,10 +678,8 @@ void BiffSheetDataContext::importRecord( BiffInputStream& rStrm ) void BiffSheetDataContext::importRow( BiffInputStream& rStrm ) { RowModel aModel; - sal_uInt16 nRow, nHeight; - rStrm >> nRow; - rStrm.skip( 4 ); - rStrm >> nHeight; + sal_uInt16 nRow, nFirstUsedCol, nFirstFreeCol, nHeight; + rStrm >> nRow >> nFirstUsedCol >> nFirstFreeCol >> nHeight; if( getBiff() == BIFF2 ) { rStrm.skip( 2 ); @@ -686,14 +706,21 @@ void BiffSheetDataContext::importRow( BiffInputStream& rStrm ) } // row index is 0-based in BIFF, but RowModel expects 1-based - aModel.mnFirstRow = aModel.mnLastRow = nRow + 1; + aModel.mnRow = static_cast< sal_Int32 >( nRow ) + 1; // row height is in twips in BIFF, convert to points aModel.mfHeight = (nHeight & BIFF_ROW_HEIGHTMASK) / 20.0; + // set column spans + if( nFirstUsedCol < nFirstFreeCol ) + { + sal_Int32 nLastCol = ::std::min< sal_Int32 >( nFirstFreeCol - 1, mrAddressConv.getMaxApiAddress().Column ); + aModel.insertColSpan( ValueRange( nFirstUsedCol, nLastCol ) ); + } + // set row properties in the current sheet setRowModel( aModel ); } -bool BiffSheetDataContext::readCellXfId( const BinAddress& rAddr, BiffInputStream& rStrm, bool bBiff2 ) +bool BiffSheetDataContext::readCellXfId( BiffInputStream& rStrm, const BinAddress& rAddr, bool bBiff2 ) { bool bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, rAddr, mnSheet, true ); if( bValidAddr ) @@ -746,7 +773,7 @@ bool BiffSheetDataContext::readCellHeader( BiffInputStream& rStrm, bool bBiff2 ) { BinAddress aAddr; rStrm >> aAddr; - return readCellXfId( aAddr, rStrm, bBiff2 ); + return readCellXfId( rStrm, aAddr, bBiff2 ); } bool BiffSheetDataContext::readFormulaRef( BiffInputStream& rStrm ) @@ -759,7 +786,7 @@ bool BiffSheetDataContext::readFormulaRef( BiffInputStream& rStrm ) void BiffSheetDataContext::importBlank( BiffInputStream& rStrm ) { if( readCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BLANK ) ) - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setBlankCell( maCellData ); } void BiffSheetDataContext::importBoolErr( BiffInputStream& rStrm ) @@ -772,18 +799,17 @@ void BiffSheetDataContext::importBoolErr( BiffInputStream& rStrm ) { case BIFF_BOOLERR_BOOL: maCellData.mnCellType = XML_b; - mrSheetData.setBooleanCell( maCellData.maCellAddr, nValue != 0 ); + mrSheetData.setBooleanCell( maCellData, nValue != 0 ); break; case BIFF_BOOLERR_ERROR: maCellData.mnCellType = XML_e; - mrSheetData.setErrorCell( maCellData.maCellAddr, nValue ); + mrSheetData.setErrorCell( maCellData, nValue ); break; default: OSL_ENSURE( false, "BiffSheetDataContext::importBoolErr - unknown cell type" ); + maCellData.mnCellType = XML_TOKEN_INVALID; + mrSheetData.setBlankCell( maCellData ); } - // #108770# set 'Standard' number format for all Boolean cells - sal_Int32 nNumFmtId = (nType == BIFF_BOOLERR_BOOL) ? 0 : -1; - mrSheetData.setCellFormat( maCellData, nNumFmtId ); } } @@ -794,8 +820,7 @@ void BiffSheetDataContext::importFormula( BiffInputStream& rStrm ) maCellData.mnCellType = XML_n; rStrm.skip( mnFormulaSkipSize ); ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_CELL, rStrm ); - mrSheetData.setFormulaCell( maCellData.maCellAddr, aTokens ); - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setFormulaCell( maCellData, aTokens ); } } @@ -804,8 +829,7 @@ void BiffSheetDataContext::importInteger( BiffInputStream& rStrm ) if( readCellHeader( rStrm, true ) ) { maCellData.mnCellType = XML_n; - mrSheetData.setValueCell( maCellData.maCellAddr, rStrm.readuInt16() ); - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setValueCell( maCellData, rStrm.readuInt16() ); } } @@ -822,10 +846,13 @@ void BiffSheetDataContext::importLabel( BiffInputStream& rStrm ) if( readCellHeader( rStrm, bBiff2Xf ) ) { maCellData.mnCellType = XML_inlineStr; - RichString aString( *this ); if( getBiff() == BIFF8 ) { - aString.importUniString( rStrm ); + // string may contain rich-text formatting + RichStringRef xString( new RichString( *this ) ); + xString->importUniString( rStrm ); + xString->finalizeImport(); + mrSheetData.setStringCell( maCellData, xString ); } else { @@ -833,13 +860,24 @@ void BiffSheetDataContext::importLabel( BiffInputStream& rStrm ) rtl_TextEncoding eTextEnc = getTextEncoding(); if( const Font* pFont = getStyles().getFontFromCellXf( maCellData.mnXfId ).get() ) eTextEnc = pFont->getFontEncoding(); - BiffStringFlags nFlags = bBiff2Xf ? BIFF_STR_8BITLENGTH : BIFF_STR_DEFAULT; - setFlag( nFlags, BIFF_STR_EXTRAFONTS, rStrm.getRecId() == BIFF_ID_RSTRING ); - aString.importByteString( rStrm, eTextEnc, nFlags ); + // RSTRING record contains rich-text formatting + if( rStrm.getRecId() == BIFF_ID_RSTRING ) + { + BiffStringFlags nFlags = BIFF_STR_EXTRAFONTS; + // BIFF2 record identifier: 8-bit string length (see above) + setFlag( nFlags, BIFF_STR_8BITLENGTH, bBiff2Xf ); + RichStringRef xString( new RichString( *this ) ); + xString->importByteString( rStrm, eTextEnc, nFlags ); + xString->finalizeImport(); + mrSheetData.setStringCell( maCellData, xString ); + } + else + { + // BIFF2 record identifier: 8-bit string length (see above) + OUString aText = rStrm.readByteStringUC( !bBiff2Xf, eTextEnc ); + mrSheetData.setStringCell( maCellData, aText ); + } } - aString.finalizeImport(); - mrSheetData.setStringCell( maCellData.maCellAddr, aString, maCellData.mnXfId ); - mrSheetData.setCellFormat( maCellData ); } } @@ -848,8 +886,7 @@ void BiffSheetDataContext::importLabelSst( BiffInputStream& rStrm ) if( readCellHeader( rStrm, false ) ) { maCellData.mnCellType = XML_s; - mrSheetData.setStringCell( maCellData.maCellAddr, rStrm.readInt32(), maCellData.mnXfId ); - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setStringCell( maCellData, rStrm.readInt32() ); } } @@ -858,8 +895,8 @@ void BiffSheetDataContext::importMultBlank( BiffInputStream& rStrm ) BinAddress aAddr; bool bValidAddr = true; for( rStrm >> aAddr; bValidAddr && (rStrm.getRemaining() > 2); ++aAddr.mnCol ) - if( (bValidAddr = readCellXfId( aAddr, rStrm, false )) == true ) - mrSheetData.setCellFormat( maCellData ); + if( (bValidAddr = readCellXfId( rStrm, aAddr, false )) == true ) + mrSheetData.setBlankCell( maCellData ); } void BiffSheetDataContext::importMultRk( BiffInputStream& rStrm ) @@ -868,12 +905,11 @@ void BiffSheetDataContext::importMultRk( BiffInputStream& rStrm ) bool bValidAddr = true; for( rStrm >> aAddr; bValidAddr && (rStrm.getRemaining() > 2); ++aAddr.mnCol ) { - if( (bValidAddr = readCellXfId( aAddr, rStrm, false )) == true ) + if( (bValidAddr = readCellXfId( rStrm, aAddr, false )) == true ) { maCellData.mnCellType = XML_n; sal_Int32 nRkValue = rStrm.readInt32(); - mrSheetData.setValueCell( maCellData.maCellAddr, BiffHelper::calcDoubleFromRk( nRkValue ) ); - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setValueCell( maCellData, BiffHelper::calcDoubleFromRk( nRkValue ) ); } } } @@ -883,8 +919,7 @@ void BiffSheetDataContext::importNumber( BiffInputStream& rStrm ) if( readCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_NUMBER ) ) { maCellData.mnCellType = XML_n; - mrSheetData.setValueCell( maCellData.maCellAddr, rStrm.readDouble() ); - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setValueCell( maCellData, rStrm.readDouble() ); } } @@ -893,8 +928,7 @@ void BiffSheetDataContext::importRk( BiffInputStream& rStrm ) if( readCellHeader( rStrm, false ) ) { maCellData.mnCellType = XML_n; - mrSheetData.setValueCell( maCellData.maCellAddr, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); - mrSheetData.setCellFormat( maCellData ); + mrSheetData.setValueCell( maCellData, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) ); } } diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx index 387aef608339..0b57d2621331 100644 --- a/oox/source/xls/worksheetfragment.cxx +++ b/oox/source/xls/worksheetfragment.cxx @@ -525,14 +525,14 @@ void WorksheetFragment::importSheetFormatPr( const AttributeList& rAttribs ) void WorksheetFragment::importCol( const AttributeList& rAttribs ) { ColumnModel aModel; - aModel.mnFirstCol = rAttribs.getInteger( XML_min, -1 ); - aModel.mnLastCol = rAttribs.getInteger( XML_max, -1 ); - aModel.mfWidth = rAttribs.getDouble( XML_width, 0.0 ); - aModel.mnXfId = rAttribs.getInteger( XML_style, -1 ); - aModel.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 ); - aModel.mbShowPhonetic = rAttribs.getBool( XML_phonetic, false ); - aModel.mbHidden = rAttribs.getBool( XML_hidden, false ); - aModel.mbCollapsed = rAttribs.getBool( XML_collapsed, false ); + aModel.maRange.mnFirst = rAttribs.getInteger( XML_min, -1 ); + aModel.maRange.mnLast = rAttribs.getInteger( XML_max, -1 ); + aModel.mfWidth = rAttribs.getDouble( XML_width, 0.0 ); + aModel.mnXfId = rAttribs.getInteger( XML_style, -1 ); + aModel.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 ); + aModel.mbShowPhonetic = rAttribs.getBool( XML_phonetic, false ); + aModel.mbHidden = rAttribs.getBool( XML_hidden, false ); + aModel.mbCollapsed = rAttribs.getBool( XML_collapsed, false ); // set column properties in the current sheet setColumnModel( aModel ); } @@ -643,11 +643,11 @@ void WorksheetFragment::importCol( SequenceInputStream& rStrm ) sal_Int32 nWidth; sal_uInt16 nFlags; - rStrm >> aModel.mnFirstCol >> aModel.mnLastCol >> nWidth >> aModel.mnXfId >> nFlags; + rStrm >> aModel.maRange.mnFirst >> aModel.maRange.mnLast >> nWidth >> aModel.mnXfId >> nFlags; // column indexes are 0-based in BIFF12, but ColumnModel expects 1-based - ++aModel.mnFirstCol; - ++aModel.mnLastCol; + ++aModel.maRange.mnFirst; + ++aModel.maRange.mnLast; // width is stored as 1/256th of a character in BIFF12, convert to entire character aModel.mfWidth = static_cast< double >( nWidth ) / 256.0; // equal flags in all BIFFs @@ -945,15 +945,15 @@ void BiffWorksheetFragment::importColInfo( BiffInputStream& rStrm ) ColumnModel aModel; // column indexes are 0-based in BIFF, but ColumnModel expects 1-based - aModel.mnFirstCol = static_cast< sal_Int32 >( nFirstCol ) + 1; - aModel.mnLastCol = static_cast< sal_Int32 >( nLastCol ) + 1; + aModel.maRange.mnFirst = static_cast< sal_Int32 >( nFirstCol ) + 1; + aModel.maRange.mnLast = static_cast< sal_Int32 >( nLastCol ) + 1; // width is stored as 1/256th of a character in BIFF, convert to entire character - aModel.mfWidth = static_cast< double >( nWidth ) / 256.0; - aModel.mnXfId = nXfId; - aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 8, 3 ); - aModel.mbShowPhonetic = getFlag( nFlags, BIFF_COLINFO_SHOWPHONETIC ); - aModel.mbHidden = getFlag( nFlags, BIFF_COLINFO_HIDDEN ); - aModel.mbCollapsed = getFlag( nFlags, BIFF_COLINFO_COLLAPSED ); + aModel.mfWidth = static_cast< double >( nWidth ) / 256.0; + aModel.mnXfId = nXfId; + aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 8, 3 ); + aModel.mbShowPhonetic = getFlag( nFlags, BIFF_COLINFO_SHOWPHONETIC ); + aModel.mbHidden = getFlag( nFlags, BIFF_COLINFO_HIDDEN ); + aModel.mbCollapsed = getFlag( nFlags, BIFF_COLINFO_COLLAPSED ); // set column properties in the current sheet setColumnModel( aModel ); } @@ -973,8 +973,8 @@ void BiffWorksheetFragment::importColWidth( BiffInputStream& rStrm ) ColumnModel aModel; // column indexes are 0-based in BIFF, but ColumnModel expects 1-based - aModel.mnFirstCol = static_cast< sal_Int32 >( nFirstCol ) + 1; - aModel.mnLastCol = static_cast< sal_Int32 >( nLastCol ) + 1; + aModel.maRange.mnFirst = static_cast< sal_Int32 >( nFirstCol ) + 1; + aModel.maRange.mnLast = static_cast< sal_Int32 >( nLastCol ) + 1; // width is stored as 1/256th of a character in BIFF, convert to entire character aModel.mfWidth = static_cast< double >( nWidth ) / 256.0; // set column properties in the current sheet diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index bba52fb0d8f2..69d17b47a570 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -51,7 +51,6 @@ #include #include #include "oox/core/filterbase.hxx" -#include "oox/helper/containerhelper.hxx" #include "oox/helper/propertyset.hxx" #include "oox/xls/addressconverter.hxx" #include "oox/xls/autofilterbuffer.hxx" @@ -109,84 +108,13 @@ void lclUpdateProgressBar( const ISegmentProgressBarRef& rxProgressBar, double f rxProgressBar->setPosition( fPosition ); } -// ---------------------------------------------------------------------------- - -struct ValueRange -{ - sal_Int32 mnFirst; - sal_Int32 mnLast; - - inline explicit ValueRange( sal_Int32 nValue ) : mnFirst( nValue ), mnLast( nValue ) {} - inline explicit ValueRange( sal_Int32 nFirst, sal_Int32 nLast ) : mnFirst( nFirst ), mnLast( nLast ) {} -}; - -typedef ::std::vector< ValueRange > ValueRangeVector; - -// ---------------------------------------------------------------------------- - -struct ValueRangeComp -{ - inline bool operator()( const ValueRange& rRange, sal_Int32 nValue ) const { return rRange.mnLast < nValue; } -}; - -// ---------------------------------------------------------------------------- - -class ValueRangeSet -{ -public: - inline explicit ValueRangeSet() {} - - void insert( sal_Int32 nValue ); - void intersect( ValueRangeVector& orRanges, sal_Int32 nFirst, sal_Int32 nLast ) const; - -private: - ValueRangeVector maData; -}; - -void ValueRangeSet::insert( sal_Int32 nValue ) -{ - // find the first range that contains nValue or that follows nValue - ValueRangeVector::iterator aBeg = maData.begin(); - ValueRangeVector::iterator aEnd = maData.end(); - ValueRangeVector::iterator aNext = ::std::lower_bound( aBeg, aEnd, nValue, ValueRangeComp() ); - - // nothing to do if found range contains nValue - if( (aNext == aEnd) || (nValue < aNext->mnFirst) ) - { - ValueRangeVector::iterator aPrev = (aNext == aBeg) ? aEnd : (aNext - 1); - bool bJoinPrev = (aPrev != aEnd) && (aPrev->mnLast + 1 == nValue); - bool bJoinNext = (aNext != aEnd) && (aNext->mnFirst - 1 == nValue); - if( bJoinPrev && bJoinNext ) - { - aPrev->mnLast = aNext->mnLast; - maData.erase( aNext ); - } - else if( bJoinPrev ) - ++aPrev->mnLast; - else if( bJoinNext ) - --aNext->mnFirst; - else - maData.insert( aNext, ValueRange( nValue ) ); - } -} - -void ValueRangeSet::intersect( ValueRangeVector& orRanges, sal_Int32 nFirst, sal_Int32 nLast ) const -{ - orRanges.clear(); - // find the range that contains nFirst or the first range that follows nFirst - ValueRangeVector::const_iterator aIt = ::std::lower_bound( maData.begin(), maData.end(), nFirst, ValueRangeComp() ); - for( ValueRangeVector::const_iterator aEnd = maData.end(); (aIt != aEnd) && (aIt->mnFirst <= nLast); ++aIt ) - orRanges.push_back( ValueRange( ::std::max( aIt->mnFirst, nFirst ), ::std::min( aIt->mnLast, nLast ) ) ); -} - } // namespace // ============================================================================ // ============================================================================ ColumnModel::ColumnModel() : - mnFirstCol( -1 ), - mnLastCol( -1 ), + maRange( -1 ), mfWidth( 0.0 ), mnXfId( -1 ), mnLevel( 0 ), @@ -196,27 +124,22 @@ ColumnModel::ColumnModel() : { } -bool ColumnModel::tryExpand( const ColumnModel& rModel ) +bool ColumnModel::isMergeable( const ColumnModel& rModel ) const { - bool bExpandable = - (mnFirstCol <= rModel.mnFirstCol) && - (rModel.mnFirstCol <= mnLastCol + 1) && - (mfWidth == rModel.mfWidth) && + return + (maRange.mnFirst <= rModel.maRange.mnFirst) && + (rModel.maRange.mnFirst <= maRange.mnLast + 1) && + (mfWidth == rModel.mfWidth) && // ignore mnXfId, cell formatting is always set directly - (mnLevel == rModel.mnLevel) && - (mbHidden == rModel.mbHidden) && - (mbCollapsed == rModel.mbCollapsed); - - if( bExpandable ) - mnLastCol = rModel.mnLastCol; - return bExpandable; + (mnLevel == rModel.mnLevel) && + (mbHidden == rModel.mbHidden) && + (mbCollapsed == rModel.mbCollapsed); } // ---------------------------------------------------------------------------- RowModel::RowModel() : - mnFirstRow( -1 ), - mnLastRow( -1 ), + mnRow( -1 ), mfHeight( 0.0 ), mnXfId( -1 ), mnLevel( 0 ), @@ -230,21 +153,22 @@ RowModel::RowModel() : { } -bool RowModel::tryExpand( const RowModel& rModel ) +void RowModel::insertColSpan( const ValueRange& rColSpan ) { - bool bExpandable = - (mnFirstRow <= rModel.mnFirstRow) && - (rModel.mnFirstRow <= mnLastRow + 1) && - (mfHeight == rModel.mfHeight) && - // ignore mnXfId, mbCustomFormat, mbShowPhonetic - cell formatting is always set directly - (mnLevel == rModel.mnLevel) && - (mbCustomHeight == rModel.mbCustomHeight) && - (mbHidden == rModel.mbHidden) && - (mbCollapsed == rModel.mbCollapsed); + if( (0 <= rColSpan.mnFirst) && (rColSpan.mnFirst <= rColSpan.mnLast) ) + maColSpans.insert( rColSpan ); +} - if( bExpandable ) - mnLastRow = rModel.mnLastRow; - return bExpandable; +bool RowModel::isMergeable( const RowModel& rModel ) const +{ + return + // ignore maColSpans - is handled separately in SheetDataBuffer class + (mfHeight == rModel.mfHeight) && + // ignore mnXfId, mbCustomFormat, mbShowPhonetic - cell formatting is always set directly + (mnLevel == rModel.mnLevel) && + (mbCustomHeight == rModel.mbCustomHeight) && + (mbHidden == rModel.mbHidden) && + (mbCollapsed == rModel.mbCollapsed); } // ---------------------------------------------------------------------------- @@ -330,9 +254,9 @@ public: Reference< XCellRange > getRow( sal_Int32 nRow ) const; /** Returns the XTableColumns interface for a range of columns. */ - Reference< XTableColumns > getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const; + Reference< XTableColumns > getColumns( const ValueRange& rColRange ) const; /** Returns the XTableRows interface for a range of rows. */ - Reference< XTableRows > getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const; + Reference< XTableRows > getRows( const ValueRange& rRowRange ) const; /** Returns the XDrawPage interface of the draw page of the current sheet. */ Reference< XDrawPage > getDrawPage() const; @@ -419,8 +343,10 @@ public: private: typedef ::std::vector< sal_Int32 > OutlineLevelVec; - typedef ::std::map< sal_Int32, ColumnModel > ColumnModelMap; - typedef ::std::map< sal_Int32, RowModel > RowModelMap; + typedef ::std::pair< ColumnModel, sal_Int32 > ColumnModelRange; + typedef ::std::map< sal_Int32, ColumnModelRange > ColumnModelRangeMap; + typedef ::std::pair< RowModel, sal_Int32 > RowModelRange; + typedef ::std::map< sal_Int32, RowModelRange > RowModelRangeMap; typedef ::std::list< HyperlinkModel > HyperlinkModelList; typedef ::std::list< ValidationModel > ValidationModelList; @@ -437,12 +363,12 @@ private: /** Converts column properties for all columns in the sheet. */ void convertColumns(); /** Converts column properties. */ - void convertColumns( OutlineLevelVec& orColLevels, sal_Int32 nFirstCol, sal_Int32 nLastCol, const ColumnModel& rModel ); + void convertColumns( OutlineLevelVec& orColLevels, const ValueRange& rColRange, const ColumnModel& rModel ); /** Converts row properties for all rows in the sheet. */ void convertRows(); /** Converts row properties. */ - void convertRows( OutlineLevelVec& orRowLevels, sal_Int32 nFirstRow, sal_Int32 nLastRow, const RowModel& rModel, double fDefHeight = -1.0 ); + void convertRows( OutlineLevelVec& orRowLevels, const ValueRange& rRowRange, const RowModel& rModel, double fDefHeight = -1.0 ); /** Converts outline grouping for the passed column or row. */ void convertOutlines( OutlineLevelVec& orLevels, sal_Int32 nColRow, sal_Int32 nLevel, bool bCollapsed, bool bRows ); @@ -461,9 +387,9 @@ private: const CellAddress& mrMaxApiPos; /// Reference to maximum Calc cell address from address converter. CellRangeAddress maUsedArea; /// Used area of the sheet, and sheet index of the sheet. ColumnModel maDefColModel; /// Default column formatting. - ColumnModelMap maColModels; /// Columns sorted by first column index. + ColumnModelRangeMap maColModels; /// Ranges of columns sorted by first column index. RowModel maDefRowModel; /// Default row formatting. - RowModelMap maRowModels; /// Rows sorted by row index. + RowModelRangeMap maRowModels; /// Ranges of rows sorted by first row index. HyperlinkModelList maHyperlinks; /// Cell ranges containing hyperlinks. ValidationModelList maValidations; /// Cell ranges containing data validation settings. ValueRangeSet maManualRowHeights; /// Rows that need manual height independent from own settings. @@ -622,26 +548,26 @@ Reference< XCellRange > WorksheetGlobals::getRow( sal_Int32 nRow ) const return xRow; } -Reference< XTableColumns > WorksheetGlobals::getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const +Reference< XTableColumns > WorksheetGlobals::getColumns( const ValueRange& rColRange ) const { Reference< XTableColumns > xColumns; - nLastCol = ::std::min( nLastCol, mrMaxApiPos.Column ); - if( (0 <= nFirstCol) && (nFirstCol <= nLastCol) ) + sal_Int32 nLastCol = ::std::min( rColRange.mnLast, mrMaxApiPos.Column ); + if( (0 <= rColRange.mnFirst) && (rColRange.mnFirst <= nLastCol) ) { - Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), nFirstCol, 0, nLastCol, 0 ) ), UNO_QUERY ); + Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), rColRange.mnFirst, 0, nLastCol, 0 ) ), UNO_QUERY ); if( xRange.is() ) xColumns = xRange->getColumns(); } return xColumns; } -Reference< XTableRows > WorksheetGlobals::getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const +Reference< XTableRows > WorksheetGlobals::getRows( const ValueRange& rRowRange ) const { Reference< XTableRows > xRows; - nLastRow = ::std::min( nLastRow, mrMaxApiPos.Row ); - if( (0 <= nFirstRow) && (nFirstRow <= nLastRow) ) + sal_Int32 nLastRow = ::std::min( rRowRange.mnLast, mrMaxApiPos.Row ); + if( (0 <= rRowRange.mnFirst) && (rRowRange.mnFirst <= nLastRow) ) { - Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), 0, nFirstRow, 0, nLastRow ) ), UNO_QUERY ); + Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), 0, rRowRange.mnFirst, 0, nLastRow ) ), UNO_QUERY ); if( xRange.is() ) xRows = xRange->getRows(); } @@ -894,15 +820,48 @@ void WorksheetGlobals::setDefaultColumnWidth( double fWidth ) void WorksheetGlobals::setColumnModel( const ColumnModel& rModel ) { // convert 1-based OOXML column indexes to 0-based API column indexes - sal_Int32 nFirstCol = rModel.mnFirstCol - 1; - sal_Int32 nLastCol = rModel.mnLastCol - 1; - if( (0 <= nFirstCol) && (nFirstCol <= mrMaxApiPos.Column) ) + sal_Int32 nFirstCol = rModel.maRange.mnFirst - 1; + sal_Int32 nLastCol = rModel.maRange.mnLast - 1; + if( getAddressConverter().checkCol( nFirstCol, true ) && (nFirstCol <= nLastCol) ) { - // set column formatting directly, nLastCol is checked inside the function - convertColumnFormat( nFirstCol, nLastCol, rModel.mnXfId ); - // expand last entry or add new entry - if( maColModels.empty() || !maColModels.rbegin()->second.tryExpand( rModel ) ) - maColModels[ nFirstCol ] = rModel; + // validate last column index + if( !getAddressConverter().checkCol( nLastCol, true ) ) + nLastCol = mrMaxApiPos.Column; + // try to find entry in column model map that is able to merge with the passed model + bool bInsertModel = true; + if( !maColModels.empty() ) + { + // find first column model range following nFirstCol (nFirstCol < aIt->first), or end of map + ColumnModelRangeMap::iterator aIt = maColModels.upper_bound( nFirstCol ); + OSL_ENSURE( aIt == maColModels.end(), "WorksheetGlobals::setColModel - columns are unsorted" ); + // if inserting before another column model, get last free column + OSL_ENSURE( (aIt == maColModels.end()) || (nLastCol < aIt->first), "WorksheetGlobals::setColModel - multiple models of the same column" ); + if( aIt != maColModels.end() ) + nLastCol = ::std::min( nLastCol, aIt->first - 1 ); + if( aIt != maColModels.begin() ) + { + // go to previous map element (which may be able to merge with the passed model) + --aIt; + // the usage of upper_bound() above ensures that aIt->first is less than or equal to nFirstCol now + sal_Int32& rnLastMapCol = aIt->second.second; + OSL_ENSURE( rnLastMapCol < nFirstCol, "WorksheetGlobals::setColModel - multiple models of the same column" ); + nFirstCol = ::std::max( rnLastMapCol + 1, nFirstCol ); + if( (rnLastMapCol + 1 == nFirstCol) && (nFirstCol <= nLastCol) && aIt->second.first.isMergeable( rModel ) ) + { + // can merge with existing model, update last column index + rnLastMapCol = nLastCol; + bInsertModel = false; + } + } + } + if( nFirstCol <= nLastCol ) + { + // insert the column model, if it has not been merged with another + if( bInsertModel ) + maColModels[ nFirstCol ] = ColumnModelRange( rModel, nLastCol ); + // set column formatting directly + convertColumnFormat( nFirstCol, nLastCol, rModel.mnXfId ); + } } } @@ -927,18 +886,46 @@ void WorksheetGlobals::setDefaultRowSettings( double fHeight, bool bCustomHeight void WorksheetGlobals::setRowModel( const RowModel& rModel ) { - // convert 1-based OOXML row indexes to 0-based API row indexes - sal_Int32 nFirstRow = rModel.mnFirstRow - 1; - sal_Int32 nLastRow = rModel.mnLastRow - 1; - if( (0 <= nFirstRow) && (nFirstRow <= mrMaxApiPos.Row) ) + // convert 1-based OOXML row index to 0-based API row index + sal_Int32 nRow = rModel.mnRow - 1; + if( getAddressConverter().checkRow( nRow, true ) ) { - // set row formatting - maSheetData.setRowFormat( nFirstRow, nLastRow, rModel.mnXfId, rModel.mbCustomFormat ); - // expand last entry or add new entry - if( maRowModels.empty() || !maRowModels.rbegin()->second.tryExpand( rModel ) ) - maRowModels[ nFirstRow ] = rModel; + // try to find entry in row model map that is able to merge with the passed model + bool bInsertModel = true; + bool bUnusedRow = true; + if( !maRowModels.empty() ) + { + // find first row model range following nRow (nRow < aIt->first), or end of map + RowModelRangeMap::iterator aIt = maRowModels.upper_bound( nRow ); + OSL_ENSURE( aIt == maRowModels.end(), "WorksheetGlobals::setRowModel - rows are unsorted" ); + if( aIt != maRowModels.begin() ) + { + // go to previous map element (which may be able to merge with the passed model) + --aIt; + // the usage of upper_bound() above ensures that aIt->first is less than or equal to nRow now + sal_Int32& rnLastMapRow = aIt->second.second; + bUnusedRow = rnLastMapRow < nRow; + OSL_ENSURE( bUnusedRow, "WorksheetGlobals::setRowModel - multiple models of the same row" ); + if( (rnLastMapRow + 1 == nRow) && aIt->second.first.isMergeable( rModel ) ) + { + // can merge with existing model, update last row index + ++rnLastMapRow; + bInsertModel = false; + } + } + } + if( bUnusedRow ) + { + // insert the row model, if it has not been merged with another + if( bInsertModel ) + maRowModels[ nRow ] = RowModelRange( rModel, nRow ); + // set row formatting + maSheetData.setRowFormat( nRow, rModel.mnXfId, rModel.mbCustomFormat ); + // set column spans + maSheetData.setColSpans( nRow, rModel.maColSpans ); + } } - lclUpdateProgressBar( mxRowProgress, maUsedArea, nLastRow ); + lclUpdateProgressBar( mxRowProgress, maUsedArea, nRow ); } void WorksheetGlobals::setManualRowHeight( sal_Int32 nRow ) @@ -1160,32 +1147,29 @@ void WorksheetGlobals::convertColumns() // stores first grouped column index for each level OutlineLevelVec aColLevels; - for( ColumnModelMap::const_iterator aIt = maColModels.begin(), aEnd = maColModels.end(); aIt != aEnd; ++aIt ) + for( ColumnModelRangeMap::iterator aIt = maColModels.begin(), aEnd = maColModels.end(); aIt != aEnd; ++aIt ) { - // convert 1-based OOXML column indexes to 0-based API column indexes - sal_Int32 nFirstCol = ::std::max( aIt->second.mnFirstCol - 1, nNextCol ); - sal_Int32 nLastCol = ::std::min( aIt->second.mnLastCol - 1, nMaxCol ); - + // column indexes are stored 0-based in maColModels + ValueRange aColRange( ::std::max( aIt->first, nNextCol ), ::std::min( aIt->second.second, nMaxCol ) ); // process gap between two column models, use default column model - if( nNextCol < nFirstCol ) - convertColumns( aColLevels, nNextCol, nFirstCol - 1, maDefColModel ); + if( nNextCol < aColRange.mnFirst ) + convertColumns( aColLevels, ValueRange( nNextCol, aColRange.mnFirst - 1 ), maDefColModel ); // process the column model - convertColumns( aColLevels, nFirstCol, nLastCol, aIt->second ); - + convertColumns( aColLevels, aColRange, aIt->second.first ); // cache next column to be processed - nNextCol = nLastCol + 1; + nNextCol = aColRange.mnLast + 1; } // remaining default columns to end of sheet - convertColumns( aColLevels, nNextCol, nMaxCol, maDefColModel ); + convertColumns( aColLevels, ValueRange( nNextCol, nMaxCol ), maDefColModel ); // close remaining column outlines spanning to end of sheet convertOutlines( aColLevels, nMaxCol + 1, 0, false, false ); } void WorksheetGlobals::convertColumns( OutlineLevelVec& orColLevels, - sal_Int32 nFirstCol, sal_Int32 nLastCol, const ColumnModel& rModel ) + const ValueRange& rColRange, const ColumnModel& rModel ) { - PropertySet aPropSet( getColumns( nFirstCol, nLastCol ) ); + PropertySet aPropSet( getColumns( rColRange ) ); // column width: convert 'number of characters' to column width in 1/100 mm sal_Int32 nWidth = getUnitConverter().scaleToMm100( rModel.mfWidth, UNIT_DIGIT ); @@ -1200,7 +1184,7 @@ void WorksheetGlobals::convertColumns( OutlineLevelVec& orColLevels, aPropSet.setProperty( PROP_IsVisible, false ); // outline settings for this column range - convertOutlines( orColLevels, nFirstCol, rModel.mnLevel, rModel.mbCollapsed, false ); + convertOutlines( orColLevels, rColRange.mnFirst, rModel.mnLevel, rModel.mbCollapsed, false ); } void WorksheetGlobals::convertRows() @@ -1210,44 +1194,45 @@ void WorksheetGlobals::convertRows() // stores first grouped row index for each level OutlineLevelVec aRowLevels; - for( RowModelMap::const_iterator aIt = maRowModels.begin(), aEnd = maRowModels.end(); aIt != aEnd; ++aIt ) + for( RowModelRangeMap::iterator aIt = maRowModels.begin(), aEnd = maRowModels.end(); aIt != aEnd; ++aIt ) { - // convert 1-based OOXML row indexes to 0-based API row indexes - sal_Int32 nFirstRow = ::std::max( aIt->second.mnFirstRow - 1, nNextRow ); - sal_Int32 nLastRow = ::std::min( aIt->second.mnLastRow - 1, nMaxRow ); - + // row indexes are stored 0-based in maRowModels + ValueRange aRowRange( ::std::max( aIt->first, nNextRow ), ::std::min( aIt->second.second, nMaxRow ) ); // process gap between two row models, use default row model - if( nNextRow < nFirstRow ) - convertRows( aRowLevels, nNextRow, nFirstRow - 1, maDefRowModel ); + if( nNextRow < aRowRange.mnFirst ) + convertRows( aRowLevels, ValueRange( nNextRow, aRowRange.mnFirst - 1 ), maDefRowModel ); // process the row model - convertRows( aRowLevels, nFirstRow, nLastRow, aIt->second, maDefRowModel.mfHeight ); - + convertRows( aRowLevels, aRowRange, aIt->second.first, maDefRowModel.mfHeight ); // cache next row to be processed - nNextRow = nLastRow + 1; + nNextRow = aRowRange.mnLast + 1; } // remaining default rows to end of sheet - convertRows( aRowLevels, nNextRow, nMaxRow, maDefRowModel ); + convertRows( aRowLevels, ValueRange( nNextRow, nMaxRow ), maDefRowModel ); // close remaining row outlines spanning to end of sheet convertOutlines( aRowLevels, nMaxRow + 1, 0, false, true ); } void WorksheetGlobals::convertRows( OutlineLevelVec& orRowLevels, - sal_Int32 nFirstRow, sal_Int32 nLastRow, const RowModel& rModel, double fDefHeight ) + const ValueRange& rRowRange, const RowModel& rModel, double fDefHeight ) { // row height: convert points to row height in 1/100 mm double fHeight = (rModel.mfHeight >= 0.0) ? rModel.mfHeight : fDefHeight; sal_Int32 nHeight = getUnitConverter().scaleToMm100( fHeight, UNIT_POINT ); if( nHeight > 0 ) { + /* Get all rows that have custom height inside the passed row model. + If the model has the custom height flag set, all its rows have + custom height, otherwise get all rows specified in the class member + maManualRowHeights that are inside the passed row model. */ ValueRangeVector aManualRows; if( rModel.mbCustomHeight ) - aManualRows.push_back( ValueRange( nFirstRow, nLastRow ) ); + aManualRows.push_back( rRowRange ); else - maManualRowHeights.intersect( aManualRows, nFirstRow, nLastRow ); + aManualRows = maManualRowHeights.getIntersection( rRowRange ); for( ValueRangeVector::const_iterator aIt = aManualRows.begin(), aEnd = aManualRows.end(); aIt != aEnd; ++aIt ) { - PropertySet aPropSet( getRows( aIt->mnFirst, aIt->mnLast ) ); + PropertySet aPropSet( getRows( *aIt ) ); aPropSet.setProperty( PROP_Height, nHeight ); } } @@ -1255,12 +1240,12 @@ void WorksheetGlobals::convertRows( OutlineLevelVec& orRowLevels, // hidden rows: TODO: #108683# hide rows later? if( rModel.mbHidden ) { - PropertySet aPropSet( getRows( nFirstRow, nLastRow ) ); + PropertySet aPropSet( getRows( rRowRange ) ); aPropSet.setProperty( PROP_IsVisible, false ); } // outline settings for this row range - convertOutlines( orRowLevels, nFirstRow, rModel.mnLevel, rModel.mbCollapsed, true ); + convertOutlines( orRowLevels, rRowRange.mnFirst, rModel.mnLevel, rModel.mbCollapsed, true ); } void WorksheetGlobals::convertOutlines( OutlineLevelVec& orLevels, @@ -1449,14 +1434,14 @@ Reference< XCellRange > WorksheetHelper::getRow( sal_Int32 nRow ) const return mrSheetGlob.getRow( nRow ); } -Reference< XTableColumns > WorksheetHelper::getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const +Reference< XTableColumns > WorksheetHelper::getColumns( const ValueRange& rColRange ) const { - return mrSheetGlob.getColumns( nFirstCol, nLastCol ); + return mrSheetGlob.getColumns( rColRange ); } -Reference< XTableRows > WorksheetHelper::getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const +Reference< XTableRows > WorksheetHelper::getRows( const ValueRange& rRowRange ) const { - return mrSheetGlob.getRows( nFirstRow, nLastRow ); + return mrSheetGlob.getRows( rRowRange ); } Reference< XDrawPage > WorksheetHelper::getDrawPage() const @@ -1661,6 +1646,34 @@ void WorksheetHelper::setManualRowHeight( sal_Int32 nRow ) mrSheetGlob.setManualRowHeight( nRow ); } +void WorksheetHelper::putValue( const CellAddress& rAddress, double fValue ) const +{ + Reference< XCell > xCell = getCell( rAddress ); + OSL_ENSURE( xCell.is(), "WorksheetHelper::putValue - missing cell interface" ); + if( xCell.is() ) xCell->setValue( fValue ); +} + +void WorksheetHelper::putString( const CellAddress& rAddress, const OUString& rText ) const +{ + Reference< XText > xText( getCell( rAddress ), UNO_QUERY ); + OSL_ENSURE( xText.is(), "WorksheetHelper::putString - missing text interface" ); + if( xText.is() ) xText->setString( rText ); +} + +void WorksheetHelper::putRichString( const CellAddress& rAddress, const RichString& rString, const Font* pFirstPortionFont ) const +{ + Reference< XText > xText( getCell( rAddress ), UNO_QUERY ); + OSL_ENSURE( xText.is(), "WorksheetHelper::putRichString - missing text interface" ); + rString.convert( xText, pFirstPortionFont ); +} + +void WorksheetHelper::putFormulaTokens( const CellAddress& rAddress, const ApiTokenSequence& rTokens ) const +{ + Reference< XFormulaTokens > xTokens( getCell( rAddress ), UNO_QUERY ); + OSL_ENSURE( xTokens.is(), "WorksheetHelper::putFormulaTokens - missing token interface" ); + if( xTokens.is() ) xTokens->setTokens( rTokens ); +} + void WorksheetHelper::initializeWorksheetImport() { mrSheetGlob.initializeWorksheetImport(); -- cgit From 1864247d585887383a0537bb9eb5be2d012cfded Mon Sep 17 00:00:00 2001 From: "Daniel Rentz [dr]" Date: Mon, 28 Feb 2011 15:24:56 +0100 Subject: dr78: #i116996# remove wrong assertions --- oox/source/helper/binaryinputstream.cxx | 5 +++-- oox/source/helper/binaryoutputstream.cxx | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'oox/source') diff --git a/oox/source/helper/binaryinputstream.cxx b/oox/source/helper/binaryinputstream.cxx index e61000675006..58c7cca37008 100644 --- a/oox/source/helper/binaryinputstream.cxx +++ b/oox/source/helper/binaryinputstream.cxx @@ -155,7 +155,7 @@ BinaryXInputStream::BinaryXInputStream( const Reference< XInputStream >& rxInStr BinaryXSeekableStream( Reference< XSeekable >( rxInStrm, UNO_QUERY ) ), maBuffer( INPUTSTREAM_BUFFERSIZE ), mxInStrm( rxInStrm ), - mbAutoClose( bAutoClose ) + mbAutoClose( bAutoClose && rxInStrm.is() ) { mbEof = !mxInStrm.is(); } @@ -167,7 +167,7 @@ BinaryXInputStream::~BinaryXInputStream() void BinaryXInputStream::close() { - OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::close - invalid call" ); + OSL_ENSURE( !mbAutoClose || mxInStrm.is(), "BinaryXInputStream::close - invalid call" ); if( mbAutoClose && mxInStrm.is() ) try { mxInStrm->closeInput(); @@ -177,6 +177,7 @@ void BinaryXInputStream::close() OSL_ENSURE( false, "BinaryXInputStream::close - closing input stream failed" ); } mxInStrm.clear(); + mbAutoClose = false; BinaryXSeekableStream::close(); } diff --git a/oox/source/helper/binaryoutputstream.cxx b/oox/source/helper/binaryoutputstream.cxx index 1ae7b15d7595..2f894ccf1bf2 100644 --- a/oox/source/helper/binaryoutputstream.cxx +++ b/oox/source/helper/binaryoutputstream.cxx @@ -52,7 +52,7 @@ BinaryXOutputStream::BinaryXOutputStream( const Reference< XOutputStream >& rxOu BinaryXSeekableStream( Reference< XSeekable >( rxOutStrm, UNO_QUERY ) ), maBuffer( OUTPUTSTREAM_BUFFERSIZE ), mxOutStrm( rxOutStrm ), - mbAutoClose( bAutoClose ) + mbAutoClose( bAutoClose && rxOutStrm.is() ) { mbEof = !mxOutStrm.is(); } @@ -64,7 +64,7 @@ BinaryXOutputStream::~BinaryXOutputStream() void BinaryXOutputStream::close() { - OSL_ENSURE( mxOutStrm.is(), "BinaryXOutputStream::close - invalid call" ); + OSL_ENSURE( !mbAutoClose || mxOutStrm.is(), "BinaryXOutputStream::close - invalid call" ); if( mxOutStrm.is() ) try { mxOutStrm->flush(); @@ -76,6 +76,7 @@ void BinaryXOutputStream::close() OSL_ENSURE( false, "BinaryXOutputStream::close - closing output stream failed" ); } mxOutStrm.clear(); + mbAutoClose = false; BinaryXSeekableStream::close(); } -- cgit From 7ea86c48b4bb23cc6e41cebf8c38d90e7979ea30 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 14 Apr 2011 15:19:53 +0200 Subject: fix crash in fdo#36203, the referenced shape didn't contain texbody --- oox/source/drawingml/shape.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'oox/source') diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 18965ed78d1c..86dea33d8eac 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -198,7 +198,7 @@ void Shape::addShape( void Shape::applyShapeReference( const Shape& rReferencedShape ) { - mpTextBody = TextBodyPtr( new TextBody( *rReferencedShape.mpTextBody.get() ) ); + mpTextBody = TextBodyPtr( rReferencedShape.mpTextBody.get() ? new TextBody( *rReferencedShape.mpTextBody.get() ) : new TextBody() ); maShapeProperties = rReferencedShape.maShapeProperties; mpLinePropertiesPtr = LinePropertiesPtr( new LineProperties( *rReferencedShape.mpLinePropertiesPtr.get() ) ); mpFillPropertiesPtr = FillPropertiesPtr( new FillProperties( *rReferencedShape.mpFillPropertiesPtr.get() ) ); -- cgit From a41acbe3896fef5cb07e10611144ae7af3f59874 Mon Sep 17 00:00:00 2001 From: Jan Holesovsky Date: Fri, 13 May 2011 23:04:53 +0200 Subject: Making oox to build - work in progress. --- oox/source/ole/vbacontrol.cxx | 2 +- oox/source/vml/vmlinputstream.cxx | 4 - oox/source/xls/commentsbuffer.cxx | 15 --- oox/source/xls/drawingfragment.cxx | 240 ++----------------------------------- oox/source/xls/formulaparser.cxx | 6 - oox/source/xls/richstring.cxx | 4 +- 6 files changed, 13 insertions(+), 258 deletions(-) (limited to 'oox/source') diff --git a/oox/source/ole/vbacontrol.cxx b/oox/source/ole/vbacontrol.cxx index 909010f8aec6..fc750ca53821 100644 --- a/oox/source/ole/vbacontrol.cxx +++ b/oox/source/ole/vbacontrol.cxx @@ -876,7 +876,7 @@ void VbaUserForm::importForm( if( convertProperties( xDialogModel, maConverter, 0 ) ) { // export the dialog to XML and insert it into the dialog library - Reference< XInputStreamProvider > xDialogSource( ::xmlscript::exportDialogModel( xDialogNC, mxCompContext, rxDocModel ), UNO_SET_THROW ); + Reference< XInputStreamProvider > xDialogSource( ::xmlscript::exportDialogModel( xDialogNC, mxContext, rxDocModel ), UNO_SET_THROW ); OSL_ENSURE( !rxDialogLib->hasByName( aFormName ), "VbaUserForm::importForm - multiple dialogs with equal name" ); ContainerHelper::insertByName( rxDialogLib, aFormName, Any( xDialogSource ) ); } diff --git a/oox/source/vml/vmlinputstream.cxx b/oox/source/vml/vmlinputstream.cxx index 4202ffd193fe..bec1654b2097 100644 --- a/oox/source/vml/vmlinputstream.cxx +++ b/oox/source/vml/vmlinputstream.cxx @@ -377,10 +377,6 @@ void InputStream::updateBuffer() throw (IOException, RuntimeException) // no CDATA part - process the contents of the element lclProcessElement( aBuffer, aElement ); } - else - { - pcCurr = pcEnd; - } } maBuffer = aBuffer.makeStringAndClear(); diff --git a/oox/source/xls/commentsbuffer.cxx b/oox/source/xls/commentsbuffer.cxx index 0b143686775c..06a77df7685d 100644 --- a/oox/source/xls/commentsbuffer.cxx +++ b/oox/source/xls/commentsbuffer.cxx @@ -251,21 +251,7 @@ void Comment::finalizeImport() switch( getFilterType() ) { case FILTER_OOXML: - if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) ) { - Reference< XSheetAnnotationsSupplier > xAnnosSupp( getSheet(), UNO_QUERY_THROW ); - Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW ); - xAnnos->insertNew( aNotePos, aNoteText ); - // receive craeted note from cell (insertNew does not return the note) - Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( aNotePos ), UNO_QUERY_THROW ); - Reference< XSheetAnnotation > xAnno( xAnnoAnchor->getAnnotation(), UNO_SET_THROW ); - Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnno, UNO_QUERY_THROW ); - Reference< XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), UNO_SET_THROW ); - Reference xText( xAnnoShape, UNO_QUERY_THROW ); - Reference xTextRange( xText, UNO_QUERY_THROW ); - xTextRange->setString( OUString() ); // Clear contents - maModel.mxText->convert( xText, -1 ); - // Add shape formatting properties (autoFill, colHidden and rowHidden are dropped) PropertySet aCommentPr( xAnnoShape ); aCommentPr.setProperty( PROP_TextFitToSize, maModel.mbAutoScale ); @@ -278,7 +264,6 @@ void Comment::finalizeImport() xAnnoShape->setSize( Size( maModel.maAnchor.Width, maModel.maAnchor.Height ) ); } - // convert shape formatting if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) ) { diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx index ffd77155dc5f..c048a3e7d60d 100644 --- a/oox/source/xls/drawingfragment.cxx +++ b/oox/source/xls/drawingfragment.cxx @@ -86,16 +86,6 @@ sal_Int64 lclCalcEmu( const UnitConverter& rUnitConv, sal_Int64 nValue, Unit eFr } // namespace -// ============================================================================ - -AnchorCellModel::AnchorCellModel() : - mnCol( -1 ), - mnRow( -1 ), - mnColOffset( 0 ), - mnRowOffset( 0 ) -{ -} - // ---------------------------------------------------------------------------- AnchorClientDataModel::AnchorClientDataModel() : @@ -108,7 +98,7 @@ AnchorClientDataModel::AnchorClientDataModel() : ShapeAnchor::ShapeAnchor( const WorksheetHelper& rHelper ) : WorksheetHelper( rHelper ), - meType( ANCHOR_INVALID ), + meAnchorType( ANCHOR_INVALID ), mnEditAs( XML_twoCell ) { } @@ -118,13 +108,13 @@ void ShapeAnchor::importAnchor( sal_Int32 nElement, const AttributeList& rAttrib switch( nElement ) { case XDR_TOKEN( absoluteAnchor ): - meType = ANCHOR_ABSOLUTE; + meAnchorType = ANCHOR_ABSOLUTE; break; case XDR_TOKEN( oneCellAnchor ): - meType = ANCHOR_ONECELL; + meAnchorType = ANCHOR_ONECELL; break; case XDR_TOKEN( twoCellAnchor ): - meType = ANCHOR_TWOCELL; + meAnchorType = ANCHOR_TWOCELL; mnEditAs = rAttribs.getToken( XML_editAs, XML_twoCell ); break; default: @@ -134,14 +124,14 @@ void ShapeAnchor::importAnchor( sal_Int32 nElement, const AttributeList& rAttrib void ShapeAnchor::importPos( const AttributeList& rAttribs ) { - OSL_ENSURE( meType == ANCHOR_ABSOLUTE, "ShapeAnchor::importPos - unexpected 'xdr:pos' element" ); + OSL_ENSURE( meAnchorType == ANCHOR_ABSOLUTE, "ShapeAnchor::importPos - unexpected 'xdr:pos' element" ); maPos.X = rAttribs.getHyper( XML_x, 0 ); maPos.Y = rAttribs.getHyper( XML_y, 0 ); } void ShapeAnchor::importExt( const AttributeList& rAttribs ) { - OSL_ENSURE( (meType == ANCHOR_ABSOLUTE) || (meType == ANCHOR_ONECELL), "ShapeAnchor::importExt - unexpected 'xdr:ext' element" ); + OSL_ENSURE( (meAnchorType == ANCHOR_ABSOLUTE) || (meAnchorType == ANCHOR_ONECELL), "ShapeAnchor::importExt - unexpected 'xdr:ext' element" ); maSize.Width = rAttribs.getHyper( XML_cx, 0 ); maSize.Height = rAttribs.getHyper( XML_cy, 0 ); } @@ -154,15 +144,15 @@ void ShapeAnchor::importClientData( const AttributeList& rAttribs ) void ShapeAnchor::setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue ) { - AnchorCellModel* pAnchorCell = 0; + CellAnchorModel* pAnchorCell = 0; switch( nParentContext ) { case XDR_TOKEN( from ): - OSL_ENSURE( (meType == ANCHOR_ONECELL) || (meType == ANCHOR_TWOCELL), "ShapeAnchor::setCellPos - unexpected 'xdr:from' element" ); + OSL_ENSURE( (meAnchorType == ANCHOR_ONECELL) || (meAnchorType == ANCHOR_TWOCELL), "ShapeAnchor::setCellPos - unexpected 'xdr:from' element" ); pAnchorCell = &maFrom; break; case XDR_TOKEN( to ): - OSL_ENSURE( meType == ANCHOR_TWOCELL, "ShapeAnchor::setCellPos - unexpected 'xdr:to' element" ); + OSL_ENSURE( meAnchorType == ANCHOR_TWOCELL, "ShapeAnchor::setCellPos - unexpected 'xdr:to' element" ); pAnchorCell = &maTo; break; default: @@ -180,7 +170,7 @@ void ShapeAnchor::setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, cons void ShapeAnchor::importVmlAnchor( const OUString& rAnchor ) { - meType = ANCHOR_VML; + meAnchorType = ANCHOR_VML; ::std::vector< OUString > aTokens; sal_Int32 nIndex = 0; @@ -201,216 +191,6 @@ void ShapeAnchor::importVmlAnchor( const OUString& rAnchor ) } } -bool ShapeAnchor::isValidAnchor() const -{ - bool bValid = false; - switch( meType ) - { - case ANCHOR_ABSOLUTE: - OSL_ENSURE( maPos.isValid(), "ShapeAnchor::isValidAnchor - invalid position" ); - OSL_ENSURE( maSize.isValid(), "ShapeAnchor::isValidAnchor - invalid size" ); - bValid = maPos.isValid() && maSize.isValid() && (maSize.Width > 0) && (maSize.Height > 0); - break; - case ANCHOR_ONECELL: - OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::isValidAnchor - invalid from position" ); - OSL_ENSURE( maSize.isValid(), "ShapeAnchor::isValidAnchor - invalid size" ); - bValid = maFrom.isValid() && maSize.isValid() && (maSize.Width > 0) && (maSize.Height > 0); - break; - case ANCHOR_TWOCELL: - case ANCHOR_VML: - OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::isValidAnchor - invalid from position" ); - OSL_ENSURE( maTo.isValid(), "ShapeAnchor::isValidAnchor - invalid to position" ); - bValid = maFrom.isValid() && maTo.isValid() && - ((maFrom.mnCol < maTo.mnCol) || ((maFrom.mnCol == maTo.mnCol) && (maFrom.mnColOffset < maTo.mnColOffset))) && - ((maFrom.mnRow < maTo.mnRow) || ((maFrom.mnRow == maTo.mnRow) && (maFrom.mnRowOffset < maTo.mnRowOffset))); - break; - case ANCHOR_INVALID: - OSL_FAIL( "ShapeAnchor::isValidAnchor - invalid anchor" ); - break; - } - return bValid; -} - -Rectangle ShapeAnchor::calcApiLocation( const Size& rApiSheetSize, const AnchorSizeModel& rEmuSheetSize ) const -{ - AddressConverter& rAddrConv = getAddressConverter(); - UnitConverter& rUnitConv = getUnitConverter(); - Rectangle aApiLoc( -1, -1, -1, -1 ); - Unit eUnitX = (meType == ANCHOR_VML) ? UNIT_SCREENX : UNIT_EMU; - Unit eUnitY = (meType == ANCHOR_VML) ? UNIT_SCREENY : UNIT_EMU; - - // calculate shape position - switch( meType ) - { - case ANCHOR_ABSOLUTE: - OSL_ENSURE( maPos.isValid(), "ShapeAnchor::calcApiLocation - invalid position" ); - if( maPos.isValid() && (maPos.X < rEmuSheetSize.Width) && (maPos.Y < rEmuSheetSize.Height) ) - { - aApiLoc.X = rUnitConv.scaleToMm100( static_cast< double >( maPos.X ), UNIT_EMU ); - aApiLoc.Y = rUnitConv.scaleToMm100( static_cast< double >( maPos.Y ), UNIT_EMU ); - } - break; - case ANCHOR_ONECELL: - case ANCHOR_TWOCELL: - case ANCHOR_VML: - OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcApiLocation - invalid position" ); - if( maFrom.isValid() && rAddrConv.checkCol( maFrom.mnCol, true ) && rAddrConv.checkRow( maFrom.mnRow, true ) ) - { - Point aPoint = getCellPosition( maFrom.mnCol, maFrom.mnRow ); - aApiLoc.X = aPoint.X + rUnitConv.scaleToMm100( static_cast< double >( maFrom.mnColOffset ), eUnitX ); - aApiLoc.Y = aPoint.Y + rUnitConv.scaleToMm100( static_cast< double >( maFrom.mnRowOffset ), eUnitY ); - } - break; - case ANCHOR_INVALID: - OSL_FAIL( "ShapeAnchor::calcApiLocation - invalid anchor" ); - break; - } - - // calculate shape size - if( (aApiLoc.X >= 0) && (aApiLoc.Y >= 0) ) switch( meType ) - { - case ANCHOR_ABSOLUTE: - case ANCHOR_ONECELL: - OSL_ENSURE( maSize.isValid(), "ShapeAnchor::calcApiLocation - invalid size" ); - if( maSize.isValid() ) - { - aApiLoc.Width = ::std::min< sal_Int32 >( - rUnitConv.scaleToMm100( static_cast< double >( maSize.Width ), UNIT_EMU ), - rApiSheetSize.Width - aApiLoc.X ); - aApiLoc.Height = ::std::min< sal_Int32 >( - rUnitConv.scaleToMm100( static_cast< double >( maSize.Height ), UNIT_EMU ), - rApiSheetSize.Height - aApiLoc.Y ); - } - break; - case ANCHOR_TWOCELL: - case ANCHOR_VML: - OSL_ENSURE( maTo.isValid(), "ShapeAnchor::calcApiLocation - invalid position" ); - if( maTo.isValid() ) - { - /* Pass a valid cell address to getCellPosition(), otherwise - nothing is returned, even if either row or column is valid. */ - CellAddress aToCell = rAddrConv.createValidCellAddress( BinAddress( maTo.mnCol, maTo.mnRow ), getSheetIndex(), true ); - Point aPoint = getCellPosition( aToCell.Column, aToCell.Row ); - // width - aApiLoc.Width = rApiSheetSize.Width - aApiLoc.X; - if( aToCell.Column == maTo.mnCol ) - { - aPoint.X += rUnitConv.scaleToMm100( static_cast< double >( maTo.mnColOffset ), eUnitX ); - aApiLoc.Width = ::std::min< sal_Int32 >( aPoint.X - aApiLoc.X + 1, aApiLoc.Width ); - } - // height - aApiLoc.Height = rApiSheetSize.Height - aApiLoc.Y; - if( aToCell.Row == maTo.mnRow ) - { - aPoint.Y += rUnitConv.scaleToMm100( static_cast< double >( maTo.mnRowOffset ), eUnitY ); - aApiLoc.Height = ::std::min< sal_Int32 >( aPoint.Y - aApiLoc.Y + 1, aApiLoc.Height ); - } - } - break; - case ANCHOR_INVALID: - break; - } - - return aApiLoc; -} - -Rectangle ShapeAnchor::calcEmuLocation( const AnchorSizeModel& rEmuSheetSize ) const -{ - AddressConverter& rAddrConv = getAddressConverter(); - UnitConverter& rUnitConv = getUnitConverter(); - - Size aSheetSize( - getLimitedValue< sal_Int32, sal_Int64 >( rEmuSheetSize.Width, 0, SAL_MAX_INT32 ), - getLimitedValue< sal_Int32, sal_Int64 >( rEmuSheetSize.Height, 0, SAL_MAX_INT32 ) ); - Rectangle aLoc( -1, -1, -1, -1 ); - Unit eUnitX = (meType == ANCHOR_VML) ? UNIT_SCREENX : UNIT_EMU; - Unit eUnitY = (meType == ANCHOR_VML) ? UNIT_SCREENY : UNIT_EMU; - - // calculate shape position - switch( meType ) - { - case ANCHOR_ABSOLUTE: - OSL_ENSURE( maPos.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" ); - if( maPos.isValid() && (maPos.X < aSheetSize.Width) && (maPos.Y < aSheetSize.Height) ) - { - aLoc.X = static_cast< sal_Int32 >( maPos.X ); - aLoc.Y = static_cast< sal_Int32 >( maPos.Y ); - } - break; - case ANCHOR_ONECELL: - case ANCHOR_TWOCELL: - case ANCHOR_VML: - OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" ); - if( maFrom.isValid() && rAddrConv.checkCol( maFrom.mnCol, true ) && rAddrConv.checkRow( maFrom.mnRow, true ) ) - { - Point aPoint = getCellPosition( maFrom.mnCol, maFrom.mnRow ); - sal_Int64 nX = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.X, UNIT_EMU ) ) + lclCalcEmu( rUnitConv, maFrom.mnColOffset, eUnitX ); - sal_Int64 nY = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.Y, UNIT_EMU ) ) + lclCalcEmu( rUnitConv, maFrom.mnRowOffset, eUnitY ); - if( (nX < aSheetSize.Width) && (nY < aSheetSize.Height) ) - { - aLoc.X = static_cast< sal_Int32 >( nX ); - aLoc.Y = static_cast< sal_Int32 >( nY ); - } - } - break; - case ANCHOR_INVALID: - OSL_FAIL( "ShapeAnchor::calcEmuLocation - invalid anchor" ); - break; - } - - // calculate shape size - if( (aLoc.X >= 0) && (aLoc.Y >= 0) ) switch( meType ) - { - case ANCHOR_ABSOLUTE: - case ANCHOR_ONECELL: - OSL_ENSURE( maSize.isValid(), "ShapeAnchor::calcEmuLocation - invalid size" ); - if( maSize.isValid() ) - { - aLoc.Width = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( maSize.Width, aSheetSize.Width - aLoc.X ) ); - aLoc.Height = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( maSize.Height, aSheetSize.Height - aLoc.Y ) ); - } - break; - case ANCHOR_TWOCELL: - case ANCHOR_VML: - OSL_ENSURE( maTo.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" ); - if( maTo.isValid() ) - { - /* Pass a valid cell address to getCellPosition(), otherwise - nothing is returned, even if either row or column is valid. */ - CellAddress aToCell = rAddrConv.createValidCellAddress( BinAddress( maTo.mnCol, maTo.mnRow ), getSheetIndex(), true ); - Point aPoint = getCellPosition( aToCell.Column, aToCell.Row ); - sal_Int64 nX = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.X, UNIT_EMU ) ); - sal_Int64 nY = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.Y, UNIT_EMU ) ); - // width - aLoc.Width = aSheetSize.Width - aLoc.X; - if( aToCell.Column == maTo.mnCol ) - { - nX += lclCalcEmu( rUnitConv, maTo.mnColOffset, eUnitX ); - aLoc.Width = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( nX - aLoc.X + 1, aLoc.Width ) ); - } - // height - aLoc.Height = aSheetSize.Height - aLoc.Y; - if( aToCell.Row == maTo.mnRow ) - { - nY += lclCalcEmu( rUnitConv, maTo.mnRowOffset, eUnitY ); - aLoc.Height = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( nY - aLoc.Y + 1, aLoc.Height ) ); - } - } - break; - case ANCHOR_INVALID: - break; - } - - // add 0.75 mm (27,000 EMUs) in X direction to correct display error - if( aLoc.X >= 0 ) - aLoc.X += 27000; - // remove 0.25 mm (9,000 EMUs) in Y direction to correct display error - if( aLoc.Y >= 9000 ) - aLoc.Y -= 9000; - - return aLoc; -} - // ============================================================================ ShapeMacroAttacher::ShapeMacroAttacher( const OUString& rMacroName, const Reference< XShape >& rxShape ) : diff --git a/oox/source/xls/formulaparser.cxx b/oox/source/xls/formulaparser.cxx index a37064e4e8d9..688c45b1cf3a 100644 --- a/oox/source/xls/formulaparser.cxx +++ b/oox/source/xls/formulaparser.cxx @@ -622,12 +622,6 @@ ApiTokenSequence FormulaParserImpl::importBiffFormula( const CellAddress&, Formu return ApiTokenSequence(); } -void FormulaParserImpl::setFormula( FormulaContext& rContext, const ApiTokenSequence& rTokens ) -{ - initializeImport( rContext ); - finalizeImport( rTokens ); -} - OUString FormulaParserImpl::resolveOleTarget( sal_Int32 nRefId, bool bUseRefSheets ) const { const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId, bUseRefSheets ).get(); diff --git a/oox/source/xls/richstring.cxx b/oox/source/xls/richstring.cxx index 5ae29587156f..132eab6339af 100644 --- a/oox/source/xls/richstring.cxx +++ b/oox/source/xls/richstring.cxx @@ -544,11 +544,11 @@ bool RichString::extractPlainString( OUString& orString, const Font* pFirstPorti void RichString::convert( const Reference< XText >& rxText, const Font* pFirstPortionFont ) const { - if (maFontPortions.size() == 1) + if (maTextPortions.size() == 1) { // Set text directly to the cell when the string has only one portion. // It's much faster this way. - RichStringPortion& rPtn = *maFontPortions.front(); + RichStringPortion& rPtn = *maTextPortions.front(); rxText->setString(rPtn.getText()); rPtn.writeFontProperties(rxText, nXfId); return; -- cgit From b6f723660177e50250058159e96436a25bb925dc Mon Sep 17 00:00:00 2001 From: Jan Holesovsky Date: Mon, 23 May 2011 15:25:26 +0200 Subject: oox builds again after the m106 merge. --- oox/source/xls/drawingbase.cxx | 3 +- oox/source/xls/drawingfragment.cxx | 103 ------------------------------------ oox/source/xls/richstring.cxx | 11 ++-- oox/source/xls/sheetdatacontext.cxx | 52 +----------------- oox/source/xls/worksheethelper.cxx | 71 ------------------------- 5 files changed, 7 insertions(+), 233 deletions(-) (limited to 'oox/source') diff --git a/oox/source/xls/drawingbase.cxx b/oox/source/xls/drawingbase.cxx index fc2ab64059c8..555ce91c966b 100755 --- a/oox/source/xls/drawingbase.cxx +++ b/oox/source/xls/drawingbase.cxx @@ -168,8 +168,7 @@ void ShapeAnchor::setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, cons void ShapeAnchor::importVmlAnchor( const OUString& rAnchor ) { - meAnchorType = ANCHOR_TWOCELL; /// VML uses two-cell anchors only - meCellAnchorType = CELLANCHOR_PIXEL; /// VML uses screen pixels for offset values + meAnchorType = ANCHOR_VML; ::std::vector< OUString > aTokens; sal_Int32 nIndex = 0; diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx index c048a3e7d60d..2dd693c7bf67 100644 --- a/oox/source/xls/drawingfragment.cxx +++ b/oox/source/xls/drawingfragment.cxx @@ -86,111 +86,8 @@ sal_Int64 lclCalcEmu( const UnitConverter& rUnitConv, sal_Int64 nValue, Unit eFr } // namespace -// ---------------------------------------------------------------------------- - -AnchorClientDataModel::AnchorClientDataModel() : - mbLocksWithSheet( true ), - mbPrintsWithSheet( true ) -{ -} - // ============================================================================ -ShapeAnchor::ShapeAnchor( const WorksheetHelper& rHelper ) : - WorksheetHelper( rHelper ), - meAnchorType( ANCHOR_INVALID ), - mnEditAs( XML_twoCell ) -{ -} - -void ShapeAnchor::importAnchor( sal_Int32 nElement, const AttributeList& rAttribs ) -{ - switch( nElement ) - { - case XDR_TOKEN( absoluteAnchor ): - meAnchorType = ANCHOR_ABSOLUTE; - break; - case XDR_TOKEN( oneCellAnchor ): - meAnchorType = ANCHOR_ONECELL; - break; - case XDR_TOKEN( twoCellAnchor ): - meAnchorType = ANCHOR_TWOCELL; - mnEditAs = rAttribs.getToken( XML_editAs, XML_twoCell ); - break; - default: - OSL_FAIL( "ShapeAnchor::importAnchor - unexpected element" ); - } -} - -void ShapeAnchor::importPos( const AttributeList& rAttribs ) -{ - OSL_ENSURE( meAnchorType == ANCHOR_ABSOLUTE, "ShapeAnchor::importPos - unexpected 'xdr:pos' element" ); - maPos.X = rAttribs.getHyper( XML_x, 0 ); - maPos.Y = rAttribs.getHyper( XML_y, 0 ); -} - -void ShapeAnchor::importExt( const AttributeList& rAttribs ) -{ - OSL_ENSURE( (meAnchorType == ANCHOR_ABSOLUTE) || (meAnchorType == ANCHOR_ONECELL), "ShapeAnchor::importExt - unexpected 'xdr:ext' element" ); - maSize.Width = rAttribs.getHyper( XML_cx, 0 ); - maSize.Height = rAttribs.getHyper( XML_cy, 0 ); -} - -void ShapeAnchor::importClientData( const AttributeList& rAttribs ) -{ - maClientData.mbLocksWithSheet = rAttribs.getBool( XML_fLocksWithSheet, true ); - maClientData.mbPrintsWithSheet = rAttribs.getBool( XML_fPrintsWithSheet, true ); -} - -void ShapeAnchor::setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue ) -{ - CellAnchorModel* pAnchorCell = 0; - switch( nParentContext ) - { - case XDR_TOKEN( from ): - OSL_ENSURE( (meAnchorType == ANCHOR_ONECELL) || (meAnchorType == ANCHOR_TWOCELL), "ShapeAnchor::setCellPos - unexpected 'xdr:from' element" ); - pAnchorCell = &maFrom; - break; - case XDR_TOKEN( to ): - OSL_ENSURE( meAnchorType == ANCHOR_TWOCELL, "ShapeAnchor::setCellPos - unexpected 'xdr:to' element" ); - pAnchorCell = &maTo; - break; - default: - OSL_FAIL( "ShapeAnchor::setCellPos - unexpected parent element" ); - } - if( pAnchorCell ) switch( nElement ) - { - case XDR_TOKEN( col ): pAnchorCell->mnCol = rValue.toInt32(); break; - case XDR_TOKEN( row ): pAnchorCell->mnRow = rValue.toInt32(); break; - case XDR_TOKEN( colOff ): pAnchorCell->mnColOffset = rValue.toInt64(); break; - case XDR_TOKEN( rowOff ): pAnchorCell->mnRowOffset = rValue.toInt64(); break; - default: OSL_FAIL( "ShapeAnchor::setCellPos - unexpected element" ); - } -} - -void ShapeAnchor::importVmlAnchor( const OUString& rAnchor ) -{ - meAnchorType = ANCHOR_VML; - - ::std::vector< OUString > aTokens; - sal_Int32 nIndex = 0; - while( nIndex >= 0 ) - aTokens.push_back( rAnchor.getToken( 0, ',', nIndex ).trim() ); - - OSL_ENSURE( aTokens.size() >= 8, "ShapeAnchor::importVmlAnchor - missing anchor tokens" ); - if( aTokens.size() >= 8 ) - { - maFrom.mnCol = aTokens[ 0 ].toInt32(); - maFrom.mnColOffset = aTokens[ 1 ].toInt32(); - maFrom.mnRow = aTokens[ 2 ].toInt32(); - maFrom.mnRowOffset = aTokens[ 3 ].toInt32(); - maTo.mnCol = aTokens[ 4 ].toInt32(); - maTo.mnColOffset = aTokens[ 5 ].toInt32(); - maTo.mnRow = aTokens[ 6 ].toInt32(); - maTo.mnRowOffset = aTokens[ 7 ].toInt32(); - } -} - // ============================================================================ ShapeMacroAttacher::ShapeMacroAttacher( const OUString& rMacroName, const Reference< XShape >& rxShape ) : diff --git a/oox/source/xls/richstring.cxx b/oox/source/xls/richstring.cxx index 132eab6339af..6a2bbd9eab1a 100644 --- a/oox/source/xls/richstring.cxx +++ b/oox/source/xls/richstring.cxx @@ -120,18 +120,15 @@ void RichStringPortion::convert( const Reference< XText >& rxText, const Font* p } } -void RichStringPortion::writeFontProperties( const Reference& rxText, sal_Int32 nXfId ) const +void RichStringPortion::writeFontProperties( const Reference& rxText, const Font* pFont ) const { PropertySet aPropSet(rxText); if (mxFont.get()) mxFont->writeToPropertySet(aPropSet, FONT_PROPTYPE_TEXT); - if (const Font* pFont = getStyles().getFontFromCellXf(nXfId).get()) - { - if (pFont->needsRichTextFormat()) - pFont->writeToPropertySet(aPropSet, FONT_PROPTYPE_TEXT); - } + if (lclNeedsRichTextFormat(pFont)) + pFont->writeToPropertySet(aPropSet, FONT_PROPTYPE_TEXT); } // ---------------------------------------------------------------------------- @@ -550,7 +547,7 @@ void RichString::convert( const Reference< XText >& rxText, const Font* pFirstPo // It's much faster this way. RichStringPortion& rPtn = *maTextPortions.front(); rxText->setString(rPtn.getText()); - rPtn.writeFontProperties(rxText, nXfId); + rPtn.writeFontProperties(rxText, pFirstPortionFont); return; } diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx index 045596e9fac9..569126e0ebad 100644 --- a/oox/source/xls/sheetdatacontext.cxx +++ b/oox/source/xls/sheetdatacontext.cxx @@ -163,56 +163,8 @@ void SheetDataContext::onCharacters( const OUString& rChars ) maCellValue = rChars; break; case XLS_TOKEN( f ): - if( maCurrCell.mxCell.is() ) try - { - switch( maCurrCell.mnFormulaType ) - { - case XML_normal: - if( rChars.getLength() > 0 ) - { - Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY_THROW ); - CellFormulaContext aContext( xTokens, maCurrCell.maAddress ); - getFormulaParser().importFormula( aContext, rChars ); - } - break; - - case XML_array: - if( (maCurrCell.maFormulaRef.getLength() > 0) && (rChars.getLength() > 0) ) - { - CellRangeAddress aArrayRange; - Reference< XArrayFormulaTokens > xTokens( getCellRange( maCurrCell.maFormulaRef, &aArrayRange ), UNO_QUERY_THROW ); - ArrayFormulaContext aContext( xTokens, aArrayRange ); - getFormulaParser().importFormula( aContext, rChars ); - } - break; - - case XML_shared: - if( maCurrCell.mnSharedId >= 0 ) - { - if( rChars.getLength() > 0 ) - getSharedFormulas().importSharedFmla( rChars, maCurrCell.maFormulaRef, maCurrCell.mnSharedId, maCurrCell.maAddress ); - Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY_THROW ); - ExtCellFormulaContext aContext( *this, xTokens, maCurrCell.maAddress ); - getSharedFormulas().setSharedFormulaCell( aContext, maCurrCell.mnSharedId ); - } - break; - - case XML_dataTable: - if( maCurrCell.maFormulaRef.getLength() > 0 ) - { - CellRangeAddress aTableRange; - if( getAddressConverter().convertToCellRange( aTableRange, maCurrCell.maFormulaRef, getSheetIndex(), true, true ) ) - setTableOperation( aTableRange, maTableData ); - } - break; - - default: - OSL_FAIL( "SheetDataContext::onEndElement - unknown formula type" ); - } - } - catch( Exception& ) - { - } + if( maFmlaData.mnFormulaType != XML_TOKEN_INVALID ) + maTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, rChars ); break; } } diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index 921cfeb893c3..068c89cde2d9 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -109,77 +109,6 @@ void lclUpdateProgressBar( const ISegmentProgressBarRef& rxProgressBar, double f rxProgressBar->setPosition( fPosition ); } -// ---------------------------------------------------------------------------- - -struct ValueRange -{ - sal_Int32 mnFirst; - sal_Int32 mnLast; - - inline explicit ValueRange( sal_Int32 nValue ) : mnFirst( nValue ), mnLast( nValue ) {} - inline explicit ValueRange( sal_Int32 nFirst, sal_Int32 nLast ) : mnFirst( nFirst ), mnLast( nLast ) {} -}; - -typedef ::std::vector< ValueRange > ValueRangeVector; - -// ---------------------------------------------------------------------------- - -struct ValueRangeComp -{ - inline bool operator()( const ValueRange& rRange, sal_Int32 nValue ) const { return rRange.mnLast < nValue; } -}; - - -// ---------------------------------------------------------------------------- - -class ValueRangeSet -{ -public: - inline explicit ValueRangeSet() {} - - void insert( sal_Int32 nValue ); - void intersect( ValueRangeVector& orRanges, sal_Int32 nFirst, sal_Int32 nLast ) const; - -private: - ValueRangeVector maData; -}; - -void ValueRangeSet::insert( sal_Int32 nValue ) -{ - // find the first range that contains nValue or that follows nValue - ValueRangeVector::iterator aBeg = maData.begin(); - ValueRangeVector::iterator aEnd = maData.end(); - ValueRangeVector::iterator aNext = ::std::lower_bound( aBeg, aEnd, nValue, ValueRangeComp() ); - - // nothing to do if found range contains nValue - if( (aNext == aEnd) || (nValue < aNext->mnFirst) ) - { - ValueRangeVector::iterator aPrev = (aNext == aBeg) ? aEnd : (aNext - 1); - bool bJoinPrev = (aPrev != aEnd) && (aPrev->mnLast + 1 == nValue); - bool bJoinNext = (aNext != aEnd) && (aNext->mnFirst - 1 == nValue); - if( bJoinPrev && bJoinNext ) - { - aPrev->mnLast = aNext->mnLast; - maData.erase( aNext ); - } - else if( bJoinPrev ) - ++aPrev->mnLast; - else if( bJoinNext ) - --aNext->mnFirst; - else - maData.insert( aNext, ValueRange( nValue ) ); - } -} - -void ValueRangeSet::intersect( ValueRangeVector& orRanges, sal_Int32 nFirst, sal_Int32 nLast ) const -{ - orRanges.clear(); - // find the range that contains nFirst or the first range that follows nFirst - ValueRangeVector::const_iterator aIt = ::std::lower_bound( maData.begin(), maData.end(), nFirst, ValueRangeComp() ); - for( ValueRangeVector::const_iterator aEnd = maData.end(); (aIt != aEnd) && (aIt->mnFirst <= nLast); ++aIt ) - orRanges.push_back( ValueRange( ::std::max( aIt->mnFirst, nFirst ), ::std::min( aIt->mnLast, nLast ) ) ); -} - } // namespace // ============================================================================ -- cgit