diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2010-03-03 14:30:52 +0100 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2010-03-03 14:30:52 +0100 |
commit | bd26f484336d86a10dcac5fc0fdbb3d35cb77f06 (patch) | |
tree | 3020687816bdcf531658970acd0daab4f92e147a /sc | |
parent | 22e99ad710239c0604f883f303d91b8c43a71f16 (diff) | |
parent | ed1b30ca81d1b33c5466e1b0e9173b8c88b5f146 (diff) |
CWS-TOOLING: integrate CWS chartshapes
Notes
Notes:
split repo tag: calc_ooo/DEV300_m74
Diffstat (limited to 'sc')
32 files changed, 1963 insertions, 1447 deletions
diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index b5e0f25f516c..bba1543dd403 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -200,8 +200,6 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList ) UINT16 nExcTabCount = rTabInfo.GetXclTabCount(); UINT16 nCodenames = static_cast< UINT16 >( GetExtDocOptions().GetCodeNameCount() ); - rR.pObjRecs = NULL; // per sheet - sal_uInt16 nWriteProtHash = 0; if( SfxObjectShell* pDocShell = GetDocShell() ) { @@ -416,7 +414,7 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList ) Add( new XclExpRecalcId ); // MSODRAWINGGROUP per-document data - Add( new XclMsodrawinggroup( rR, ESCHER_DggContainer ) ); + aRecList.AppendRecord( GetObjectManager().CreateDrawingGroup() ); // Shared string table: SST, EXTSST aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) ); @@ -438,9 +436,8 @@ void ExcTable::FillAsTable( size_t nCodeNameIdx ) DBG_ASSERT( (mnScTab >= 0L) && (mnScTab <= MAXTAB), "-ExcTable::Table(): mnScTab - no ordinary table!" ); DBG_ASSERT( nExcTab <= static_cast<sal_uInt16>(MAXTAB), "-ExcTable::Table(): nExcTab - no ordinary table!" ); - if ( eBiff == EXC_BIFF8 ) - // list holding OBJ records and creating MSODRAWING per-sheet data - rR.pObjRecs = new XclObjList( GetRoot() ); + // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation) + GetObjectManager().StartSheet(); // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records mxCellTable.reset( new XclExpCellTable( GetRoot() ) ); @@ -512,13 +509,8 @@ void ExcTable::FillAsTable( size_t nCodeNameIdx ) if( eBiff == EXC_BIFF8 ) { - rR.pEscher->AddSdrPage(); - //! close Escher group shape and ESCHER_DgContainer - //! opened by XclObjList ctor MSODRAWING - rR.pObjRecs->EndSheet(); // all MSODRAWING and OBJ stuff of this sheet goes here - Add( rR.pObjRecs ); - + aRecList.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab ) ) ); // pivot tables aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) ); } @@ -590,12 +582,13 @@ void ExcTable::FillAsXmlTable( size_t nCodeNameIdx ) // label ranges Add( new XclExpLabelranges( GetRoot() ) ); - rR.pEscher->AddSdrPage(); - //! close Escher group shape and ESCHER_DgContainer - //! opened by XclObjList ctor MSODRAWING - rR.pObjRecs->EndSheet(); - // all MSODRAWING and OBJ stuff of this sheet goes here - Add( rR.pObjRecs ); + // DFF not needed in MSOOXML export +// GetObjectManager().AddSdrPage(); +// //! close Escher group shape and ESCHER_DgContainer +// //! opened by XclExpObjList ctor MSODRAWING +// rR.pObjRecs->EndSheet(); +// // all MSODRAWING and OBJ stuff of this sheet goes here +// Add( rR.pObjRecs ); // pivot tables aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) ); @@ -756,7 +749,7 @@ void ExcDocument::ReadDoc( void ) if ( GetBiff() == EXC_BIFF8 ) { // complete temporary Escher stream - GetOldRoot().pEscher->GetEx()->EndDocument(); + GetObjectManager().EndDocument(); // change tracking if ( GetDoc().GetChangeTrack() ) @@ -771,9 +764,6 @@ void ExcDocument::Write( SvStream& rSvStrm ) { InitializeSave(); - if ( GetBiff() == EXC_BIFF8 ) - GetOldRoot().pEscher->GetStrm().Seek(0); // ready for take off - XclExpStream aXclStrm( rSvStrm, GetRoot() ); aHeader.Write( aXclStrm ); @@ -807,8 +797,6 @@ void ExcDocument::WriteXml( SvStream& rStrm ) XclExpXmlStream aStrm( ::comphelper::getProcessServiceFactory(), rStrm, GetRoot() ); - GetOldRoot().pEscher->GetStrm().Seek(0); // ready for take off - sax_fastparser::FSHelperPtr& rWorkbook = aStrm.GetCurrentStream(); rWorkbook->startElement( XML_workbook, XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main", diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx index d49c04624cdf..9a66325db419 100644 --- a/sc/source/filter/excel/excrecds.cxx +++ b/sc/source/filter/excel/excrecds.cxx @@ -88,6 +88,7 @@ #include "formula/errorcodes.hxx" #include "excdoc.hxx" +#include "xeescher.hxx" #include "xeformula.hxx" #include "xelink.hxx" #include "xename.hxx" @@ -976,8 +977,8 @@ void ExcAutoFilterRecs::AddObjRecs() ScAddress aAddr( pFilterInfo->GetStartPos() ); for( SCCOL nObj = 0, nCount = pFilterInfo->GetColCount(); nObj < nCount; nObj++ ) { - XclObjDropDown* pObj = new XclObjDropDown( GetRoot(), aAddr, IsFiltered( nObj ) ); - GetOldRoot().pObjRecs->Add( pObj ); + XclObj* pObjRec = new XclObjDropDown( GetObjectManager(), aAddr, IsFiltered( nObj ) ); + GetObjectManager().AddObj( pObjRec ); aAddr.IncCol( 1 ); } } diff --git a/sc/source/filter/excel/exctools.cxx b/sc/source/filter/excel/exctools.cxx index ba4a8339c829..e6453c2f11e2 100644 --- a/sc/source/filter/excel/exctools.cxx +++ b/sc/source/filter/excel/exctools.cxx @@ -76,9 +76,6 @@ RootData::RootData( void ) pTabId = NULL; pUserBViewList = NULL; - pObjRecs = NULL; - pEscher = NULL; - pIR = NULL; pER = NULL; } diff --git a/sc/source/filter/excel/expop2.cxx b/sc/source/filter/excel/expop2.cxx index d28fa2063c91..dbe70ae6a0ee 100644 --- a/sc/source/filter/excel/expop2.cxx +++ b/sc/source/filter/excel/expop2.cxx @@ -141,14 +141,11 @@ ExportBiff8::ExportBiff8( XclExpRootData& rExpData, SvStream& rStrm ) : ExportBiff5( rExpData, rStrm ) { pExcRoot->eDateiTyp = Biff8; - pExcRoot->pEscher = new XclEscher( GetRoot(), GetDoc().GetTableCount() ); } ExportBiff8::~ExportBiff8() { - delete pExcRoot->pEscher; - pExcRoot->pEscher = NULL; } @@ -159,16 +156,12 @@ ExportXml2007::ExportXml2007( XclExpRootData& rExpData, SvStream& rStrm ) pExcRoot = &GetOldRoot(); pExcRoot->pER = this; pExcRoot->eDateiTyp = Biff8; - pExcRoot->pEscher = new XclEscher( *pExcRoot->pER, GetDoc().GetTableCount() ); pExcDoc = new ExcDocument( *this ); } ExportXml2007::~ExportXml2007() { - delete pExcRoot->pEscher; - pExcRoot->pEscher = NULL; - delete pExcDoc; } diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx index dfb3a69c219a..e62f050f2351 100644 --- a/sc/source/filter/excel/impop.cxx +++ b/sc/source/filter/excel/impop.cxx @@ -1241,7 +1241,7 @@ void ImportExcel::PostDocLoad( void ) } // #111099# open forms in alive mode (has no effect, if no controls in document) - pDocObj->setPropertyValue( CREATE_OUSTRING( SC_UNO_APPLYFMDES ), ::comphelper::makeBoolAny( sal_False ) ); + pDocObj->setPropertyValue( CREATE_OUSTRING( SC_UNO_APPLYFMDES ), uno::Any( false ) ); } // enables extended options to be set to the view after import diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index 91b749030dd7..637a4777c8ed 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -64,6 +64,8 @@ FltError ImportExcel::Read( void ) XclImpXFBuffer& rXFBfr = GetXFBuffer(); XclImpNameManager& rNameMgr = GetNameManager(); XclImpObjectManager& rObjMgr = GetObjectManager(); + (void)rObjMgr; + // call to GetCurrSheetDrawing() cannot be cached (changes in new sheets) enum Zustand { Z_BiffNull, // Nicht in gueltigem Biff-Format @@ -246,7 +248,7 @@ FltError ImportExcel::Read( void ) case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break; case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345] case 0x18: rNameMgr.ReadName( maStrm ); break; - case 0x1C: rObjMgr.ReadNote( maStrm ); break; + case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break; case 0x1D: rTabViewSett.ReadSelection( maStrm ); break; case 0x1E: rNumFmtBfr.ReadFormat( maStrm ); break; case 0x20: Columndefault(); break; // COLUMNDEFAULT[ 2 ] @@ -309,7 +311,7 @@ FltError ImportExcel::Read( void ) case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345] case 0x1A: case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break; - case 0x1C: rObjMgr.ReadNote( maStrm ); break; + case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break; case 0x1D: rTabViewSett.ReadSelection( maStrm ); break; case 0x1E: rNumFmtBfr.ReadFormat( maStrm ); break; case 0x22: Rec1904(); break; // 1904 [ 2345] @@ -328,7 +330,7 @@ FltError ImportExcel::Read( void ) case 0x41: rTabViewSett.ReadPane( maStrm ); break; case 0x42: Codepage(); break; // CODEPAGE [ 2345] case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ] - case 0x5D: rObjMgr.ReadObj( maStrm ); break; + case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break; case 0x7D: Colinfo(); break; // COLINFO [ 345] case 0x8C: Country(); break; // COUNTRY [ 345] case 0x92: rPal.ReadPalette( maStrm ); break; @@ -380,7 +382,7 @@ FltError ImportExcel::Read( void ) case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345] case 0x1A: case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break; - case 0x1C: rObjMgr.ReadNote( maStrm ); break; + case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break; case 0x1D: rTabViewSett.ReadSelection( maStrm ); break; case 0x22: Rec1904(); break; // 1904 [ 2345] case 0x26: @@ -399,7 +401,7 @@ FltError ImportExcel::Read( void ) case 0x42: Codepage(); break; // CODEPAGE [ 2345] case 0x55: DefColWidth(); break; case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ] - case 0x5D: rObjMgr.ReadObj( maStrm ); break; + case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break; case 0x7D: Colinfo(); break; // COLINFO [ 345] case 0x8C: Country(); break; // COUNTRY [ 345] case 0x92: rPal.ReadPalette( maStrm ); break; @@ -496,7 +498,7 @@ FltError ImportExcel::Read( void ) case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break; case 0x1A: case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break; - case 0x1C: rObjMgr.ReadNote( maStrm ); break; + case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break; case 0x1D: rTabViewSett.ReadSelection( maStrm ); break; case 0x2F: // FILEPASS [ 2345] eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm ); @@ -507,7 +509,7 @@ FltError ImportExcel::Read( void ) case 0x42: Codepage(); break; // CODEPAGE [ 2345] case 0x55: DefColWidth(); break; case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ] - case 0x5D: rObjMgr.ReadObj( maStrm ); break; + case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break; case 0x7D: Colinfo(); break; // COLINFO [ 345] case 0x8C: Country(); break; // COUNTRY [ 345] case 0x8F: Bundleheader(); break; // BUNDLEHEADER [ 4 ] @@ -666,7 +668,7 @@ FltError ImportExcel::Read( void ) case 0x14: case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break; case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345] - case 0x1C: rObjMgr.ReadNote( maStrm ); break; + case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break; case 0x1D: rTabViewSett.ReadSelection( maStrm ); break; case 0x23: Externname25(); break; // EXTERNNAME [ 2 5] case 0x26: @@ -680,7 +682,7 @@ FltError ImportExcel::Read( void ) if( eLastErr != ERRCODE_NONE ) eAkt = Z_Ende; break; - case 0x5D: rObjMgr.ReadObj( maStrm ); break; + case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break; case 0x83: case 0x84: rPageSett.ReadCenter( maStrm ); break; case 0xA0: rTabViewSett.ReadScl( maStrm ); break; @@ -714,7 +716,7 @@ FltError ImportExcel::Read( void ) aIn.StoreGlobalPosition(); // und Position merken break; case Biff5C: // chart sheet - GetObjectManager().ReadTabChart( maStrm ); + GetCurrSheetDrawing().ReadTabChart( maStrm ); Eof(); GetTracer().TraceChartOnlySheet(); break; @@ -799,6 +801,7 @@ FltError ImportExcel8::Read( void ) XclImpNameManager& rNameMgr = GetNameManager(); XclImpLinkManager& rLinkMgr = GetLinkManager(); XclImpObjectManager& rObjMgr = GetObjectManager(); + // call to GetCurrSheetDrawing() cannot be cached (changes in new sheets) XclImpCondFormatManager& rCondFmtMgr = GetCondFormatManager(); XclImpPivotTableManager& rPTableMgr = GetPivotTableManager(); XclImpWebQueryBuffer& rWQBfr = GetWebQueryBuffer(); @@ -1040,7 +1043,7 @@ FltError ImportExcel8::Read( void ) aIn.StoreGlobalPosition(); break; case Biff8C: // chart sheet - rObjMgr.ReadTabChart( maStrm ); + GetCurrSheetDrawing().ReadTabChart( maStrm ); Eof(); GetTracer().TraceChartOnlySheet(); break; @@ -1161,10 +1164,10 @@ FltError ImportExcel8::Read( void ) case EXC_ID_SETUP: rPageSett.ReadSetup( maStrm ); break; case EXC_ID8_IMGDATA: rPageSett.ReadImgData( maStrm ); break; - case EXC_ID_MSODRAWING: rObjMgr.ReadMsoDrawing( maStrm ); break; + case EXC_ID_MSODRAWING: GetCurrSheetDrawing().ReadMsoDrawing( maStrm ); break; // #i61786# weird documents: OBJ without MSODRAWING -> read in BIFF5 format - case EXC_ID_OBJ: rObjMgr.ReadObj( maStrm ); break; - case EXC_ID_NOTE: rObjMgr.ReadNote( maStrm ); break; + case EXC_ID_OBJ: GetCurrSheetDrawing().ReadObj( maStrm ); break; + case EXC_ID_NOTE: GetCurrSheetDrawing().ReadNote( maStrm ); break; case EXC_ID_HLINK: XclImpHyperlink::ReadHlink( maStrm ); break; case EXC_ID_LABELRANGES: XclImpLabelranges::ReadLabelranges( maStrm ); break; diff --git a/sc/source/filter/excel/xechart.cxx b/sc/source/filter/excel/xechart.cxx index 637aacd4e722..1564b2db834e 100644 --- a/sc/source/filter/excel/xechart.cxx +++ b/sc/source/filter/excel/xechart.cxx @@ -33,6 +33,7 @@ #include <com/sun/star/i18n/XBreakIterator.hpp> #include <com/sun/star/i18n/ScriptType.hpp> #include <com/sun/star/drawing/FillStyle.hpp> +#include <com/sun/star/drawing/XShapes.hpp> #include <com/sun/star/chart/ChartAxisLabelPosition.hpp> #include <com/sun/star/chart/ChartAxisPosition.hpp> #include <com/sun/star/chart/DataLabelPlacement.hpp> @@ -63,6 +64,7 @@ #include "compiler.hxx" #include "tokenarray.hxx" #include "token.hxx" +#include "xeescher.hxx" #include "xeformula.hxx" #include "xehelper.hxx" #include "xepage.hxx" @@ -77,6 +79,7 @@ using ::com::sun::star::uno::Exception; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::i18n::XBreakIterator; using ::com::sun::star::frame::XModel; +using ::com::sun::star::drawing::XShapes; using ::com::sun::star::chart2::XChartDocument; using ::com::sun::star::chart2::XDiagram; using ::com::sun::star::chart2::XCoordinateSystemContainer; @@ -97,7 +100,6 @@ using ::com::sun::star::chart2::XTitled; using ::com::sun::star::chart2::XTitle; using ::com::sun::star::chart2::XFormattedString; using ::com::sun::star::chart2::XColorScheme; - using ::com::sun::star::chart2::data::XDataSource; using ::com::sun::star::chart2::data::XLabeledDataSequence; using ::com::sun::star::chart2::data::XDataSequence; @@ -2766,6 +2768,15 @@ XclExpChAxesSet::XclExpChAxesSet( const XclExpChRoot& rRoot, sal_uInt16 nAxesSet { maData.mnAxesSetId = nAxesSetId; SetFutureRecordContext( 0, nAxesSetId ); + + /* Need to set a reasonable size for the plot area, otherwise Excel will + move away embedded shapes while auto-sizing the plot area. This is just + a wild guess, but will be fixed with implementing manual positioning of + chart elements. */ + maData.maRect.mnX = 262; + maData.maRect.mnY = 626; + maData.maRect.mnWidth = 3187; + maData.maRect.mnHeight = 2633; } sal_uInt16 XclExpChAxesSet::Convert( Reference< XDiagram > xDiagram, sal_uInt16 nFirstGroupIdx ) @@ -2904,6 +2915,14 @@ bool XclExpChAxesSet::Is3dChart() const void XclExpChAxesSet::WriteSubRecords( XclExpStream& rStrm ) { + /* Need to set a reasonable size for the plot area, otherwise Excel will + move away embedded shapes while auto-sizing the plot area. This is just + a wild guess, but will be fixed with implementing manual positioning of + chart elements. */ + rStrm.StartRecord( EXC_ID_CHFRAMEPOS, 20 ); + rStrm << sal_uInt16(2) << sal_uInt16(2) << sal_uInt32(66) << sal_uInt32(626) << sal_uInt32(3384) << sal_uInt32(3231); + rStrm.EndRecord(); + lclSaveRecord( rStrm, mxXAxis ); lclSaveRecord( rStrm, mxYAxis ); lclSaveRecord( rStrm, mxZAxis ); @@ -2965,8 +2984,8 @@ XclExpChChart::XclExpChChart( const XclExpRoot& rRoot, maRect.mnHeight = static_cast< sal_Int32 >( aPtSize.Height() << 16 ); // global chart properties (default values) - ::set_flag( maProps.mnFlags, EXC_CHPROPS_MANSERIES ); ::set_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY, false ); + ::set_flag( maProps.mnFlags, EXC_CHPROPS_MANPLOTAREA ); maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_SKIP; // always create both axes set objects @@ -3073,12 +3092,49 @@ void XclExpChChart::WriteBody( XclExpStream& rStrm ) // ---------------------------------------------------------------------------- +XclExpChartDrawing::XclExpChartDrawing( const XclExpRoot& rRoot, + const Reference< XModel >& rxModel, const Size& rChartSize ) : + XclExpRoot( rRoot ) +{ + if( (rChartSize.Width() > 0) && (rChartSize.Height() > 0) ) + { + ScfPropertySet aPropSet( rxModel ); + Reference< XShapes > xShapes; + if( aPropSet.GetProperty( xShapes, EXC_CHPROP_ADDITIONALSHAPES ) && xShapes.is() && (xShapes->getCount() > 0) ) + { + /* Create a new independent object manager with own DFF stream for the + DGCONTAINER, pass global manager as parent for shared usage of + global DFF data (picture container etc.). */ + mxObjMgr.reset( new XclExpEmbeddedObjectManager( GetObjectManager(), rChartSize, EXC_CHART_UNIT, EXC_CHART_UNIT ) ); + // initialize the drawing object list + mxObjMgr->StartSheet(); + // process the draw page (convert all shapes) + mxObjRecs = mxObjMgr->ProcessDrawing( xShapes ); + // finalize the DFF stream + mxObjMgr->EndDocument(); + } + } +} + +XclExpChartDrawing::~XclExpChartDrawing() +{ +} + +void XclExpChartDrawing::Save( XclExpStream& rStrm ) +{ + if( mxObjRecs.is() ) + mxObjRecs->Save( rStrm ); +} + +// ---------------------------------------------------------------------------- + XclExpChart::XclExpChart( const XclExpRoot& rRoot, Reference< XModel > xModel, const Size& rSize ) : XclExpSubStream( EXC_BOF_CHART ), XclExpRoot( rRoot ) { AppendNewRecord( new XclExpChartPageSettings( rRoot ) ); AppendNewRecord( new XclExpBoolRecord( EXC_ID_PROTECT, false ) ); + AppendNewRecord( new XclExpChartDrawing( rRoot, xModel, rSize ) ); AppendNewRecord( new XclExpUInt16Record( EXC_ID_CHUNITS, EXC_CHUNITS_TWIPS ) ); Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY ); diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx index 1f46bdb66178..2df531a9b932 100644 --- a/sc/source/filter/excel/xeescher.cxx +++ b/sc/source/filter/excel/xeescher.cxx @@ -28,9 +28,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" -#include <set> -#include <iterator> - #include "xeescher.hxx" #include <com/sun/star/lang/XServiceInfo.hpp> @@ -45,12 +42,15 @@ #include <com/sun/star/form/binding/XListEntrySource.hpp> #include <com/sun/star/script/ScriptEventDescriptor.hpp> +#include <set> #include <rtl/ustrbuf.h> #include <vcl/bmpacc.hxx> #include <svx/svdoole2.hxx> #include <svx/svdocapt.hxx> #include <editeng/outlobj.hxx> #include <editeng/editobj.hxx> +#include <unotools/tempfile.hxx> +#include <unotools/ucbstreamhelper.hxx> #include "editutil.hxx" #include "unonames.hxx" @@ -75,6 +75,7 @@ using ::com::sun::star::uno::Sequence; using ::com::sun::star::lang::XServiceInfo; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::drawing::XShape; +using ::com::sun::star::drawing::XShapes; using ::com::sun::star::frame::XModel; using ::com::sun::star::embed::XEmbeddedObject; using ::com::sun::star::awt::XControlModel; @@ -86,6 +87,163 @@ using ::com::sun::star::script::ScriptEventDescriptor; using ::com::sun::star::table::CellAddress; using ::com::sun::star::table::CellRangeAddress; +// Escher client anchor ======================================================= + +XclExpDffAnchorBase::XclExpDffAnchorBase( const XclExpRoot& rRoot, sal_uInt16 nFlags ) : + XclExpRoot( rRoot ), + mnFlags( nFlags ) +{ +} + +void XclExpDffAnchorBase::SetFlags( const SdrObject& rSdrObj ) +{ + ImplSetFlags( rSdrObj ); +} + +void XclExpDffAnchorBase::SetSdrObject( const SdrObject& rSdrObj ) +{ + ImplSetFlags( rSdrObj ); + ImplCalcAnchorRect( rSdrObj.GetCurrentBoundRect(), MAP_100TH_MM ); +} + +void XclExpDffAnchorBase::WriteDffData( EscherEx& rEscherEx ) const +{ + rEscherEx.AddAtom( 18, ESCHER_ClientAnchor ); + rEscherEx.GetStream() << mnFlags << maAnchor; +} + +void XclExpDffAnchorBase::WriteData( EscherEx& rEscherEx, const Rectangle& rRect ) +{ + // the passed rectangle is in twips + ImplCalcAnchorRect( rRect, MAP_TWIP ); + WriteDffData( rEscherEx ); +} + +void XclExpDffAnchorBase::ImplSetFlags( const SdrObject& ) +{ + OSL_ENSURE( false, "XclExpDffAnchorBase::ImplSetFlags - not implemented" ); +} + +void XclExpDffAnchorBase::ImplCalcAnchorRect( const Rectangle&, MapUnit ) +{ + OSL_ENSURE( false, "XclExpDffAnchorBase::ImplCalcAnchorRect - not implemented" ); +} + +// ---------------------------------------------------------------------------- + +XclExpDffSheetAnchor::XclExpDffSheetAnchor( const XclExpRoot& rRoot ) : + XclExpDffAnchorBase( rRoot ), + mnScTab( rRoot.GetCurrScTab() ) +{ +} + +void XclExpDffSheetAnchor::ImplSetFlags( const SdrObject& rSdrObj ) +{ + // Special case "page anchor" (X==0,Y==1) -> lock pos and size. + const Point& rPos = rSdrObj.GetAnchorPos(); + mnFlags = ((rPos.X() == 0) && (rPos.Y() == 1)) ? EXC_ESC_ANCHOR_LOCKED : 0; +} + +void XclExpDffSheetAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit ) +{ + maAnchor.SetRect( GetDoc(), mnScTab, rRect, eMapUnit ); +} + +// ---------------------------------------------------------------------------- + +XclExpDffEmbeddedAnchor::XclExpDffEmbeddedAnchor( const XclExpRoot& rRoot, + const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ) : + XclExpDffAnchorBase( rRoot ), + maPageSize( rPageSize ), + mnScaleX( nScaleX ), + mnScaleY( nScaleY ) +{ +} + +void XclExpDffEmbeddedAnchor::ImplSetFlags( const SdrObject& /*rSdrObj*/ ) +{ + // TODO (unsupported feature): fixed size +} + +void XclExpDffEmbeddedAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit ) +{ + maAnchor.SetRect( maPageSize, mnScaleX, mnScaleY, rRect, eMapUnit, true ); +} + +// ---------------------------------------------------------------------------- + +XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ) : + XclExpDffAnchorBase( rRoot, EXC_ESC_ANCHOR_SIZELOCKED ) +{ + maAnchor.SetRect( GetDoc(), rRoot.GetCurrScTab(), rRect, MAP_100TH_MM ); +} + +// ---------------------------------------------------------------------------- + +XclExpDffDropDownAnchor::XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos ) : + XclExpDffAnchorBase( rRoot, EXC_ESC_ANCHOR_POSLOCKED ) +{ + GetAddressConverter().ConvertAddress( maAnchor.maFirst, rScPos, true ); + maAnchor.maLast.mnCol = maAnchor.maFirst.mnCol + 1; + maAnchor.maLast.mnRow = maAnchor.maFirst.mnRow + 1; + maAnchor.mnLX = maAnchor.mnTY = maAnchor.mnRX = maAnchor.mnBY = 0; +} + +// MSODRAWING* records ======================================================== + +XclExpMsoDrawingBase::XclExpMsoDrawingBase( XclEscherEx& rEscherEx, sal_uInt16 nRecId ) : + XclExpRecord( nRecId ), + mrEscherEx( rEscherEx ), + mnFragmentKey( rEscherEx.InitNextDffFragment() ) +{ +} + +void XclExpMsoDrawingBase::WriteBody( XclExpStream& rStrm ) +{ + OSL_ENSURE( mrEscherEx.GetStreamPos() == mrEscherEx.GetDffFragmentPos( mnFragmentKey ), + "XclExpMsoDrawingBase::WriteBody - DFF stream position mismatch" ); + rStrm.CopyFromStream( mrEscherEx.GetStream(), mrEscherEx.GetDffFragmentSize( mnFragmentKey ) ); +} + +// ---------------------------------------------------------------------------- + +XclExpMsoDrawingGroup::XclExpMsoDrawingGroup( XclEscherEx& rEscherEx ) : + XclExpMsoDrawingBase( rEscherEx, EXC_ID_MSODRAWINGGROUP ) +{ + SvStream& rDffStrm = mrEscherEx.GetStream(); + + // write the DGGCONTAINER with some default settings + mrEscherEx.OpenContainer( ESCHER_DggContainer ); + + // TODO: stuff the OPT atom with our own document defaults? + static const sal_uInt8 spnDffOpt[] = { + 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01, + 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00, + 0x00, 0x08 + }; + mrEscherEx.AddAtom( sizeof( spnDffOpt ), ESCHER_OPT, 3, 3 ); + rDffStrm.Write( spnDffOpt, sizeof( spnDffOpt ) ); + + // SPLITMENUCOLORS contains colors in toolbar + static const sal_uInt8 spnDffSplitMenuColors[] = { + 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08, + 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10 + }; + mrEscherEx.AddAtom( sizeof( spnDffSplitMenuColors ), ESCHER_SplitMenuColors, 0, 4 ); + rDffStrm.Write( spnDffSplitMenuColors, sizeof( spnDffSplitMenuColors ) ); + + // close the DGGCONTAINER + mrEscherEx.CloseContainer(); + mrEscherEx.UpdateDffFragmentEnd(); +} + +// ---------------------------------------------------------------------------- + +XclExpMsoDrawing::XclExpMsoDrawing( XclEscherEx& rEscherEx ) : + XclExpMsoDrawingBase( rEscherEx, EXC_ID_MSODRAWING ) +{ +} + // ============================================================================ XclExpImgData::XclExpImgData( const Graphic& rGraphic, sal_uInt16 nRecId ) : @@ -221,10 +379,10 @@ void XclExpControlHelper::WriteFormulaSubRec( XclExpStream& rStrm, sal_uInt16 nS #if EXC_EXP_OCX_CTRL -XclExpOcxControlObj::XclExpOcxControlObj( const XclExpRoot& rRoot, Reference< XShape > xShape, - const String& rClassName, sal_uInt32 nStrmStart, sal_uInt32 nStrmSize ) : - XclObj( rRoot, EXC_OBJTYPE_PICTURE, true ), - XclExpControlHelper( rRoot ), +XclExpOcxControlObj::XclExpOcxControlObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape, + const Rectangle* pChildAnchor, const String& rClassName, sal_uInt32 nStrmStart, sal_uInt32 nStrmSize ) : + XclObj( rObjMgr, EXC_OBJTYPE_PICTURE, true ), + XclExpControlHelper( rObjMgr.GetRoot() ), maClassName( rClassName ), mnStrmStart( nStrmStart ), mnStrmSize( nStrmSize ) @@ -238,11 +396,10 @@ XclExpOcxControlObj::XclExpOcxControlObj( const XclExpRoot& rRoot, Reference< XS SetAutoLine( FALSE ); // fill DFF property set - XclEscherEx& rEscherEx = *pMsodrawing->GetEscherEx(); - rEscherEx.OpenContainer( ESCHER_SpContainer ); - rEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_OLESHAPE ); + mrEscherEx.OpenContainer( ESCHER_SpContainer ); + mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_OLESHAPE ); Rectangle aDummyRect; - EscherPropertyContainer aPropOpt( rEscherEx, rEscherEx.QueryPicStream(), aDummyRect ); + EscherPropertyContainer aPropOpt( mrEscherEx, mrEscherEx.QueryPicStream(), aDummyRect ); aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x08000040 ); aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field @@ -263,15 +420,14 @@ XclExpOcxControlObj::XclExpOcxControlObj( const XclExpRoot& rRoot, Reference< XS } // write DFF property set to stream - aPropOpt.Commit( rEscherEx.GetStream() ); + aPropOpt.Commit( mrEscherEx.GetStream() ); // anchor - if( SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape( xShape ) ) - XclExpDffAnchor( rRoot, *pSdrObj ).WriteData( rEscherEx ); - rEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record - rEscherEx.CloseContainer(); // ESCHER_SpContainer + ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape ), pChildAnchor ); - pMsodrawing->UpdateStopPos(); + mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record + mrEscherEx.CloseContainer(); // ESCHER_SpContainer + mrEscherEx.UpdateDffFragmentEnd(); // spreadsheet links ConvertSheetLinks( xShape ); @@ -328,9 +484,9 @@ void XclExpOcxControlObj::WriteSubRecs( XclExpStream& rStrm ) #else -XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot& rRoot, Reference< XShape > xShape ) : - XclObj( rRoot, EXC_OBJTYPE_UNKNOWN, true ), - XclExpControlHelper( rRoot ), +XclExpTbxControlObj::XclExpTbxControlObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape, const Rectangle* pChildAnchor ) : + XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN, true ), + XclExpControlHelper( rObjMgr.GetRoot() ), mnHeight( 0 ), mnState( 0 ), mnLineCount( 0 ), @@ -384,9 +540,8 @@ XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot& rRoot, Reference< XS SetAutoLine( FALSE ); // fill DFF property set - XclEscherEx& rEscherEx = *pMsodrawing->GetEscherEx(); - rEscherEx.OpenContainer( ESCHER_SpContainer ); - rEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); + mrEscherEx.OpenContainer( ESCHER_SpContainer ); + mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); EscherPropertyContainer aPropOpt; bool bVisible = aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "EnableVisible" ) ); aPropOpt.AddOpt( ESCHER_Prop_fPrint, bVisible ? 0x00080000 : 0x00080002 ); // visible flag @@ -404,13 +559,13 @@ XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot& rRoot, Reference< XS aPropOpt.AddOpt( ESCHER_Prop_wzName, aCtrlName ); // write DFF property set to stream - aPropOpt.Commit( rEscherEx.GetStream() ); + aPropOpt.Commit( mrEscherEx.GetStream() ); // anchor - if( SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape( xShape ) ) - XclExpDffAnchor( rRoot, *pSdrObj ).WriteData( rEscherEx ); - rEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record - pMsodrawing->UpdateStopPos(); + ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape ), pChildAnchor ); + + mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record + mrEscherEx.UpdateDffFragmentEnd(); // control label OUString aString; @@ -419,9 +574,9 @@ XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot& rRoot, Reference< XS /* Be sure to construct the MSODRAWING record containing the ClientTextbox atom after the base OBJ's MSODRAWING record data is completed. */ - pClientTextbox = new XclMsodrawing( GetRoot() ); - pClientTextbox->GetEscherEx()->AddAtom( 0, ESCHER_ClientTextbox ); // TXO record - pClientTextbox->UpdateStopPos(); + pClientTextbox = new XclExpMsoDrawing( mrEscherEx ); + mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record + mrEscherEx.UpdateDffFragmentEnd(); sal_uInt16 nXclFont = EXC_FONT_APP; if( aString.getLength() > 0 ) @@ -437,7 +592,7 @@ XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot& rRoot, Reference< XS pTxo->SetVerAlign( EXC_OBJ_VER_CENTER ); } - rEscherEx.CloseContainer(); // ESCHER_SpContainer + mrEscherEx.CloseContainer(); // ESCHER_SpContainer // other properties aCtrlProp.GetProperty( mnLineCount, CREATE_OUSTRING( "LineCount" ) ); @@ -763,14 +918,13 @@ void XclExpTbxControlObj::WriteSbs( XclExpStream& rStrm ) // ---------------------------------------------------------------------------- -XclExpChartObj::XclExpChartObj( const XclExpRoot& rRoot, Reference< XShape > xShape ) : - XclObj( rRoot, EXC_OBJTYPE_CHART ), - XclExpRoot( rRoot ) +XclExpChartObj::XclExpChartObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape, const Rectangle* pChildAnchor ) : + XclObj( rObjMgr, EXC_OBJTYPE_CHART ), + XclExpRoot( rObjMgr.GetRoot() ) { // create the MSODRAWING record contents for the chart object - XclEscherEx& rEscherEx = *pMsodrawing->GetEscherEx(); - rEscherEx.OpenContainer( ESCHER_SpContainer ); - rEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); + mrEscherEx.OpenContainer( ESCHER_SpContainer ); + mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); EscherPropertyContainer aPropOpt; aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 ); aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); @@ -781,17 +935,16 @@ XclExpChartObj::XclExpChartObj( const XclExpRoot& rRoot, Reference< XShape > xSh aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080008 ); aPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x00020000 ); aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x00080000 ); - aPropOpt.Commit( rEscherEx.GetStream() ); + aPropOpt.Commit( mrEscherEx.GetStream() ); - // client anchor + // anchor SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape( xShape ); - if( pSdrObj ) - XclExpDffAnchor( rRoot, *pSdrObj ).WriteData( rEscherEx ); + ImplWriteAnchor( GetRoot(), pSdrObj, pChildAnchor ); // client data (the following OBJ record) - rEscherEx.AddAtom( 0, ESCHER_ClientData ); - rEscherEx.CloseContainer(); // ESCHER_SpContainer - pMsodrawing->UpdateStopPos(); + mrEscherEx.AddAtom( 0, ESCHER_ClientData ); + mrEscherEx.CloseContainer(); // ESCHER_SpContainer + mrEscherEx.UpdateDffFragmentEnd(); // load the chart OLE object if( SdrOle2Obj* pSdrOleObj = dynamic_cast< SdrOle2Obj* >( pSdrObj ) ) @@ -804,7 +957,7 @@ XclExpChartObj::XclExpChartObj( const XclExpRoot& rRoot, Reference< XShape > xSh ::com::sun::star::awt::Rectangle aBoundRect; aShapeProp.GetProperty( aBoundRect, CREATE_OUSTRING( "BoundRect" ) ); Size aSize( aBoundRect.Width, aBoundRect.Height ); - mxChart.reset( new XclExpChart( rRoot, xModel, aSize ) ); + mxChart.reset( new XclExpChart( GetRoot(), xModel, aSize ) ); } XclExpChartObj::~XclExpChartObj() @@ -849,7 +1002,7 @@ XclExpNote::XclExpNote( const XclExpRoot& rRoot, const ScAddress& rScPos, if( pScNote ) if( SdrCaptionObj* pCaption = pScNote->GetOrCreateCaption( maScPos ) ) if( const OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() ) - mnObjId = rRoot.GetOldRoot().pObjRecs->Add( new XclObjComment( rRoot, pCaption->GetLogicRect(), pOPO->GetTextObject(), pCaption, mbVisible ) ); + mnObjId = rRoot.GetObjectManager().AddObj( new XclObjComment( rRoot.GetObjectManager(), pCaption->GetLogicRect(), pOPO->GetTextObject(), pCaption, mbVisible ) ); SetRecSize( 9 + maAuthor.GetSize() ); } @@ -1007,5 +1160,125 @@ void XclExpComments::SaveXml( XclExpXmlStream& rStrm ) rStrm.PopStream(); } +// object manager ============================================================= + +XclExpObjectManager::XclExpObjectManager( const XclExpRoot& rRoot ) : + XclExpRoot( rRoot ) +{ + InitStream( true ); + mxEscherEx.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm ) ); +} + +XclExpObjectManager::XclExpObjectManager( const XclExpObjectManager& rParent ) : + XclExpRoot( rParent.GetRoot() ) +{ + InitStream( false ); + mxEscherEx.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm, rParent.mxEscherEx.get() ) ); +} + +XclExpObjectManager::~XclExpObjectManager() +{ +} + +XclExpDffAnchorBase* XclExpObjectManager::CreateDffAnchor() const +{ + return new XclExpDffSheetAnchor( GetRoot() ); +} + +ScfRef< XclExpRecordBase > XclExpObjectManager::CreateDrawingGroup() +{ + return ScfRef< XclExpRecordBase >( new XclExpMsoDrawingGroup( *mxEscherEx ) ); +} + +void XclExpObjectManager::StartSheet() +{ + mxObjList.reset( new XclExpObjList( GetRoot(), *mxEscherEx ) ); +} + +ScfRef< XclExpRecordBase > XclExpObjectManager::ProcessDrawing( SdrPage* pSdrPage ) +{ + if( pSdrPage ) + mxEscherEx->AddSdrPage( *pSdrPage ); + // #106213# the first dummy object may still be open + DBG_ASSERT( mxEscherEx->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" ); + while( mxEscherEx->GetGroupLevel() ) + mxEscherEx->LeaveGroup(); + mxObjList->EndSheet(); + return mxObjList; +} + +ScfRef< XclExpRecordBase > XclExpObjectManager::ProcessDrawing( const Reference< XShapes >& rxShapes ) +{ + if( rxShapes.is() ) + mxEscherEx->AddUnoShapes( rxShapes ); + // #106213# the first dummy object may still be open + DBG_ASSERT( mxEscherEx->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" ); + while( mxEscherEx->GetGroupLevel() ) + mxEscherEx->LeaveGroup(); + mxObjList->EndSheet(); + return mxObjList; +} + +void XclExpObjectManager::EndDocument() +{ + mxEscherEx->EndDocument(); +} + +XclExpMsoDrawing* XclExpObjectManager::GetMsodrawingPerSheet() +{ + return mxObjList->GetMsodrawingPerSheet(); +} + +bool XclExpObjectManager::HasObj() const +{ + return mxObjList->Count() > 0; +} + +sal_uInt16 XclExpObjectManager::AddObj( XclObj* pObjRec ) +{ + return mxObjList->Add( pObjRec ); +} + +XclObj* XclExpObjectManager::RemoveLastObj() +{ + XclObj* pLastObj = static_cast< XclObj* >( mxObjList->Last() ); + mxObjList->Remove(); // remove current, which is the Last() + return pLastObj; +} + +void XclExpObjectManager::InitStream( bool bTempFile ) +{ + if( bTempFile ) + { + mxTempFile.reset( new ::utl::TempFile ); + if( mxTempFile->IsValid() ) + { + mxTempFile->EnableKillingFile(); + mxDffStrm.reset( ::utl::UcbStreamHelper::CreateStream( mxTempFile->GetURL(), STREAM_STD_READWRITE ) ); + } + } + + if( !mxDffStrm.get() ) + mxDffStrm.reset( new SvMemoryStream ); + + mxDffStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); +} + +// ---------------------------------------------------------------------------- + +XclExpEmbeddedObjectManager::XclExpEmbeddedObjectManager( + const XclExpObjectManager& rParent, const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ) : + XclExpObjectManager( rParent ), + maPageSize( rPageSize ), + mnScaleX( nScaleX ), + mnScaleY( nScaleY ) +{ +} + +XclExpDffAnchorBase* XclExpEmbeddedObjectManager::CreateDffAnchor() const +{ + return new XclExpDffEmbeddedAnchor( GetRoot(), maPageSize, mnScaleX, mnScaleY ); +} + // ============================================================================ diff --git a/sc/source/filter/excel/xerecord.cxx b/sc/source/filter/excel/xerecord.cxx index 853a0e52bc8b..fed58411aa5c 100644 --- a/sc/source/filter/excel/xerecord.cxx +++ b/sc/source/filter/excel/xerecord.cxx @@ -46,16 +46,10 @@ void XclExpRecordBase::SaveXml( XclExpXmlStream& /*rStrm*/ ) { } -//UNUSED2008-05 void XclExpRecordBase::SaveRepeated( XclExpStream& rStrm, size_t nCount ) -//UNUSED2008-05 { -//UNUSED2008-05 for( size_t nIndex = 0; nIndex < nCount; ++nIndex ) -//UNUSED2008-05 Save( rStrm ); -//UNUSED2008-05 } - // ---------------------------------------------------------------------------- -XclExpDelegatingRecord::XclExpDelegatingRecord( XclExpRecordBase* pRecord ) - : mpRecord( pRecord ) +XclExpDelegatingRecord::XclExpDelegatingRecord( XclExpRecordBase* pRecord ) : + mpRecord( pRecord ) { } @@ -67,9 +61,8 @@ XclExpDelegatingRecord::~XclExpDelegatingRecord() void XclExpDelegatingRecord::SaveXml( XclExpXmlStream& rStrm ) { - if( !mpRecord ) - return; - mpRecord->SaveXml( rStrm ); + if( mpRecord ) + mpRecord->SaveXml( rStrm ); } // ---------------------------------------------------------------------------- diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx index 922adceb061b..834873740d68 100644 --- a/sc/source/filter/excel/xeroot.cxx +++ b/sc/source/filter/excel/xeroot.cxx @@ -27,6 +27,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" + #include <sfx2/docfile.hxx> #include <sfx2/sfxsids.hrc> #include <unotools/saveopt.hxx> @@ -35,12 +36,13 @@ #include <svl/eitem.hxx> #include "xecontent.hxx" #include "xltracer.hxx" -#include "xehelper.hxx" +#include "xeescher.hxx" #include "xeformula.hxx" +#include "xehelper.hxx" #include "xelink.hxx" #include "xename.hxx" -#include "xestyle.hxx" #include "xepivot.hxx" +#include "xestyle.hxx" #include "xeroot.hxx" #include "excrecds.hxx" // for filter manager @@ -142,6 +144,12 @@ XclExpNameManager& XclExpRoot::GetNameManager() const return *mrExpData.mxNameMgr; } +XclExpObjectManager& XclExpRoot::GetObjectManager() const +{ + DBG_ASSERT( mrExpData.mxObjMgr.is(), "XclExpRoot::GetObjectManager - missing object (wrong BIFF?)" ); + return *mrExpData.mxObjMgr; +} + XclExpFilterManager& XclExpRoot::GetFilterManager() const { DBG_ASSERT( mrExpData.mxFilterMgr.is(), "XclExpRoot::GetFilterManager - missing object (wrong BIFF?)" ); @@ -181,6 +189,7 @@ void XclExpRoot::InitializeGlobals() if( GetBiff() == EXC_BIFF8 ) { mrExpData.mxSst.reset( new XclExpSst ); + mrExpData.mxObjMgr.reset( new XclExpObjectManager( GetRoot() ) ); mrExpData.mxFilterMgr.reset( new XclExpFilterManager( GetRoot() ) ); mrExpData.mxPTableMgr.reset( new XclExpPivotTableManager( GetRoot() ) ); // BIFF8: only one link manager for all sheets diff --git a/sc/source/filter/excel/xichart.cxx b/sc/source/filter/excel/xichart.cxx index 4470bf789412..6734f90948e4 100644 --- a/sc/source/filter/excel/xichart.cxx +++ b/sc/source/filter/excel/xichart.cxx @@ -37,6 +37,7 @@ #include <com/sun/star/drawing/Direction3D.hpp> #include <com/sun/star/drawing/ProjectionMode.hpp> #include <com/sun/star/drawing/ShadeMode.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp> #include <com/sun/star/chart/ChartAxisLabelPosition.hpp> #include <com/sun/star/chart/ChartAxisMarkPosition.hpp> @@ -63,6 +64,8 @@ #include <com/sun/star/chart/MissingValueTreatment.hpp> #include <sfx2/objsh.hxx> +#include <svx/svdpage.hxx> +#include <svx/unoapi.hxx> #include "document.hxx" #include "drwlayer.hxx" @@ -79,7 +82,6 @@ #include "xistyle.hxx" #include "xipage.hxx" #include "xiview.hxx" -#include "xiescher.hxx" using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -88,11 +90,14 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::UNO_SET_THROW; using ::com::sun::star::uno::Exception; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::frame::XModel; using ::com::sun::star::util::XNumberFormatsSupplier; +using ::com::sun::star::drawing::XDrawPage; +using ::com::sun::star::drawing::XDrawPageSupplier; using ::com::sun::star::chart2::XChartDocument; using ::com::sun::star::chart2::XDiagram; @@ -123,8 +128,6 @@ using ::com::sun::star::chart2::data::XDataSequence; using ::formula::FormulaToken; using ::formula::StackVar; -using ::std::vector; - // Helpers ==================================================================== namespace { @@ -248,14 +251,14 @@ void XclImpChRoot::InitConversion( Reference< XChartDocument > xChartDoc ) const } } -void XclImpChRoot::FinishConversion( ScfProgressBar& rProgress ) const +void XclImpChRoot::FinishConversion( XclImpDffConverter& rDffConv ) const { - rProgress.Progress( EXC_CHART_PROGRESS_SIZE ); + rDffConv.Progress( EXC_CHART_PROGRESS_SIZE ); // unlock the model Reference< XModel > xModel( mxChData->GetChartDoc(), UNO_QUERY ); if( xModel.is() ) xModel->unlockControllers(); - rProgress.Progress( EXC_CHART_PROGRESS_SIZE ); + rDffConv.Progress( EXC_CHART_PROGRESS_SIZE ); mxChData->FinishConversion(); } @@ -793,9 +796,9 @@ Sequence< Reference< XFormattedString > > XclImpChSourceLink::CreateStringSequen return ScfApiHelper::VectorToSequence( aStringVec ); } -void XclImpChSourceLink::FillSourceLink(vector<ScSharedTokenRef>& rTokens) const +void XclImpChSourceLink::FillSourceLink( ::std::vector< ScSharedTokenRef >& rTokens ) const { - if (!mxTokenArray.is()) + if( !mxTokenArray.is() ) // no links to fill. return; @@ -1855,16 +1858,16 @@ Reference< XDataSeries > XclImpChSeries::CreateDataSeries() const return xDataSeries; } -void XclImpChSeries::FillAllSourceLinks(vector<ScSharedTokenRef>& rTokens) const +void XclImpChSeries::FillAllSourceLinks( ::std::vector< ScSharedTokenRef >& rTokens ) const { - if (mxValueLink.is()) - mxValueLink->FillSourceLink(rTokens); - if (mxCategLink.is()) - mxCategLink->FillSourceLink(rTokens); - if (mxTitleLink.is()) - mxTitleLink->FillSourceLink(rTokens); - if (mxBubbleLink.is()) - mxBubbleLink->FillSourceLink(rTokens); + if( mxValueLink.is() ) + mxValueLink->FillSourceLink( rTokens ); + if( mxCategLink.is() ) + mxCategLink->FillSourceLink( rTokens ); + if( mxTitleLink.is() ) + mxTitleLink->FillSourceLink( rTokens ); + if( mxBubbleLink.is() ) + mxBubbleLink->FillSourceLink( rTokens ); } void XclImpChSeries::ReadChSourceLink( XclImpStream& rStrm ) @@ -3513,7 +3516,7 @@ XclImpChTextRef XclImpChChart::GetDefaultText( XclChTextType eTextType ) const return maDefTexts.get( nDefTextId ); } -void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc, ScfProgressBar& rProgress, const OUString& rObjName ) const +void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc, XclImpDffConverter& rDffConv, const OUString& rObjName ) const { // initialize conversion (locks the model to suppress any internal updates) InitConversion( xChartDoc ); @@ -3555,27 +3558,21 @@ void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc, ScfProgressB } // unlock the model - FinishConversion( rProgress ); + FinishConversion( rDffConv ); - ScDocument* pDoc = &GetRoot().GetDoc(); - ScChartListenerCollection* pChartCollection = pDoc->GetChartListenerCollection(); - if (pChartCollection) + // start listening to this chart + ScDocument& rDoc = GetRoot().GetDoc(); + if( ScChartListenerCollection* pChartCollection = rDoc.GetChartListenerCollection() ) { - // Now, start listening to this chart. - ::std::auto_ptr< vector<ScSharedTokenRef> > pRefTokens(new vector<ScSharedTokenRef>); - for (XclImpChSeriesVec::const_iterator itr = maSeries.begin(), itrEnd = maSeries.end(); itr != itrEnd; ++itr) - { - const XclImpChSeriesRef& rSeries = *itr; - rSeries->FillAllSourceLinks(*pRefTokens); - } - if (!pRefTokens->empty()) + ::std::auto_ptr< ::std::vector< ScSharedTokenRef > > xRefTokens( new ::std::vector< ScSharedTokenRef > ); + for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end(); aIt != aEnd; ++aIt ) + (*aIt)->FillAllSourceLinks( *xRefTokens ); + if( !xRefTokens->empty() ) { - ::std::auto_ptr<ScChartListener> pListener( - new ScChartListener(rObjName, pDoc, pRefTokens.release())); - pListener->SetUsed(true); - pListener->StartListeningTo(); - pChartCollection->Insert(pListener.release()); - + ::std::auto_ptr< ScChartListener > xListener( new ScChartListener( rObjName, &rDoc, xRefTokens.release() ) ); + xListener->SetUsed( true ); + xListener->StartListeningTo(); + pChartCollection->Insert( xListener.release() ); } } } @@ -3733,6 +3730,68 @@ Reference< XDiagram > XclImpChChart::CreateDiagram() const // ---------------------------------------------------------------------------- +XclImpChartDrawing::XclImpChartDrawing( const XclImpRoot& rRoot, bool bOwnTab ) : + XclImpDrawing( rRoot, bOwnTab ), // sheet charts may contain OLE objects + mnScTab( rRoot.GetCurrScTab() ), + mbOwnTab( bOwnTab ) +{ +} + +void XclImpChartDrawing::ConvertObjects( XclImpDffConverter& rDffConv, + const Reference< XModel >& rxModel, const Rectangle& rChartRect ) +{ + maChartRect = rChartRect; // needed in CalcAnchorRect() callback + + SdrModel* pSdrModel = 0; + SdrPage* pSdrPage = 0; + if( mbOwnTab ) + { + // chart sheet: insert all shapes into the sheet, not into the chart object + pSdrModel = GetDoc().GetDrawLayer(); + pSdrPage = GetSdrPage( mnScTab ); + } + else + { + // embedded chart object: insert all shapes into the chart + try + { + Reference< XDrawPageSupplier > xDrawPageSupp( rxModel, UNO_QUERY_THROW ); + Reference< XDrawPage > xDrawPage( xDrawPageSupp->getDrawPage(), UNO_SET_THROW ); + pSdrPage = ::GetSdrPageFromXDrawPage( xDrawPage ); + pSdrModel = pSdrPage ? pSdrPage->GetModel() : 0; + } + catch( Exception& ) + { + } + } + + if( pSdrModel && pSdrPage ) + ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage ); +} + +Rectangle XclImpChartDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const +{ + /* In objects with DFF client anchor, the position of the shape is stored + in the cell address components of the client anchor. In old BIFF3-BIFF5 + objects, the position is stored in the offset components of the anchor. */ + Rectangle aRect( + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnCol : rAnchor.mnLX ) / EXC_CHART_UNIT * maChartRect.GetWidth() + 0.5 ), + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnRow : rAnchor.mnTY ) / EXC_CHART_UNIT * maChartRect.GetHeight() + 0.5 ), + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnCol : rAnchor.mnRX ) / EXC_CHART_UNIT * maChartRect.GetWidth() + 0.5 ), + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnRow : rAnchor.mnBY ) / EXC_CHART_UNIT * maChartRect.GetHeight() + 0.5 ) ); + aRect.Justify(); + // move shapes into chart area for sheet charts + if( mbOwnTab ) + aRect.Move( maChartRect.Left(), maChartRect.Top() ); + return aRect; +} + +void XclImpChartDrawing::OnObjectInserted( const XclImpDrawObjBase& ) +{ +} + +// ---------------------------------------------------------------------------- + XclImpChart::XclImpChart( const XclImpRoot& rRoot, bool bOwnTab ) : XclImpRoot( rRoot ), mbOwnTab( bOwnTab ), @@ -3740,6 +3799,10 @@ XclImpChart::XclImpChart( const XclImpRoot& rRoot, bool bOwnTab ) : { } +XclImpChart::~XclImpChart() +{ +} + void XclImpChart::ReadChartSubStream( XclImpStream& rStrm ) { XclImpPageSettings& rPageSett = GetPageSettings(); @@ -3770,6 +3833,7 @@ void XclImpChart::ReadChartSubStream( XclImpStream& rStrm ) case EXC_ID_SCL: rTabViewSett.ReadScl( rStrm ); break; } + // common records switch( rStrm.GetRecId() ) { case EXC_ID_EOF: bLoop = false; break; @@ -3781,12 +3845,29 @@ void XclImpChart::ReadChartSubStream( XclImpStream& rStrm ) case EXC_ID5_BOF: XclTools::SkipSubStream( rStrm ); break; case EXC_ID_CHCHART: ReadChChart( rStrm ); break; - case EXC_ID_OBJ: GetTracer().TraceChartEmbeddedObj(); break; case EXC_ID8_CHPIVOTREF: GetTracer().TracePivotChartExists(); mbIsPivotChart = true; break; + + // BIFF specific records + default: switch( GetBiff() ) + { + case EXC_BIFF5: switch( rStrm.GetRecId() ) + { + case EXC_ID_OBJ: GetChartDrawing().ReadObj( rStrm ); break; + } + break; + case EXC_BIFF8: switch( rStrm.GetRecId() ) + { + case EXC_ID_MSODRAWING: GetChartDrawing().ReadMsoDrawing( rStrm ); break; + // #i61786# weird documents: OBJ without MSODRAWING -> read in BIFF5 format + case EXC_ID_OBJ: GetChartDrawing().ReadObj( rStrm ); break; + } + break; + default:; + } } } } @@ -3800,14 +3881,28 @@ void XclImpChart::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjF sal_Size XclImpChart::GetProgressSize() const { - return mxChartData.is() ? mxChartData->GetProgressSize() : 0; + return + (mxChartData.is() ? mxChartData->GetProgressSize() : 0) + + (mxChartDrawing.is() ? mxChartDrawing->GetProgressSize() : 0); } -void XclImpChart::Convert( Reference< XModel > xModel, ScfProgressBar& rProgress, const OUString& rObjName ) const +void XclImpChart::Convert( Reference< XModel > xModel, XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const { Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY ); - if( mxChartData.is() && xChartDoc.is() ) - mxChartData->Convert( xChartDoc, rProgress, rObjName ); + if( xChartDoc.is() ) + { + if( mxChartData.is() ) + mxChartData->Convert( xChartDoc, rDffConv, rObjName ); + if( mxChartDrawing.is() ) + mxChartDrawing->ConvertObjects( rDffConv, xModel, rChartRect ); + } +} + +XclImpChartDrawing& XclImpChart::GetChartDrawing() +{ + if( !mxChartDrawing ) + mxChartDrawing.reset( new XclImpChartDrawing( GetRoot(), mbOwnTab ) ); + return *mxChartDrawing; } void XclImpChart::ReadChChart( XclImpStream& rStrm ) diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx index 9c130d2ebb78..e095ef987615 100644 --- a/sc/source/filter/excel/xicontent.cxx +++ b/sc/source/filter/excel/xicontent.cxx @@ -710,7 +710,7 @@ void XclImpValidation::ReadDval( XclImpStream& rStrm ) if( nObjId != EXC_DVAL_NOOBJ ) { DBG_ASSERT( nObjId <= 0xFFFF, "XclImpValidation::ReadDval - invalid object ID" ); - rRoot.GetObjectManager().SetSkipObj( rRoot.GetCurrScTab(), static_cast< sal_uInt16 >( nObjId ) ); + rRoot.GetCurrSheetDrawing().SetSkipObj( static_cast< sal_uInt16 >( nObjId ) ); } } diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx index e963495a3f4b..64ed79e3d3b2 100644 --- a/sc/source/filter/excel/xiescher.cxx +++ b/sc/source/filter/excel/xiescher.cxx @@ -118,13 +118,13 @@ using ::rtl::OUString; using ::rtl::OUStringBuffer; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Any; -using ::com::sun::star::uno::XInterface; using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::UNO_SET_THROW; using ::com::sun::star::beans::NamedValue; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::container::XIndexContainer; @@ -193,10 +193,11 @@ typedef TSdrObjectPtr< SdrObject > SdrObjectPtr; XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot& rRoot ) : XclImpRoot( rRoot ), - maObjId( rRoot.GetCurrScTab(), EXC_OBJ_INVALID_ID ), + mnObjId( EXC_OBJ_INVALID_ID ), mnObjType( EXC_OBJTYPE_UNKNOWN ), mnDffShapeId( 0 ), mnDffFlags( 0 ), + mbHasAnchor( false ), mbHidden( false ), mbVisible( true ), mbPrintable( true ), @@ -213,9 +214,8 @@ XclImpDrawObjBase::~XclImpDrawObjBase() { } -XclImpDrawObjRef XclImpDrawObjBase::ReadObj3( XclImpStream& rStrm ) +/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj3( const XclImpRoot& rRoot, XclImpStream& rStrm ) { - const XclImpRoot& rRoot = rStrm.GetRoot(); XclImpDrawObjRef xDrawObj; if( rStrm.GetRecLeft() >= 30 ) @@ -245,9 +245,8 @@ XclImpDrawObjRef XclImpDrawObjBase::ReadObj3( XclImpStream& rStrm ) return xDrawObj; } -XclImpDrawObjRef XclImpDrawObjBase::ReadObj4( XclImpStream& rStrm ) +/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj4( const XclImpRoot& rRoot, XclImpStream& rStrm ) { - const XclImpRoot& rRoot = rStrm.GetRoot(); XclImpDrawObjRef xDrawObj; if( rStrm.GetRecLeft() >= 30 ) @@ -278,9 +277,8 @@ XclImpDrawObjRef XclImpDrawObjBase::ReadObj4( XclImpStream& rStrm ) return xDrawObj; } -XclImpDrawObjRef XclImpDrawObjBase::ReadObj5( XclImpStream& rStrm ) +/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj5( const XclImpRoot& rRoot, XclImpStream& rStrm ) { - const XclImpRoot& rRoot = rStrm.GetRoot(); XclImpDrawObjRef xDrawObj; if( rStrm.GetRecLeft() >= 34 ) @@ -321,9 +319,8 @@ XclImpDrawObjRef XclImpDrawObjBase::ReadObj5( XclImpStream& rStrm ) return xDrawObj; } -XclImpDrawObjRef XclImpDrawObjBase::ReadObj8( XclImpStream& rStrm ) +/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj8( const XclImpRoot& rRoot, XclImpStream& rStrm ) { - const XclImpRoot& rRoot = rStrm.GetRoot(); XclImpDrawObjRef xDrawObj; if( rStrm.GetRecLeft() >= 10 ) @@ -380,6 +377,12 @@ XclImpDrawObjRef XclImpDrawObjBase::ReadObj8( XclImpStream& rStrm ) return xDrawObj; } +void XclImpDrawObjBase::SetAnchor( const XclObjAnchor& rAnchor ) +{ + maAnchor = rAnchor; + mbHasAnchor = true; +} + void XclImpDrawObjBase::SetDffData( const DffObjData& rDffObjData, const String& rObjName, const String& rHyperlink, bool bVisible, bool bAutoMargin ) { mnDffShapeId = rDffObjData.nShapeId; @@ -390,11 +393,6 @@ void XclImpDrawObjBase::SetDffData( const DffObjData& rDffObjData, const String& mbAutoMargin = bAutoMargin; } -void XclImpDrawObjBase::SetAnchor( const XclObjAnchor& rAnchor ) -{ - mxAnchor.reset( new XclObjAnchor( rAnchor ) ); -} - String XclImpDrawObjBase::GetObjName() const { /* #118053# #i51348# Always return a non-empty name. Create English @@ -404,6 +402,11 @@ String XclImpDrawObjBase::GetObjName() const return (maObjName.Len() > 0) ? maObjName : GetObjectManager().GetDefaultObjName( *this ); } +const XclObjAnchor* XclImpDrawObjBase::GetAnchor() const +{ + return mbHasAnchor ? &maAnchor : 0; +} + bool XclImpDrawObjBase::IsValidSize( const Rectangle& rAnchorRect ) const { // XclObjAnchor rounds up the width, width of 3 is the result of an Excel width of 0 @@ -412,56 +415,45 @@ bool XclImpDrawObjBase::IsValidSize( const Rectangle& rAnchorRect ) const ((rAnchorRect.GetWidth() > 3) || (rAnchorRect.GetHeight() > 1)); } -ScRange XclImpDrawObjBase::GetUsedArea() const +ScRange XclImpDrawObjBase::GetUsedArea( SCTAB nScTab ) const { ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID ); - if( mxAnchor.is() ) + // #i44077# object inserted -> update used area for OLE object import + if( mbHasAnchor && GetAddressConverter().ConvertRange( aScUsedArea, maAnchor, nScTab, nScTab, false ) ) { - // #i44077# object inserted -> update used area for OLE object import - if( GetAddressConverter().ConvertRange( aScUsedArea, *mxAnchor, GetScTab(), GetScTab(), false ) ) - { - // reduce range, if object ends directly on borders between two columns or rows - if( (mxAnchor->mnRX == 0) && (aScUsedArea.aStart.Col() < aScUsedArea.aEnd.Col()) ) - aScUsedArea.aEnd.IncCol( -1 ); - if( (mxAnchor->mnBY == 0) && (aScUsedArea.aStart.Row() < aScUsedArea.aEnd.Row()) ) - aScUsedArea.aEnd.IncRow( -1 ); - } + // reduce range, if object ends directly on borders between two columns or rows + if( (maAnchor.mnRX == 0) && (aScUsedArea.aStart.Col() < aScUsedArea.aEnd.Col()) ) + aScUsedArea.aEnd.IncCol( -1 ); + if( (maAnchor.mnBY == 0) && (aScUsedArea.aStart.Row() < aScUsedArea.aEnd.Row()) ) + aScUsedArea.aEnd.IncRow( -1 ); } return aScUsedArea; } -Rectangle XclImpDrawObjBase::GetAnchorRect() const -{ - Rectangle aAnchorRect; - if( mxAnchor.is() ) - aAnchorRect = mxAnchor->GetRect( GetDoc(), MAP_100TH_MM ); - return aAnchorRect; -} - sal_Size XclImpDrawObjBase::GetProgressSize() const { return DoGetProgressSize(); } -SdrObject* XclImpDrawObjBase::CreateSdrObject( const Rectangle& rAnchorRect, ScfProgressBar& rProgress, bool bDffImport ) const +SdrObject* XclImpDrawObjBase::CreateSdrObject( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect, bool bIsDff ) const { SdrObjectPtr xSdrObj; - if( bDffImport && !mbCustomDff ) + if( bIsDff && !mbCustomDff ) { - rProgress.Progress( GetProgressSize() ); + rDffConv.Progress( GetProgressSize() ); } else { - xSdrObj.reset( DoCreateSdrObj( rAnchorRect, rProgress ) ); + xSdrObj.reset( DoCreateSdrObj( rDffConv, rAnchorRect ) ); if( xSdrObj.is() ) - xSdrObj->SetModel( GetDoc().GetDrawLayer() ); + xSdrObj->SetModel( rDffConv.GetModel() ); } return xSdrObj.release(); } -void XclImpDrawObjBase::ProcessSdrObject( SdrObject& rSdrObj ) const +void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const { - // default: front layer, derived classes may have to set other layer in DoProcessSdrObj() + // default: front layer, derived classes may have to set other layer in DoPreProcessSdrObj() rSdrObj.NbcSetLayer( SC_LAYER_FRONT ); // set object name (GetObjName() will always return a non-empty name) @@ -473,7 +465,7 @@ void XclImpDrawObjBase::ProcessSdrObject( SdrObject& rSdrObj ) const // automatic text margin if( mbAutoMargin ) { - sal_Int32 nMargin = GetObjectManager().GetDffManager().GetDefaultTextMargin(); + sal_Int32 nMargin = rDffConv.GetDefaultTextMargin(); rSdrObj.SetMergedItem( SdrTextLeftDistItem( nMargin ) ); rSdrObj.SetMergedItem( SdrTextRightDistItem( nMargin ) ); rSdrObj.SetMergedItem( SdrTextUpperDistItem( nMargin ) ); @@ -497,7 +489,13 @@ void XclImpDrawObjBase::ProcessSdrObject( SdrObject& rSdrObj ) const #endif // call virtual function for object type specific processing - DoProcessSdrObj( rSdrObj ); + DoPreProcessSdrObj( rDffConv, rSdrObj ); +} + +void XclImpDrawObjBase::PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const +{ + // call virtual function for object type specific processing + DoPostProcessSdrObj( rDffConv, rSdrObj ); } // protected ------------------------------------------------------------------ @@ -759,68 +757,69 @@ sal_Size XclImpDrawObjBase::DoGetProgressSize() const return 1; } -SdrObject* XclImpDrawObjBase::DoCreateSdrObj( const Rectangle&, ScfProgressBar& rProgress ) const +SdrObject* XclImpDrawObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& ) const { - rProgress.Progress( GetProgressSize() ); + rDffConv.Progress( GetProgressSize() ); return 0; } -void XclImpDrawObjBase::DoProcessSdrObj( SdrObject& /*rSdrObj*/ ) const +void XclImpDrawObjBase::DoPreProcessSdrObj( XclImpDffConverter&, SdrObject& ) const { // trace if object is not printable if( !IsPrintable() ) GetTracer().TraceObjectNotPrintable(); } -void XclImpDrawObjBase::ImplReadObj3( XclImpStream& rStrm ) +void XclImpDrawObjBase::DoPostProcessSdrObj( XclImpDffConverter&, SdrObject& ) const { - sal_uInt16 nObjFlags, nMacroSize; - XclObjAnchor aAnchor( GetCurrScTab() ); +} +void XclImpDrawObjBase::ImplReadObj3( XclImpStream& rStrm ) +{ // back to offset 4 (ignore object count field) rStrm.Seek( 4 ); - rStrm >> mnObjType >> maObjId.mnObjId >> nObjFlags >> aAnchor >> nMacroSize; + + sal_uInt16 nObjFlags, nMacroSize; + rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize; rStrm.Ignore( 2 ); + mbHasAnchor = true; mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN ); mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE ); - SetAnchor( aAnchor ); DoReadObj3( rStrm, nMacroSize ); } void XclImpDrawObjBase::ImplReadObj4( XclImpStream& rStrm ) { - sal_uInt16 nObjFlags, nMacroSize; - XclObjAnchor aAnchor( GetCurrScTab() ); - // back to offset 4 (ignore object count field) rStrm.Seek( 4 ); - rStrm >> mnObjType >> maObjId.mnObjId >> nObjFlags >> aAnchor >> nMacroSize; + + sal_uInt16 nObjFlags, nMacroSize; + rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize; rStrm.Ignore( 2 ); + mbHasAnchor = true; mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN ); mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE ); mbPrintable = ::get_flag( nObjFlags, EXC_OBJ_PRINTABLE ); - SetAnchor( aAnchor ); DoReadObj4( rStrm, nMacroSize ); } void XclImpDrawObjBase::ImplReadObj5( XclImpStream& rStrm ) { - sal_uInt16 nObjFlags, nMacroSize, nNameLen; - XclObjAnchor aAnchor( GetCurrScTab() ); - // back to offset 4 (ignore object count field) rStrm.Seek( 4 ); - rStrm >> mnObjType >> maObjId.mnObjId >> nObjFlags >> aAnchor >> nMacroSize; + + sal_uInt16 nObjFlags, nMacroSize, nNameLen; + rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize; rStrm.Ignore( 2 ); rStrm >> nNameLen; rStrm.Ignore( 2 ); + mbHasAnchor = true; mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN ); mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE ); mbPrintable = ::get_flag( nObjFlags, EXC_OBJ_PRINTABLE ); - SetAnchor( aAnchor ); DoReadObj5( rStrm, nNameLen, nMacroSize ); } @@ -845,7 +844,7 @@ void XclImpDrawObjBase::ImplReadObj8( XclImpStream& rStrm ) if( (rStrm.GetRecPos() == 4) && (nSubRecSize >= 6) ) { sal_uInt16 nObjFlags; - rStrm >> mnObjType >> maObjId.mnObjId >> nObjFlags; + rStrm >> mnObjType >> mnObjId >> nObjFlags; mbPrintable = ::get_flag( nObjFlags, EXC_OBJCMO_PRINTABLE ); } break; @@ -928,7 +927,7 @@ XclImpGroupObj::XclImpGroupObj( const XclImpRoot& rRoot ) : bool XclImpGroupObj::TryInsert( XclImpDrawObjRef xDrawObj ) { - if( (xDrawObj->GetScTab() != GetScTab()) || (xDrawObj->GetObjId().mnObjId == mnFirstUngrouped) ) + if( xDrawObj->GetObjId() == mnFirstUngrouped ) return false; // insert into own list or into nested group maChildren.InsertGrouped( xDrawObj ); @@ -965,13 +964,14 @@ sal_Size XclImpGroupObj::DoGetProgressSize() const return XclImpDrawObjBase::DoGetProgressSize() + maChildren.GetProgressSize(); } -SdrObject* XclImpGroupObj::DoCreateSdrObj( const Rectangle& /*rAnchorRect*/, ScfProgressBar& rProgress ) const +SdrObject* XclImpGroupObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& /*rAnchorRect*/ ) const { TSdrObjectPtr< SdrObjGroup > xSdrObj( new SdrObjGroup ); // child objects in BIFF2-BIFF5 have absolute size, not needed to pass own anchor rectangle + SdrObjList& rObjList = *xSdrObj->GetSubList(); // SdrObjGroup always returns existing sublist for( XclImpDrawObjVector::const_iterator aIt = maChildren.begin(), aEnd = maChildren.end(); aIt != aEnd; ++aIt ) - GetObjectManager().GetDffManager().ProcessObject( xSdrObj->GetSubList(), **aIt ); - rProgress.Progress(); + rDffConv.ProcessObject( rObjList, **aIt ); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1007,7 +1007,7 @@ void XclImpLineObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uI ReadMacro5( rStrm, nMacroSize ); } -SdrObject* XclImpLineObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpLineObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { ::basegfx::B2DPolygon aB2DPolygon; switch( mnStartPoint ) @@ -1100,7 +1100,7 @@ SdrObject* XclImpLineObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgr xSdrObj->SetMergedItem( XLineEndCenterItem( FALSE ) ); } } - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1144,11 +1144,11 @@ void XclImpRectObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uI ReadMacro5( rStrm, nMacroSize ); } -SdrObject* XclImpRectObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpRectObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { SdrObjectPtr xSdrObj( new SdrRectObj( rAnchorRect ) ); ConvertRectStyle( *xSdrObj ); - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1159,11 +1159,11 @@ XclImpOvalObj::XclImpOvalObj( const XclImpRoot& rRoot ) : { } -SdrObject* XclImpOvalObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpOvalObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { SdrObjectPtr xSdrObj( new SdrCircObj( OBJ_CIRC, rAnchorRect ) ); ConvertRectStyle( *xSdrObj ); - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1198,7 +1198,7 @@ void XclImpArcObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uIn ReadMacro5( rStrm, nMacroSize ); } -SdrObject* XclImpArcObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpArcObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { Rectangle aNewRect = rAnchorRect; long nStartAngle = 0; @@ -1235,7 +1235,7 @@ SdrObject* XclImpArcObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgre SdrObjectPtr xSdrObj( new SdrCircObj( eObjKind, aNewRect, nStartAngle, nEndAngle ) ); ConvertFillStyle( *xSdrObj, maFillData ); ConvertLineStyle( *xSdrObj, maLineData ); - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1297,7 +1297,7 @@ namespace { } // namespace -SdrObject* XclImpPolygonObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpPolygonObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { SdrObjectPtr xSdrObj; if( maCoords.size() >= 2 ) @@ -1314,7 +1314,7 @@ SdrObject* XclImpPolygonObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfPr xSdrObj.reset( new SdrPathObj( eObjKind, ::basegfx::B2DPolyPolygon( aB2DPolygon ) ) ); ConvertRectStyle( *xSdrObj ); } - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1375,7 +1375,7 @@ void XclImpTextObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uI maTextData.ReadFormats( rStrm ); } -SdrObject* XclImpTextObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpTextObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { TSdrObjectPtr< SdrObjCustomShape > xSdrObj( new SdrObjCustomShape ); xSdrObj->NbcSetSnapRect( rAnchorRect ); @@ -1386,11 +1386,11 @@ SdrObject* XclImpTextObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgr xSdrObj->SetMergedItem( SdrTextAutoGrowWidthItem( bAutoSize ) ); xSdrObj->SetMergedItem( SdrTextAutoGrowHeightItem( bAutoSize ) ); xSdrObj->SetMergedItem( SdrTextWordWrapItem( TRUE ) ); - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } -void XclImpTextObj::DoProcessSdrObj( SdrObject& rSdrObj ) const +void XclImpTextObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const { // set text data if( SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( &rSdrObj ) ) @@ -1469,7 +1469,7 @@ void XclImpTextObj::DoProcessSdrObj( SdrObject& rSdrObj ) const case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break; case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break; } - MSO_Anchor eTextAnchor = (MSO_Anchor)GetObjectManager().GetDffManager().GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); + MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); switch( eTextAnchor ) { case mso_anchorTopCentered : @@ -1508,7 +1508,7 @@ void XclImpTextObj::DoProcessSdrObj( SdrObject& rSdrObj ) const case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_TOP; break; case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break; } - MSO_Anchor eTextAnchor = (MSO_Anchor)GetObjectManager().GetDffManager().GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); + MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); switch ( eTextAnchor ) { case mso_anchorTopCentered : @@ -1539,7 +1539,7 @@ void XclImpTextObj::DoProcessSdrObj( SdrObject& rSdrObj ) const } } // base class processing - XclImpRectObj::DoProcessSdrObj( rSdrObj ); + XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj ); } // ---------------------------------------------------------------------------- @@ -1633,11 +1633,11 @@ sal_Size XclImpChartObj::DoGetProgressSize() const return mxChart.is() ? mxChart->GetProgressSize() : 1; } -SdrObject* XclImpChartObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpChartObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { SdrObjectPtr xSdrObj; SfxObjectShell* pDocShell = GetDocShell(); - if( SvtModuleOptions().IsChart() && pDocShell && mxChart.is() && !mxChart->IsPivotChart() ) + if( rDffConv.SupportsOleObjects() && SvtModuleOptions().IsChart() && pDocShell && mxChart.is() && !mxChart->IsPivotChart() ) { // create embedded chart object OUString aEmbObjName; @@ -1655,20 +1655,28 @@ SdrObject* XclImpChartObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProg // create the container OLE object xSdrObj.reset( new SdrOle2Obj( svt::EmbeddedObjectRef( xEmbObj, nAspect ), aEmbObjName, rAnchorRect ) ); + } - // convert Excel chart to OOo Chart - if( svt::EmbeddedObjectRef::TryRunningState( xEmbObj ) ) - { - Reference< XModel > xModel( xEmbObj->getComponent(), UNO_QUERY ); - mxChart->Convert( xModel, rProgress, aEmbObjName ); + return xSdrObj.release(); +} - Reference< XEmbedPersist > xPers( xEmbObj, UNO_QUERY ); - if( xPers.is() ) - xPers->storeOwn(); +void XclImpChartObj::DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const +{ + const SdrOle2Obj* pSdrOleObj = dynamic_cast< const SdrOle2Obj* >( &rSdrObj ); + if( mxChart.is() && pSdrOleObj ) + { + Reference< XEmbeddedObject > xEmbObj = pSdrOleObj->GetObjRef(); + if( xEmbObj.is() && ::svt::EmbeddedObjectRef::TryRunningState( xEmbObj ) ) try + { + Reference< XEmbedPersist > xPersist( xEmbObj, UNO_QUERY_THROW ); + Reference< XModel > xModel( xEmbObj->getComponent(), UNO_QUERY_THROW ); + mxChart->Convert( xModel, rDffConv, xPersist->getEntryName(), rSdrObj.GetLogicRect() ); + xPersist->storeOwn(); + } + catch( Exception& ) + { } } - - return xSdrObj.release(); } void XclImpChartObj::FinalizeTabChart() @@ -1683,12 +1691,12 @@ void XclImpChartObj::FinalizeTabChart() // calculate size of the chart object const XclPageData& rPageData = GetPageSettings().GetPageData(); - Size aPaperSize( rPageData.GetScPaperSize() ); + Size aPaperSize = rPageData.GetScPaperSize(); long nWidth = XclTools::GetHmmFromTwips( aPaperSize.Width() ); long nHeight = XclTools::GetHmmFromTwips( aPaperSize.Height() ); - // subtract page margins, give 1cm extra space + // subtract page margins, give some more extra space nWidth -= (XclTools::GetHmmFromInch( rPageData.mfLeftMargin + rPageData.mfRightMargin ) + 2000); nHeight -= (XclTools::GetHmmFromInch( rPageData.mfTopMargin + rPageData.mfBottomMargin ) + 1000); @@ -1700,8 +1708,8 @@ void XclImpChartObj::FinalizeTabChart() } // create the object anchor - XclObjAnchor aAnchor( GetScTab() ); - aAnchor.SetRect( GetDoc(), Rectangle( 1000, 500, nWidth, nHeight ), MAP_100TH_MM ); + XclObjAnchor aAnchor; + aAnchor.SetRect( GetDoc(), GetCurrScTab(), Rectangle( 1000, 500, nWidth, nHeight ), MAP_100TH_MM ); SetAnchor( aAnchor ); } @@ -1723,10 +1731,10 @@ void XclImpNoteObj::SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags mnNoteFlags = nNoteFlags; } -void XclImpNoteObj::DoProcessSdrObj( SdrObject& rSdrObj ) const +void XclImpNoteObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const { // create formatted text - XclImpTextObj::DoProcessSdrObj( rSdrObj ); + XclImpTextObj::DoPreProcessSdrObj( rDffConv, rSdrObj ); OutlinerParaObject* pOutlinerObj = rSdrObj.GetOutlinerParaObject(); if( maScPos.IsValid() && pOutlinerObj ) { @@ -1970,16 +1978,16 @@ void XclImpTbxObjBase::ConvertLabel( ScfPropertySet& rPropSet ) const ConvertFont( rPropSet ); } -SdrObject* XclImpTbxObjBase::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpTbxObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { - SdrObjectPtr xSdrObj( GetObjectManager().GetDffManager().CreateSdrObject( *this, rAnchorRect ) ); - rProgress.Progress(); + SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) ); + rDffConv.Progress(); return xSdrObj.release(); } -void XclImpTbxObjBase::DoProcessSdrObj( SdrObject& /*rSdrObj*/ ) const +void XclImpTbxObjBase::DoPreProcessSdrObj( XclImpDffConverter& /*rDffConv*/, SdrObject& /*rSdrObj*/ ) const { - // do not call DoProcessSdrObj() from base class (to skip text processing) + // do not call DoPreProcessSdrObj() from base class (to skip text processing) ProcessControl( *this ); } @@ -2740,7 +2748,7 @@ void XclImpPictureObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize ) ReadPictFmla( rStrm, nLinkSize ); if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() ) - maGraphic = XclImpObjectManager::ReadImgData( rStrm ); + maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); } void XclImpPictureObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) @@ -2755,7 +2763,7 @@ void XclImpPictureObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) ReadPictFmla( rStrm, nLinkSize ); if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() ) - maGraphic = XclImpObjectManager::ReadImgData( rStrm ); + maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); } void XclImpPictureObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) @@ -2777,7 +2785,7 @@ void XclImpPictureObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal if( IsHidden() && (GetObjName() == CREATE_STRING( "__BkgndObj" )) ) GetPageSettings().ReadImgData( rStrm ); else - maGraphic = XclImpObjectManager::ReadImgData( rStrm ); + maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); } } @@ -2796,10 +2804,10 @@ void XclImpPictureObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRec } } -SdrObject* XclImpPictureObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpPictureObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { // try to create an OLE object or form control - SdrObjectPtr xSdrObj( GetObjectManager().GetDffManager().CreateSdrObject( *this, rAnchorRect ) ); + SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) ); // no OLE - create a plain picture from IMGDATA record data if( !xSdrObj && (maGraphic.GetType() != GRAPHIC_NONE) ) @@ -2808,21 +2816,21 @@ SdrObject* XclImpPictureObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfPr ConvertRectStyle( *xSdrObj ); } - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } -void XclImpPictureObj::DoProcessSdrObj( SdrObject& rSdrObj ) const +void XclImpPictureObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const { if( IsOcxControl() ) { - // do not call XclImpRectObj::DoProcessSdrObj(), it would trace missing "printable" feature + // do not call XclImpRectObj::DoPreProcessSdrObj(), it would trace missing "printable" feature ProcessControl( *this ); } else if( mbEmbedded || mbLinked ) { // trace missing "printable" feature - XclImpRectObj::DoProcessSdrObj( rSdrObj ); + XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj ); SfxObjectShell* pDocShell = GetDocShell(); SdrOle2Obj* pOleSdrObj = dynamic_cast< SdrOle2Obj* >( &rSdrObj ); @@ -3062,18 +3070,18 @@ void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId, SdrObject* // ---------------------------------------------------------------------------- -XclImpSimpleDffManager::XclImpSimpleDffManager( const XclImpRoot& rRoot, SvStream& rDffStrm ) : +XclImpSimpleDffConverter::XclImpSimpleDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ) : SvxMSDffManager( rDffStrm, rRoot.GetBasePath(), 0, 0, rRoot.GetDoc().GetDrawLayer(), 1440, COL_DEFAULT, 24, 0, &rRoot.GetTracer().GetBaseTracer() ), XclImpRoot( rRoot ) { SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS | SVXMSDFF_SETTINGS_IMPORT_EXCEL ); } -XclImpSimpleDffManager::~XclImpSimpleDffManager() +XclImpSimpleDffConverter::~XclImpSimpleDffConverter() { } -FASTBOOL XclImpSimpleDffManager::GetColorFromPalette( USHORT nIndex, Color& rColor ) const +FASTBOOL XclImpSimpleDffConverter::GetColorFromPalette( USHORT nIndex, Color& rColor ) const { ColorData nColor = GetPalette().GetColorData( static_cast< sal_uInt16 >( nIndex ) ); @@ -3086,14 +3094,23 @@ FASTBOOL XclImpSimpleDffManager::GetColorFromPalette( USHORT nIndex, Color& rCol // ---------------------------------------------------------------------------- -XclImpDffManager::XclImpDffManager( - const XclImpRoot& rRoot, XclImpObjectManager& rObjManager, SvStream& rDffStrm ) : - XclImpSimpleDffManager( rRoot, rDffStrm ), - SvxMSConvertOCXControls( rRoot.GetDocShell(), 0 ), - mrObjManager( rObjManager ), - mnOleImpFlags( 0 ), +XclImpDffConverter::XclImpDffConvData::XclImpDffConvData( + XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ) : + mrDrawing( rDrawing ), + mrSdrModel( rSdrModel ), + mrSdrPage( rSdrPage ), mnLastCtrlIndex( -1 ), - mnCurrFormScTab( -1 ) + mbHasCtrlForm( false ) +{ +} + +// ---------------------------------------------------------------------------- + +XclImpDffConverter::XclImpDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ) : + XclImpSimpleDffConverter( rRoot, rDffStrm ), + SvxMSConvertOCXControls( rRoot.GetDocShell(), 0 ), + maStdFormName( CREATE_OUSTRING( "Standard" ) ), + mnOleImpFlags( 0 ) { if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() ) { @@ -3113,81 +3130,104 @@ XclImpDffManager::XclImpDffManager( ScaleEmu( mnDefTextMargin ); } -XclImpDffManager::~XclImpDffManager() +XclImpDffConverter::~XclImpDffConverter() { } -void XclImpDffManager::StartProgressBar( sal_Size nProgressSize ) +void XclImpDffConverter::StartProgressBar( sal_Size nProgressSize ) { mxProgress.reset( new ScfProgressBar( GetDocShell(), STR_PROGRESS_CALCULATING ) ); mxProgress->AddSegment( nProgressSize ); mxProgress->Activate(); } -void XclImpDffManager::ProcessObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj ) +void XclImpDffConverter::Progress( sal_Size nDelta ) { - Rectangle aAnchorRect = rDrawObj.GetAnchorRect(); - if( rDrawObj.IsProcessSdrObj() && rDrawObj.IsValidSize( aAnchorRect ) ) - { - // CreateSdrObject() recursively creates embedded child objects - SdrObjectPtr xSdrObj( rDrawObj.CreateSdrObject( aAnchorRect, *mxProgress, false ) ); - if( xSdrObj.is() ) - rDrawObj.ProcessSdrObject( *xSdrObj ); - // call InsertSdrObject() also, if SdrObject is missing - InsertSdrObject( pObjList, rDrawObj, xSdrObj.release() ); - UpdateUsedArea( rDrawObj ); - } + DBG_ASSERT( mxProgress.is(), "XclImpDffConverter::Progress - invalid call, no progress bar" ); + mxProgress->Progress( nDelta ); } -void XclImpDffManager::ProcessDrawingGroup( SvStream& rDffStrm ) +void XclImpDffConverter::InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ) { - rDffStrm.Seek( STREAM_SEEK_TO_BEGIN ); - DffRecordHeader aHeader; - rDffStrm >> aHeader; - if( aHeader.nRecType == DFF_msofbtDggContainer ) - ProcessDggContainer( rDffStrm, aHeader ); - else + XclImpDffConvDataRef xConvData( new XclImpDffConvData( rDrawing, rSdrModel, rSdrPage ) ); + maDataStack.push_back( xConvData ); + SetModel( &xConvData->mrSdrModel, 1440 ); +} + +void XclImpDffConverter::ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj ) +{ + if( rDrawObj.IsProcessSdrObj() ) { - DBG_ERRORFILE( "XclImpDffManager::ProcessDrawingGroup - unexpected record" ); + if( const XclObjAnchor* pAnchor = rDrawObj.GetAnchor() ) + { + Rectangle aAnchorRect = GetConvData().mrDrawing.CalcAnchorRect( *pAnchor, false ); + if( rDrawObj.IsValidSize( aAnchorRect ) ) + { + // CreateSdrObject() recursively creates embedded child objects + SdrObjectPtr xSdrObj( rDrawObj.CreateSdrObject( *this, aAnchorRect, false ) ); + if( xSdrObj.is() ) + rDrawObj.PreProcessSdrObject( *this, *xSdrObj ); + // call InsertSdrObject() also, if SdrObject is missing + InsertSdrObject( rObjList, rDrawObj, xSdrObj.release() ); + } + } } } -void XclImpDffManager::ProcessDrawing( SvStream& rDffStrm, sal_Size nStrmPos ) +void XclImpDffConverter::ProcessDrawing( const XclImpDrawObjVector& rDrawObjs ) { - rDffStrm.Seek( nStrmPos ); - DffRecordHeader aHeader; - rDffStrm >> aHeader; - if( aHeader.nRecType == DFF_msofbtDgContainer ) - ProcessDgContainer( rDffStrm, aHeader ); - else + SdrPage& rSdrPage = GetConvData().mrSdrPage; + for( XclImpDrawObjVector::const_iterator aIt = rDrawObjs.begin(), aEnd = rDrawObjs.end(); aIt != aEnd; ++aIt ) + ProcessObject( rSdrPage, **aIt ); +} + +void XclImpDffConverter::ProcessDrawing( SvStream& rDffStrm ) +{ + rDffStrm.Seek( STREAM_SEEK_TO_END ); + if( rDffStrm.Tell() > 0 ) { - DBG_ERRORFILE( "XclImpDffManager::ProcessDrawing - unexpected record" ); + rDffStrm.Seek( STREAM_SEEK_TO_BEGIN ); + DffRecordHeader aHeader; + rDffStrm >> aHeader; + DBG_ASSERT( aHeader.nRecType == DFF_msofbtDgContainer, "XclImpDffConverter::ProcessDrawing - unexpected record" ); + if( aHeader.nRecType == DFF_msofbtDgContainer ) + ProcessDgContainer( rDffStrm, aHeader ); } } -SdrObject* XclImpDffManager::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect ) +void XclImpDffConverter::FinalizeDrawing() +{ + DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::FinalizeDrawing - no drawing manager on stack" ); + maDataStack.pop_back(); + // restore previous model at core DFF converter + if( !maDataStack.empty() ) + SetModel( &maDataStack.back()->mrSdrModel, 1440 ); +} + +SdrObject* XclImpDffConverter::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect ) { SdrObjectPtr xSdrObj; OUString aServiceName = rTbxObj.GetServiceName(); - if( aServiceName.getLength() > 0 ) try + if( SupportsOleObjects() && (aServiceName.getLength() > 0) ) try { // create the form control from scratch Reference< XFormComponent > xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName ), UNO_QUERY_THROW ); - // set current controls form, needed in virtual function InsertControl() - SetCurrentForm( rTbxObj.GetScTab() ); + // set controls form, needed in virtual function InsertControl() + InitControlForm(); // try to insert the control into the form ::com::sun::star::awt::Size aDummySize; Reference< XShape > xShape; - if( mxCurrForm.is() && InsertControl( xFormComp, aDummySize, &xShape, TRUE ) ) + XclImpDffConvData& rConvData = GetConvData(); + if( rConvData.mxCtrlForm.is() && InsertControl( xFormComp, aDummySize, &xShape, TRUE ) ) { xSdrObj.reset( rTbxObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) ); // try to attach a macro to the control ScriptEventDescriptor aDescriptor; - if( (mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) ) + if( (rConvData.mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) ) { - Reference< XEventAttacherManager > xEventMgr( mxCurrForm, UNO_QUERY_THROW ); - xEventMgr->registerScriptEvent( mnLastCtrlIndex, aDescriptor ); + Reference< XEventAttacherManager > xEventMgr( rConvData.mxCtrlForm, UNO_QUERY_THROW ); + xEventMgr->registerScriptEvent( rConvData.mnLastCtrlIndex, aDescriptor ); } } } @@ -3198,52 +3238,55 @@ SdrObject* XclImpDffManager::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, c return xSdrObj.release(); } -SdrObject* XclImpDffManager::CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect ) +SdrObject* XclImpDffConverter::CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect ) { SdrObjectPtr xSdrObj; - if( rPicObj.IsOcxControl() ) - { - if( mxCtlsStrm.Is() ) try - { - /* set current controls form, needed in virtual function InsertControl() - called from ReadOCXExcelKludgeStream() */ - SetCurrentForm( rPicObj.GetScTab() ); - // seek to stream position of the extra data for this control - mxCtlsStrm->Seek( rPicObj.GetCtlsStreamPos() ); - // read from mxCtlsStrm into xShape, insert the control model into the form - Reference< XShape > xShape; - if( mxCurrForm.is() && ReadOCXExcelKludgeStream( mxCtlsStrm, &xShape, TRUE ) ) - xSdrObj.reset( rPicObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) ); - } - catch( Exception& ) - { - } - } - else + if( SupportsOleObjects() ) { - SfxObjectShell* pDocShell = GetDocShell(); - SotStorageRef xSrcStrg = GetRootStorage(); - String aStrgName = rPicObj.GetOleStorageName(); - if( pDocShell && xSrcStrg.Is() && (aStrgName.Len() > 0) ) + if( rPicObj.IsOcxControl() ) { - // first try to resolve graphic from DFF storage - Graphic aGraphic; - Rectangle aVisArea; - if( !GetBLIP( GetPropertyValue( DFF_Prop_pib ), aGraphic, &aVisArea ) ) + if( mxCtlsStrm.Is() ) try { - // if not found, use graphic from object (imported from IMGDATA record) - aGraphic = rPicObj.GetGraphic(); - aVisArea = rPicObj.GetVisArea(); + /* set controls form, needed in virtual function InsertControl() + called from ReadOCXExcelKludgeStream() */ + InitControlForm(); + // seek to stream position of the extra data for this control + mxCtlsStrm->Seek( rPicObj.GetCtlsStreamPos() ); + // read from mxCtlsStrm into xShape, insert the control model into the form + Reference< XShape > xShape; + if( GetConvData().mxCtrlForm.is() && ReadOCXExcelKludgeStream( mxCtlsStrm, &xShape, TRUE ) ) + xSdrObj.reset( rPicObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) ); } - if( aGraphic.GetType() != GRAPHIC_NONE ) + catch( Exception& ) { - ErrCode nError = ERRCODE_NONE; - namespace cssea = ::com::sun::star::embed::Aspects; - sal_Int64 nAspects = rPicObj.IsSymbol() ? cssea::MSOLE_ICON : cssea::MSOLE_CONTENT; - xSdrObj.reset( CreateSdrOLEFromStorage( - aStrgName, xSrcStrg, pDocShell->GetStorage(), aGraphic, - rAnchorRect, aVisArea, 0, nError, mnOleImpFlags, nAspects ) ); + } + } + else + { + SfxObjectShell* pDocShell = GetDocShell(); + SotStorageRef xSrcStrg = GetRootStorage(); + String aStrgName = rPicObj.GetOleStorageName(); + if( pDocShell && xSrcStrg.Is() && (aStrgName.Len() > 0) ) + { + // first try to resolve graphic from DFF storage + Graphic aGraphic; + Rectangle aVisArea; + if( !GetBLIP( GetPropertyValue( DFF_Prop_pib ), aGraphic, &aVisArea ) ) + { + // if not found, use graphic from object (imported from IMGDATA record) + aGraphic = rPicObj.GetGraphic(); + aVisArea = rPicObj.GetVisArea(); + } + if( aGraphic.GetType() != GRAPHIC_NONE ) + { + ErrCode nError = ERRCODE_NONE; + namespace cssea = ::com::sun::star::embed::Aspects; + sal_Int64 nAspects = rPicObj.IsSymbol() ? cssea::MSOLE_ICON : cssea::MSOLE_CONTENT; + xSdrObj.reset( CreateSdrOLEFromStorage( + aStrgName, xSrcStrg, pDocShell->GetStorage(), aGraphic, + rAnchorRect, aVisArea, 0, nError, mnOleImpFlags, nAspects ) ); + } } } } @@ -3251,44 +3294,43 @@ SdrObject* XclImpDffManager::CreateSdrObject( const XclImpPictureObj& rPicObj, c return xSdrObj.release(); } -ScRange XclImpDffManager::GetUsedArea( SCTAB nScTab ) const +bool XclImpDffConverter::SupportsOleObjects() const { - ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID ); - ScRangeMap::const_iterator aIt = maUsedAreaMap.find( nScTab ); - if( aIt != maUsedAreaMap.end() ) - aScUsedArea = aIt->second; - return aScUsedArea; + return GetConvData().mrDrawing.SupportsOleObjects(); } // virtual functions ---------------------------------------------------------- -void XclImpDffManager::ProcessClientAnchor2( SvStream& rDffStrm, +void XclImpDffConverter::ProcessClientAnchor2( SvStream& rDffStrm, DffRecordHeader& rHeader, void* /*pClientData*/, DffObjData& rObjData ) { // find the OBJ record data related to the processed shape - if( XclImpDrawObjBase* pDrawObj = mrObjManager.FindDrawObj( rObjData.rSpHd ).get() ) + XclImpDffConvData& rConvData = GetConvData(); + if( XclImpDrawObjBase* pDrawObj = rConvData.mrDrawing.FindDrawObj( rObjData.rSpHd ).get() ) { - DBG_ASSERT( rHeader.nRecType == DFF_msofbtClientAnchor, "XclImpDffManager::ProcessClientAnchor2 - no client anchor record" ); - XclObjAnchor aAnchor( pDrawObj->GetScTab() ); + DBG_ASSERT( rHeader.nRecType == DFF_msofbtClientAnchor, "XclImpDffConverter::ProcessClientAnchor2 - no client anchor record" ); + XclObjAnchor aAnchor; rHeader.SeekToContent( rDffStrm ); rDffStrm.SeekRel( 2 ); // flags rDffStrm >> aAnchor; // anchor format equal to BIFF5 OBJ records pDrawObj->SetAnchor( aAnchor ); - rObjData.aChildAnchor = pDrawObj->GetAnchorRect(); + rObjData.aChildAnchor = rConvData.mrDrawing.CalcAnchorRect( aAnchor, true ); rObjData.bChildAnchor = sal_True; } } -SdrObject* XclImpDffManager::ProcessObj( SvStream& rDffStrm, - DffObjData& rDffObjData, void* pClientData, Rectangle& /*rTextRect*/, SdrObject* pOldSdrObj ) +SdrObject* XclImpDffConverter::ProcessObj( SvStream& rDffStrm, DffObjData& rDffObjData, + void* pClientData, Rectangle& /*rTextRect*/, SdrObject* pOldSdrObj ) { + XclImpDffConvData& rConvData = GetConvData(); + /* pOldSdrObj passes a generated SdrObject. This function owns this object and can modify it. The function has either to return it back to caller or to delete it by itself. */ SdrObjectPtr xSdrObj( pOldSdrObj ); // find the OBJ record data related to the processed shape - XclImpDrawObjRef xDrawObj = mrObjManager.FindDrawObj( rDffObjData.rSpHd ); + XclImpDrawObjRef xDrawObj = rConvData.mrDrawing.FindDrawObj( rDffObjData.rSpHd ); const Rectangle& rAnchorRect = rDffObjData.aChildAnchor; // #102378# Do not process the global page group shape (flag SP_FPATRIARCH) @@ -3326,7 +3368,7 @@ SdrObject* XclImpDffManager::ProcessObj( SvStream& rDffStrm, /* Connect textbox data (string, alignment, text orientation) to object. #98132# don't ask for a text-ID, DFF export doesn't set one. */ if( XclImpTextObj* pTextObj = dynamic_cast< XclImpTextObj* >( xDrawObj.get() ) ) - if( const XclImpObjTextData* pTextData = mrObjManager.FindTextData( rDffObjData.rSpHd ) ) + if( const XclImpObjTextData* pTextData = rConvData.mrDrawing.FindTextData( rDffObjData.rSpHd ) ) pTextObj->SetTextData( *pTextData ); // copy line and fill formatting of TBX form controls from DFF properties @@ -3334,7 +3376,7 @@ SdrObject* XclImpDffManager::ProcessObj( SvStream& rDffStrm, pTbxObj->SetDffProperties( *this ); // try to create a custom SdrObject that overwrites the passed object - SdrObjectPtr xNewSdrObj( xDrawObj->CreateSdrObject( rAnchorRect, *mxProgress, true ) ); + SdrObjectPtr xNewSdrObj( xDrawObj->CreateSdrObject( *this, rAnchorRect, true ) ); if( xNewSdrObj.is() ) xSdrObj.reset( xNewSdrObj.release() ); @@ -3346,40 +3388,50 @@ SdrObject* XclImpDffManager::ProcessObj( SvStream& rDffStrm, xSdrObj->SetMergedItem( XFillColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWBACK ) ) ); // additional processing on the SdrObject - xDrawObj->ProcessSdrObject( *xSdrObj ); - - // add the area used by this object to the internal map of used areas - UpdateUsedArea( *xDrawObj ); + xDrawObj->PreProcessSdrObject( *this, *xSdrObj ); /* If the SdrObject will not be inserted into the draw page, delete it - here. Happens e.g. for notes: The ProcessSdrObject() call above has - inserted the note into the document, and the SdrObject is not + here. Happens e.g. for notes: The PreProcessSdrObject() call above + has inserted the note into the document, and the SdrObject is not needed anymore. */ if( !xDrawObj->IsInsertSdrObj() ) xSdrObj.reset(); } - /* Store the relation between shape ID and SdrObject for connectors. Must - be done here (and not in InsertSdrObject() function), otherwise all - SdrObjects embedded in groups would be lost. */ if( xSdrObj.is() ) - maSolverCont.InsertSdrObjectInfo( *xSdrObj, xDrawObj->GetDffShapeId(), xDrawObj->GetDffFlags() ); + { + /* Store the relation between shape ID and SdrObject for connectors. + Must be done here (and not in InsertSdrObject() function), + otherwise all SdrObjects embedded in groups would be lost. */ + rConvData.maSolverCont.InsertSdrObjectInfo( *xSdrObj, xDrawObj->GetDffShapeId(), xDrawObj->GetDffFlags() ); + + /* If the drawing object is embedded in a group object, call + PostProcessSdrObject() here. For top-level objects this will be + done automatically in InsertSdrObject() but grouped shapes are + inserted into their groups somewhere in the SvxMSDffManager base + class without chance of notification. Unfortunately, now this is + called before the object is really inserted into its group object, + but that should not have any effect for grouped objects. */ + if( !bIsTopLevel ) + xDrawObj->PostProcessSdrObject( *this, *xSdrObj ); + } return xSdrObj.release(); } -ULONG XclImpDffManager::Calc_nBLIPPos( ULONG /*nOrgVal*/, ULONG nStreamPos ) const +ULONG XclImpDffConverter::Calc_nBLIPPos( ULONG /*nOrgVal*/, ULONG nStreamPos ) const { return nStreamPos + 4; } -sal_Bool XclImpDffManager::InsertControl( const Reference< XFormComponent >& rxFormComp, +sal_Bool XclImpDffConverter::InsertControl( const Reference< XFormComponent >& rxFormComp, const ::com::sun::star::awt::Size& /*rSize*/, Reference< XShape >* pxShape, BOOL /*bFloatingCtrl*/ ) { if( GetDocShell() ) try { - Reference< XIndexContainer > xFormIC( mxCurrForm, UNO_QUERY_THROW ); + XclImpDffConvData& rConvData = GetConvData(); + Reference< XIndexContainer > xFormIC( rConvData.mxCtrlForm, UNO_QUERY_THROW ); Reference< XControlModel > xCtrlModel( rxFormComp, UNO_QUERY_THROW ); // create the control shape @@ -3390,7 +3442,7 @@ sal_Bool XclImpDffManager::InsertControl( const Reference< XFormComponent >& rxF sal_Int32 nNewIndex = xFormIC->getCount(); xFormIC->insertByIndex( nNewIndex, Any( rxFormComp ) ); // on success: store new index of the control for later use (macro events) - mnLastCtrlIndex = nNewIndex; + rConvData.mnLastCtrlIndex = nNewIndex; // set control model at control shape and pass back shape to caller xCtrlShape->setControl( xCtrlModel ); @@ -3399,7 +3451,7 @@ sal_Bool XclImpDffManager::InsertControl( const Reference< XFormComponent >& rxF } catch( Exception& ) { - DBG_ERRORFILE( "XclImpDffManager::InsertControl - cannot create form control" ); + DBG_ERRORFILE( "XclImpDffConverter::InsertControl - cannot create form control" ); } return sal_False; @@ -3407,7 +3459,19 @@ sal_Bool XclImpDffManager::InsertControl( const Reference< XFormComponent >& rxF // private -------------------------------------------------------------------- -String XclImpDffManager::ReadHlinkProperty( SvStream& rDffStrm ) const +XclImpDffConverter::XclImpDffConvData& XclImpDffConverter::GetConvData() +{ + DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" ); + return *maDataStack.back(); +} + +const XclImpDffConverter::XclImpDffConvData& XclImpDffConverter::GetConvData() const +{ + DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" ); + return *maDataStack.back(); +} + +String XclImpDffConverter::ReadHlinkProperty( SvStream& rDffStrm ) const { /* Reads hyperlink data from a complex DFF property. Contents of this property are equal to the HLINK record, import of this record is @@ -3438,13 +3502,7 @@ String XclImpDffManager::ReadHlinkProperty( SvStream& rDffStrm ) const return aString; } -void XclImpDffManager::ProcessDggContainer( SvStream& rDffStrm, const DffRecordHeader& rDggHeader ) -{ - // seek to end of drawing group container - rDggHeader.SeekToEndOfRecord( rDffStrm ); -} - -void XclImpDffManager::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader ) +void XclImpDffConverter::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader ) { sal_Size nEndPos = rDgHeader.GetRecEndFilePos(); while( rDffStrm.Tell() < nEndPos ) @@ -3467,12 +3525,13 @@ void XclImpDffManager::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHe rDgHeader.SeekToEndOfRecord( rDffStrm ); // #i12638# #i37900# connector rules - maSolverCont.UpdateConnectorRules(); - SolveSolver( maSolverCont ); - maSolverCont.RemoveConnectorRules(); + XclImpSolverContainer& rSolverCont = GetConvData().maSolverCont; + rSolverCont.UpdateConnectorRules(); + SolveSolver( rSolverCont ); + rSolverCont.RemoveConnectorRules(); } -void XclImpDffManager::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader ) +void XclImpDffConverter::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader ) { sal_Size nEndPos = rShGrHeader.GetRecEndFilePos(); while( rDffStrm.Tell() < nEndPos ) @@ -3493,17 +3552,17 @@ void XclImpDffManager::ProcessShGrContainer( SvStream& rDffStrm, const DffRecord rShGrHeader.SeekToEndOfRecord( rDffStrm ); } -void XclImpDffManager::ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader ) +void XclImpDffConverter::ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader ) { // solver container wants to read the solver container header again rSolverHeader.SeekToBegOfRecord( rDffStrm ); // read the entire solver container - rDffStrm >> maSolverCont; + rDffStrm >> GetConvData().maSolverCont; // seek to end of solver container rSolverHeader.SeekToEndOfRecord( rDffStrm ); } -void XclImpDffManager::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader ) +void XclImpDffConverter::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader ) { rShHeader.SeekToBegOfRecord( rDffStrm ); Rectangle aDummy; @@ -3516,112 +3575,70 @@ void XclImpDffManager::ProcessShContainer( SvStream& rDffStrm, const DffRecordHe the pointer to the related draw object data (OBJ record) into pDrawObj. */ SdrObjectPtr xSdrObj( ImportObj( rDffStrm, &pDrawObj, aDummy, aDummy, 0, 0 ) ); if( pDrawObj && xSdrObj.is() ) - InsertSdrObject( GetSdrPage( pDrawObj->GetScTab() ), *pDrawObj, xSdrObj.release() ); + InsertSdrObject( GetConvData().mrSdrPage, *pDrawObj, xSdrObj.release() ); rShHeader.SeekToEndOfRecord( rDffStrm ); } -void XclImpDffManager::InsertSdrObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj ) +void XclImpDffConverter::InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj ) { + XclImpDffConvData& rConvData = GetConvData(); /* Take ownership of the passed object. If insertion fails (e.g. rDrawObj - states to skip insertion, or missing draw page), the object is - automatically deleted. */ + states to skip insertion), the object is automatically deleted. */ SdrObjectPtr xSdrObj( pSdrObj ); - if( pObjList && xSdrObj.is() && rDrawObj.IsInsertSdrObj() ) - pObjList->NbcInsertObject( xSdrObj.release() ); - // SdrObject still here? Insertion failed, remove data from shape ID map. + if( xSdrObj.is() && rDrawObj.IsInsertSdrObj() ) + { + rObjList.NbcInsertObject( xSdrObj.release() ); + // callback to drawing manager for e.g. tracking of used sheet area + rConvData.mrDrawing.OnObjectInserted( rDrawObj ); + // callback to drawing object for post processing (use pSdrObj, xSdrObj already released) + rDrawObj.PostProcessSdrObject( *this, *pSdrObj ); + } + /* SdrObject still here? Insertion failed, remove data from shape ID map. + The SdrObject will be destructed then. */ if( xSdrObj.is() ) - maSolverCont.RemoveSdrObjectInfo( *xSdrObj ); + rConvData.maSolverCont.RemoveSdrObjectInfo( *xSdrObj ); } -void XclImpDffManager::SetCurrentForm( SCTAB nScTab ) +void XclImpDffConverter::InitControlForm() { - if( nScTab != mnCurrFormScTab ) - { - mxCurrForm.clear(); - mnCurrFormScTab = nScTab; + XclImpDffConvData& rConvData = GetConvData(); + if( rConvData.mbHasCtrlForm ) + return; - SdrPage* pSdrPage = GetSdrPage( nScTab ); - if( GetDocShell() && pSdrPage ) try + rConvData.mbHasCtrlForm = true; + if( SupportsOleObjects() ) try + { + Reference< XFormsSupplier > xFormsSupplier( rConvData.mrSdrPage.getUnoPage(), UNO_QUERY_THROW ); + Reference< XNameContainer > xFormsNC( xFormsSupplier->getForms(), UNO_SET_THROW ); + // find or create the Standard form used to insert the imported controls + if( xFormsNC->hasByName( maStdFormName ) ) { - Reference< XFormsSupplier > xFormsSupplier( pSdrPage->getUnoPage(), UNO_QUERY_THROW ); - Reference< XNameContainer > xFormsNC = xFormsSupplier->getForms(); - if( xFormsNC.is() ) - { - // find or create the Standard form used to insert the imported controls - OUString aFormName = CREATE_OUSTRING( "Standard" ); - if( xFormsNC->hasByName( aFormName ) ) - { - xFormsNC->getByName( aFormName ) >>= mxCurrForm; - } - else - { - mxCurrForm.set( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), UNO_QUERY_THROW ); - xFormsNC->insertByName( aFormName, Any( mxCurrForm ) ); - } - } + xFormsNC->getByName( maStdFormName ) >>= rConvData.mxCtrlForm; } - catch( Exception& ) + else if( SfxObjectShell* pDocShell = GetDocShell() ) { + rConvData.mxCtrlForm.set( ScfApiHelper::CreateInstance( pDocShell, CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), UNO_QUERY_THROW ); + xFormsNC->insertByName( maStdFormName, Any( rConvData.mxCtrlForm ) ); } } -} - -void XclImpDffManager::UpdateUsedArea( const XclImpDrawObjBase& rDrawObj ) -{ - ScRange aScObjArea = rDrawObj.GetUsedArea(); - if( aScObjArea.IsValid() ) + catch( Exception& ) { - ScRange* pScTabArea = 0; - ScRangeMap::iterator aIt = maUsedAreaMap.find( rDrawObj.GetScTab() ); - if( aIt == maUsedAreaMap.end() ) - { - pScTabArea = &maUsedAreaMap[ rDrawObj.GetScTab() ]; - pScTabArea->SetInvalid(); - } - else - pScTabArea = &aIt->second; - - if( pScTabArea ) - pScTabArea->ExtendTo( aScObjArea ); } } -// The object manager ========================================================= +// Drawing manager ============================================================ -XclImpObjectManager::XclImpObjectManager( const XclImpRoot& rRoot ) : - XclImpRoot( rRoot ) +XclImpDrawing::XclImpDrawing( const XclImpRoot& rRoot, bool bOleObjects ) : + XclImpRoot( rRoot ), + mbOleObjs( bOleObjects ) { - maDefObjNames[ EXC_OBJTYPE_GROUP ] = CREATE_STRING( "Group" ); - maDefObjNames[ EXC_OBJTYPE_LINE ] = CREATE_STRING( "Line" ); - maDefObjNames[ EXC_OBJTYPE_RECTANGLE ] = CREATE_STRING( "Rectangle" ); - maDefObjNames[ EXC_OBJTYPE_OVAL ] = CREATE_STRING( "Oval" ); - maDefObjNames[ EXC_OBJTYPE_ARC ] = CREATE_STRING( "Arc" ); - maDefObjNames[ EXC_OBJTYPE_CHART ] = CREATE_STRING( "Chart" ); - maDefObjNames[ EXC_OBJTYPE_TEXT ] = CREATE_STRING( "Text" ); - maDefObjNames[ EXC_OBJTYPE_BUTTON ] = CREATE_STRING( "Button" ); - maDefObjNames[ EXC_OBJTYPE_PICTURE ] = CREATE_STRING( "Picture" ); - maDefObjNames[ EXC_OBJTYPE_POLYGON ] = CREATE_STRING( "Freeform" ); - maDefObjNames[ EXC_OBJTYPE_CHECKBOX ] = CREATE_STRING( "Check Box" ); - maDefObjNames[ EXC_OBJTYPE_OPTIONBUTTON ] = CREATE_STRING( "Option Button" ); - maDefObjNames[ EXC_OBJTYPE_EDIT ] = CREATE_STRING( "Edit Box" ); - maDefObjNames[ EXC_OBJTYPE_LABEL ] = CREATE_STRING( "Label" ); - maDefObjNames[ EXC_OBJTYPE_DIALOG ] = CREATE_STRING( "Dialog Frame" ); - maDefObjNames[ EXC_OBJTYPE_SPIN ] = CREATE_STRING( "Spinner" ); - maDefObjNames[ EXC_OBJTYPE_SCROLLBAR ] = CREATE_STRING( "Scroll Bar" ); - maDefObjNames[ EXC_OBJTYPE_LISTBOX ] = CREATE_STRING( "List Box" ); - maDefObjNames[ EXC_OBJTYPE_GROUPBOX ] = CREATE_STRING( "Group Box" ); - maDefObjNames[ EXC_OBJTYPE_DROPDOWN ] = CREATE_STRING( "Drop Down" ); - maDefObjNames[ EXC_OBJTYPE_NOTE ] = CREATE_STRING( "Comment" ); - maDefObjNames[ EXC_OBJTYPE_DRAWING ] = CREATE_STRING( "AutoShape" ); } -XclImpObjectManager::~XclImpObjectManager() +XclImpDrawing::~XclImpDrawing() { } -// *** Read Excel records *** ------------------------------------------------- - -Graphic XclImpObjectManager::ReadImgData( XclImpStream& rStrm ) // static helper +/*static*/ Graphic XclImpDrawing::ReadImgData( const XclImpRoot& rRoot, XclImpStream& rStrm ) { Graphic aGraphic; sal_uInt16 nFormat, nEnv; @@ -3631,33 +3648,33 @@ Graphic XclImpObjectManager::ReadImgData( XclImpStream& rStrm ) // static helper { switch( nFormat ) { - case EXC_IMGDATA_WMF: ReadWmf( aGraphic, rStrm ); break; - case EXC_IMGDATA_BMP: ReadBmp( aGraphic, rStrm ); break; - default: DBG_ERRORFILE( "XclImpObjectManager::ReadImgData - unknown image format" ); + case EXC_IMGDATA_WMF: ReadWmf( aGraphic, rRoot, rStrm ); break; + case EXC_IMGDATA_BMP: ReadBmp( aGraphic, rRoot, rStrm ); break; + default: DBG_ERRORFILE( "XclImpDrawing::ReadImgData - unknown image format" ); } } return aGraphic; } -void XclImpObjectManager::ReadObj( XclImpStream& rStrm ) +void XclImpDrawing::ReadObj( XclImpStream& rStrm ) { XclImpDrawObjRef xDrawObj; /* #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, "XclImpObjectManager::ReadObj - unexpected DFF stream data, OBJ will be ignored" ); + DBG_ASSERT( maDffStrm.Tell() == 0, "XclImpDrawing::ReadObj - unexpected DFF stream data, OBJ will be ignored" ); if( maDffStrm.Tell() == 0 ) switch( GetBiff() ) { case EXC_BIFF3: - xDrawObj = XclImpDrawObjBase::ReadObj3( rStrm ); + xDrawObj = XclImpDrawObjBase::ReadObj3( GetRoot(), rStrm ); break; case EXC_BIFF4: - xDrawObj = XclImpDrawObjBase::ReadObj4( rStrm ); + xDrawObj = XclImpDrawObjBase::ReadObj4( GetRoot(), rStrm ); break; case EXC_BIFF5: case EXC_BIFF8: - xDrawObj = XclImpDrawObjBase::ReadObj5( rStrm ); + xDrawObj = XclImpDrawObjBase::ReadObj5( GetRoot(), rStrm ); break; default: DBG_ERROR_BIFF(); @@ -3672,30 +3689,11 @@ void XclImpObjectManager::ReadObj( XclImpStream& rStrm ) } } -void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream& rStrm ) -{ - DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 ); - // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm. - rStrm.ResetRecord( true, EXC_ID_MSODRAWINGGROUP ); - ReadDffRecord( rStrm ); -} - -void XclImpObjectManager::ReadMsoDrawing( XclImpStream& rStrm ) +void XclImpDrawing::ReadMsoDrawing( XclImpStream& rStrm ) { DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 ); // disable internal CONTINUE handling rStrm.ResetRecord( false ); - /* #i60510# real life: MSODRAWINGSELECTION record may contain garbage - - this makes it impossible to process the DFF stream in one run. - Store stream start position for every sheet separately, will be used - to seek the stream to these positions later, when processing the next - sheet. */ - size_t nTabIdx = static_cast< size_t >( GetCurrScTab() ); - if( nTabIdx >= maTabStrmPos.size() ) - { - maTabStrmPos.resize( nTabIdx, STREAM_SEEK_TO_END ); - maTabStrmPos.push_back( maDffStrm.Tell() ); - } // read leading MSODRAWING record ReadDffRecord( rStrm ); @@ -3725,36 +3723,7 @@ void XclImpObjectManager::ReadMsoDrawing( XclImpStream& rStrm ) rStrm.ResetRecord( true ); } -void XclImpObjectManager::ReadNote( XclImpStream& rStrm ) -{ - switch( GetBiff() ) - { - case EXC_BIFF2: - case EXC_BIFF3: - case EXC_BIFF4: - case EXC_BIFF5: - ReadNote3( rStrm ); - break; - case EXC_BIFF8: - ReadNote8( rStrm ); - break; - default: - DBG_ERROR_BIFF(); - } -} - -void XclImpObjectManager::ReadTabChart( XclImpStream& rStrm ) -{ - DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF5 ); - ScfRef< XclImpChartObj > xChartObj( new XclImpChartObj( GetRoot(), true ) ); - xChartObj->ReadChartSubStream( rStrm ); - // insert the chart as raw object without connected DFF data - maRawObjs.push_back( xChartObj ); -} - -// *** Drawing objects *** ---------------------------------------------------- - -XclImpDrawObjRef XclImpObjectManager::FindDrawObj( const DffRecordHeader& rHeader ) const +XclImpDrawObjRef XclImpDrawing::FindDrawObj( const DffRecordHeader& rHeader ) const { /* maObjMap stores objects by position of the client data (OBJ record) in the DFF stream, which is always behind shape start position of the @@ -3769,16 +3738,16 @@ XclImpDrawObjRef XclImpObjectManager::FindDrawObj( const DffRecordHeader& rHeade return xDrawObj; } -XclImpDrawObjRef XclImpObjectManager::FindDrawObj( const XclObjId& rObjId ) const +XclImpDrawObjRef XclImpDrawing::FindDrawObj( sal_uInt16 nObjId ) const { XclImpDrawObjRef xDrawObj; - XclImpObjMapById::const_iterator aIt = maObjMapId.find( rObjId ); + XclImpObjMapById::const_iterator aIt = maObjMapId.find( nObjId ); if( aIt != maObjMapId.end() ) xDrawObj = aIt->second; return xDrawObj; } -const XclImpObjTextData* XclImpObjectManager::FindTextData( const DffRecordHeader& rHeader ) const +const XclImpObjTextData* XclImpDrawing::FindTextData( const DffRecordHeader& rHeader ) const { /* maTextMap stores textbox data by position of the client data (TXO record) in the DFF stream, which is always behind shape start position @@ -3792,75 +3761,46 @@ const XclImpObjTextData* XclImpObjectManager::FindTextData( const DffRecordHeade return 0; } -void XclImpObjectManager::SetSkipObj( SCTAB nScTab, sal_uInt16 nObjId ) +void XclImpDrawing::SetSkipObj( sal_uInt16 nObjId ) { - maSkipObjs.push_back( XclObjId( nScTab, nObjId ) ); + maSkipObjs.push_back( nObjId ); } -// *** Drawing object conversion *** ------------------------------------------ - -XclImpDffManager& XclImpObjectManager::GetDffManager() +sal_Size XclImpDrawing::GetProgressSize() const { - if( !mxDffManager ) - mxDffManager.reset( new XclImpDffManager( GetRoot(), *this, maDffStrm ) ); - return *mxDffManager; + sal_Size nProgressSize = maRawObjs.GetProgressSize(); + for( XclImpObjMap::const_iterator aIt = maObjMap.begin(), aEnd = maObjMap.end(); aIt != aEnd; ++aIt ) + nProgressSize += aIt->second->GetProgressSize(); + return nProgressSize; } -void XclImpObjectManager::ConvertObjects() +void XclImpDrawing::ImplConvertObjects( XclImpDffConverter& rDffConv, SdrModel& rSdrModel, SdrPage& rSdrPage ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "sc", "dr104026", "XclImpObjectManager::ConvertObjects" ); - - // do nothing if the document does not contain a drawing layer - if( GetDoc().GetDrawLayer() ) - { - // process list of identifiers of objects to be skipped - for( XclObjIdVec::const_iterator aVIt = maSkipObjs.begin(), aVEnd = maSkipObjs.end(); aVIt != aVEnd; ++aVIt ) - if( XclImpDrawObjBase* pDrawObj = FindDrawObj( *aVIt ).get() ) - pDrawObj->SetProcessSdrObj( false ); - - // get progress bar size for all valid objects - sal_Size nProgressSize = GetProgressSize(); - if( nProgressSize > 0 ) - { - XclImpDffManager& rDffManager = GetDffManager(); - rDffManager.StartProgressBar( nProgressSize ); - // process drawing objects without DFF data - for( XclImpDrawObjVector::const_iterator aVIt = maRawObjs.begin(), aVEnd = maRawObjs.end(); aVIt != aVEnd; ++aVIt ) - rDffManager.ProcessObject( GetSdrPage( (*aVIt)->GetScTab() ), **aVIt ); - // process the global DFF container, contains pictures - if( !maTabStrmPos.empty() && (maTabStrmPos.front() > 0) ) - rDffManager.ProcessDrawingGroup( maDffStrm ); - // process the sheet records, this inserts the objects into the drawing layer - for( StreamPosVec::const_iterator aPIt = maTabStrmPos.begin(), aPEnd = maTabStrmPos.end(); aPIt != aPEnd; ++aPIt ) - if( *aPIt != STREAM_SEEK_TO_END ) - rDffManager.ProcessDrawing( maDffStrm, *aPIt ); - } - } - ScChartListenerCollection* pChartListeners = GetDoc().GetChartListenerCollection(); - if (pChartListeners && pChartListeners->GetCount()) - pChartListeners->SetDirty(); + // register this drawing manager at the passed (global) DFF manager + rDffConv.InitializeDrawing( *this, rSdrModel, rSdrPage ); + // process list of objects to be skipped + for( ScfUInt16Vec::const_iterator aIt = maSkipObjs.begin(), aEnd = maSkipObjs.end(); aIt != aEnd; ++aIt ) + if( XclImpDrawObjBase* pDrawObj = FindDrawObj( *aIt ).get() ) + pDrawObj->SetProcessSdrObj( false ); + // process drawing objects without DFF data + rDffConv.ProcessDrawing( maRawObjs ); + // process all objects in the DFF stream + rDffConv.ProcessDrawing( maDffStrm ); + // unregister this drawing manager at the passed (global) DFF manager + rDffConv.FinalizeDrawing(); } -String XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const -{ - String aDefName; - DefObjNameMap::const_iterator aIt = maDefObjNames.find( rDrawObj.GetObjType() ); - if( aIt != maDefObjNames.end() ) - aDefName.Append( aIt->second ); - return aDefName.Append( sal_Unicode( ' ' ) ).Append( String::CreateFromInt32( rDrawObj.GetObjId().mnObjId ) ); -} +// protected ------------------------------------------------------------------ -ScRange XclImpObjectManager::GetUsedArea( SCTAB nScTab ) const +void XclImpDrawing::AppendRawObject( const XclImpDrawObjRef& rxDrawObj ) { - ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID ); - if( mxDffManager.is() ) - aScUsedArea = mxDffManager->GetUsedArea( nScTab ); - return aScUsedArea; + DBG_ASSERT( rxDrawObj.is(), "XclImpDrawing::AppendRawObject - unexpected empty reference" ); + maRawObjs.push_back( rxDrawObj ); } // private -------------------------------------------------------------------- -void XclImpObjectManager::ReadWmf( Graphic& rGraphic, XclImpStream& rStrm ) // static helper +void XclImpDrawing::ReadWmf( Graphic& rGraphic, const XclImpRoot&, XclImpStream& rStrm ) // static helper { // extract graphic data from IMGDATA and following CONTINUE records rStrm.Ignore( 8 ); @@ -3873,7 +3813,7 @@ void XclImpObjectManager::ReadWmf( Graphic& rGraphic, XclImpStream& rStrm ) // s rGraphic = aGDIMetaFile; } -void XclImpObjectManager::ReadBmp( Graphic& rGraphic, XclImpStream& rStrm ) // static helper +void XclImpDrawing::ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm ) // static helper { // extract graphic data from IMGDATA and following CONTINUE records SvMemoryStream aMemStrm; @@ -3883,7 +3823,7 @@ void XclImpObjectManager::ReadBmp( Graphic& rGraphic, XclImpStream& rStrm ) // s pixel depth = 32 bit. After that, 3 unused bytes are added before the actual pixel data. This does even confuse Excel 5 and later, which cannot read the image data correctly. */ - if( rStrm.GetRoot().GetBiff() <= EXC_BIFF4 ) + if( rRoot.GetBiff() <= EXC_BIFF4 ) { rStrm.PushPosition(); sal_uInt32 nHdrSize; @@ -3910,21 +3850,21 @@ void XclImpObjectManager::ReadBmp( Graphic& rGraphic, XclImpStream& rStrm ) // s rGraphic = aBitmap; } -void XclImpObjectManager::ReadDffRecord( XclImpStream& rStrm ) +void XclImpDrawing::ReadDffRecord( XclImpStream& rStrm ) { maDffStrm.Seek( STREAM_SEEK_TO_END ); rStrm.CopyRecordToStream( maDffStrm ); } -void XclImpObjectManager::ReadObj8( XclImpStream& rStrm ) +void XclImpDrawing::ReadObj8( XclImpStream& rStrm ) { - XclImpDrawObjRef xDrawObj = XclImpDrawObjBase::ReadObj8( rStrm ); + XclImpDrawObjRef xDrawObj = XclImpDrawObjBase::ReadObj8( GetRoot(), rStrm ); // store the new object in the internal containers maObjMap[ maDffStrm.Tell() ] = xDrawObj; maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj; } -void XclImpObjectManager::ReadTxo( XclImpStream& rStrm ) +void XclImpDrawing::ReadTxo( XclImpStream& rStrm ) { XclImpObjTextRef xTextData( new XclImpObjTextData ); maTextMap[ maDffStrm.Tell() ] = xTextData; @@ -3938,7 +3878,7 @@ void XclImpObjectManager::ReadTxo( XclImpStream& rStrm ) if( xTextData->maData.mnTextLen > 0 ) { bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord(); - DBG_ASSERT( bValid, "XclImpObjectManager::ReadTxo - missing CONTINUE record" ); + DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" ); if( bValid ) xTextData->mxString.reset( new XclImpString( rStrm.ReadUniString( xTextData->maData.mnTextLen ) ) ); } @@ -3947,21 +3887,78 @@ void XclImpObjectManager::ReadTxo( XclImpStream& rStrm ) if( xTextData->maData.mnFormatSize > 0 ) { bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord(); - DBG_ASSERT( bValid, "XclImpObjectManager::ReadTxo - missing CONTINUE record" ); + DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" ); if( bValid ) xTextData->ReadFormats( rStrm ); } } -void XclImpObjectManager::ReadNote3( XclImpStream& rStrm ) +// ---------------------------------------------------------------------------- + +XclImpSheetDrawing::XclImpSheetDrawing( const XclImpRoot& rRoot, SCTAB nScTab ) : + XclImpDrawing( rRoot, true ), + maScUsedArea( ScAddress::INITIALIZE_INVALID ) +{ + maScUsedArea.aStart.SetTab( nScTab ); + maScUsedArea.aEnd.SetTab( nScTab ); +} + +void XclImpSheetDrawing::ReadNote( XclImpStream& rStrm ) +{ + switch( GetBiff() ) + { + case EXC_BIFF2: + case EXC_BIFF3: + case EXC_BIFF4: + case EXC_BIFF5: + ReadNote3( rStrm ); + break; + case EXC_BIFF8: + ReadNote8( rStrm ); + break; + default: + DBG_ERROR_BIFF(); + } +} + +void XclImpSheetDrawing::ReadTabChart( XclImpStream& rStrm ) +{ + DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF5 ); + ScfRef< XclImpChartObj > xChartObj( new XclImpChartObj( GetRoot(), true ) ); + xChartObj->ReadChartSubStream( rStrm ); + // insert the chart as raw object without connected DFF data + AppendRawObject( xChartObj ); +} + +void XclImpSheetDrawing::ConvertObjects( XclImpDffConverter& rDffConv ) +{ + if( SdrModel* pSdrModel = GetDoc().GetDrawLayer() ) + if( SdrPage* pSdrPage = GetSdrPage( maScUsedArea.aStart.Tab() ) ) + ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage ); +} + +Rectangle XclImpSheetDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool /*bDffAnchor*/ ) const +{ + return rAnchor.GetRect( GetDoc(), maScUsedArea.aStart.Tab(), MAP_100TH_MM ); +} + +void XclImpSheetDrawing::OnObjectInserted( const XclImpDrawObjBase& rDrawObj ) +{ + ScRange aScObjArea = rDrawObj.GetUsedArea( maScUsedArea.aStart.Tab() ); + if( aScObjArea.IsValid() ) + maScUsedArea.ExtendTo( aScObjArea ); +} + +// private -------------------------------------------------------------------- + +void XclImpSheetDrawing::ReadNote3( XclImpStream& rStrm ) { XclAddress aXclPos; sal_uInt16 nTotalLen; rStrm >> aXclPos >> nTotalLen; - SCTAB nScTab = GetCurrScTab(); ScAddress aScNotePos( ScAddress::UNINITIALIZED ); - if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, nScTab, true ) ) + if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) ) { sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.GetRecLeft() ) ); String aNoteText = rStrm.ReadRawByteString( nPartLen ); @@ -3988,33 +3985,117 @@ void XclImpObjectManager::ReadNote3( XclImpStream& rStrm ) } } -void XclImpObjectManager::ReadNote8( XclImpStream& rStrm ) +void XclImpSheetDrawing::ReadNote8( XclImpStream& rStrm ) { XclAddress aXclPos; sal_uInt16 nFlags, nObjId; rStrm >> aXclPos >> nFlags >> nObjId; - SCTAB nScTab = GetCurrScTab(); ScAddress aScNotePos( ScAddress::UNINITIALIZED ); - if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, nScTab, true ) ) + if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) ) if( nObjId != EXC_OBJ_INVALID_ID ) - if( XclImpNoteObj* pNoteObj = dynamic_cast< XclImpNoteObj* >( FindDrawObj( XclObjId( nScTab, nObjId ) ).get() ) ) + if( XclImpNoteObj* pNoteObj = dynamic_cast< XclImpNoteObj* >( FindDrawObj( nObjId ).get() ) ) pNoteObj->SetNoteData( aScNotePos, nFlags ); } -sal_Size XclImpObjectManager::GetProgressSize() const +// The object manager ========================================================= + +XclImpObjectManager::XclImpObjectManager( const XclImpRoot& rRoot ) : + XclImpRoot( rRoot ) { - sal_Size nProgressSize = maRawObjs.GetProgressSize(); - for( XclImpObjMap::const_iterator aMIt = maObjMap.begin(), aMEnd = maObjMap.end(); aMIt != aMEnd; ++aMIt ) - nProgressSize += aMIt->second->GetProgressSize(); - return nProgressSize; + maDefObjNames[ EXC_OBJTYPE_GROUP ] = CREATE_STRING( "Group" ); + maDefObjNames[ EXC_OBJTYPE_LINE ] = CREATE_STRING( "Line" ); + maDefObjNames[ EXC_OBJTYPE_RECTANGLE ] = CREATE_STRING( "Rectangle" ); + maDefObjNames[ EXC_OBJTYPE_OVAL ] = CREATE_STRING( "Oval" ); + maDefObjNames[ EXC_OBJTYPE_ARC ] = CREATE_STRING( "Arc" ); + maDefObjNames[ EXC_OBJTYPE_CHART ] = CREATE_STRING( "Chart" ); + maDefObjNames[ EXC_OBJTYPE_TEXT ] = CREATE_STRING( "Text" ); + maDefObjNames[ EXC_OBJTYPE_BUTTON ] = CREATE_STRING( "Button" ); + maDefObjNames[ EXC_OBJTYPE_PICTURE ] = CREATE_STRING( "Picture" ); + maDefObjNames[ EXC_OBJTYPE_POLYGON ] = CREATE_STRING( "Freeform" ); + maDefObjNames[ EXC_OBJTYPE_CHECKBOX ] = CREATE_STRING( "Check Box" ); + maDefObjNames[ EXC_OBJTYPE_OPTIONBUTTON ] = CREATE_STRING( "Option Button" ); + maDefObjNames[ EXC_OBJTYPE_EDIT ] = CREATE_STRING( "Edit Box" ); + maDefObjNames[ EXC_OBJTYPE_LABEL ] = CREATE_STRING( "Label" ); + maDefObjNames[ EXC_OBJTYPE_DIALOG ] = CREATE_STRING( "Dialog Frame" ); + maDefObjNames[ EXC_OBJTYPE_SPIN ] = CREATE_STRING( "Spinner" ); + maDefObjNames[ EXC_OBJTYPE_SCROLLBAR ] = CREATE_STRING( "Scroll Bar" ); + maDefObjNames[ EXC_OBJTYPE_LISTBOX ] = CREATE_STRING( "List Box" ); + maDefObjNames[ EXC_OBJTYPE_GROUPBOX ] = CREATE_STRING( "Group Box" ); + maDefObjNames[ EXC_OBJTYPE_DROPDOWN ] = CREATE_STRING( "Drop Down" ); + maDefObjNames[ EXC_OBJTYPE_NOTE ] = CREATE_STRING( "Comment" ); + maDefObjNames[ EXC_OBJTYPE_DRAWING ] = CREATE_STRING( "AutoShape" ); +} + +XclImpObjectManager::~XclImpObjectManager() +{ +} + +void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream& rStrm ) +{ + DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 ); + // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm. + rStrm.ResetRecord( true, EXC_ID_MSODRAWINGGROUP ); + maDggStrm.Seek( STREAM_SEEK_TO_END ); + rStrm.CopyRecordToStream( maDggStrm ); +} + +XclImpSheetDrawing& XclImpObjectManager::GetSheetDrawing( SCTAB nScTab ) +{ + XclImpSheetDrawingRef& rxDrawing = maSheetDrawings[ nScTab ]; + if( !rxDrawing ) + rxDrawing.reset( new XclImpSheetDrawing( GetRoot(), nScTab ) ); + return *rxDrawing; +} + +void XclImpObjectManager::ConvertObjects() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "sc", "dr104026", "XclImpObjectManager::ConvertObjects" ); + + // do nothing if the document does not contain a drawing layer + if( !GetDoc().GetDrawLayer() ) + return; + + // get total progress bar size for all sheet drawing managers + sal_Size nProgressSize = 0; + for( XclImpSheetDrawingMap::iterator aIt = maSheetDrawings.begin(), aEnd = maSheetDrawings.end(); aIt != aEnd; ++aIt ) + nProgressSize += aIt->second->GetProgressSize(); + // nothing to do if progress bar is zero (no objects present) + if( nProgressSize == 0 ) + return; + + XclImpDffConverter aDffConv( GetRoot(), maDggStrm ); + aDffConv.StartProgressBar( nProgressSize ); + for( XclImpSheetDrawingMap::iterator aIt = maSheetDrawings.begin(), aEnd = maSheetDrawings.end(); aIt != aEnd; ++aIt ) + aIt->second->ConvertObjects( aDffConv ); + + ScChartListenerCollection* pChartListeners = GetDoc().GetChartListenerCollection(); + if( pChartListeners && (pChartListeners->GetCount() > 0) ) + pChartListeners->SetDirty(); +} + +String XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const +{ + String aDefName; + DefObjNameMap::const_iterator aIt = maDefObjNames.find( rDrawObj.GetObjType() ); + if( aIt != maDefObjNames.end() ) + aDefName.Append( aIt->second ); + return aDefName.Append( sal_Unicode( ' ' ) ).Append( String::CreateFromInt32( rDrawObj.GetObjId() ) ); +} + +ScRange XclImpObjectManager::GetUsedArea( SCTAB nScTab ) const +{ + XclImpSheetDrawingMap::const_iterator aIt = maSheetDrawings.find( nScTab ); + if( aIt != maSheetDrawings.end() ) + return aIt->second->GetUsedArea(); + return ScRange( ScAddress::INITIALIZE_INVALID ); } // DFF property set helper ==================================================== XclImpDffPropSet::XclImpDffPropSet( const XclImpRoot& rRoot ) : XclImpRoot( rRoot ), - maDffManager( rRoot, maDummyStrm ) + maDffConv( rRoot, maDummyStrm ) { } @@ -4030,18 +4111,18 @@ void XclImpDffPropSet::Read( XclImpStream& rStrm ) mxMemStrm.reset( new SvMemoryStream ); rStrm.CopyToStream( *mxMemStrm, 8 + nPropSetSize ); mxMemStrm->Seek( STREAM_SEEK_TO_BEGIN ); - maDffManager.ReadPropSet( *mxMemStrm, 0 ); + maDffConv.ReadPropSet( *mxMemStrm, 0 ); } sal_uInt32 XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId, sal_uInt32 nDefault ) const { - return maDffManager.GetPropertyValue( nPropId, nDefault ); + return maDffConv.GetPropertyValue( nPropId, nDefault ); } void XclImpDffPropSet::FillToItemSet( SfxItemSet& rItemSet ) const { if( mxMemStrm.get() ) - maDffManager.ApplyAttributes( *mxMemStrm, rItemSet ); + maDffConv.ApplyAttributes( *mxMemStrm, rItemSet ); } XclImpStream& operator>>( XclImpStream& rStrm, XclImpDffPropSet& rPropSet ) diff --git a/sc/source/filter/excel/xipage.cxx b/sc/source/filter/excel/xipage.cxx index 75ec91626cf6..c689d0eb7feb 100644 --- a/sc/source/filter/excel/xipage.cxx +++ b/sc/source/filter/excel/xipage.cxx @@ -168,7 +168,7 @@ void XclImpPageSettings::ReadPrintGridLines( XclImpStream& rStrm ) void XclImpPageSettings::ReadImgData( XclImpStream& rStrm ) { - Graphic aGraphic = XclImpObjectManager::ReadImgData( rStrm ); + Graphic aGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); if( aGraphic.GetType() != GRAPHIC_NONE ) maData.mxBrushItem.reset( new SvxBrushItem( aGraphic, GPOS_TILED, ATTR_BACKGROUND ) ); } diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index ac184224c611..29e27a698a42 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -1311,7 +1311,7 @@ void XclImpPivotTable::ReadSxpi( XclImpStream& rStrm ) maPageFields.push_back( aPageInfo.mnField ); pField->SetPageFieldInfo( aPageInfo ); } - GetObjectManager().SetSkipObj( GetCurrScTab(), aPageInfo.mnObjId ); + GetCurrSheetDrawing().SetSkipObj( aPageInfo.mnObjId ); } } diff --git a/sc/source/filter/excel/xiroot.cxx b/sc/source/filter/excel/xiroot.cxx index 7b03d56408c9..3384cf248c87 100644 --- a/sc/source/filter/excel/xiroot.cxx +++ b/sc/source/filter/excel/xiroot.cxx @@ -206,6 +206,12 @@ XclImpObjectManager& XclImpRoot::GetObjectManager() const return *mrImpData.mxObjMgr; } +XclImpSheetDrawing& XclImpRoot::GetCurrSheetDrawing() const +{ + DBG_ASSERT( !IsInGlobals(), "XclImpRoot::GetCurrSheetDrawing - must not be called from workbook globals" ); + return mrImpData.mxObjMgr->GetSheetDrawing( GetCurrScTab() ); +} + XclImpCondFormatManager& XclImpRoot::GetCondFormatManager() const { DBG_ASSERT( mrImpData.mxCondFmtMgr.is(), "XclImpRoot::GetCondFormatManager - invalid call, wrong BIFF" ); diff --git a/sc/source/filter/excel/xlchart.cxx b/sc/source/filter/excel/xlchart.cxx index 2391eb7ef92e..41e682f85808 100644 --- a/sc/source/filter/excel/xlchart.cxx +++ b/sc/source/filter/excel/xlchart.cxx @@ -308,7 +308,7 @@ XclChTypeGroup::XclChTypeGroup() : // ---------------------------------------------------------------------------- XclChProperties::XclChProperties() : - mnFlags( EXC_CHPROPS_MANSERIES ), + mnFlags( 0 ), mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP ) { } @@ -988,8 +988,8 @@ void XclChPropSetHelper::ReadLegendProperties( XclChLegend& rLegend, const ScfPr cssc::RelativePosition aRelPos; if( aRelPosAny >>= aRelPos ) { - rLegend.maRect.mnX = limit_cast< sal_Int32 >( aRelPos.Primary * 4000.0, 0, 4000 ); - rLegend.maRect.mnY = limit_cast< sal_Int32 >( aRelPos.Secondary * 4000.0, 0, 4000 ); + rLegend.maRect.mnX = limit_cast< sal_Int32 >( aRelPos.Primary * EXC_CHART_UNIT, 0, EXC_CHART_UNIT ); + rLegend.maRect.mnY = limit_cast< sal_Int32 >( aRelPos.Secondary * EXC_CHART_UNIT, 0, EXC_CHART_UNIT ); } else rLegend.mnDockMode = EXC_CHLEGEND_LEFT; @@ -1240,8 +1240,8 @@ void XclChPropSetHelper::WriteLegendProperties( eApiExpand = cssc::LegendExpansion_BALANCED; // set position cssc::RelativePosition aRelPos; - aRelPos.Primary = rLegend.maRect.mnX / 4000.0; - aRelPos.Secondary = rLegend.maRect.mnY / 4000.0; + aRelPos.Primary = static_cast< double >( rLegend.maRect.mnX ) / EXC_CHART_UNIT; + aRelPos.Secondary = static_cast< double >( rLegend.maRect.mnY ) / EXC_CHART_UNIT; aRelPos.Anchor = cssd::Alignment_TOP_LEFT; aRelPosAny <<= aRelPos; } diff --git a/sc/source/filter/excel/xlescher.cxx b/sc/source/filter/excel/xlescher.cxx index 5d74346608fd..538fd7fd7242 100644 --- a/sc/source/filter/excel/xlescher.cxx +++ b/sc/source/filter/excel/xlescher.cxx @@ -159,12 +159,16 @@ void lclMirrorRectangle( Rectangle& rRect ) rRect.Right() = -nLeft; } +sal_uInt16 lclGetEmbeddedScale( long nPageSize, sal_Int32 nPageScale, long nPos, double fPosScale ) +{ + return static_cast< sal_uInt16 >( nPos * fPosScale / nPageSize * nPageScale + 0.5 ); +} + } // namespace // ---------------------------------------------------------------------------- -XclObjAnchor::XclObjAnchor( SCTAB nScTab ) : - mnScTab( nScTab ), +XclObjAnchor::XclObjAnchor() : mnLX( 0 ), mnTY( 0 ), mnRX( 0 ), @@ -172,35 +176,61 @@ XclObjAnchor::XclObjAnchor( SCTAB nScTab ) : { } -Rectangle XclObjAnchor::GetRect( ScDocument& rDoc, MapUnit eMapUnit ) const +Rectangle XclObjAnchor::GetRect( ScDocument& rDoc, SCTAB nScTab, MapUnit eMapUnit ) const { double fScale = lclGetTwipsScale( eMapUnit ); Rectangle aRect( - lclGetXFromCol( rDoc, mnScTab, maFirst.mnCol, mnLX, fScale ), - lclGetYFromRow( rDoc, mnScTab, maFirst.mnRow, mnTY, fScale ), - lclGetXFromCol( rDoc, mnScTab, maLast.mnCol, mnRX + 1, fScale ), - lclGetYFromRow( rDoc, mnScTab, maLast.mnRow, mnBY, fScale ) ); + lclGetXFromCol( rDoc, nScTab, maFirst.mnCol, mnLX, fScale ), + lclGetYFromRow( rDoc, nScTab, maFirst.mnRow, mnTY, fScale ), + lclGetXFromCol( rDoc, nScTab, maLast.mnCol, mnRX + 1, fScale ), + lclGetYFromRow( rDoc, nScTab, maLast.mnRow, mnBY, fScale ) ); // #106948# adjust coordinates in mirrored sheets - if( rDoc.IsLayoutRTL( mnScTab ) ) + if( rDoc.IsLayoutRTL( nScTab ) ) lclMirrorRectangle( aRect ); return aRect; } -void XclObjAnchor::SetRect( ScDocument& rDoc, const Rectangle& rRect, MapUnit eMapUnit ) +void XclObjAnchor::SetRect( ScDocument& rDoc, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit ) { Rectangle aRect( rRect ); // #106948# adjust coordinates in mirrored sheets - if( rDoc.IsLayoutRTL( mnScTab ) ) + if( rDoc.IsLayoutRTL( nScTab ) ) lclMirrorRectangle( aRect ); double fScale = lclGetTwipsScale( eMapUnit ); long nDummy = 0; - lclGetColFromX( rDoc, mnScTab, maFirst.mnCol, mnLX, 0, nDummy, aRect.Left(), fScale ); - lclGetColFromX( rDoc, mnScTab, maLast.mnCol, mnRX, maFirst.mnCol, nDummy, aRect.Right(), fScale ); + lclGetColFromX( rDoc, nScTab, maFirst.mnCol, mnLX, 0, nDummy, aRect.Left(), fScale ); + lclGetColFromX( rDoc, nScTab, maLast.mnCol, mnRX, maFirst.mnCol, nDummy, aRect.Right(), fScale ); nDummy = 0; - lclGetRowFromY( rDoc, mnScTab, maFirst.mnRow, mnTY, 0, nDummy, aRect.Top(), fScale ); - lclGetRowFromY( rDoc, mnScTab, maLast.mnRow, mnBY, maFirst.mnRow, nDummy, aRect.Bottom(), fScale ); + lclGetRowFromY( rDoc, nScTab, maFirst.mnRow, mnTY, 0, nDummy, aRect.Top(), fScale ); + lclGetRowFromY( rDoc, nScTab, maLast.mnRow, mnBY, maFirst.mnRow, nDummy, aRect.Bottom(), fScale ); +} + +void XclObjAnchor::SetRect( const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY, + const Rectangle& rRect, MapUnit eMapUnit, bool bDffAnchor ) +{ + double fScale = 1.0; + switch( eMapUnit ) + { + case MAP_TWIP: fScale = HMM_PER_TWIPS; break; // Calc twips -> 1/100mm + case MAP_100TH_MM: fScale = 1.0; break; // Calc 1/100mm -> 1/100mm + default: DBG_ERRORFILE( "XclObjAnchor::SetRect - map unit not implemented" ); + } + + /* In objects with DFF client anchor, the position of the shape is stored + in the cell address components of the client anchor. In old BIFF3-BIFF5 + objects, the position is stored in the offset components of the anchor. */ + (bDffAnchor ? maFirst.mnCol : mnLX) = lclGetEmbeddedScale( rPageSize.Width(), nScaleX, rRect.Left(), fScale ); + (bDffAnchor ? maFirst.mnRow : mnTY) = lclGetEmbeddedScale( rPageSize.Height(), nScaleY, rRect.Top(), fScale ); + (bDffAnchor ? maLast.mnCol : mnRX) = lclGetEmbeddedScale( rPageSize.Width(), nScaleX, rRect.Right(), fScale ); + (bDffAnchor ? maLast.mnRow : mnBY) = lclGetEmbeddedScale( rPageSize.Height(), nScaleY, rRect.Bottom(), fScale ); + + // for safety, clear the other members + if( bDffAnchor ) + mnLX = mnTY = mnRX = mnBY = 0; + else + Set( 0, 0, 0, 0 ); } // ---------------------------------------------------------------------------- diff --git a/sc/source/filter/inc/root.hxx b/sc/source/filter/inc/root.hxx index fcac4da4be62..facc8b1b2fa0 100644 --- a/sc/source/filter/inc/root.hxx +++ b/sc/source/filter/inc/root.hxx @@ -52,9 +52,6 @@ class _ScRangeListTabs; class XclExpChTrTabId; class XclExpUserBViewList; -class XclObjList; -class XclEscher; - class XclImpRoot; class XclExpRoot; @@ -78,10 +75,6 @@ struct RootData // -> Inkarnation jeweils im ImportExcel-Objekt! XclExpChTrTabId* pTabId; // pointer to rec list, do not destroy XclExpUserBViewList* pUserBViewList; // pointer to rec list, do not destroy - // Biff8 - XclObjList* pObjRecs; - XclEscher* pEscher; - XclImpRoot* pIR; XclExpRoot* pER; diff --git a/sc/source/filter/inc/xcl97esc.hxx b/sc/source/filter/inc/xcl97esc.hxx index 2aa7c824af99..fde03337cc0f 100644 --- a/sc/source/filter/inc/xcl97esc.hxx +++ b/sc/source/filter/inc/xcl97esc.hxx @@ -28,9 +28,10 @@ #ifndef SC_XCL97ESC_HXX #define SC_XCL97ESC_HXX -#include <filter/msfilter/escherex.hxx> +#include <memory> #include <tools/table.hxx> #include <tools/stack.hxx> +#include <filter/msfilter/escherex.hxx> #include "xlescher.hxx" #include "xeroot.hxx" @@ -39,10 +40,28 @@ namespace utl { class TempFile; } -// --- class XclEscherEx --------------------------------------------- +// ============================================================================ class SvStream; + +class XclEscherExGlobal : public EscherExGlobal, protected XclExpRoot +{ +public: + explicit XclEscherExGlobal( const XclExpRoot& rRoot ); + +private: + /** Overloaded to create a new temporary file and return its stream. */ + virtual SvStream* ImplQueryPictureStream(); + +private: + ::std::auto_ptr< ::utl::TempFile > mxPicTempFile; + ::std::auto_ptr< SvStream > mxPicStrm; +}; + +// ============================================================================ + class XclObj; +class XclExpDffAnchorBase; class XclEscherHostAppData; class XclEscherClientData; class XclEscherClientTextbox; @@ -54,56 +73,56 @@ class XclExpTbxControlObj; class XclEscherEx : public EscherEx, protected XclExpRoot { -private: - List aOffsetMap; - Stack aStack; - utl::TempFile* pPicTempFile; - SvStream* pPicStrm; - XclObj* pCurrXclObj; - XclEscherHostAppData* pCurrAppData; - XclEscherClientData* pTheClientData; // always the same - XclEscherClientTextbox* pAdditionalText; - USHORT nAdditionalText; - - void DeleteCurrAppData(); - public: - XclEscherEx( const XclExpRoot& rRoot, SvStream& rStrm, UINT32 nDrawings ); - virtual ~XclEscherEx(); - - /// maintains OffsetMap - virtual void InsertAtCurrentPos( UINT32 nBytes, BOOL bCont = FALSE ); - - virtual SvStream* QueryPicStream(); - virtual EscherExHostAppData* StartShape( const com::sun::star::uno::Reference< - com::sun::star::drawing::XShape>& rShape ); + explicit XclEscherEx( + const XclExpRoot& rRoot, + XclExpObjectManager& rObjMgr, + SvStream& rStrm, + const XclEscherEx* pParent = 0 ); + virtual ~XclEscherEx(); + + /** Called by MSODRAWING record constructors to initialize the DFF stream + fragment they will own. returns the DFF fragment identifier. */ + sal_uInt32 InitNextDffFragment(); + /** Called after some data has been written to the DFF stream, to update + the end position of the DFF fragment owned by an MSODRAWING record. */ + void UpdateDffFragmentEnd(); + + /** Returns the position of the specified DFF stream fragment. */ + sal_uInt32 GetDffFragmentPos( sal_uInt32 nFragmentKey ); + /** Returns the size of the specified DFF stream fragment. */ + sal_uInt32 GetDffFragmentSize( sal_uInt32 nFragmentKey ); + /** Returns true, if there is more data left in the DFF stream than owned + by the last MSODRAWING record. */ + bool HasPendingDffData(); + + /** Creates a new DFF client anchor object and calculates the anchor + position of the passed object. Caller takes ownership! */ + XclExpDffAnchorBase* CreateDffAnchor( const SdrObject& rSdrObj ) const; + + virtual EscherExHostAppData* StartShape( + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape>& rxShape, + const Rectangle* pChildAnchor ); virtual void EndShape( UINT16 nShapeType, UINT32 nShapeID ); virtual EscherExHostAppData* EnterAdditionalTextGroup(); - /// appends stream offset to list and returns position in list - ULONG AddCurrentOffsetToMap(); - /// replaces position in list with current stream offset - void ReplaceCurrentOffsetInMap( ULONG nPos ); - /// returns stream offset for position in list - inline ULONG GetOffsetFromMap( ULONG nPos ) const; - /// last position in list (count-1) - inline ULONG GetLastOffsetMapPos() const; - /// Flush and merge PicStream into EscherStream void EndDocument(); #if EXC_EXP_OCX_CTRL /** Creates an OCX form control OBJ record from the passed form control. @descr Writes the form control data to the 'Ctls' stream. */ - XclExpOcxControlObj* CreateCtrlObj( ::com::sun::star::uno::Reference< - ::com::sun::star::drawing::XShape > xShape ); + XclExpOcxControlObj* CreateCtrlObj( + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, + const Rectangle* pChildAnchor ); private: SotStorageStreamRef mxCtlsStrm; /// The 'Ctls' stream. #else /** Creates a TBX form control OBJ record from the passed form control. */ - XclExpTbxControlObj* CreateCtrlObj( ::com::sun::star::uno::Reference< - ::com::sun::star::drawing::XShape > xShape ); + XclExpTbxControlObj* CreateCtrlObj( + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, + const Rectangle* pChildAnchor ); private: /** Tries to get the name of a Basic macro from a control. */ @@ -112,43 +131,21 @@ private: ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xCtrlModel ); #endif -}; - - -inline ULONG XclEscherEx::GetOffsetFromMap( ULONG nPos ) const -{ - return (ULONG) aOffsetMap.GetObject( nPos ); -} - - -inline ULONG XclEscherEx::GetLastOffsetMapPos() const -{ - return aOffsetMap.Count() - 1; -} - -// --- class XclEscher ----------------------------------------------- + void DeleteCurrAppData(); -struct RootData; - -class XclEscher : protected XclExpRoot -{ private: - utl::TempFile* pTempFile; - SvStream* pStrm; - XclEscherEx* pEx; - -public: - XclEscher( const XclExpRoot& rRoot, UINT32 nDrawings ); - ~XclEscher(); - - inline XclEscherEx* GetEx() const { return pEx; } - inline SvStream& GetStrm() const { return *pStrm; } - - void AddSdrPage(); + XclExpObjectManager& mrObjMgr; + Stack aStack; + XclObj* pCurrXclObj; + XclEscherHostAppData* pCurrAppData; + XclEscherClientData* pTheClientData; // always the same + XclEscherClientTextbox* pAdditionalText; + USHORT nAdditionalText; + sal_uInt32 mnNextKey; + bool mbIsRootDff; }; - // --- class XclEscherHostAppData ------------------------------------ class XclEscherHostAppData : public EscherExHostAppData @@ -164,55 +161,6 @@ public: }; -// DFF client anchor ========================================================== - -class Rectangle; -class SdrObject; -class ScAddress; - -/** Represents the position (anchor) of an object in a Calc document. */ -class XclExpDffAnchor : public EscherExClientAnchor_Base, protected XclExpRoot -{ -public: - /** Constructs a dummy client anchor. */ - explicit XclExpDffAnchor( const XclExpRoot& rRoot, sal_uInt16 nFlags = 0 ); - /** Constructs a client anchor directly from an SdrObject. */ - explicit XclExpDffAnchor( const XclExpRoot& rRoot, const SdrObject& rSdrObj ); - - /** Sets the flags according to the passed SdrObject. */ - void SetFlags( const SdrObject& rSdrObj ); - - /** Called from SVX Escher exporter. - @param rRect The object anchor rectangle to be exported (in twips). */ - virtual void WriteData( EscherEx& rEx, const Rectangle& rRect ); - - /** Writes the anchor structure with the current anchor position. */ - void WriteData( EscherEx& rEx ) const; - -protected: // for access in derived classes - XclObjAnchor maAnchor; /// The client anchor data. - sal_uInt16 mnFlags; /// Flags for DFF stream export. -}; - -// ---------------------------------------------------------------------------- - -/** Represents the position (anchor) of a note object. */ -class XclExpDffNoteAnchor : public XclExpDffAnchor -{ -public: - explicit XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ); -}; - - -// ---------------------------------------------------------------------------- - -/** Represents the position (anchor) of a cell dropdown object. */ -class XclExpDffDropDownAnchor : public XclExpDffAnchor -{ -public: - explicit XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos ); -}; - // ============================================================================ @@ -221,8 +169,8 @@ public: class XclEscherClientData : public EscherExClientRecord_Base { public: - XclEscherClientData() {} - virtual void WriteData( EscherEx& rEx ) const; + XclEscherClientData() {} + virtual void WriteData( EscherEx& rEx ) const; }; @@ -233,20 +181,19 @@ class SdrTextObj; class XclEscherClientTextbox : public EscherExClientRecord_Base, protected XclExpRoot { private: - const SdrTextObj& rTextObj; - XclObj* pXclObj; + const SdrTextObj& rTextObj; + XclObj* pXclObj; public: - XclEscherClientTextbox( - const XclExpRoot& rRoot, - const SdrTextObj& rObj, - XclObj* pObj - ); + XclEscherClientTextbox( + const XclExpRoot& rRoot, + const SdrTextObj& rObj, + XclObj* pObj ); //! ONLY for the AdditionalText mimic - inline void SetXclObj( XclObj* p ) { pXclObj = p; } + inline void SetXclObj( XclObj* p ) { pXclObj = p; } - virtual void WriteData( EscherEx& rEx ) const; + virtual void WriteData( EscherEx& rEx ) const; }; diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx index 2c6ae2f9ab0c..7a2a33795520 100644 --- a/sc/source/filter/inc/xcl97rec.hxx +++ b/sc/source/filter/inc/xcl97rec.hxx @@ -32,88 +32,35 @@ #include "xcl97esc.hxx" #include "xlstyle.hxx" -#include <vector> - -// --- class XclMsodrawing_Base -------------------------------------- - -class XclMsodrawing_Base -{ -protected: - XclEscher* pEscher; - sal_Size nStartPos; // position in OffsetMap - sal_Size nStopPos; // position in OffsetMap - -public: - XclMsodrawing_Base( XclEscher& rEscher, sal_Size nInitialSize = 0 ); - virtual ~XclMsodrawing_Base(); - - inline XclEscher* GetEscher() const { return pEscher; } - inline XclEscherEx* GetEscherEx() const { return pEscher->GetEx(); } - void UpdateStopPos(); - sal_Size GetDataLen() const; -}; - - -// --- class XclMsodrawinggroup -------------------------------------- - -class XclMsodrawinggroup : public XclMsodrawing_Base, public XclExpRecord -{ -private: - - virtual void WriteBody( XclExpStream& rStrm ); - -public: - XclMsodrawinggroup( RootData& rRoot, - UINT16 nEscherType = 0 ); - virtual ~XclMsodrawinggroup(); -}; - - -// --- class XclMsodrawing ------------------------------------------- - -class XclMsodrawing : public XclMsodrawing_Base, public XclExpRecord -{ -private: - - virtual void WriteBody( XclExpStream& rStrm ); - -public: - XclMsodrawing( - const XclExpRoot& rRoot, - UINT16 nEscherType = 0, - sal_Size nInitialSize = 0 ); - virtual ~XclMsodrawing(); -}; - - -// --- class XclObjList ---------------------------------------------- +// ============================================================================ class XclObj; -class XclMsodrawing; +class XclExpMsoDrawing; -class XclObjList : public List, public ExcEmptyRec, protected XclExpRoot +class XclExpObjList : public List, public ExcEmptyRec, protected XclExpRoot { -private: - XclMsodrawing* pMsodrawingPerSheet; - XclMsodrawing* pSolverContainer; - public: - XclObjList( const XclExpRoot& rRoot ); - virtual ~XclObjList(); + explicit XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx ); + virtual ~XclExpObjList(); - XclObj* First() { return (XclObj*) List::First(); } - XclObj* Next() { return (XclObj*) List::Next(); } + XclObj* First() { return (XclObj*) List::First(); } + XclObj* Next() { return (XclObj*) List::Next(); } - /// return: 1-based ObjId - ///! count>=0xFFFF: Obj will be deleted, return 0 - UINT16 Add( XclObj* ); + /// return: 1-based ObjId + ///! count>=0xFFFF: Obj will be deleted, return 0 + UINT16 Add( XclObj* ); - inline XclMsodrawing* GetMsodrawingPerSheet() { return pMsodrawingPerSheet; } + inline XclExpMsoDrawing* GetMsodrawingPerSheet() { return pMsodrawingPerSheet; } /// close groups and DgContainer opened in ctor - void EndSheet(); + void EndSheet(); - virtual void Save( XclExpStream& rStrm ); + virtual void Save( XclExpStream& rStrm ); + +private: + XclEscherEx& mrEscherEx; + XclExpMsoDrawing* pMsodrawingPerSheet; + XclExpMsoDrawing* pSolverContainer; }; @@ -125,8 +72,9 @@ class SdrTextObj; class XclObj : public XclExpRecord { protected: - XclMsodrawing* pMsodrawing; - XclMsodrawing* pClientTextbox; + XclEscherEx& mrEscherEx; + XclExpMsoDrawing* pMsodrawing; + XclExpMsoDrawing* pClientTextbox; XclTxo* pTxo; sal_uInt16 mnObjType; UINT16 nObjId; @@ -137,7 +85,9 @@ protected: /** @param bOwnEscher If set to true, this object will create its escher data. See SetOwnEscher() for details. */ - explicit XclObj( const XclExpRoot& rRoot, sal_uInt16 nObjType, bool bOwnEscher = false ); + explicit XclObj( XclExpObjectManager& rObjMgr, sal_uInt16 nObjType, bool bOwnEscher = false ); + + void ImplWriteAnchor( const XclExpRoot& rRoot, const SdrObject* pSdrObj, const Rectangle* pChildAnchor ); // overwritten for writing MSODRAWING record virtual void WriteBody( XclExpStream& rStrm ); @@ -179,27 +129,15 @@ public: //! actually writes ESCHER_ClientTextbox void SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj ); - inline void UpdateStopPos(); - virtual void Save( XclExpStream& rStrm ); }; - -inline void XclObj::UpdateStopPos() -{ - if ( pClientTextbox ) - pClientTextbox->UpdateStopPos(); - else - pMsodrawing->UpdateStopPos(); -} - - // --- class XclObjComment ------------------------------------------- class XclObjComment : public XclObj { public: - XclObjComment( const XclExpRoot& rRoot, + XclObjComment( XclExpObjectManager& rObjMgr, const Rectangle& rRect, const EditTextObject& rEditObj, SdrObject* pCaption, bool bVisible ); virtual ~XclObjComment(); @@ -224,7 +162,7 @@ private: protected: public: - XclObjDropDown( const XclExpRoot& rRoot, const ScAddress& rPos, BOOL bFilt ); + XclObjDropDown( XclExpObjectManager& rObjMgr, const ScAddress& rPos, BOOL bFilt ); virtual ~XclObjDropDown(); }; @@ -271,7 +209,7 @@ private: virtual void WriteSubRecs( XclExpStream& rStrm ); public: - XclObjOle( const XclExpRoot& rRoot, const SdrObject& rObj ); + XclObjOle( XclExpObjectManager& rObjMgr, const SdrObject& rObj ); virtual ~XclObjOle(); virtual void Save( XclExpStream& rStrm ); @@ -286,7 +224,7 @@ private: virtual void WriteSubRecs( XclExpStream& rStrm ); public: - XclObjAny( const XclExpRoot& rRoot ); + XclObjAny( XclExpObjectManager& rObjMgr ); virtual ~XclObjAny(); virtual void Save( XclExpStream& rStrm ); diff --git a/sc/source/filter/inc/xechart.hxx b/sc/source/filter/inc/xechart.hxx index eb6026a82e9a..2cf976b11efe 100644 --- a/sc/source/filter/inc/xechart.hxx +++ b/sc/source/filter/inc/xechart.hxx @@ -28,6 +28,7 @@ #ifndef SC_XECHART_HXX #define SC_XECHART_HXX +#include <tools/gen.hxx> #include "xerecord.hxx" #include "xlchart.hxx" #include "xlformula.hxx" @@ -1194,6 +1195,27 @@ private: // ---------------------------------------------------------------------------- +/** Represents the group of DFF and OBJ records containing all drawing shapes + embedded in the chart object. + */ +class XclExpChartDrawing : public XclExpRecordBase, protected XclExpRoot +{ +public: + explicit XclExpChartDrawing( + const XclExpRoot& rRoot, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel, + const Size& rChartSize ); + virtual ~XclExpChartDrawing(); + + virtual void Save( XclExpStream& rStrm ); + +private: + ScfRef< XclExpObjectManager > mxObjMgr; + ScfRef< XclExpRecordBase > mxObjRecs; +}; + +// ---------------------------------------------------------------------------- + /** Represents the entire chart substream (all records in BOF/EOF block). */ class XclExpChart : public XclExpSubStream, protected XclExpRoot { diff --git a/sc/source/filter/inc/xeescher.hxx b/sc/source/filter/inc/xeescher.hxx index 6448ccb4853e..d227db184f1a 100644 --- a/sc/source/filter/inc/xeescher.hxx +++ b/sc/source/filter/inc/xeescher.hxx @@ -29,6 +29,7 @@ #define SC_XEESCHER_HXX #include <vcl/graph.hxx> +#include <filter/msfilter/escherex.hxx> #include "xcl97rec.hxx" #include "xlescher.hxx" @@ -36,6 +37,127 @@ namespace com { namespace sun { namespace star { namespace script { struct ScriptEventDescriptor; } } } } +// DFF client anchor ========================================================== + +/** Base class for DFF client anchor atoms used in spreadsheets. */ +class XclExpDffAnchorBase : public EscherExClientAnchor_Base, protected XclExpRoot +{ +public: + /** Constructs a dummy client anchor. */ + explicit XclExpDffAnchorBase( const XclExpRoot& rRoot, sal_uInt16 nFlags = 0 ); + + /** Sets the flags according to the passed SdrObject. */ + void SetFlags( const SdrObject& rSdrObj ); + /** Sets the anchor position and flags according to the passed SdrObject. */ + void SetSdrObject( const SdrObject& rSdrObj ); + + /** Writes the DFF client anchor structure with the current anchor position. */ + void WriteDffData( EscherEx& rEscherEx ) const; + + /** Called from SVX DFF converter. + @param rRect The object anchor rectangle to be exported (in twips). */ + virtual void WriteData( EscherEx& rEscherEx, const Rectangle& rRect ); + +private: + virtual void ImplSetFlags( const SdrObject& rSdrObj ); + virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit ); + +protected: // for access in derived classes + XclObjAnchor maAnchor; /// The client anchor data. + sal_uInt16 mnFlags; /// Flags for DFF stream export. +}; + +// ---------------------------------------------------------------------------- + +/** Represents the position (anchor) of an object in a Calc sheet. */ +class XclExpDffSheetAnchor : public XclExpDffAnchorBase +{ +public: + explicit XclExpDffSheetAnchor( const XclExpRoot& rRoot ); + +private: + virtual void ImplSetFlags( const SdrObject& rSdrObj ); + virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit ); + +private: + SCTAB mnScTab; /// Calc sheet index. +}; + +// ---------------------------------------------------------------------------- + +/** Represents the position (anchor) of a shape in an embedded draw page. */ +class XclExpDffEmbeddedAnchor : public XclExpDffAnchorBase +{ +public: + explicit XclExpDffEmbeddedAnchor( const XclExpRoot& rRoot, + const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ); + +private: + virtual void ImplSetFlags( const SdrObject& rSdrObj ); + virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit ); + +private: + Size maPageSize; + sal_Int32 mnScaleX; + sal_Int32 mnScaleY; +}; + +// ---------------------------------------------------------------------------- + +/** Represents the position (anchor) of a note object. */ +class XclExpDffNoteAnchor : public XclExpDffAnchorBase +{ +public: + explicit XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ); +}; + +// ---------------------------------------------------------------------------- + +/** Represents the position (anchor) of a cell dropdown object. */ +class XclExpDffDropDownAnchor : public XclExpDffAnchorBase +{ +public: + explicit XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos ); +}; + +// MSODRAWING* records ======================================================== + +/** Base class for records holding DFF stream fragments. */ +class XclExpMsoDrawingBase : public XclExpRecord +{ +public: + explicit XclExpMsoDrawingBase( XclEscherEx& rEscherEx, sal_uInt16 nRecId ); + +private: + virtual void WriteBody( XclExpStream& rStrm ); + +protected: + XclEscherEx& mrEscherEx; /// Reference to the DFF converter containing the DFF stream. + sal_uInt32 mnFragmentKey; /// The key of the DFF stream fragment to be written by this record. +}; + +// ---------------------------------------------------------------------------- + +/** The MSODRAWINGGROUP record contains the DGGCONTAINER with global DFF data + such as the picture container. + */ +class XclExpMsoDrawingGroup : public XclExpMsoDrawingBase +{ +public: + explicit XclExpMsoDrawingGroup( XclEscherEx& rEscherEx ); +}; + +// ---------------------------------------------------------------------------- + +/** One or more MSODRAWING records contain the DFF stream data for a drawing + shape. + */ +class XclExpMsoDrawing : public XclExpMsoDrawingBase +{ +public: + explicit XclExpMsoDrawing( XclEscherEx& rEscherEx ); +}; + // ============================================================================ /** Provides export of bitmap data to an IMGDATA record. */ @@ -94,8 +216,9 @@ class XclExpOcxControlObj : public XclObj, public XclExpControlHelper { public: explicit XclExpOcxControlObj( - const XclExpRoot& rRoot, + XclExpObjectManager& rObjMgr, ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, + const Rectangle* pChildAnchor, const String& rClassName, sal_uInt32 nStrmStart, sal_uInt32 nStrmSize ); @@ -115,8 +238,9 @@ class XclExpTbxControlObj : public XclObj, public XclExpControlHelper { public: explicit XclExpTbxControlObj( - const XclExpRoot& rRoot, - ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ); + XclExpObjectManager& rObjMgr, + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, + const Rectangle* pChildAnchor ); /** Sets the name of a macro attached to this control. @return true = The passed event descriptor was valid, macro name has been found. */ @@ -161,10 +285,10 @@ class XclExpChart; class XclExpChartObj : public XclObj, protected XclExpRoot { public: - typedef ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > XShapeRef; - -public: - explicit XclExpChartObj( const XclExpRoot& rRoot, XShapeRef xShape ); + explicit XclExpChartObj( + XclExpObjectManager& rObjMgr, + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, + const Rectangle* pChildAnchor ); virtual ~XclExpChartObj(); /** Writes the OBJ record and the entire chart substream. */ @@ -237,6 +361,74 @@ private: XclExpNoteList& mrNotes; }; +// object manager ============================================================= + +class XclExpObjectManager : public XclExpRoot +{ +public: + explicit XclExpObjectManager( const XclExpRoot& rRoot ); + virtual ~XclExpObjectManager(); + + /** Creates a new DFF client anchor object. Caller takes ownership! May be + overwritten in derived classes. */ + virtual XclExpDffAnchorBase* CreateDffAnchor() const; + + /** Creates and returns the MSODRAWINGGROUP record containing global DFF + data in the DGGCONTAINER. */ + ScfRef< XclExpRecordBase > CreateDrawingGroup(); + + /** Initializes the object manager for a new sheet. */ + void StartSheet(); + + /** Processes a drawing page and returns the record block containing all + related records (MSODRAWING, OBJ, TXO, charts, etc.). */ + ScfRef< XclExpRecordBase > ProcessDrawing( SdrPage* pSdrPage ); + /** Processes a collection of UNO shapes and returns the record block + containing all related records (MSODRAWING, OBJ, TXO, charts, etc.). */ + ScfRef< XclExpRecordBase > ProcessDrawing( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes ); + + /** Finalizes the object manager after conversion of all sheets. */ + void EndDocument(); + + inline XclEscherEx& GetEscherEx() { return *mxEscherEx; } + XclExpMsoDrawing* GetMsodrawingPerSheet(); + bool HasObj() const; + sal_uInt16 AddObj( XclObj* pObjRec ); + XclObj* RemoveLastObj(); + +protected: + explicit XclExpObjectManager( const XclExpObjectManager& rParent ); + +private: + void InitStream( bool bTempFile ); + +private: + ScfRef< ::utl::TempFile > mxTempFile; + ScfRef< SvStream > mxDffStrm; + ScfRef< XclEscherEx > mxEscherEx; + ScfRef< XclExpObjList > mxObjList; +}; + +// ---------------------------------------------------------------------------- + +class XclExpEmbeddedObjectManager : public XclExpObjectManager +{ +public: + explicit XclExpEmbeddedObjectManager( + const XclExpObjectManager& rParent, + const Size& rPageSize, + sal_Int32 nScaleX, sal_Int32 nScaleY ); + + /** Creates a new DFF client anchor object for embedded objects according + to the scaling data passed to the constructor. Caller takes ownership! */ + virtual XclExpDffAnchorBase* CreateDffAnchor() const; + +private: + Size maPageSize; + sal_Int32 mnScaleX; + sal_Int32 mnScaleY; +}; + // ============================================================================ #endif diff --git a/sc/source/filter/inc/xerecord.hxx b/sc/source/filter/inc/xerecord.hxx index fa3810c0e92b..a191cd9b1c20 100644 --- a/sc/source/filter/inc/xerecord.hxx +++ b/sc/source/filter/inc/xerecord.hxx @@ -48,9 +48,6 @@ public: /** Overwrite this method to do any operation while saving the record. */ virtual void Save( XclExpStream& rStrm ); virtual void SaveXml( XclExpXmlStream& rStrm ); - -//UNUSED2008-05 /** Calls Save(XclExpStream&) nCount times. */ -//UNUSED2008-05 void SaveRepeated( XclExpStream& rStrm, size_t nCount ); }; // ---------------------------------------------------------------------------- diff --git a/sc/source/filter/inc/xeroot.hxx b/sc/source/filter/inc/xeroot.hxx index ce32a46cbc66..f9d3a6ab2f95 100644 --- a/sc/source/filter/inc/xeroot.hxx +++ b/sc/source/filter/inc/xeroot.hxx @@ -52,6 +52,7 @@ class XclExpNumFmtBuffer; class XclExpXFBuffer; class XclExpLinkManager; class XclExpNameManager; +class XclExpObjectManager; class XclExpFilterManager; class XclExpPivotTableManager; @@ -70,6 +71,7 @@ struct XclExpRootData : public XclRootData typedef ScfRef< XclExpXFBuffer > XclExpXFBfrRef; typedef ScfRef< XclExpNameManager > XclExpNameMgrRef; typedef ScfRef< XclExpLinkManager > XclExpLinkMgrRef; + typedef ScfRef< XclExpObjectManager > XclExpObjectMgrRef; typedef ScfRef< XclExpFilterManager > XclExpFilterMgrRef; typedef ScfRef< XclExpPivotTableManager > XclExpPTableMgrRef; @@ -86,6 +88,7 @@ struct XclExpRootData : public XclRootData XclExpNameMgrRef mxNameMgr; /// Internal defined names. XclExpLinkMgrRef mxGlobLinkMgr; /// Global link manager for defined names. XclExpLinkMgrRef mxLocLinkMgr; /// Local link manager for a sheet. + XclExpObjectMgrRef mxObjMgr; /// All drawing objects. XclExpFilterMgrRef mxFilterMgr; /// Manager for filtered areas in all sheets. XclExpPTableMgrRef mxPTableMgr; /// All pivot tables and pivot caches. @@ -134,6 +137,8 @@ public: XclExpLinkManager& GetLocalLinkManager() const; /** Returns the buffer that contains internal defined names. */ XclExpNameManager& GetNameManager() const; + /** Returns the drawing object manager. */ + XclExpObjectManager& GetObjectManager() const; /** Returns the filter manager. */ XclExpFilterManager& GetFilterManager() const; /** Returns the pivot table manager. */ diff --git a/sc/source/filter/inc/xichart.hxx b/sc/source/filter/inc/xichart.hxx index 25e52f3f0168..5d03c99b124a 100644 --- a/sc/source/filter/inc/xichart.hxx +++ b/sc/source/filter/inc/xichart.hxx @@ -39,8 +39,8 @@ #include "token.hxx" #include "xlchart.hxx" #include "xlstyle.hxx" +#include "xiescher.hxx" #include "xistring.hxx" -#include "xiroot.hxx" namespace com { namespace sun { namespace star { namespace frame @@ -111,7 +111,7 @@ public: /** Starts the API chart document conversion. Must be called once before all API conversion. */ void InitConversion( XChartDocRef xChartDoc ) const; /** Finishes the API chart document conversion. Must be called once after all API conversion. */ - void FinishConversion( ScfProgressBar& rProgress ) const; + void FinishConversion( XclImpDffConverter& rDffConv ) const; /** Returns the data provider for the chart document. */ XDataProviderRef GetDataProvider() const; @@ -1355,7 +1355,9 @@ public: inline sal_Size GetProgressSize() const { return 2 * EXC_CHART_PROGRESS_SIZE; } /** Converts and writes all properties to the passed chart. */ - void Convert( XChartDocRef xChartDoc, ScfProgressBar& rProgress, const ::rtl::OUString& rObjName ) const; + void Convert( XChartDocRef xChartDoc, + XclImpDffConverter& rDffConv, + const ::rtl::OUString& rObjName ) const; private: /** Reads a CHSERIES group (data series source and formatting). */ @@ -1400,6 +1402,31 @@ typedef ScfRef< XclImpChChart > XclImpChChartRef; // ---------------------------------------------------------------------------- +/** Drawing container of a chart. */ +class XclImpChartDrawing : public XclImpDrawing +{ +public: + explicit XclImpChartDrawing( const XclImpRoot& rRoot, bool bOwnTab ); + + /** Converts all objects and inserts them into the chart drawing page. */ + void ConvertObjects( + XclImpDffConverter& rDffConv, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel, + const Rectangle& rChartRect ); + + /** Calculate the resulting rectangle of the passed anchor. */ + virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const; + /** Called whenever an object has been inserted into the draw page. */ + virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj ); + +private: + Rectangle maChartRect; /// Position and size of the chart shape in 1/100 mm. + SCTAB mnScTab; /// Index of the sheet that contains the chart. + bool mbOwnTab; /// True = own sheet, false = embedded object. +}; + +// ---------------------------------------------------------------------------- + /** Represents the entire chart substream (all records in BOF/EOF block). */ class XclImpChart : protected XclImpRoot { @@ -1410,6 +1437,7 @@ public: /** Constructs a new chart object. @param bOwnTab True = chart is on an own sheet; false = chart is an embedded object. */ explicit XclImpChart( const XclImpRoot& rRoot, bool bOwnTab ); + virtual ~XclImpChart(); /** Reads the complete chart substream (BOF/EOF block). @descr The passed stream must be located in the BOF record of the chart substream. */ @@ -1423,14 +1451,22 @@ public: inline bool IsPivotChart() const { return mbIsPivotChart; } /** Creates the chart object in the passed component. */ - void Convert( XModelRef xModel, ScfProgressBar& rProgress, const ::rtl::OUString& rObjName ) const; + void Convert( XModelRef xModel, + XclImpDffConverter& rDffConv, + const ::rtl::OUString& rObjName, + const Rectangle& rChartRect ) const; private: + /** Returns (initially creates) the drawing container for embedded shapes. **/ + XclImpChartDrawing& GetChartDrawing(); /** Reads the CHCHART group (entire chart data). */ void ReadChChart( XclImpStream& rStrm ); private: + typedef ScfRef< XclImpChartDrawing > XclImpChartDrawingRef; + XclImpChChartRef mxChartData; /// The chart data (CHCHART group). + XclImpChartDrawingRef mxChartDrawing; /// Drawing container for embedded shapes. bool mbOwnTab; /// true = own sheet; false = embedded object. bool mbIsPivotChart; /// true = chart is based on a pivot table. }; diff --git a/sc/source/filter/inc/xiescher.hxx b/sc/source/filter/inc/xiescher.hxx index 258720e89584..0167d160f297 100644 --- a/sc/source/filter/inc/xiescher.hxx +++ b/sc/source/filter/inc/xiescher.hxx @@ -42,9 +42,12 @@ namespace com { namespace sun { namespace star { namespace form { class XForm; } } } } +class SdrObjList; class ScfProgressBar; class ScfPropertySet; class XclImpChart; +class XclImpDffConverter; +class XclImpDrawing; // Drawing objects ============================================================ @@ -59,23 +62,23 @@ public: virtual ~XclImpDrawObjBase(); /** Reads the BIFF3 OBJ record, returns a new drawing object. */ - static XclImpDrawObjRef ReadObj3( XclImpStream& rStrm ); + static XclImpDrawObjRef ReadObj3( const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads the BIFF4 OBJ record, returns a new drawing object. */ - static XclImpDrawObjRef ReadObj4( XclImpStream& rStrm ); + static XclImpDrawObjRef ReadObj4( const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads the BIFF5 OBJ record, returns a new drawing object. */ - static XclImpDrawObjRef ReadObj5( XclImpStream& rStrm ); + static XclImpDrawObjRef ReadObj5( const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads the BIFF8 OBJ record, returns a new drawing object. */ - static XclImpDrawObjRef ReadObj8( XclImpStream& rStrm ); + static XclImpDrawObjRef ReadObj8( const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Sets whether this is an area object (then its width and height must be greater than 0). */ inline void SetAreaObj( bool bAreaObj ) { mbAreaObj = bAreaObj; } /** If set to true, a new SdrObject will be created while in DFF import. */ inline void SetSimpleMacro( bool bMacro ) { mbSimpleMacro = bMacro; } - /** Sets shape data from DFF stream. */ - void SetDffData( const DffObjData& rDffObjData, const String& rObjName, const String& rHyperlink, bool bVisible, bool bAutoMargin ); /** Sets the object anchor explicitly. */ void SetAnchor( const XclObjAnchor& rAnchor ); + /** Sets shape data from DFF stream. */ + void SetDffData( const DffObjData& rDffObjData, const String& rObjName, const String& rHyperlink, bool bVisible, bool bAutoMargin ); /** If set to false, the SdrObject will not be created, processed, or inserted into the draw page. */ inline void SetProcessSdrObj( bool bProcess ) { mbProcessSdr = bProcess; } @@ -84,10 +87,8 @@ public: /** If set to true, a new SdrObject will be created while in DFF import. */ inline void SetCustomDffObj( bool bCustom ) { mbCustomDff = bCustom; } - /** Returns the Calc sheet index of this object. */ - inline SCTAB GetScTab() const { return maObjId.mnScTab; } /** Returns the sheet index and Excel object identifier from OBJ record. */ - inline const XclObjId& GetObjId() const { return maObjId; } + inline sal_uInt16 GetObjId() const { return mnObjId; } /** Returns the Excel object type from OBJ record. */ inline sal_uInt16 GetObjType() const { return mnObjType; } /** Returns the name of this object, may generate a default name. */ @@ -107,14 +108,14 @@ public: /** Returns true, if the object is printable. */ inline bool IsPrintable() const { return mbPrintable; } + /** Returns the object anchor if existing, null otherwise. */ + const XclObjAnchor* GetAnchor() const; /** Returns true, if the passed size is valid for this object. */ bool IsValidSize( const Rectangle& rAnchorRect ) const; - /** Returns the area in the sheet used by this object. */ - ScRange GetUsedArea() const; - /** Returns the area on the drawing layer for this object. */ - Rectangle GetAnchorRect() const; + /** Returns the range in the sheet covered by this object. */ + ScRange GetUsedArea( SCTAB nScTab ) const; - /** Returns true, if the object is valid and will be processed.. */ + /** Returns true, if the object is valid and will be processed. */ inline bool IsProcessSdrObj() const { return mbProcessSdr && !mbHidden; } /** Returns true, if the SdrObject will be created or processed, but not be inserted into the draw page. */ inline bool IsInsertSdrObj() const { return mbInsertSdr; } @@ -122,9 +123,13 @@ public: /** Returns the needed size on the progress bar (calls virtual DoGetProgressSize() function). */ sal_Size GetProgressSize() const; /** Creates and returns an SdrObject from the contained data. Caller takes ownership! */ - SdrObject* CreateSdrObject( const Rectangle& rAnchorRect, ScfProgressBar& rProgress, bool bDffImport ) const; - /** Additional processing for the passed SdrObject (calls virtual DoProcessSdrObj() function). */ - void ProcessSdrObject( SdrObject& rSdrObj ) const; + SdrObject* CreateSdrObject( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect, bool bIsDff ) const; + /** Additional processing for the passed SdrObject before insertion into + the drawing page (calls virtual DoPreProcessSdrObj() function). */ + void PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; + /** Additional processing for the passed SdrObject after insertion into the + drawing page (calls virtual DoPostProcessSdrObj() function). */ + void PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; protected: /** Reads the object name in a BIFF5 OBJ record. */ @@ -162,9 +167,11 @@ protected: /** Derived classes may return a progress bar size different from 1. */ virtual sal_Size DoGetProgressSize() const; /** Derived classes create and return a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; - /** Derived classes may perform additional processing for the passed SdrObject. */ - virtual void DoProcessSdrObj( SdrObject& rSdrObj ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; + /** Derived classes may perform additional processing for the passed SdrObject before insertion. */ + virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; + /** Derived classes may perform additional processing for the passed SdrObject after insertion. */ + virtual void DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; private: /** Reads the contents of a BIFF3 OBJ record. */ @@ -177,16 +184,15 @@ private: void ImplReadObj8( XclImpStream& rStrm ); private: - typedef ScfRef< XclObjAnchor > XclObjAnchorRef; - - XclObjAnchorRef mxAnchor; /// The position of the object in the containing sheet. - XclObjId maObjId; /// Sheet index and object identifier. + XclObjAnchor maAnchor; /// The position of the object in its parent. + sal_uInt16 mnObjId; /// The object identifier (unique per drawing). sal_uInt16 mnObjType; /// The Excel object type from OBJ record. sal_uInt32 mnDffShapeId; /// Shape ID from DFF stream. sal_uInt32 mnDffFlags; /// Shape flags from DFF stream. String maObjName; /// Name of the object. String maMacroName; /// Name of an attached macro. String maHyperlink; /// On-click hyperlink URL. + bool mbHasAnchor; /// true = maAnchor is initialized. bool mbHidden; /// true = Object is hidden. bool mbVisible; /// true = Object is visible. bool mbPrintable; /// true = Object is printable. @@ -242,7 +248,7 @@ protected: /** Returns a progress bar size that takes all group children into account. */ virtual sal_Size DoGetProgressSize() const; /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; protected: XclImpDrawObjVector maChildren; /// Grouped objects. @@ -265,7 +271,7 @@ protected: /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; protected: XclObjLineData maLineData; /// BIFF5 line formatting. @@ -295,7 +301,7 @@ protected: /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; protected: XclObjFillData maFillData; /// BIFF5 fill formatting. @@ -313,7 +319,7 @@ public: protected: /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; }; // ---------------------------------------------------------------------------- @@ -332,7 +338,7 @@ protected: /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; protected: XclObjFillData maFillData; /// BIFF5 fill formatting. @@ -357,7 +363,7 @@ protected: /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; protected: typedef ::std::vector< Point > PointVector; @@ -398,9 +404,9 @@ protected: /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; /** Inserts the contained text data at the passed object. */ - virtual void DoProcessSdrObj( SdrObject& rSdrObj ) const; + virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; protected: XclImpObjTextData maTextData; /// Textbox data from BIFF5 OBJ or BIFF8 TXO record. @@ -430,7 +436,9 @@ protected: /** Returns the needed size on the progress bar. */ virtual sal_Size DoGetProgressSize() const; /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; + /** Converts the chart document. */ + virtual void DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; private: /** Calculates the object anchor of a sheet chart (chart fills one page). */ @@ -456,7 +464,7 @@ public: protected: /** Inserts the note into the document, sets visibility. */ - virtual void DoProcessSdrObj( SdrObject& rSdrObj ) const; + virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; private: ScAddress maScPos; /// Cell position of the note object. @@ -533,9 +541,9 @@ protected: void ConvertLabel( ScfPropertySet& rPropSet ) const; /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; /** Additional processing on the SdrObject, calls new virtual function DoProcessControl(). */ - virtual void DoProcessSdrObj( SdrObject& rSdrObj ) const; + virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; /** Derived classes return the service name of the control component to be created. */ virtual ::rtl::OUString DoGetServiceName() const = 0; @@ -882,9 +890,9 @@ protected: /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; /** Overloaded to do additional processing on the SdrObject. */ - virtual void DoProcessSdrObj( SdrObject& rSdrObj ) const; + virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; private: /** Reads and sets the picture flags from a BIFF3-BIFF5 OBJ picture record. */ @@ -955,13 +963,13 @@ private: // ---------------------------------------------------------------------------- /** Simple implementation of the SVX DFF manager. Implements resolving palette - colors. Used by XclImpDffPropSet (as is), extended by XclImpDffManager. + colors. Used by XclImpDffPropSet (as is), extended by XclImpDffConverter. */ -class XclImpSimpleDffManager : public SvxMSDffManager, protected XclImpRoot +class XclImpSimpleDffConverter : public SvxMSDffManager, protected XclImpRoot { public: - explicit XclImpSimpleDffManager( const XclImpRoot& rRoot, SvStream& rDffStrm ); - virtual ~XclImpSimpleDffManager(); + explicit XclImpSimpleDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ); + virtual ~XclImpSimpleDffConverter(); protected: /** Returns a color from the Excel color palette. */ @@ -970,42 +978,46 @@ protected: // ---------------------------------------------------------------------------- -class XclImpObjectManager; -class SdrObjList; +/** This is the central instance for converting binary DFF data into shape + objects. Used for all sheet shapes and shapes embedded in chart objects. -/** Derived from SvxMSDffManager and SvxMSConvertOCXControls, contains core - implementation of DFF stream import and OCX form control import. + The class derives from SvxMSDffManager and SvxMSConvertOCXControls and + contains core implementation of DFF stream import and OCX form control + import. */ -class XclImpDffManager : public XclImpSimpleDffManager, protected SvxMSConvertOCXControls +class XclImpDffConverter : public XclImpSimpleDffConverter, private SvxMSConvertOCXControls { public: - explicit XclImpDffManager( - const XclImpRoot& rRoot, - XclImpObjectManager& rObjManager, - SvStream& rDffStrm ); - virtual ~XclImpDffManager(); + explicit XclImpDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ); + virtual ~XclImpDffConverter(); /** Initializes the internal progress bar with the passed size and starts it. */ void StartProgressBar( sal_Size nProgressSize ); + /** Increase the progress bar by the passed value. */ + void Progress( sal_Size nDelta = 1 ); + /** Initially called before the objects of the passed drawing manager are converted. */ + void InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ); /** Processes BIFF5 drawing objects without DFF data, inserts into the passed object list. */ - void ProcessObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj ); - /** Processes the leading drawing group container in the DFF stream. */ - void ProcessDrawingGroup( SvStream& rDffStrm ); - /** Processes a drawing container for a sheet in the DFF stream, converts all objects. */ - void ProcessDrawing( SvStream& rDffStrm, sal_Size nStrmPos ); + void ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj ); + /** Processes all objects in the passed list. */ + void ProcessDrawing( const XclImpDrawObjVector& rDrawObjs ); + /** Processes a drawing container in the passed DFF stream, converts all objects. */ + void ProcessDrawing( SvStream& rDffStrm ); + /** Finally called after the objects of the passed drawing manager have been converted. */ + void FinalizeDrawing(); /** Creates the SdrObject for the passed Excel TBX form control object. */ SdrObject* CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect ); /** Creates the SdrObject for the passed Excel OLE object or OCX form control object. */ SdrObject* CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect ); + /** Returns true, if the conversion of OLE objects is supported. */ + bool SupportsOleObjects() const; /** Returns the default text margin in drawing layer units. */ inline sal_Int32 GetDefaultTextMargin() const { return mnDefTextMargin; } - /** Returns the used area in the sheet with the passed index. */ - ScRange GetUsedArea( SCTAB nScTab ) const; -protected: +private: // virtual functions of SvxMSDffManager /** Reads the client anchor from the DFF stream and sets it at the correct object. */ @@ -1036,11 +1048,30 @@ protected: BOOL bFloatingCtrl ); private: + /** Data per registered drawing manager, will be stacked for recursive calls. */ + struct XclImpDffConvData + { + XclImpDrawing& mrDrawing; /// Current drawing container with all drawing objects. + SdrModel& mrSdrModel; /// The SdrModel of the drawing manager. + SdrPage& mrSdrPage; /// The SdrPage of the drawing manager. + XclImpSolverContainer maSolverCont; /// The solver container for connector rules. + ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm > + mxCtrlForm; /// Controls form of current drawing page. + sal_Int32 mnLastCtrlIndex; /// Last insertion index of a form control (for macro events). + bool mbHasCtrlForm; /// True = mxCtrlForm is initialized (but maybe still null). + + explicit XclImpDffConvData( XclImpDrawing& rDrawing, + SdrModel& rSdrModel, SdrPage& rSdrPage ); + }; + + /** Returns the current drawing manager data struct from top of the stack. */ + XclImpDffConvData& GetConvData(); + /** Returns the current drawing manager data struct from top of the stack. */ + const XclImpDffConvData& GetConvData() const; + /** Reads contents of a hyperlink property and returns the extracted URL. */ String ReadHlinkProperty( SvStream& rDffStrm ) const; - /** Processes a drawing group container (global drawing data). */ - void ProcessDggContainer( SvStream& rDffStrm, const DffRecordHeader& rDggHeader ); /** Processes a drawing container (all drawing data of a sheet). */ void ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader ); /** Processes the global shape group container (all shapes of a sheet). */ @@ -1051,87 +1082,71 @@ private: void ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader ); /** Inserts the passed SdrObject into the document. This function takes ownership of pSdrObj! */ - void InsertSdrObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj ); - /** Stores the standard controls form for the passed sheet in mxCurrForm member. */ - void SetCurrentForm( SCTAB nScTab ); - - /** Updates the used area of a sheet with the position and size of the passed object. */ - void UpdateUsedArea( const XclImpDrawObjBase& rDrawObj ); + void InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj ); + /** Initializes the mxCtrlForm referring to the standard controls form. */ + void InitControlForm(); private: - typedef ::std::map< SCTAB, ScRange > ScRangeMap; - typedef ScfRef< ScfProgressBar > ScfProgressBarRef; + typedef ScfRef< ScfProgressBar > ScfProgressBarRef; + typedef ScfRef< XclImpDffConvData > XclImpDffConvDataRef; + typedef ::std::vector< XclImpDffConvDataRef > XclImpDffConvDataStack; - XclImpObjectManager& mrObjManager; /// The Excel object manager. - XclImpSolverContainer maSolverCont; /// The solver container for connector rules. + const ::rtl::OUString maStdFormName; /// Standard name of control forms. SotStorageStreamRef mxCtlsStrm; /// The 'Ctls' stream for OCX form controls. - ScRangeMap maUsedAreaMap; /// Used ranges for all sheets. ScfProgressBarRef mxProgress; /// The progress bar used in ProcessObj(). - ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm > - mxCurrForm; /// Controls form of current sheet (needed in virtual functions). + XclImpDffConvDataStack maDataStack; /// Stack for registered drawing managers. sal_uInt32 mnOleImpFlags; /// Application OLE import settings. sal_Int32 mnDefTextMargin; /// Default margin in text boxes. - sal_Int32 mnLastCtrlIndex; /// Last insertion index of a form control (for macro events). - SCTAB mnCurrFormScTab; /// Sheet index of form stored in mxCurrForm. }; -// The object manager ========================================================= +// Drawing manager ============================================================ -/** Stores all drawing and OLE objects and additional data related to these objects. */ -class XclImpObjectManager : protected XclImpRoot +/** Base class for a container for all objects on a drawing (spreadsheet or + embedded chart object). */ +class XclImpDrawing : protected XclImpRoot { public: - explicit XclImpObjectManager( const XclImpRoot& rRoot ); - virtual ~XclImpObjectManager(); - - // *** Read Excel records *** --------------------------------------------- + explicit XclImpDrawing( const XclImpRoot& rRoot, bool bOleObjects ); + virtual ~XclImpDrawing(); /** Reads and returns a bitmap from the IMGDATA record. */ - static Graphic ReadImgData( XclImpStream& rStrm ); + static Graphic ReadImgData( const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads a plain OBJ record (without leading DFF data). */ void ReadObj( XclImpStream& rStrm ); - /** Reads the MSODRAWINGGROUP record. */ - void ReadMsoDrawingGroup( XclImpStream& rStrm ); /** Reads the MSODRAWING or MSODRAWINGSELECTION record. */ void ReadMsoDrawing( XclImpStream& rStrm ); - /** Reads the NOTE record. */ - void ReadNote( XclImpStream& rStrm ); - - /** Inserts a new chart object and reads the chart substream (BOF/EOF block). - @descr Used to import chart sheets, which do not have a corresponding OBJ record. */ - void ReadTabChart( XclImpStream& rStrm ); - - // *** Drawing objects *** ------------------------------------------------ + /** Returns true, if the conversion of OLE objects is supported. */ + inline bool SupportsOleObjects() const { return mbOleObjs; } /** Finds the OBJ record data related to the DFF shape at the passed position. */ XclImpDrawObjRef FindDrawObj( const DffRecordHeader& rHeader ) const; /** Finds the OBJ record data specified by the passed object identifier. */ - XclImpDrawObjRef FindDrawObj( const XclObjId& rObjId ) const; + XclImpDrawObjRef FindDrawObj( sal_uInt16 nObjId ) const; /** Finds the textbox data related to the DFF shape at the passed position. */ const XclImpObjTextData* FindTextData( const DffRecordHeader& rHeader ) const; /** Sets the object with the passed identification to be skipped on import. */ - void SetSkipObj( SCTAB nScTab, sal_uInt16 nObjId ); - - // *** Drawing object conversion *** -------------------------------------- + void SetSkipObj( sal_uInt16 nObjId ); + /** Returns the size of the progress bar shown while processing all objects. */ + sal_Size GetProgressSize() const; - /** Returns the DFF manager (DFF stream converter). Don't call before the DFF stream is read. */ - XclImpDffManager& GetDffManager(); - /** Inserts all objects into the Calc document. */ - void ConvertObjects(); + /** Derived classes calculate the resulting rectangle of the passed anchor. */ + virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const = 0; + /** Called whenever an object has been inserted into the draw page. */ + virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj ) = 0; - /** Returns the default name for the passed object. */ - String GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const; - /** Returns the used area in the sheet with the passed index. */ - ScRange GetUsedArea( SCTAB nScTab ) const; +protected: + /** Appends a new drawing object to the list of raw objects (without DFF data). */ + void AppendRawObject( const XclImpDrawObjRef& rxDrawObj ); + /** Converts all objects and inserts them into the current drawing page. */ + void ImplConvertObjects( XclImpDffConverter& rDffConv, SdrModel& rSdrModel, SdrPage& rSdrPage ); - // ------------------------------------------------------------------------ private: /** Reads and returns a bitmap from WMF/PICT format. */ - static void ReadWmf( Graphic& rGraphic, XclImpStream& rStrm ); + static void ReadWmf( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads and returns a bitmap from BMP format. */ - static void ReadBmp( Graphic& rGraphic, XclImpStream& rStrm ); + static void ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads contents of an DFF record and append data to internal DFF stream. */ void ReadDffRecord( XclImpStream& rStrm ); @@ -1140,36 +1155,86 @@ private: /** Reads the TXO record and following CONTINUE records containing string and formatting. */ void ReadTxo( XclImpStream& rStrm ); +private: + typedef ::std::map< sal_Size, XclImpDrawObjRef > XclImpObjMap; + typedef ::std::map< sal_uInt16, XclImpDrawObjRef > XclImpObjMapById; + typedef ScfRef< XclImpObjTextData > XclImpObjTextRef; + typedef ::std::map< sal_Size, XclImpObjTextRef > XclImpObjTextMap; + + XclImpDrawObjVector maRawObjs; /// BIFF5 objects without DFF data. + SvMemoryStream maDffStrm; /// Copy of the DFF page stream in memory. + XclImpObjMap maObjMap; /// Maps BIFF8 drawing objects to DFF stream position. + XclImpObjMapById maObjMapId; /// Maps BIFF8 drawing objects to object ID. + XclImpObjTextMap maTextMap; /// Maps BIFF8 TXO textbox data to DFF stream position. + ScfUInt16Vec maSkipObjs; /// IDs of all objects to be skipped. + bool mbOleObjs; /// True = draw model supports OLE objects. +}; + +// ---------------------------------------------------------------------------- + +/** Drawing manager of a single sheet. */ +class XclImpSheetDrawing : public XclImpDrawing +{ +public: + explicit XclImpSheetDrawing( const XclImpRoot& rRoot, SCTAB nScTab ); + + /** Reads the NOTE record. */ + void ReadNote( XclImpStream& rStrm ); + /** Inserts a new chart object and reads the chart substream (BOF/EOF block). + @descr Used to import chart sheets, which do not have a corresponding OBJ record. */ + void ReadTabChart( XclImpStream& rStrm ); + + /** Returns the total cell range covered by any shapes in the sheet. */ + inline const ScRange& GetUsedArea() const { return maScUsedArea; } + /** Converts all objects and inserts them into the sheet drawing page. */ + void ConvertObjects( XclImpDffConverter& rDffConv ); + + /** Calculate the resulting rectangle of the passed anchor. */ + virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const; + /** On call, updates the used area of the sheet. */ + virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj ); + +private: /** Reads a BIFF3-BIFF5 NOTE record. */ void ReadNote3( XclImpStream& rStrm ); /** Reads a BIFF8 NOTE record. */ void ReadNote8( XclImpStream& rStrm ); - /** Returns the size of the progress bar shown while processing all objects. */ - sal_Size GetProgressSize() const; +private: + ScRange maScUsedArea; /// Sheet index and used area in this sheet. +}; + +// The object manager ========================================================= + +/** Stores all drawing and OLE objects and additional data related to these objects. */ +class XclImpObjectManager : protected XclImpRoot +{ +public: + explicit XclImpObjectManager( const XclImpRoot& rRoot ); + virtual ~XclImpObjectManager(); + + /** Reads the MSODRAWINGGROUP record. */ + void ReadMsoDrawingGroup( XclImpStream& rStrm ); + + /** Returns (initially creates) the drawing manager of the specified sheet. */ + XclImpSheetDrawing& GetSheetDrawing( SCTAB nScTab ); + /** Inserts all objects into the Calc document. */ + void ConvertObjects(); + + /** Returns the default name for the passed object. */ + String GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const; + /** Returns the used area in the sheet with the passed index. */ + ScRange GetUsedArea( SCTAB nScTab ) const; // ------------------------------------------------------------------------ private: - typedef ::std::map< sal_Size, XclImpDrawObjRef > XclImpObjMap; - typedef ::std::map< XclObjId, XclImpDrawObjRef > XclImpObjMapById; - typedef ScfRef< XclImpObjTextData > XclImpObjTextRef; - typedef ::std::map< sal_Size, XclImpObjTextRef > XclImpObjTextMap; - typedef ::std::vector< XclObjId > XclObjIdVec; - typedef ::std::map< sal_uInt16, String > DefObjNameMap; - typedef ::std::vector< sal_Size > StreamPosVec; - typedef ScfRef< XclImpDffManager > XclImpDffMgrRef; - - XclImpDrawObjVector maRawObjs; /// BIFF5 objects without DFF data. - XclImpObjMap maObjMap; /// Maps BIFF8 drawing objects to DFF stream position. - XclImpObjMapById maObjMapId; /// Maps BIFF8 drawing objects to sheet index and object ID. - XclImpObjTextMap maTextMap; /// Maps BIFF8 TXO textbox data to DFF stream position. - XclObjIdVec maSkipObjs; /// All objects to be skipped. + typedef ScfRef< XclImpSheetDrawing > XclImpSheetDrawingRef; + typedef ::std::map< SCTAB, XclImpSheetDrawingRef > XclImpSheetDrawingMap; DefObjNameMap maDefObjNames; /// Default base names for all object types. - SvMemoryStream maDffStrm; /// Copy of DFF stream in memory. - StreamPosVec maTabStrmPos; /// Start positions of DFF stream fragments for all sheets. - XclImpDffMgrRef mxDffManager; /// The DFF stream converter. + SvMemoryStream maDggStrm; /// Copy of global DFF data (DGG container) in memory. + XclImpSheetDrawingMap maSheetDrawings; /// Drawing managers of all sheets. }; // DFF property set helper ==================================================== @@ -1197,8 +1262,8 @@ public: private: typedef ::std::auto_ptr< SvMemoryStream > SvMemoryStreamPtr; - SvMemoryStream maDummyStrm; /// Dummy stream for DFF manager. - XclImpSimpleDffManager maDffManager;/// DFF manager used to resolve palette colors. + SvMemoryStream maDummyStrm; /// Dummy DGG stream for DFF manager. + XclImpSimpleDffConverter maDffConv; /// DFF converter used to resolve palette colors. SvMemoryStreamPtr mxMemStrm; /// Helper stream. }; diff --git a/sc/source/filter/inc/xiroot.hxx b/sc/source/filter/inc/xiroot.hxx index 3881adaaf911..0e06b31b650d 100644 --- a/sc/source/filter/inc/xiroot.hxx +++ b/sc/source/filter/inc/xiroot.hxx @@ -51,6 +51,7 @@ class XclImpTabInfo; class XclImpNameManager; class XclImpLinkManager; class XclImpObjectManager; +class XclImpSheetDrawing; class XclImpCondFormatManager; class XclImpAutoFilterBuffer; class XclImpWebQueryBuffer; @@ -176,6 +177,8 @@ public: /** Returns the drawing object manager. */ XclImpObjectManager& GetObjectManager() const; + /** Returns the drawing container of the current sheet. */ + XclImpSheetDrawing& GetCurrSheetDrawing() const; /** Returns the conditional formattings manager. */ XclImpCondFormatManager& GetCondFormatManager() const; /** Returns the filter manager. */ diff --git a/sc/source/filter/inc/xlchart.hxx b/sc/source/filter/inc/xlchart.hxx index 7e5f90fda4a7..f6711211bc13 100644 --- a/sc/source/filter/inc/xlchart.hxx +++ b/sc/source/filter/inc/xlchart.hxx @@ -71,6 +71,7 @@ namespace com { namespace sun { namespace star { #define SERVICE_CHART2_TITLE CREATE_OUSTRING( "com.sun.star.chart2.Title" ) // property names +#define EXC_CHPROP_ADDITIONALSHAPES CREATE_OUSTRING( "AdditionalShapes" ) #define EXC_CHPROP_ARRANGEORDER CREATE_OUSTRING( "ArrangeOrder" ) #define EXC_CHPROP_ATTAXISINDEX CREATE_OUSTRING( "AttachedAxisIndex" ) #define EXC_CHPROP_ATTRIBDATAPOINTS CREATE_OUSTRING( "AttributedDataPoints" ) @@ -168,6 +169,8 @@ const sal_Int32 EXC_CHART_AXESSET_NONE = -1; /// For internal use const sal_Int32 EXC_CHART_AXESSET_PRIMARY = 0; /// API primary axes set index. const sal_Int32 EXC_CHART_AXESSET_SECONDARY = 1; /// API secondary axes set index. +const sal_Int32 EXC_CHART_UNIT = 4000; /// Chart objects are positioned in 1/4000 of chart area. + // (0x0850) CHFRINFO ---------------------------------------------------------- const sal_uInt16 EXC_ID_CHFRINFO = 0x0850; diff --git a/sc/source/filter/inc/xlescher.hxx b/sc/source/filter/inc/xlescher.hxx index f60d6d3a5ee5..33b75af8cd2c 100644 --- a/sc/source/filter/inc/xlescher.hxx +++ b/sc/source/filter/inc/xlescher.hxx @@ -312,18 +312,21 @@ bool operator<( const XclObjId& rL, const XclObjId& rR ); /** Represents the position (anchor) of an object in a Calc document. */ struct XclObjAnchor : public XclRange { - SCTAB mnScTab; /// Calc sheet index. sal_uInt16 mnLX; /// X offset in left column (1/1024 of column width). sal_uInt16 mnTY; /// Y offset in top row (1/256 of row height). sal_uInt16 mnRX; /// X offset in right column (1/1024 of column width). sal_uInt16 mnBY; /// Y offset in bottom row (1/256 of row height). - explicit XclObjAnchor( SCTAB nScTab ); + explicit XclObjAnchor(); /** Calculates a rectangle from the contained coordinates. */ - Rectangle GetRect( ScDocument& rDoc, MapUnit eMapUnit ) const; - /** Initializes the anchor coordinates from a rectangle. */ - void SetRect( ScDocument& rDoc, const Rectangle& rRect, MapUnit eMapUnit ); + Rectangle GetRect( ScDocument& rDoc, SCTAB nScTab, MapUnit eMapUnit ) const; + /** Initializes the anchor coordinates for a sheet. */ + void SetRect( ScDocument& rDoc, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit ); + + /** Initializes the anchor coordinates for an embedded draw page. */ + void SetRect( const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY, + const Rectangle& rRect, MapUnit eMapUnit, bool bDffAnchor ); }; template< typename StreamType > diff --git a/sc/source/filter/xcl97/xcl97esc.cxx b/sc/source/filter/xcl97/xcl97esc.cxx index 2c5a30f085d3..a7c6dee67dc5 100644 --- a/sc/source/filter/xcl97/xcl97esc.cxx +++ b/sc/source/filter/xcl97/xcl97esc.cxx @@ -59,9 +59,11 @@ #include "xechart.hxx" #include "xcl97esc.hxx" +using ::rtl::OUString; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; -using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::container::XIndexAccess; @@ -72,24 +74,40 @@ using ::com::sun::star::form::XFormsSupplier; using ::com::sun::star::script::ScriptEventDescriptor; using ::com::sun::star::script::XEventAttacherManager; -// --- class XclEscherEx --------------------------------------------- +// ============================================================================ -XclEscherEx::XclEscherEx( const XclExpRoot& rRoot, SvStream& rStrm, UINT32 nDrawings ) - : - EscherEx( rStrm, nDrawings ), - XclExpRoot( rRoot ), - pPicTempFile( NULL ), - pPicStrm( NULL ), - pCurrXclObj( NULL ), - pCurrAppData( NULL ), - pTheClientData( new XclEscherClientData ), - pAdditionalText( NULL ), - nAdditionalText( 0 ) +XclEscherExGlobal::XclEscherExGlobal( const XclExpRoot& rRoot ) : + XclExpRoot( rRoot ) +{ +} + +SvStream* XclEscherExGlobal::ImplQueryPictureStream() +{ + mxPicTempFile.reset( new ::utl::TempFile ); + if( mxPicTempFile->IsValid() ) + { + mxPicTempFile->EnableKillingFile(); + mxPicStrm.reset( ::utl::UcbStreamHelper::CreateStream( mxPicTempFile->GetURL(), STREAM_STD_READWRITE ) ); + mxPicStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); + } + return mxPicStrm.get(); +} + +// ============================================================================ + +XclEscherEx::XclEscherEx( const XclExpRoot& rRoot, XclExpObjectManager& rObjMgr, SvStream& rStrm, const XclEscherEx* pParent ) : + EscherEx( pParent ? pParent->mxGlobal : EscherExGlobalRef( new XclEscherExGlobal( rRoot ) ), rStrm ), + XclExpRoot( rRoot ), + mrObjMgr( rObjMgr ), + pCurrXclObj( NULL ), + pCurrAppData( NULL ), + pTheClientData( new XclEscherClientData ), + pAdditionalText( NULL ), + nAdditionalText( 0 ), + mnNextKey( 0 ), + mbIsRootDff( pParent == 0 ) { - aOffsetMap.Insert( (void*) 0, LIST_APPEND ); // start of stream - // Xcl forgets OLE objects completely if the Escher object is not EMF and - // the corresponding OLE application is opened and nothing is changed. - SetOleEmf( TRUE ); + InsertPersistOffset( mnNextKey, 0 ); } @@ -98,86 +116,83 @@ XclEscherEx::~XclEscherEx() DBG_ASSERT( !aStack.Count(), "~XclEscherEx: stack not empty" ); DeleteCurrAppData(); delete pTheClientData; - if ( pPicStrm ) - { - delete pPicStrm; - } - if ( pPicTempFile ) - delete pPicTempFile; } -SvStream* XclEscherEx::QueryPicStream() +sal_uInt32 XclEscherEx::InitNextDffFragment() { - if ( !pPicStrm ) - { - if ( !pPicTempFile ) - { - pPicTempFile = new utl::TempFile; - if ( pPicTempFile->IsValid() ) - pPicTempFile->EnableKillingFile(); - else - { - delete pPicTempFile; - pPicTempFile = NULL; - } - } - if ( pPicTempFile ) - { - pPicStrm = utl::UcbStreamHelper::CreateStream( pPicTempFile->GetURL(), STREAM_STD_READWRITE ); - pPicStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - } - } - return pPicStrm; + /* Current value of mnNextKey will be used by caller to refer to the + starting point of the DFF fragment. The key exists already in the + PersistTable (has been inserted by c'tor of previous call of + InitNextDffFragment(), has been updated by UpdateDffFragmentEnd(). */ + sal_uInt32 nPersistKey = mnNextKey; + + /* Prepare the next key that is used by caller as end point of the DFF + fragment. Will be updated by caller when writing to the DFF stream, + using the UpdateDffFragmentEnd() function. This is needed to find DFF + data written by the SVX base class implementation without interaction, + e.g. the solver container that will be written after the last shape. */ + ++mnNextKey; + InsertPersistOffset( mnNextKey, mpOutStrm->Tell() ); + + return nPersistKey; } - -void XclEscherEx::InsertAtCurrentPos( UINT32 nBytes, BOOL bCont ) +void XclEscherEx::UpdateDffFragmentEnd() { - ULONG nPos = GetStreamPos(); - ULONG nCnt = aOffsetMap.Count(); - ULONG j, nOff; - for ( j=0, nOff = (ULONG) aOffsetMap.First(); j<nCnt; - j++, nOff = (ULONG) aOffsetMap.Next() ) - { - if ( nOff >= nPos ) - aOffsetMap.Replace( (void*) (nOff + nBytes) ); - } - EscherEx::InsertAtCurrentPos( nBytes, bCont ); + // update existing fragment key with new stream position + ReplacePersistOffset( mnNextKey, mpOutStrm->Tell() ); } - -ULONG XclEscherEx::AddCurrentOffsetToMap() +sal_uInt32 XclEscherEx::GetDffFragmentPos( sal_uInt32 nFragmentKey ) { - aOffsetMap.Insert( (void*) GetStreamPos(), LIST_APPEND ); - return aOffsetMap.Count() - 1; + /* TODO: this function is non-const because PersistTable::PtGetOffsetByID() + is non-const due to tools/List usage. */ + return GetPersistOffset( nFragmentKey ); } +sal_uInt32 XclEscherEx::GetDffFragmentSize( sal_uInt32 nFragmentKey ) +{ + /* TODO: this function is non-const because PersistTable::PtGetOffsetByID() + is non-const due to tools/List usage. */ + return GetDffFragmentPos( nFragmentKey + 1 ) - GetDffFragmentPos( nFragmentKey ); +} -void XclEscherEx::ReplaceCurrentOffsetInMap( ULONG nPos ) +bool XclEscherEx::HasPendingDffData() { - aOffsetMap.Replace( (void*) GetStreamPos(), nPos ); + /* TODO: this function is non-const because PersistTable::PtGetOffsetByID() + is non-const due to tools/List usage. */ + return GetDffFragmentPos( mnNextKey ) < GetStreamPos(); } -sal_Bool ImplXclEscherExIsFontwork( const SdrObject* pObj ) +XclExpDffAnchorBase* XclEscherEx::CreateDffAnchor( const SdrObject& rSdrObj ) const { - const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) ); + // the object manager creates the correct anchor type according to context + XclExpDffAnchorBase* pAnchor = mrObjMgr.CreateDffAnchor(); + // pass the drawing object, that will calculate the anchor position + pAnchor->SetSdrObject( rSdrObj ); + return pAnchor; +} - sal_Bool bIsFontwork = sal_False; - if ( pObj->GetObjIdentifier() == OBJ_CUSTOMSHAPE ) +namespace { + +bool lcl_IsFontwork( const SdrObject* pObj ) +{ + bool bIsFontwork = false; + if( pObj->GetObjIdentifier() == OBJ_CUSTOMSHAPE ) { + const OUString aTextPath = CREATE_OUSTRING( "TextPath" ); SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&) pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); - - com::sun::star::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath ); - if ( pAny ) + if( Any* pAny = rGeometryItem.GetPropertyValueByName( aTextPath, aTextPath ) ) *pAny >>= bIsFontwork; } return bIsFontwork; } -EscherExHostAppData* XclEscherEx::StartShape( const com::sun::star::uno::Reference< - com::sun::star::drawing::XShape >& rShape ) +} // namespace + +EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape, const Rectangle* pChildAnchor ) { if ( nAdditionalText ) nAdditionalText++; @@ -185,17 +200,17 @@ EscherExHostAppData* XclEscherEx::StartShape( const com::sun::star::uno::Referen if ( bInGroup ) { // stacked recursive group object if ( !pCurrAppData->IsStackedGroup() ) - { //! UpdateStopPos only once + { //! UpdateDffFragmentEnd only once pCurrAppData->SetStackedGroup( TRUE ); - pCurrXclObj->UpdateStopPos(); + UpdateDffFragmentEnd(); } } aStack.Push( pCurrXclObj ); aStack.Push( pCurrAppData ); pCurrAppData = new XclEscherHostAppData; - SdrObject* pObj = GetSdrObjectFromXShape( rShape ); + SdrObject* pObj = GetSdrObjectFromXShape( rxShape ); if ( !pObj ) - pCurrXclObj = new XclObjAny( GetRoot() ); // just what is it?!? + pCurrXclObj = new XclObjAny( mrObjMgr ); // just what is it?!? else { pCurrXclObj = NULL; @@ -203,38 +218,50 @@ EscherExHostAppData* XclEscherEx::StartShape( const com::sun::star::uno::Referen if( nObjType == OBJ_OLE2 ) { - //! not-const because GetObjRef may load the OLE object - Reference < XClassifiedObject > xObj( ((SdrOle2Obj*)pObj)->GetObjRef(), UNO_QUERY ); - if ( xObj.is() ) + // no OLE objects in embedded drawings (chart shapes) + if( mbIsRootDff ) { - SvGlobalName aObjClsId( xObj->getClassID() ); - if ( SotExchange::IsChart( aObjClsId ) ) - { // yes, it's a chart diagram - GetOldRoot().pObjRecs->Add( new XclExpChartObj( GetRoot(), rShape ) ); - pCurrXclObj = NULL; // no metafile or whatsoever + //! not-const because GetObjRef may load the OLE object + Reference < XClassifiedObject > xObj( ((SdrOle2Obj*)pObj)->GetObjRef(), UNO_QUERY ); + if ( xObj.is() ) + { + SvGlobalName aObjClsId( xObj->getClassID() ); + if ( SotExchange::IsChart( aObjClsId ) ) + { // yes, it's a chart diagram + mrObjMgr.AddObj( new XclExpChartObj( mrObjMgr, rxShape, pChildAnchor ) ); + pCurrXclObj = NULL; // no metafile or whatsoever + } + else // metafile and OLE object + pCurrXclObj = new XclObjOle( mrObjMgr, *pObj ); } - else // metafile and OLE object - pCurrXclObj = new XclObjOle( GetRoot(), *pObj ); + else // just a metafile + pCurrXclObj = new XclObjAny( mrObjMgr ); } - else // just a metafile - pCurrXclObj = new XclObjAny( GetRoot() ); + else + pCurrXclObj = new XclObjAny( mrObjMgr ); } else if( nObjType == OBJ_UNO ) { - pCurrXclObj = CreateCtrlObj( rShape ); +#if EXC_EXP_OCX_CTRL + // no ActiveX controls in embedded drawings (chart shapes) + if( mbIsRootDff ) + pCurrXclObj = CreateCtrlObj( rxShape, pChildAnchor ); +#else + pCurrXclObj = CreateCtrlObj( rxShape, pChildAnchor ); +#endif if( !pCurrXclObj ) - pCurrXclObj = new XclObjAny( GetRoot() ); // just a metafile + pCurrXclObj = new XclObjAny( mrObjMgr ); // just a metafile } else if( !ScDrawLayer::IsNoteCaption( pObj ) ) { // #107540# ignore permanent note shapes // #i12190# do not ignore callouts (do not filter by object type ID) - pCurrXclObj = new XclObjAny( GetRoot() ); // just a metafile + pCurrXclObj = new XclObjAny( mrObjMgr ); // just a metafile } } if ( pCurrXclObj ) { - if ( !GetOldRoot().pObjRecs->Add( pCurrXclObj ) ) + if ( !mrObjMgr.AddObj( pCurrXclObj ) ) { // maximum count reached, object got deleted pCurrXclObj = NULL; } @@ -247,14 +274,15 @@ EscherExHostAppData* XclEscherEx::StartShape( const com::sun::star::uno::Referen { if ( !bInGroup ) { - /* Create a dummy anchor carrying the flags. Real coordinates are - calculated later in WriteData(EscherEx&,const Rectangle&). */ - XclExpDffAnchor* pAnchor = new XclExpDffAnchor( GetRoot() ); + /* Create a dummy anchor carrying the flags. Real + coordinates are calculated later in virtual call of + WriteData(EscherEx&,const Rectangle&). */ + XclExpDffAnchorBase* pAnchor = mrObjMgr.CreateDffAnchor(); pAnchor->SetFlags( *pObj ); pCurrAppData->SetClientAnchor( pAnchor ); } const SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, pObj ); - if ( pTextObj && !ImplXclEscherExIsFontwork( pTextObj ) && ( pObj->GetObjIdentifier() != OBJ_CAPTION ) ) + if( pTextObj && !lcl_IsFontwork( pTextObj ) && (pObj->GetObjIdentifier() != OBJ_CAPTION) ) { const OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject(); if( pParaObj ) @@ -265,7 +293,7 @@ EscherExHostAppData* XclEscherEx::StartShape( const com::sun::star::uno::Referen else { if ( !bInGroup ) - pCurrAppData->SetClientAnchor( new XclExpDffAnchor( GetRoot() ) ); + pCurrAppData->SetClientAnchor( mrObjMgr.CreateDffAnchor() ); } } else if ( nAdditionalText == 3 ) @@ -295,13 +323,10 @@ void XclEscherEx::EndShape( UINT16 nShapeType, UINT32 nShapeID ) // escher data of last shape not written? -> delete it from object list if( nShapeID == 0 ) { - XclObj* pLastObj = static_cast< XclObj* >( GetOldRoot().pObjRecs->Last() ); + XclObj* pLastObj = mrObjMgr.RemoveLastObj(); DBG_ASSERT( pLastObj == pCurrXclObj, "XclEscherEx::EndShape - wrong object" ); - if ( pLastObj == pCurrXclObj ) - { - GetOldRoot().pObjRecs->Remove(); - DELETEZ( pCurrXclObj ); - } + DELETEZ( pLastObj ); + pCurrXclObj = 0; } if( pCurrXclObj ) @@ -312,7 +337,7 @@ void XclEscherEx::EndShape( UINT16 nShapeType, UINT32 nShapeID ) else { pCurrXclObj->SetEscherShapeType( nShapeType ); - pCurrXclObj->UpdateStopPos(); + UpdateDffFragmentEnd(); } } } @@ -335,26 +360,18 @@ EscherExHostAppData* XclEscherEx::EnterAdditionalTextGroup() } -void XclEscherEx::DeleteCurrAppData() -{ - if ( pCurrAppData ) - { - delete pCurrAppData->GetClientAnchor(); -// delete pCurrAppData->GetClientData(); - delete pCurrAppData->GetClientTextbox(); - delete pCurrAppData; - } -} - - void XclEscherEx::EndDocument() { - Flush( pPicStrm ); + if( mbIsRootDff ) + Flush( static_cast< XclEscherExGlobal& >( *mxGlobal ).GetPictureStream() ); + + // seek back DFF stream to prepare saving the MSODRAWING[GROUP] records + mpOutStrm->Seek( 0 ); } #if EXC_EXP_OCX_CTRL -XclExpOcxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape ) +XclExpOcxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape, const Rectangle* pChildAnchor ) { ::std::auto_ptr< XclExpOcxControlObj > xOcxCtrl; @@ -375,7 +392,7 @@ XclExpOcxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape ) sal_uInt32 nStrmSize = static_cast< sal_uInt32 >( mxCtlsStrm->Tell() - nStrmStart ); // adjust the class name to "Forms.***.1" aClassName.InsertAscii( "Forms.", 0 ).AppendAscii( ".1" ); - xOcxCtrl.reset( new XclExpOcxControlObj( GetRoot(), xShape, aClassName, nStrmStart, nStrmSize ) ); + xOcxCtrl.reset( new XclExpOcxControlObj( mrObjMgr, xShape, pChildAnchor, aClassName, nStrmStart, nStrmSize ) ); } } } @@ -384,9 +401,9 @@ XclExpOcxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape ) #else -XclExpTbxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape ) +XclExpTbxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape, const Rectangle* pChildAnchor ) { - ::std::auto_ptr< XclExpTbxControlObj > xTbxCtrl( new XclExpTbxControlObj( GetRoot(), xShape ) ); + ::std::auto_ptr< XclExpTbxControlObj > xTbxCtrl( new XclExpTbxControlObj( mrObjMgr, xShape, pChildAnchor ) ); if( xTbxCtrl->GetObjType() == EXC_OBJTYPE_UNKNOWN ) xTbxCtrl.reset(); @@ -454,98 +471,17 @@ void XclEscherEx::ConvertTbxMacro( XclExpTbxControlObj& rTbxCtrlObj, Reference< #endif -// --- class XclEscher ----------------------------------------------- - -XclEscher::XclEscher( const XclExpRoot& rRoot, UINT32 nDrawings ) : - XclExpRoot( rRoot ) -{ - pTempFile = new utl::TempFile; - pTempFile->EnableKillingFile(); - pStrm = utl::UcbStreamHelper::CreateStream( pTempFile->GetURL(), STREAM_STD_READWRITE ); - pStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - pEx = new XclEscherEx( rRoot, *pStrm, nDrawings ); -} - - -XclEscher::~XclEscher() -{ - delete pEx; - delete pStrm; - delete pTempFile; -} - - -void XclEscher::AddSdrPage() -{ - if( SdrPage* pPage = GetSdrPage( GetCurrScTab() ) ) - pEx->AddSdrPage( *pPage ); - // #106213# the first dummy object may still be open - DBG_ASSERT( pEx->GetGroupLevel() <= 1, "XclEscher::AddSdrPage - still groups open?" ); - while( pEx->GetGroupLevel() ) - pEx->LeaveGroup(); -} - - -// Escher client anchor ======================================================= - -XclExpDffAnchor::XclExpDffAnchor( const XclExpRoot& rRoot, sal_uInt16 nFlags ) : - XclExpRoot( rRoot ), - maAnchor( rRoot.GetCurrScTab() ), - mnFlags( nFlags ) -{ -} - -XclExpDffAnchor::XclExpDffAnchor( const XclExpRoot& rRoot, const SdrObject& rSdrObj ) : - XclExpRoot( rRoot ), - maAnchor( rRoot.GetCurrScTab() ) -{ - SetFlags( rSdrObj ); - maAnchor.SetRect( GetDoc(), rSdrObj.GetCurrentBoundRect(), MAP_100TH_MM ); -} - -void XclExpDffAnchor::SetFlags( const SdrObject& rSdrObj ) -{ - // Special case "page anchor" (X==0,Y==1) -> lock pos and size. - const Point& rPos = rSdrObj.GetAnchorPos(); - mnFlags = ((rPos.X() == 0) && (rPos.Y() == 1)) ? EXC_ESC_ANCHOR_LOCKED : 0; -} - -void XclExpDffAnchor::WriteData( EscherEx& rEx, const Rectangle& rRect ) -{ - // the rectangle is already in twips - maAnchor.SetRect( GetDoc(), rRect, MAP_TWIP ); - WriteData( rEx ); -} - - -void XclExpDffAnchor::WriteData( EscherEx& rEx ) const -{ - rEx.AddAtom( 18, ESCHER_ClientAnchor ); - rEx.GetStream() << mnFlags << maAnchor; -} - - -// ---------------------------------------------------------------------------- - -XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ) : - XclExpDffAnchor( rRoot, EXC_ESC_ANCHOR_SIZELOCKED ) -{ - maAnchor.SetRect( GetDoc(), rRect, MAP_100TH_MM ); -} - - -// ---------------------------------------------------------------------------- - -XclExpDffDropDownAnchor::XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos ) : - XclExpDffAnchor( rRoot, EXC_ESC_ANCHOR_POSLOCKED ) +void XclEscherEx::DeleteCurrAppData() { - GetAddressConverter().ConvertAddress( maAnchor.maFirst, rScPos, true ); - maAnchor.maLast.mnCol = maAnchor.maFirst.mnCol + 1; - maAnchor.maLast.mnRow = maAnchor.maFirst.mnRow + 1; - maAnchor.mnLX = maAnchor.mnTY = maAnchor.mnRX = maAnchor.mnBY = 0; + if ( pCurrAppData ) + { + delete pCurrAppData->GetClientAnchor(); +// delete pCurrAppData->GetClientData(); + delete pCurrAppData->GetClientTextbox(); + delete pCurrAppData; + } } - // ============================================================================ // --- class XclEscherClientData ------------------------------------- diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index e4c4443ea56e..67a295ccec8b 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -49,6 +49,7 @@ #include "xcl97esc.hxx" #include "editutil.hxx" #include "xecontent.hxx" +#include "xeescher.hxx" #include "xestyle.hxx" #include "xelink.hxx" @@ -86,158 +87,22 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::drawing::XShape; +// ============================================================================ -//___________________________________________________________________ - -// --- class XclMsodrawing_Base -------------------------------------- - -XclMsodrawing_Base::XclMsodrawing_Base( XclEscher& rEscher, sal_Size nInitialSize ) - : - pEscher( &rEscher ), - nStartPos( rEscher.GetEx()->GetLastOffsetMapPos() ) -{ - // for safety's sake add this now - nStopPos = GetEscherEx()->AddCurrentOffsetToMap(); - (void)nInitialSize; // avoid compiler warning - DBG_ASSERT( GetDataLen() == nInitialSize, "XclMsodrawing_Base ctor: do I really own that data?" ); -} - - -XclMsodrawing_Base::~XclMsodrawing_Base() -{ -} - - -void XclMsodrawing_Base::UpdateStopPos() -{ - if ( nStopPos > 0 ) - GetEscherEx()->ReplaceCurrentOffsetInMap( nStopPos ); - else - nStopPos = GetEscherEx()->AddCurrentOffsetToMap(); -} - - -sal_Size XclMsodrawing_Base::GetDataLen() const -{ - if ( nStartPos < nStopPos ) - { - XclEscherEx* pEx = GetEscherEx(); - return pEx->GetOffsetFromMap( nStopPos ) - pEx->GetOffsetFromMap( nStartPos ); - } - DBG_ERRORFILE( "XclMsodrawing_Base::GetDataLen: position mismatch" ); - return 0; -} - - - -// --- class XclMsodrawinggroup -------------------------------------- - -XclMsodrawinggroup::XclMsodrawinggroup( RootData& rRoot, UINT16 nEscherType ) : - XclMsodrawing_Base( *rRoot.pEscher ), - XclExpRecord(0x00EB, 2) // bogus record size since we don't know the actual size yet. -{ - if ( nEscherType ) - { - XclEscherEx* pEx = GetEscherEx(); - SvStream& rOut = pEx->GetStream(); - switch ( nEscherType ) - { - case ESCHER_DggContainer : - { // per-document data - pEx->OpenContainer( nEscherType ); -//2do: stuff it with our own document defaults? -#if 0 - pEx->BeginCount(); - pEx->AddOpt( ... ); - pEx->EndCount( ESCHER_OPT, 3 ); -#else - BYTE pDummyOPT[] = { - 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01, - 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00, - 0x00, 0x08 - }; - pEx->AddAtom( sizeof(pDummyOPT), ESCHER_OPT, 3, 3 ); - rOut.Write( pDummyOPT, sizeof(pDummyOPT) ); -#endif - BYTE pDummySplitMenuColors[] = { - 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08, - 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10 - }; - pEx->AddAtom( sizeof(pDummySplitMenuColors), ESCHER_SplitMenuColors, 0, 4 ); - rOut.Write( pDummySplitMenuColors, sizeof(pDummySplitMenuColors) ); - pEx->CloseContainer(); // ESCHER_DggContainer - } - break; - } - UpdateStopPos(); - } -} - - -XclMsodrawinggroup::~XclMsodrawinggroup() -{ -} - - -void XclMsodrawinggroup::WriteBody( XclExpStream& rStrm ) -{ - DBG_ASSERT( GetEscherEx()->GetStreamPos() == GetEscherEx()->GetOffsetFromMap( nStartPos ), - "XclMsodrawinggroup::SaveCont: Escher stream position mismatch" ); - rStrm.CopyFromStream( pEscher->GetStrm(), GetDataLen() ); -} - - -// --- class XclMsodrawing -------------------------------------- - -XclMsodrawing::XclMsodrawing( const XclExpRoot& rRoot, UINT16 nEscherType, sal_Size nInitialSize ) : - XclMsodrawing_Base( *rRoot.GetOldRoot().pEscher, nInitialSize ), - XclExpRecord( 0x00EC, nInitialSize ) -{ - if ( nEscherType ) - { - XclEscherEx* pEx = GetEscherEx(); - switch ( nEscherType ) - { - case ESCHER_DgContainer : - { // per-sheet data - pEx->OpenContainer( nEscherType ); - // open group shape container - Rectangle aRect( 0, 0, 0, 0 ); - pEx->EnterGroup( &aRect ); - } - break; - } - UpdateStopPos(); - } -} - - -XclMsodrawing::~XclMsodrawing() -{ -} - - -void XclMsodrawing::WriteBody( XclExpStream& rStrm ) -{ - DBG_ASSERT( GetEscherEx()->GetStreamPos() == GetEscherEx()->GetOffsetFromMap( nStartPos ), - "XclMsodrawing::SaveCont: Escher stream position mismatch" ); - rStrm.CopyFromStream( pEscher->GetStrm(), GetDataLen() ); -} - - - - -// --- class XclObjList ---------------------------------------------- - -XclObjList::XclObjList( const XclExpRoot& rRoot ) : +XclExpObjList::XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx ) : XclExpRoot( rRoot ), - pMsodrawingPerSheet( new XclMsodrawing( rRoot, ESCHER_DgContainer ) ), - pSolverContainer( NULL ) + mrEscherEx( rEscherEx ), + pSolverContainer( 0 ) { + pMsodrawingPerSheet = new XclExpMsoDrawing( rEscherEx ); + // open the DGCONTAINER and the patriarch group shape + mrEscherEx.OpenContainer( ESCHER_DgContainer ); + Rectangle aRect( 0, 0, 0, 0 ); + mrEscherEx.EnterGroup( &aRect ); + mrEscherEx.UpdateDffFragmentEnd(); } - -XclObjList::~XclObjList() +XclExpObjList::~XclExpObjList() { for ( XclObj* p = First(); p; p = Next() ) delete p; @@ -245,10 +110,9 @@ XclObjList::~XclObjList() delete pSolverContainer; } - -UINT16 XclObjList::Add( XclObj* pObj ) +UINT16 XclExpObjList::Add( XclObj* pObj ) { - DBG_ASSERT( Count() < 0xFFFF, "XclObjList::Add: too much for Xcl" ); + DBG_ASSERT( Count() < 0xFFFF, "XclExpObjList::Add: too much for Xcl" ); if ( Count() < 0xFFFF ) { Insert( pObj, LIST_APPEND ); @@ -263,22 +127,17 @@ UINT16 XclObjList::Add( XclObj* pObj ) } } - -void XclObjList::EndSheet() +void XclExpObjList::EndSheet() { - XclEscherEx* pEx = pMsodrawingPerSheet->GetEscherEx(); - // Is there still something in the stream? -> The solver container - sal_Size nSolverSize = pEx->GetStreamPos() - pEx->GetOffsetFromMap( pEx->GetLastOffsetMapPos() ); - if( nSolverSize > 0 ) - pSolverContainer = new XclMsodrawing( GetRoot(), ESCHER_SolverContainer, nSolverSize ); + if( mrEscherEx.HasPendingDffData() ) + pSolverContainer = new XclExpMsoDrawing( mrEscherEx ); - //! close ESCHER_DgContainer created by XclObjList ctor MSODRAWING - pEx->CloseContainer(); + // close the DGCONTAINER created by XclExpObjList ctor MSODRAWING + mrEscherEx.CloseContainer(); } - -void XclObjList::Save( XclExpStream& rStrm ) +void XclExpObjList::Save( XclExpStream& rStrm ) { //! Escher must be written, even if there are no objects pMsodrawingPerSheet->Save( rStrm ); @@ -290,28 +149,26 @@ void XclObjList::Save( XclExpStream& rStrm ) pSolverContainer->Save( rStrm ); } - - // --- class XclObj -------------------------------------------------- -XclObj::XclObj( const XclExpRoot& rRoot, sal_uInt16 nObjType, bool bOwnEscher ) : +XclObj::XclObj( XclExpObjectManager& rObjMgr, sal_uInt16 nObjType, bool bOwnEscher ) : XclExpRecord( EXC_ID_OBJ, 26 ), + mrEscherEx( rObjMgr.GetEscherEx() ), pClientTextbox( NULL ), pTxo( NULL ), mnObjType( nObjType ), nObjId(0), nGrbit( 0x6011 ), // AutoLine, AutoFill, Printable, Locked - bFirstOnSheet( rRoot.GetOldRoot().pObjRecs->Count() == 0 ), + bFirstOnSheet( !rObjMgr.HasObj() ), mbOwnEscher( bOwnEscher ) { //! first object continues the first MSODRAWING record if ( bFirstOnSheet ) - pMsodrawing = rRoot.GetOldRoot().pObjRecs->GetMsodrawingPerSheet(); + pMsodrawing = rObjMgr.GetMsodrawingPerSheet(); else - pMsodrawing = new XclMsodrawing( rRoot ); + pMsodrawing = new XclExpMsoDrawing( mrEscherEx ); } - XclObj::~XclObj() { if ( !bFirstOnSheet ) @@ -320,6 +177,18 @@ XclObj::~XclObj() delete pTxo; } +void XclObj::ImplWriteAnchor( const XclExpRoot& /*rRoot*/, const SdrObject* pSdrObj, const Rectangle* pChildAnchor ) +{ + if( pChildAnchor ) + { + mrEscherEx.AddChildAnchor( *pChildAnchor ); + } + else if( pSdrObj ) + { + ::std::auto_ptr< XclExpDffAnchorBase > xDffAnchor( mrEscherEx.CreateDffAnchor( *pSdrObj ) ); + xDffAnchor->WriteDffData( mrEscherEx ); + } +} void XclObj::SetEscherShapeType( UINT16 nType ) { @@ -350,21 +219,19 @@ void XclObj::SetEscherShapeType( UINT16 nType ) } } - void XclObj::SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj ) { DBG_ASSERT( !pClientTextbox, "XclObj::SetText: already set" ); if ( !pClientTextbox ) { - pMsodrawing->UpdateStopPos(); - pClientTextbox = new XclMsodrawing( rRoot ); - pClientTextbox->GetEscherEx()->AddAtom( 0, ESCHER_ClientTextbox ); // TXO record - pClientTextbox->UpdateStopPos(); + mrEscherEx.UpdateDffFragmentEnd(); + pClientTextbox = new XclExpMsoDrawing( mrEscherEx ); + mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record + mrEscherEx.UpdateDffFragmentEnd(); pTxo = new XclTxo( rRoot, rObj ); } } - void XclObj::WriteBody( XclExpStream& rStrm ) { DBG_ASSERT( mnObjType != EXC_OBJTYPE_UNKNOWN, "XclObj::WriteBody - unknown type" ); @@ -392,7 +259,6 @@ void XclObj::WriteBody( XclExpStream& rStrm ) rStrm.CopyFromStream( aMemStrm ); } - void XclObj::Save( XclExpStream& rStrm ) { // MSODRAWING record (msofbtSpContainer) @@ -406,7 +272,6 @@ void XclObj::Save( XclExpStream& rStrm ) SaveTextRecs( rStrm ); } - void XclObj::WriteSubRecs( XclExpStream& /*rStrm*/ ) { } @@ -421,17 +286,14 @@ void XclObj::SaveTextRecs( XclExpStream& rStrm ) pTxo->Save( rStrm ); } - // --- class XclObjComment ------------------------------------------- - -XclObjComment::XclObjComment( const XclExpRoot& rRoot, const Rectangle& rRect, const EditTextObject& rEditObj, SdrObject* pCaption, bool bVisible ) - : - XclObj( rRoot, EXC_OBJTYPE_NOTE, true ) +XclObjComment::XclObjComment( XclExpObjectManager& rObjMgr, const Rectangle& rRect, const EditTextObject& rEditObj, SdrObject* pCaption, bool bVisible ) : + XclObj( rObjMgr, EXC_OBJTYPE_NOTE, true ) { - ProcessEscherObj(rRoot, rRect, pCaption, bVisible); + ProcessEscherObj( rObjMgr.GetRoot(), rRect, pCaption, bVisible); // TXO - pTxo = new XclTxo( rRoot, rEditObj, pCaption ); + pTxo = new XclTxo( rObjMgr.GetRoot(), rEditObj, pCaption ); } void XclObjComment::ProcessEscherObj( const XclExpRoot& rRoot, const Rectangle& rRect, SdrObject* pCaption, const bool bVisible ) @@ -482,66 +344,62 @@ void XclObjComment::ProcessEscherObj( const XclExpRoot& rRoot, const Rectangle& } nGrbit = 0; // all off: AutoLine, AutoFill, Printable, Locked - XclEscherEx* pEx = pMsodrawing->GetEscherEx(); - pEx->OpenContainer( ESCHER_SpContainer ); - pEx->AddShape( ESCHER_ShpInst_TextBox, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); + mrEscherEx.OpenContainer( ESCHER_SpContainer ); + mrEscherEx.AddShape( ESCHER_ShpInst_TextBox, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); sal_uInt32 nFlags = 0x000A0000; ::set_flag( nFlags, sal_uInt32(2), !bVisible ); aPropOpt.AddOpt( ESCHER_Prop_fPrint, nFlags ); // bool field - aPropOpt.Commit( pEx->GetStream() ); + aPropOpt.Commit( mrEscherEx.GetStream() ); - XclExpDffNoteAnchor( rRoot, rRect ).WriteData( *pEx); + XclExpDffNoteAnchor( rRoot, rRect ).WriteDffData( mrEscherEx ); + + mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record + mrEscherEx.UpdateDffFragmentEnd(); - pEx->AddAtom( 0, ESCHER_ClientData ); // OBJ record - pMsodrawing->UpdateStopPos(); //! Be sure to construct the MSODRAWING ClientTextbox record _after_ the //! base OBJ's MSODRAWING record Escher data is completed. - pClientTextbox = new XclMsodrawing( rRoot ); - pClientTextbox->GetEscherEx()->AddAtom( 0, ESCHER_ClientTextbox ); // TXO record - pClientTextbox->UpdateStopPos(); - pEx->CloseContainer(); // ESCHER_SpContainer + pClientTextbox = new XclExpMsoDrawing( mrEscherEx ); + mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record + mrEscherEx.UpdateDffFragmentEnd(); + mrEscherEx.CloseContainer(); // ESCHER_SpContainer } - XclObjComment::~XclObjComment() { } - void XclObjComment::Save( XclExpStream& rStrm ) { // content of this record XclObj::Save( rStrm ); } - // --- class XclObjDropDown ------------------------------------------ -XclObjDropDown::XclObjDropDown( const XclExpRoot& rRoot, const ScAddress& rPos, BOOL bFilt ) : - XclObj( rRoot, EXC_OBJTYPE_DROPDOWN, true ), - bIsFiltered( bFilt ) +XclObjDropDown::XclObjDropDown( XclExpObjectManager& rObjMgr, const ScAddress& rPos, BOOL bFilt ) : + XclObj( rObjMgr, EXC_OBJTYPE_DROPDOWN, true ), + bIsFiltered( bFilt ) { SetLocked( TRUE ); SetPrintable( FALSE ); SetAutoFill( TRUE ); SetAutoLine( FALSE ); nGrbit |= 0x0100; // undocumented - XclEscherEx* pEx = pMsodrawing->GetEscherEx(); - pEx->OpenContainer( ESCHER_SpContainer ); - pEx->AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); + mrEscherEx.OpenContainer( ESCHER_SpContainer ); + mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); EscherPropertyContainer aPropOpt; aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 ); // bool field aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00010000 ); // bool field aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x000A0000 ); // bool field - aPropOpt.Commit( pEx->GetStream() ); + aPropOpt.Commit( mrEscherEx.GetStream() ); - XclExpDffDropDownAnchor( rRoot, rPos ).WriteData( *pEx ); + XclExpDffDropDownAnchor( rObjMgr.GetRoot(), rPos ).WriteDffData( mrEscherEx ); - pEx->AddAtom( 0, ESCHER_ClientData ); // OBJ record - pMsodrawing->UpdateStopPos(); - pEx->CloseContainer(); // ESCHER_SpContainer + mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record + mrEscherEx.UpdateDffFragmentEnd(); + mrEscherEx.CloseContainer(); // ESCHER_SpContainer // old size + ftSbs + ftLbsData AddRecSize( 24 + 20 ); @@ -568,7 +426,6 @@ void XclObjDropDown::WriteSubRecs( XclExpStream& rStrm ) rStrm.EndRecord(); } - // --- class XclTxo -------------------------------------------------- sal_uInt8 lcl_GetHorAlignFromItemSet( const SfxItemSet& rItemSet ) @@ -725,22 +582,19 @@ sal_Size XclTxo::GetLen() const return 18; } - // --- class XclObjOle ------------------------------------------- -XclObjOle::XclObjOle( const XclExpRoot& rRoot, const SdrObject& rObj ) : - XclObj( rRoot, EXC_OBJTYPE_PICTURE ), +XclObjOle::XclObjOle( XclExpObjectManager& rObjMgr, const SdrObject& rObj ) : + XclObj( rObjMgr, EXC_OBJTYPE_PICTURE ), rOleObj( rObj ), - pRootStorage( rRoot.GetRootStorage() ) + pRootStorage( rObjMgr.GetRoot().GetRootStorage() ) { } - XclObjOle::~XclObjOle() { } - void XclObjOle::WriteSubRecs( XclExpStream& rStrm ) { // write only as embedded, not linked @@ -810,18 +664,16 @@ void XclObjOle::WriteSubRecs( XclExpStream& rStrm ) } } - void XclObjOle::Save( XclExpStream& rStrm ) { // content of this record XclObj::Save( rStrm ); } - // --- class XclObjAny ------------------------------------------- -XclObjAny::XclObjAny( const XclExpRoot& rRoot ) : - XclObj( rRoot, EXC_OBJTYPE_UNKNOWN ) +XclObjAny::XclObjAny( XclExpObjectManager& rObjMgr ) : + XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN ) { } @@ -846,7 +698,6 @@ void XclObjAny::Save( XclExpStream& rStrm ) XclObj::Save( rStrm ); } - // --- class ExcBof8_Base -------------------------------------------- ExcBof8_Base::ExcBof8_Base() |