| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sc.hxx" |
| |
| #include "xiescher.hxx" |
| |
| #include <com/sun/star/beans/NamedValue.hpp> |
| #include <com/sun/star/container/XIndexContainer.hpp> |
| #include <com/sun/star/container/XNameContainer.hpp> |
| #include <com/sun/star/embed/Aspects.hpp> |
| #include <com/sun/star/embed/XEmbeddedObject.hpp> |
| #include <com/sun/star/embed/XEmbedPersist.hpp> |
| #include <com/sun/star/awt/PushButtonType.hpp> |
| #include <com/sun/star/awt/ScrollBarOrientation.hpp> |
| #include <com/sun/star/awt/VisualEffect.hpp> |
| #include <com/sun/star/style/HorizontalAlignment.hpp> |
| #include <com/sun/star/style/VerticalAlignment.hpp> |
| #include <com/sun/star/drawing/XControlShape.hpp> |
| #include <com/sun/star/form/XForm.hpp> |
| #include <com/sun/star/form/XFormsSupplier.hpp> |
| #include <com/sun/star/form/binding/XBindableValue.hpp> |
| #include <com/sun/star/form/binding/XValueBinding.hpp> |
| #include <com/sun/star/form/binding/XListEntrySink.hpp> |
| #include <com/sun/star/form/binding/XListEntrySource.hpp> |
| #include <com/sun/star/script/ScriptEventDescriptor.hpp> |
| #include <com/sun/star/script/XEventAttacherManager.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| |
| #include <rtl/logfile.hxx> |
| #include <sfx2/objsh.hxx> |
| #include <unotools/moduleoptions.hxx> |
| #include <unotools/fltrcfg.hxx> |
| #include <svtools/wmf.hxx> |
| #include <comphelper/types.hxx> |
| #include <comphelper/classids.hxx> |
| #include <toolkit/helper/vclunohelper.hxx> |
| #include <basegfx/point/b2dpoint.hxx> |
| #include <basegfx/polygon/b2dpolygon.hxx> |
| |
| #include <svx/svdopath.hxx> |
| #include <svx/svdocirc.hxx> |
| #include <svx/svdoedge.hxx> |
| #include <svx/svdogrp.hxx> |
| #include <svx/svdoashp.hxx> |
| #include <svx/svdograf.hxx> |
| #include <svx/svdoole2.hxx> |
| #include <svx/svdocapt.hxx> |
| #include <svx/svdouno.hxx> |
| #include <svx/svdpage.hxx> |
| #include <editeng/editobj.hxx> |
| #include <editeng/outliner.hxx> |
| #include <editeng/outlobj.hxx> |
| #include <svx/unoapi.hxx> |
| #include <svx/svditer.hxx> |
| #include <editeng/writingmodeitem.hxx> |
| #include <svx/charthelper.hxx> |
| |
| #include "scitems.hxx" |
| #include <editeng/eeitem.hxx> |
| #include <editeng/colritem.hxx> |
| #include <svx/xflclit.hxx> |
| #include <editeng/adjitem.hxx> |
| #include <svx/xlineit.hxx> |
| #include <svx/xlinjoit.hxx> |
| #include <svx/xlntrit.hxx> |
| #include <svx/xbtmpit.hxx> |
| #include <vcl/dibtools.hxx> |
| |
| #include "document.hxx" |
| #include "drwlayer.hxx" |
| #include "userdat.hxx" |
| #include "chartarr.hxx" |
| #include "detfunc.hxx" |
| #include "unonames.hxx" |
| #include "convuno.hxx" |
| #include "postit.hxx" |
| #include "globstr.hrc" |
| |
| #include "fprogressbar.hxx" |
| #include "xltracer.hxx" |
| #include "xistream.hxx" |
| #include "xihelper.hxx" |
| #include "xiformula.hxx" |
| #include "xilink.hxx" |
| #include "xistyle.hxx" |
| #include "xipage.hxx" |
| #include "xichart.hxx" |
| #include "xicontent.hxx" |
| #include "namebuff.hxx" |
| |
| using ::rtl::OUString; |
| using ::rtl::OUStringBuffer; |
| using ::com::sun::star::uno::makeAny; |
| using ::com::sun::star::uno::Any; |
| using ::com::sun::star::beans::XPropertySet; |
| using ::com::sun::star::uno::makeAny; |
| 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; |
| using ::com::sun::star::container::XNameContainer; |
| using ::com::sun::star::frame::XModel; |
| using ::com::sun::star::awt::XControlModel; |
| using ::com::sun::star::embed::XEmbeddedObject; |
| using ::com::sun::star::embed::XEmbedPersist; |
| using ::com::sun::star::drawing::XControlShape; |
| using ::com::sun::star::drawing::XShape; |
| using ::com::sun::star::form::XForm; |
| using ::com::sun::star::form::XFormComponent; |
| using ::com::sun::star::form::XFormsSupplier; |
| using ::com::sun::star::form::binding::XBindableValue; |
| using ::com::sun::star::form::binding::XValueBinding; |
| using ::com::sun::star::form::binding::XListEntrySink; |
| using ::com::sun::star::form::binding::XListEntrySource; |
| using ::com::sun::star::script::ScriptEventDescriptor; |
| using ::com::sun::star::script::XEventAttacherManager; |
| using ::com::sun::star::table::CellAddress; |
| using ::com::sun::star::table::CellRangeAddress; |
| |
| // ============================================================================ |
| |
| namespace { |
| |
| /** Helper class which mimics the auto_ptr< SdrObject > semantics, but calls |
| SdrObject::Free instead of deleting the SdrObject directly. */ |
| template< typename SdrObjType > |
| class TSdrObjectPtr |
| { |
| public: |
| inline explicit TSdrObjectPtr( SdrObjType* pObj = 0 ) : mpObj( pObj ) {} |
| inline ~TSdrObjectPtr() { free(); } |
| |
| inline const SdrObjType* operator->() const { return mpObj; } |
| inline SdrObjType* operator->() { return mpObj; } |
| |
| inline const SdrObjType* get() const { return mpObj; } |
| inline SdrObjType* get() { return mpObj; } |
| |
| inline const SdrObjType& operator*() const { return *mpObj; } |
| inline SdrObjType& operator*() { return *mpObj; } |
| |
| inline bool is() const { return mpObj != 0; } |
| inline bool operator!() const { return mpObj == 0; } |
| |
| inline void reset( SdrObjType* pObj = 0 ) { free(); mpObj = pObj; } |
| inline SdrObjType* release() { SdrObjType* pObj = mpObj; mpObj = 0; return pObj; } |
| |
| private: |
| TSdrObjectPtr( const TSdrObjectPtr& ); // not implemented |
| TSdrObjectPtr& operator=( TSdrObjectPtr& rxObj ); // not implemented |
| |
| inline void free() { SdrObject* pObj = mpObj; mpObj = 0; SdrObject::Free( pObj ); } |
| |
| private: |
| SdrObjType* mpObj; |
| }; |
| |
| typedef TSdrObjectPtr< SdrObject > SdrObjectPtr; |
| |
| } // namespace |
| |
| // Drawing objects ============================================================ |
| |
| XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot& rRoot ) : |
| XclImpRoot( rRoot ), |
| mnObjId( EXC_OBJ_INVALID_ID ), |
| mnObjType( EXC_OBJTYPE_UNKNOWN ), |
| mnDffShapeId( 0 ), |
| mnDffFlags( 0 ), |
| mbHasAnchor( false ), |
| mbHidden( false ), |
| mbVisible( true ), |
| mbPrintable( true ), |
| mbAreaObj( false ), |
| mbAutoMargin( true ), |
| mbSimpleMacro( true ), |
| mbProcessSdr( true ), |
| mbInsertSdr( true ), |
| mbCustomDff( false ) |
| { |
| // if this sheet(ScTab) have an xclimpdrawobjbase (i.e. it contain sdrobject), |
| // then the sheet should be 'updaterowheights' in loading procedure. i120586 |
| GetDoc().SetPendingRowHeights( rRoot.GetCurrScTab(), false ); |
| } |
| |
| XclImpDrawObjBase::~XclImpDrawObjBase() |
| { |
| } |
| |
| /*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj3( const XclImpRoot& rRoot, XclImpStream& rStrm ) |
| { |
| XclImpDrawObjRef xDrawObj; |
| |
| if( rStrm.GetRecLeft() >= 30 ) |
| { |
| sal_uInt16 nObjType; |
| rStrm.Ignore( 4 ); |
| rStrm >> nObjType; |
| switch( nObjType ) |
| { |
| case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break; |
| case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break; |
| case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break; |
| case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break; |
| case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break; |
| case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break; |
| case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break; |
| case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break; |
| case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break; |
| default: |
| DBG_ERROR1( "XclImpDrawObjBase::ReadObj3 - unknown object type 0x%04hX", nObjType ); |
| rRoot.GetTracer().TraceUnsupportedObjects(); |
| xDrawObj.reset( new XclImpPhObj( rRoot ) ); |
| } |
| } |
| |
| xDrawObj->ImplReadObj3( rStrm ); |
| return xDrawObj; |
| } |
| |
| /*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj4( const XclImpRoot& rRoot, XclImpStream& rStrm ) |
| { |
| XclImpDrawObjRef xDrawObj; |
| |
| if( rStrm.GetRecLeft() >= 30 ) |
| { |
| sal_uInt16 nObjType; |
| rStrm.Ignore( 4 ); |
| rStrm >> nObjType; |
| switch( nObjType ) |
| { |
| case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break; |
| case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break; |
| case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break; |
| case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break; |
| case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break; |
| case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break; |
| case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break; |
| case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break; |
| case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break; |
| case EXC_OBJTYPE_POLYGON: xDrawObj.reset( new XclImpPolygonObj( rRoot ) ); break; |
| default: |
| DBG_ERROR1( "XclImpDrawObjBase::ReadObj4 - unknown object type 0x%04hX", nObjType ); |
| rRoot.GetTracer().TraceUnsupportedObjects(); |
| xDrawObj.reset( new XclImpPhObj( rRoot ) ); |
| } |
| } |
| |
| xDrawObj->ImplReadObj4( rStrm ); |
| return xDrawObj; |
| } |
| |
| /*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj5( const XclImpRoot& rRoot, XclImpStream& rStrm ) |
| { |
| XclImpDrawObjRef xDrawObj; |
| |
| if( rStrm.GetRecLeft() >= 34 ) |
| { |
| sal_uInt16 nObjType; |
| rStrm.Ignore( 4 ); |
| rStrm >> nObjType; |
| switch( nObjType ) |
| { |
| case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break; |
| case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break; |
| case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break; |
| case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break; |
| case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break; |
| case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break; |
| case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break; |
| case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break; |
| case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break; |
| case EXC_OBJTYPE_POLYGON: xDrawObj.reset( new XclImpPolygonObj( rRoot ) ); break; |
| case EXC_OBJTYPE_CHECKBOX: xDrawObj.reset( new XclImpCheckBoxObj( rRoot ) ); break; |
| case EXC_OBJTYPE_OPTIONBUTTON: xDrawObj.reset( new XclImpOptionButtonObj( rRoot ) ); break; |
| case EXC_OBJTYPE_EDIT: xDrawObj.reset( new XclImpEditObj( rRoot ) ); break; |
| case EXC_OBJTYPE_LABEL: xDrawObj.reset( new XclImpLabelObj( rRoot ) ); break; |
| case EXC_OBJTYPE_DIALOG: xDrawObj.reset( new XclImpDialogObj( rRoot ) ); break; |
| case EXC_OBJTYPE_SPIN: xDrawObj.reset( new XclImpSpinButtonObj( rRoot ) ); break; |
| case EXC_OBJTYPE_SCROLLBAR: xDrawObj.reset( new XclImpScrollBarObj( rRoot ) ); break; |
| case EXC_OBJTYPE_LISTBOX: xDrawObj.reset( new XclImpListBoxObj( rRoot ) ); break; |
| case EXC_OBJTYPE_GROUPBOX: xDrawObj.reset( new XclImpGroupBoxObj( rRoot ) ); break; |
| case EXC_OBJTYPE_DROPDOWN: xDrawObj.reset( new XclImpDropDownObj( rRoot ) ); break; |
| default: |
| DBG_ERROR1( "XclImpDrawObjBase::ReadObj5 - unknown object type 0x%04hX", nObjType ); |
| rRoot.GetTracer().TraceUnsupportedObjects(); |
| xDrawObj.reset( new XclImpPhObj( rRoot ) ); |
| } |
| } |
| |
| xDrawObj->ImplReadObj5( rStrm ); |
| return xDrawObj; |
| } |
| |
| /*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj8( const XclImpRoot& rRoot, XclImpStream& rStrm ) |
| { |
| XclImpDrawObjRef xDrawObj; |
| |
| if( rStrm.GetRecLeft() >= 10 ) |
| { |
| sal_uInt16 nSubRecId, nSubRecSize, nObjType; |
| rStrm >> nSubRecId >> nSubRecSize >> nObjType; |
| |
| if(EXC_ID_OBJCMO == nSubRecId) |
| { |
| if( (nSubRecSize >= 6) ) |
| { |
| switch( nObjType ) |
| { |
| // in BIFF8, all simple objects support text |
| case EXC_OBJTYPE_LINE: |
| case EXC_OBJTYPE_ARC: |
| xDrawObj.reset( new XclImpTextObj( rRoot ) ); |
| // lines and arcs may be 2-dimensional |
| xDrawObj->SetAreaObj( false ); |
| break; |
| |
| // in BIFF8, all simple objects support text |
| case EXC_OBJTYPE_RECTANGLE: |
| case EXC_OBJTYPE_OVAL: |
| case EXC_OBJTYPE_POLYGON: |
| case EXC_OBJTYPE_DRAWING: |
| case EXC_OBJTYPE_TEXT: |
| xDrawObj.reset( new XclImpTextObj( rRoot ) ); |
| break; |
| |
| case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break; |
| case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break; |
| case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break; |
| case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break; |
| case EXC_OBJTYPE_CHECKBOX: xDrawObj.reset( new XclImpCheckBoxObj( rRoot ) ); break; |
| case EXC_OBJTYPE_OPTIONBUTTON: xDrawObj.reset( new XclImpOptionButtonObj( rRoot ) ); break; |
| case EXC_OBJTYPE_EDIT: xDrawObj.reset( new XclImpEditObj( rRoot ) ); break; |
| case EXC_OBJTYPE_LABEL: xDrawObj.reset( new XclImpLabelObj( rRoot ) ); break; |
| case EXC_OBJTYPE_DIALOG: xDrawObj.reset( new XclImpDialogObj( rRoot ) ); break; |
| case EXC_OBJTYPE_SPIN: xDrawObj.reset( new XclImpSpinButtonObj( rRoot ) ); break; |
| case EXC_OBJTYPE_SCROLLBAR: xDrawObj.reset( new XclImpScrollBarObj( rRoot ) ); break; |
| case EXC_OBJTYPE_LISTBOX: xDrawObj.reset( new XclImpListBoxObj( rRoot ) ); break; |
| case EXC_OBJTYPE_GROUPBOX: xDrawObj.reset( new XclImpGroupBoxObj( rRoot ) ); break; |
| case EXC_OBJTYPE_DROPDOWN: xDrawObj.reset( new XclImpDropDownObj( rRoot ) ); break; |
| case EXC_OBJTYPE_NOTE: xDrawObj.reset( new XclImpNoteObj( rRoot ) ); break; |
| |
| default: |
| DBG_ERROR1( "XclImpDrawObjBase::ReadObj8 - unknown object type 0x%04hX", nObjType ); |
| rRoot.GetTracer().TraceUnsupportedObjects(); |
| xDrawObj.reset( new XclImpPhObj( rRoot ) ); |
| } |
| } |
| |
| xDrawObj->ImplReadObj8( rStrm ); |
| } |
| else |
| { |
| DBG_ASSERT(false, "XclImpDrawObjBase::ReadObj8 - OBJCMO subrecord expected" ); |
| } |
| } |
| |
| 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; |
| mnDffFlags = rDffObjData.nSpFlags; |
| maObjName = rObjName; |
| maHyperlink = rHyperlink; |
| mbVisible = bVisible; |
| mbAutoMargin = bAutoMargin; |
| } |
| |
| String XclImpDrawObjBase::GetObjName() const |
| { |
| /* #118053# #i51348# Always return a non-empty name. Create English |
| default names depending on the object type. This is not implemented as |
| virtual functions in derived classes, as class type and object type may |
| not match. */ |
| 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 |
| return mbAreaObj ? |
| ((rAnchorRect.GetWidth() > 3) && (rAnchorRect.GetHeight() > 1)) : |
| ((rAnchorRect.GetWidth() > 3) || (rAnchorRect.GetHeight() > 1)); |
| } |
| |
| ScRange XclImpDrawObjBase::GetUsedArea( SCTAB nScTab ) const |
| { |
| ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID ); |
| // #i44077# object inserted -> update used area for OLE object import |
| if( mbHasAnchor && GetAddressConverter().ConvertRange( aScUsedArea, maAnchor, nScTab, nScTab, false ) ) |
| { |
| // 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; |
| } |
| |
| sal_Size XclImpDrawObjBase::GetProgressSize() const |
| { |
| return DoGetProgressSize(); |
| } |
| |
| SdrObject* XclImpDrawObjBase::CreateSdrObject( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect, bool bIsDff ) const |
| { |
| SdrObjectPtr xSdrObj; |
| if( bIsDff && !mbCustomDff ) |
| { |
| rDffConv.Progress( GetProgressSize() ); |
| } |
| else |
| { |
| xSdrObj.reset( DoCreateSdrObj( rDffConv, rAnchorRect ) ); |
| if( xSdrObj.is() ) |
| xSdrObj->SetModel( rDffConv.GetModel() ); |
| //added for exporting OCX control |
| /* mnObjType value set should be as below table: |
| 0x0000 Group 0x0001 Line |
| 0x0002 Rectangle 0x0003 Oval |
| 0x0004 Arc 0x0005 Chart |
| 0x0006 Text 0x0009 Polygon |
| +-----------------------------------------------------+ |
| OCX ==>| 0x0008 Picture | |
| +-----------------------------------------------------+ |
| | 0x0007 Button | |
| | 0x000B Checkbox 0x000C Radio button | |
| | 0x000D Edit box 0x000E Label | |
| TBX ==> | 0x000F Dialog box 0x0010 Spin control | |
| | 0x0011 Scrollbar 0x0012 List | |
| | 0x0013 Group box 0x0014 Dropdown list | |
| +-----------------------------------------------------+ |
| 0x0019 Note 0x001E OfficeArt object |
| */ |
| if( xSdrObj.is() && xSdrObj->IsUnoObj() && |
| ( (mnObjType < 25 && mnObjType > 10) || mnObjType == 7 || mnObjType == 8 ) ) |
| { |
| SdrUnoObj* pSdrUnoObj = dynamic_cast< SdrUnoObj* >( xSdrObj.get() ); |
| if( pSdrUnoObj != NULL ) |
| { |
| Reference< XControlModel > xCtrlModel = pSdrUnoObj->GetUnoControlModel(); |
| Reference< XPropertySet > xPropSet(xCtrlModel,UNO_QUERY); |
| const static rtl::OUString sPropertyName = rtl::OUString::createFromAscii("ControlTypeinMSO"); |
| |
| enum ControlType { eCreateFromAOO = 0, eCreateFromMSTBXControl, eCreateFromMSOCXControl }; |
| |
| if( mnObjType == 7 || (mnObjType < 25 && mnObjType > 10) )//TBX |
| { |
| //Need summary type for export. Detail type(checkbox, button ...) has been contained by mnObjType |
| const sal_Int16 nTBXControlType = eCreateFromMSTBXControl ; |
| Any aAny; |
| aAny <<= nTBXControlType; |
| try{ |
| xPropSet->setPropertyValue(sPropertyName, aAny); |
| }catch(...) |
| { |
| OSL_TRACE("XclImpDrawObjBase::CreateSdrObject, this control can't be set the property ControlTypeinMSO!"); |
| } |
| } |
| if( mnObjType == 8 )//OCX |
| { |
| //Need summary type for export |
| const static rtl::OUString sObjIdPropertyName = rtl::OUString::createFromAscii("ObjIDinMSO"); |
| const XclImpPictureObj* const pObj = dynamic_cast< const XclImpPictureObj* const >(this); |
| if( pObj != NULL && pObj->IsOcxControl() ) |
| { |
| const sal_Int16 nOCXControlType = eCreateFromMSOCXControl; |
| Any aAny; |
| try{ |
| aAny <<= nOCXControlType; |
| xPropSet->setPropertyValue(sPropertyName, aAny); |
| //Detail type(checkbox, button ...) |
| aAny<<= mnObjId; |
| xPropSet->setPropertyValue(sObjIdPropertyName, aAny); |
| }catch(...) |
| { |
| OSL_TRACE("XclImpDrawObjBase::CreateSdrObject, this control can't be set the property ObjIDinMSO!"); |
| } |
| } |
| } |
| |
| } |
| } |
| } |
| return xSdrObj.release(); |
| } |
| |
| void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const |
| { |
| // default: front layer, derived classes may have to set other layer in DoPreProcessSdrObj() |
| rSdrObj.NbcSetLayer( SC_LAYER_FRONT ); |
| SdrModel * pModel = rSdrObj.GetModel(); |
| if ( pModel ) { |
| const bool bEnableUndo = pModel->IsUndoEnabled(); |
| pModel->EnableUndo(false); |
| // set object name (GetObjName() will always return a non-empty name) |
| rSdrObj.SetName( GetObjName() ); |
| pModel->EnableUndo(bEnableUndo); |
| } else |
| rSdrObj.SetName( GetObjName() ); |
| // #i39167# full width for all objects regardless of horizontal alignment |
| rSdrObj.SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK ) ); |
| |
| // automatic text margin |
| if( mbAutoMargin ) |
| { |
| sal_Int32 nMargin = rDffConv.GetDefaultTextMargin(); |
| rSdrObj.SetMergedItem( SdrTextLeftDistItem( nMargin ) ); |
| rSdrObj.SetMergedItem( SdrTextRightDistItem( nMargin ) ); |
| rSdrObj.SetMergedItem( SdrTextUpperDistItem( nMargin ) ); |
| rSdrObj.SetMergedItem( SdrTextLowerDistItem( nMargin ) ); |
| } |
| |
| // macro and hyperlink |
| #ifdef ISSUE66550_HLINK_FOR_SHAPES |
| if( mbSimpleMacro && ((maMacroName.Len() > 0) || (maHyperlink.getLength() > 0)) ) |
| { |
| if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, sal_True ) ) |
| { |
| pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) ); |
| pInfo->SetHlink( maHyperlink ); |
| } |
| } |
| #else |
| if( mbSimpleMacro && (maMacroName.Len() > 0) ) |
| if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, sal_True ) ) |
| pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) ); |
| #endif |
| |
| // call virtual function for object type specific processing |
| DoPreProcessSdrObj( rDffConv, rSdrObj ); |
| } |
| |
| void XclImpDrawObjBase::PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const |
| { |
| // call virtual function for object type specific processing |
| DoPostProcessSdrObj( rDffConv, rSdrObj ); |
| } |
| |
| // protected ------------------------------------------------------------------ |
| |
| void XclImpDrawObjBase::ReadName5( XclImpStream& rStrm, sal_uInt16 nNameLen ) |
| { |
| maObjName.Erase(); |
| if( nNameLen > 0 ) |
| { |
| // name length field is repeated before the name |
| maObjName = rStrm.ReadByteString( false ); |
| // skip padding byte for word boundaries |
| if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 ); |
| } |
| } |
| |
| void XclImpDrawObjBase::ReadMacro3( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| maMacroName.Erase(); |
| rStrm.Ignore( nMacroSize ); |
| // skip padding byte for word boundaries, not contained in nMacroSize |
| if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 ); |
| } |
| |
| void XclImpDrawObjBase::ReadMacro4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| maMacroName.Erase(); |
| rStrm.Ignore( nMacroSize ); |
| } |
| |
| void XclImpDrawObjBase::ReadMacro5( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| maMacroName.Erase(); |
| rStrm.Ignore( nMacroSize ); |
| } |
| |
| void XclImpDrawObjBase::ReadMacro8( XclImpStream& rStrm ) |
| { |
| maMacroName.Erase(); |
| if( rStrm.GetRecLeft() > 6 ) |
| { |
| // macro is stored in a tNameXR token containing a link to a defined name |
| sal_uInt16 nFmlaSize; |
| rStrm >> nFmlaSize; |
| rStrm.Ignore( 4 ); |
| DBG_ASSERT( nFmlaSize == 7, "XclImpDrawObjBase::ReadMacro - unexpected formula size" ); |
| if( nFmlaSize == 7 ) |
| { |
| sal_uInt8 nTokenId; |
| sal_uInt16 nExtSheet, nExtName; |
| rStrm >> nTokenId >> nExtSheet >> nExtName; |
| DBG_ASSERT( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ), |
| "XclImpDrawObjBase::ReadMacro - tNameXR token expected" ); |
| if( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) ) |
| maMacroName = GetLinkManager().GetMacroName( nExtSheet, nExtName ); |
| } |
| } |
| } |
| |
| void XclImpDrawObjBase::ConvertLineStyle( SdrObject& rSdrObj, const XclObjLineData& rLineData ) const |
| { |
| if( rLineData.IsAuto() ) |
| { |
| XclObjLineData aAutoData; |
| aAutoData.mnAuto = 0; |
| ConvertLineStyle( rSdrObj, aAutoData ); |
| } |
| else |
| { |
| long nLineWidth = 35 * ::std::min( rLineData.mnWidth, EXC_OBJ_LINE_THICK ); |
| rSdrObj.SetMergedItem( XLineWidthItem( nLineWidth ) ); |
| rSdrObj.SetMergedItem( XLineColorItem( EMPTY_STRING, GetPalette().GetColor( rLineData.mnColorIdx ) ) ); |
| rSdrObj.SetMergedItem( XLineJointItem( com::sun::star::drawing::LineJoint_MITER ) ); |
| |
| sal_uLong nDotLen = ::std::max< sal_uLong >( 70 * rLineData.mnWidth, 35 ); |
| sal_uLong nDashLen = 3 * nDotLen; |
| sal_uLong nDist = 2 * nDotLen; |
| |
| switch( rLineData.mnStyle ) |
| { |
| default: |
| case EXC_OBJ_LINE_SOLID: |
| rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) ); |
| break; |
| case EXC_OBJ_LINE_DASH: |
| rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) ); |
| rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 0, nDotLen, 1, nDashLen, nDist ) ) ); |
| break; |
| case EXC_OBJ_LINE_DOT: |
| rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) ); |
| rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 1, nDotLen, 0, nDashLen, nDist ) ) ); |
| break; |
| case EXC_OBJ_LINE_DASHDOT: |
| rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) ); |
| rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 1, nDotLen, 1, nDashLen, nDist ) ) ); |
| break; |
| case EXC_OBJ_LINE_DASHDOTDOT: |
| rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) ); |
| rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 2, nDotLen, 1, nDashLen, nDist ) ) ); |
| break; |
| case EXC_OBJ_LINE_MEDTRANS: |
| rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) ); |
| rSdrObj.SetMergedItem( XLineTransparenceItem( 50 ) ); |
| break; |
| case EXC_OBJ_LINE_DARKTRANS: |
| rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) ); |
| rSdrObj.SetMergedItem( XLineTransparenceItem( 25 ) ); |
| break; |
| case EXC_OBJ_LINE_LIGHTTRANS: |
| rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) ); |
| rSdrObj.SetMergedItem( XLineTransparenceItem( 75 ) ); |
| break; |
| case EXC_OBJ_LINE_NONE: |
| rSdrObj.SetMergedItem( XLineStyleItem( XLINE_NONE ) ); |
| break; |
| } |
| } |
| } |
| |
| void XclImpDrawObjBase::ConvertFillStyle( SdrObject& rSdrObj, const XclObjFillData& rFillData ) const |
| { |
| if( rFillData.IsAuto() ) |
| { |
| XclObjFillData aAutoData; |
| aAutoData.mnAuto = 0; |
| ConvertFillStyle( rSdrObj, aAutoData ); |
| } |
| else if( rFillData.mnPattern == EXC_PATT_NONE ) |
| { |
| rSdrObj.SetMergedItem( XFillStyleItem( XFILL_NONE ) ); |
| } |
| else |
| { |
| Color aPattColor = GetPalette().GetColor( rFillData.mnPattColorIdx ); |
| Color aBackColor = GetPalette().GetColor( rFillData.mnBackColorIdx ); |
| if( (rFillData.mnPattern == EXC_PATT_SOLID) || (aPattColor == aBackColor) ) |
| { |
| rSdrObj.SetMergedItem( XFillStyleItem( XFILL_SOLID ) ); |
| rSdrObj.SetMergedItem( XFillColorItem( EMPTY_STRING, aPattColor ) ); |
| } |
| else |
| { |
| static const sal_uInt8 sppnPatterns[][ 8 ] = |
| { |
| { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 }, |
| { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD }, |
| { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 }, |
| { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 }, |
| { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }, |
| { 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 }, |
| { 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99 }, |
| { 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 }, |
| { 0xCC, 0xFF, 0x33, 0xFF, 0xCC, 0xFF, 0x33, 0xFF }, |
| { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 }, |
| { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, |
| { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, |
| { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, |
| { 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x11, 0x11, 0x11 }, |
| { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 }, |
| { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 }, |
| { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00 } |
| }; |
| const sal_uInt8* const pnPattern = sppnPatterns[ ::std::min< size_t >( rFillData.mnPattern - 2, STATIC_ARRAY_SIZE( sppnPatterns ) ) ]; |
| // create 2-colored 8x8 DIB |
| SvMemoryStream aMemStrm; |
| aMemStrm << sal_uInt32( 12 ) << sal_Int16( 8 ) << sal_Int16( 8 ) << sal_uInt16( 1 ) << sal_uInt16( 1 ); |
| aMemStrm << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF ); |
| aMemStrm << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 ); |
| for( size_t nIdx = 0; nIdx < 8; ++nIdx ) |
| aMemStrm << sal_uInt32( pnPattern[ nIdx ] ); // 32-bit little-endian |
| aMemStrm.Seek( STREAM_SEEK_TO_BEGIN ); |
| Bitmap aBitmap; |
| ReadDIB(aBitmap, aMemStrm, false); |
| rSdrObj.SetMergedItem(XFillStyleItem(XFILL_BITMAP)); |
| rSdrObj.SetMergedItem(XFillBitmapItem(EMPTY_STRING, Graphic(aBitmap))); |
| } |
| } |
| } |
| |
| void XclImpDrawObjBase::ConvertFrameStyle( SdrObject& rSdrObj, sal_uInt16 nFrameFlags ) const |
| { |
| if( ::get_flag( nFrameFlags, EXC_OBJ_FRAME_SHADOW ) ) |
| { |
| rSdrObj.SetMergedItem( SdrShadowItem( sal_True ) ); |
| rSdrObj.SetMergedItem( SdrShadowXDistItem( 35 ) ); |
| rSdrObj.SetMergedItem( SdrShadowYDistItem( 35 ) ); |
| rSdrObj.SetMergedItem( SdrShadowColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWTEXT ) ) ); |
| } |
| } |
| |
| Color XclImpDrawObjBase::GetSolidLineColor( const XclObjLineData& rLineData ) const |
| { |
| Color aColor( COL_TRANSPARENT ); |
| if( rLineData.IsAuto() ) |
| { |
| XclObjLineData aAutoData; |
| aAutoData.mnAuto = 0; |
| aColor = GetSolidLineColor( aAutoData ); |
| } |
| else if( rLineData.mnStyle != EXC_OBJ_LINE_NONE ) |
| { |
| aColor = GetPalette().GetColor( rLineData.mnColorIdx ); |
| } |
| return aColor; |
| } |
| |
| Color XclImpDrawObjBase::GetSolidFillColor( const XclObjFillData& rFillData ) const |
| { |
| Color aColor( COL_TRANSPARENT ); |
| if( rFillData.IsAuto() ) |
| { |
| XclObjFillData aAutoData; |
| aAutoData.mnAuto = 0; |
| aColor = GetSolidFillColor( aAutoData ); |
| } |
| else if( rFillData.mnPattern != EXC_PATT_NONE ) |
| { |
| Color aPattColor = GetPalette().GetColor( rFillData.mnPattColorIdx ); |
| Color aBackColor = GetPalette().GetColor( rFillData.mnBackColorIdx ); |
| aColor = XclTools::GetPatternColor( aPattColor, aBackColor, rFillData.mnPattern ); |
| } |
| return aColor; |
| } |
| |
| void XclImpDrawObjBase::DoReadObj3( XclImpStream&, sal_uInt16 ) |
| { |
| } |
| |
| void XclImpDrawObjBase::DoReadObj4( XclImpStream&, sal_uInt16 ) |
| { |
| } |
| |
| void XclImpDrawObjBase::DoReadObj5( XclImpStream&, sal_uInt16, sal_uInt16 ) |
| { |
| } |
| |
| void XclImpDrawObjBase::DoReadObj8SubRec( XclImpStream&, sal_uInt16, sal_uInt16 ) |
| { |
| } |
| |
| sal_Size XclImpDrawObjBase::DoGetProgressSize() const |
| { |
| return 1; |
| } |
| |
| SdrObject* XclImpDrawObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& ) const |
| { |
| rDffConv.Progress( GetProgressSize() ); |
| return 0; |
| } |
| |
| void XclImpDrawObjBase::DoPreProcessSdrObj( XclImpDffConverter&, SdrObject& ) const |
| { |
| // trace if object is not printable |
| if( !IsPrintable() ) |
| GetTracer().TraceObjectNotPrintable(); |
| } |
| |
| void XclImpDrawObjBase::DoPostProcessSdrObj( XclImpDffConverter&, SdrObject& ) const |
| { |
| } |
| |
| void XclImpDrawObjBase::ImplReadObj3( XclImpStream& rStrm ) |
| { |
| // back to offset 4 (ignore object count field) |
| rStrm.Seek( 4 ); |
| |
| 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 ); |
| DoReadObj3( rStrm, nMacroSize ); |
| } |
| |
| void XclImpDrawObjBase::ImplReadObj4( XclImpStream& rStrm ) |
| { |
| // back to offset 4 (ignore object count field) |
| rStrm.Seek( 4 ); |
| |
| 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 ); |
| DoReadObj4( rStrm, nMacroSize ); |
| } |
| |
| void XclImpDrawObjBase::ImplReadObj5( XclImpStream& rStrm ) |
| { |
| // back to offset 4 (ignore object count field) |
| rStrm.Seek( 4 ); |
| |
| 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 ); |
| DoReadObj5( rStrm, nNameLen, nMacroSize ); |
| } |
| |
| void XclImpDrawObjBase::ImplReadObj8( XclImpStream& rStrm ) |
| { |
| // back to beginning |
| rStrm.Seek( EXC_REC_SEEK_TO_BEGIN ); |
| |
| bool bLoop = true; |
| while( bLoop && (rStrm.GetRecLeft() >= 4) ) |
| { |
| sal_uInt16 nSubRecId, nSubRecSize; |
| rStrm >> nSubRecId >> nSubRecSize; |
| rStrm.PushPosition(); |
| // sometimes the last subrecord has an invalid length (OBJLBSDATA) -> min() |
| nSubRecSize = static_cast< sal_uInt16 >( ::std::min< sal_Size >( nSubRecSize, rStrm.GetRecLeft() ) ); |
| |
| switch( nSubRecId ) |
| { |
| case EXC_ID_OBJCMO: |
| DBG_ASSERT( rStrm.GetRecPos() == 4, "XclImpDrawObjBase::ImplReadObj8 - unexpected OBJCMO subrecord" ); |
| if( (rStrm.GetRecPos() == 4) && (nSubRecSize >= 6) ) |
| { |
| sal_uInt16 nObjFlags; |
| rStrm >> mnObjType >> mnObjId >> nObjFlags; |
| mbPrintable = ::get_flag( nObjFlags, EXC_OBJCMO_PRINTABLE ); |
| } |
| break; |
| case EXC_ID_OBJMACRO: |
| ReadMacro8( rStrm ); |
| break; |
| case EXC_ID_OBJEND: |
| bLoop = false; |
| break; |
| default: |
| DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize ); |
| } |
| |
| rStrm.PopPosition(); |
| rStrm.Ignore( nSubRecSize ); |
| } |
| |
| /* Call DoReadObj8SubRec() with EXC_ID_OBJEND for further stream |
| processing (e.g. charts), even if the OBJEND subrecord is missing. */ |
| DoReadObj8SubRec( rStrm, EXC_ID_OBJEND, 0 ); |
| |
| /* Pictures that Excel reads from BIFF5 and writes to BIFF8 still have the |
| IMGDATA record following the OBJ record (but they use the image data |
| stored in DFF). The IMGDATA record may be continued by several CONTINUE |
| records. But the last CONTINUE record may be in fact an MSODRAWING |
| record that contains the DFF data of the next drawing object! So we |
| have to skip just enough CONTINUE records to look at the next |
| MSODRAWING/CONTINUE record. */ |
| if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() ) |
| { |
| sal_uInt32 nDataSize; |
| rStrm.Ignore( 4 ); |
| rStrm >> nDataSize; |
| nDataSize -= rStrm.GetRecLeft(); |
| // skip following CONTINUE records until IMGDATA ends |
| while( (nDataSize > 0) && (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord() ) |
| { |
| DBG_ASSERT( nDataSize >= rStrm.GetRecLeft(), "XclImpDrawObjBase::ImplReadObj8 - CONTINUE too long" ); |
| nDataSize -= ::std::min< sal_uInt32 >( rStrm.GetRecLeft(), nDataSize ); |
| } |
| DBG_ASSERT( nDataSize == 0, "XclImpDrawObjBase::ImplReadObj8 - missing CONTINUE records" ); |
| // next record may be MSODRAWING or CONTINUE or anything else |
| } |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| void XclImpDrawObjVector::InsertGrouped( XclImpDrawObjRef xDrawObj ) |
| { |
| if( !empty() ) |
| if( XclImpGroupObj* pGroupObj = dynamic_cast< XclImpGroupObj* >( back().get() ) ) |
| if( pGroupObj->TryInsert( xDrawObj ) ) |
| return; |
| push_back( xDrawObj ); |
| } |
| |
| sal_Size XclImpDrawObjVector::GetProgressSize() const |
| { |
| sal_Size nProgressSize = 0; |
| for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt ) |
| nProgressSize += (*aIt)->GetProgressSize(); |
| return nProgressSize; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpPhObj::XclImpPhObj( const XclImpRoot& rRoot ) : |
| XclImpDrawObjBase( rRoot ) |
| { |
| SetProcessSdrObj( false ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpGroupObj::XclImpGroupObj( const XclImpRoot& rRoot ) : |
| XclImpDrawObjBase( rRoot ), |
| mnFirstUngrouped( 0 ) |
| { |
| } |
| |
| bool XclImpGroupObj::TryInsert( XclImpDrawObjRef xDrawObj ) |
| { |
| if( xDrawObj->GetObjId() == mnFirstUngrouped ) |
| return false; |
| // insert into own list or into nested group |
| maChildren.InsertGrouped( xDrawObj ); |
| return true; |
| } |
| |
| void XclImpGroupObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| rStrm.Ignore( 4 ); |
| rStrm >> mnFirstUngrouped; |
| rStrm.Ignore( 16 ); |
| ReadMacro3( rStrm, nMacroSize ); |
| } |
| |
| void XclImpGroupObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| rStrm.Ignore( 4 ); |
| rStrm >> mnFirstUngrouped; |
| rStrm.Ignore( 16 ); |
| ReadMacro4( rStrm, nMacroSize ); |
| } |
| |
| void XclImpGroupObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) |
| { |
| rStrm.Ignore( 4 ); |
| rStrm >> mnFirstUngrouped; |
| rStrm.Ignore( 16 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, nMacroSize ); |
| } |
| |
| sal_Size XclImpGroupObj::DoGetProgressSize() const |
| { |
| return XclImpDrawObjBase::DoGetProgressSize() + maChildren.GetProgressSize(); |
| } |
| |
| 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 ) |
| rDffConv.ProcessObject( rObjList, **aIt ); |
| rDffConv.Progress(); |
| return xSdrObj.release(); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpLineObj::XclImpLineObj( const XclImpRoot& rRoot ) : |
| XclImpDrawObjBase( rRoot ), |
| mnArrows( 0 ), |
| mnStartPoint( EXC_OBJ_LINE_TL ) |
| { |
| SetAreaObj( false ); |
| } |
| |
| void XclImpLineObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| rStrm >> maLineData >> mnArrows >> mnStartPoint; |
| rStrm.Ignore( 1 ); |
| ReadMacro3( rStrm, nMacroSize ); |
| } |
| |
| void XclImpLineObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| rStrm >> maLineData >> mnArrows >> mnStartPoint; |
| rStrm.Ignore( 1 ); |
| ReadMacro4( rStrm, nMacroSize ); |
| } |
| |
| void XclImpLineObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) |
| { |
| rStrm >> maLineData >> mnArrows >> mnStartPoint; |
| rStrm.Ignore( 1 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, nMacroSize ); |
| } |
| |
| SdrObject* XclImpLineObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const |
| { |
| ::basegfx::B2DPolygon aB2DPolygon; |
| switch( mnStartPoint ) |
| { |
| default: |
| case EXC_OBJ_LINE_TL: |
| aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) ); |
| aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) ); |
| break; |
| case EXC_OBJ_LINE_TR: |
| aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) ); |
| aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) ); |
| break; |
| case EXC_OBJ_LINE_BR: |
| aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) ); |
| aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) ); |
| break; |
| case EXC_OBJ_LINE_BL: |
| aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) ); |
| aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) ); |
| break; |
| } |
| SdrObjectPtr xSdrObj( new SdrPathObj( OBJ_LINE, ::basegfx::B2DPolyPolygon( aB2DPolygon ) ) ); |
| ConvertLineStyle( *xSdrObj, maLineData ); |
| |
| // line ends |
| sal_uInt8 nArrowType = ::extract_value< sal_uInt8 >( mnArrows, 0, 4 ); |
| bool bLineStart = false; |
| bool bLineEnd = false; |
| bool bFilled = false; |
| switch( nArrowType ) |
| { |
| case EXC_OBJ_ARROW_OPEN: bLineStart = false; bLineEnd = true; bFilled = false; break; |
| case EXC_OBJ_ARROW_OPENBOTH: bLineStart = true; bLineEnd = true; bFilled = false; break; |
| case EXC_OBJ_ARROW_FILLED: bLineStart = false; bLineEnd = true; bFilled = true; break; |
| case EXC_OBJ_ARROW_FILLEDBOTH: bLineStart = true; bLineEnd = true; bFilled = true; break; |
| } |
| if( bLineStart || bLineEnd ) |
| { |
| sal_uInt8 nArrowWidth = ::extract_value< sal_uInt8 >( mnArrows, 4, 4 ); |
| double fArrowWidth = 3.0; |
| switch( nArrowWidth ) |
| { |
| case EXC_OBJ_ARROW_NARROW: fArrowWidth = 2.0; break; |
| case EXC_OBJ_ARROW_MEDIUM: fArrowWidth = 3.0; break; |
| case EXC_OBJ_ARROW_WIDE: fArrowWidth = 5.0; break; |
| } |
| |
| sal_uInt8 nArrowLength = ::extract_value< sal_uInt8 >( mnArrows, 8, 4 ); |
| double fArrowLength = 3.0; |
| switch( nArrowLength ) |
| { |
| case EXC_OBJ_ARROW_NARROW: fArrowLength = 2.5; break; |
| case EXC_OBJ_ARROW_MEDIUM: fArrowLength = 3.5; break; |
| case EXC_OBJ_ARROW_WIDE: fArrowLength = 6.0; break; |
| } |
| |
| ::basegfx::B2DPolygon aArrowPoly; |
| #define EXC_ARROW_POINT( x, y ) ::basegfx::B2DPoint( fArrowWidth * (x), fArrowLength * (y) ) |
| if( bFilled ) |
| { |
| aArrowPoly.append( EXC_ARROW_POINT( 0, 100 ) ); |
| aArrowPoly.append( EXC_ARROW_POINT( 50, 0 ) ); |
| aArrowPoly.append( EXC_ARROW_POINT( 100, 100 ) ); |
| } |
| else |
| { |
| sal_uInt8 nLineWidth = ::limit_cast< sal_uInt8 >( maLineData.mnWidth, EXC_OBJ_LINE_THIN, EXC_OBJ_LINE_THICK ); |
| aArrowPoly.append( EXC_ARROW_POINT( 50, 0 ) ); |
| aArrowPoly.append( EXC_ARROW_POINT( 100, 100 - 3 * nLineWidth ) ); |
| aArrowPoly.append( EXC_ARROW_POINT( 100 - 5 * nLineWidth, 100 ) ); |
| aArrowPoly.append( EXC_ARROW_POINT( 50, 12 * nLineWidth ) ); |
| aArrowPoly.append( EXC_ARROW_POINT( 5 * nLineWidth, 100 ) ); |
| aArrowPoly.append( EXC_ARROW_POINT( 0, 100 - 3 * nLineWidth ) ); |
| } |
| #undef EXC_ARROW_POINT |
| |
| ::basegfx::B2DPolyPolygon aArrowPolyPoly( aArrowPoly ); |
| long nWidth = static_cast< long >( 125 * fArrowWidth ); |
| if( bLineStart ) |
| { |
| xSdrObj->SetMergedItem( XLineStartItem( EMPTY_STRING, aArrowPolyPoly ) ); |
| xSdrObj->SetMergedItem( XLineStartWidthItem( nWidth ) ); |
| xSdrObj->SetMergedItem( XLineStartCenterItem( sal_False ) ); |
| } |
| if( bLineEnd ) |
| { |
| xSdrObj->SetMergedItem( XLineEndItem( EMPTY_STRING, aArrowPolyPoly ) ); |
| xSdrObj->SetMergedItem( XLineEndWidthItem( nWidth ) ); |
| xSdrObj->SetMergedItem( XLineEndCenterItem( sal_False ) ); |
| } |
| } |
| rDffConv.Progress(); |
| return xSdrObj.release(); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpRectObj::XclImpRectObj( const XclImpRoot& rRoot ) : |
| XclImpDrawObjBase( rRoot ), |
| mnFrameFlags( 0 ) |
| { |
| SetAreaObj( true ); |
| } |
| |
| void XclImpRectObj::ReadFrameData( XclImpStream& rStrm ) |
| { |
| rStrm >> maFillData >> maLineData >> mnFrameFlags; |
| } |
| |
| void XclImpRectObj::ConvertRectStyle( SdrObject& rSdrObj ) const |
| { |
| ConvertLineStyle( rSdrObj, maLineData ); |
| ConvertFillStyle( rSdrObj, maFillData ); |
| ConvertFrameStyle( rSdrObj, mnFrameFlags ); |
| } |
| |
| void XclImpRectObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| ReadFrameData( rStrm ); |
| ReadMacro3( rStrm, nMacroSize ); |
| } |
| |
| void XclImpRectObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| ReadFrameData( rStrm ); |
| ReadMacro4( rStrm, nMacroSize ); |
| } |
| |
| void XclImpRectObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) |
| { |
| ReadFrameData( rStrm ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, nMacroSize ); |
| } |
| |
| SdrObject* XclImpRectObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const |
| { |
| SdrObjectPtr xSdrObj( new SdrRectObj( rAnchorRect ) ); |
| ConvertRectStyle( *xSdrObj ); |
| rDffConv.Progress(); |
| return xSdrObj.release(); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpOvalObj::XclImpOvalObj( const XclImpRoot& rRoot ) : |
| XclImpRectObj( rRoot ) |
| { |
| } |
| |
| SdrObject* XclImpOvalObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const |
| { |
| SdrObjectPtr xSdrObj( new SdrCircObj( OBJ_CIRC, rAnchorRect ) ); |
| ConvertRectStyle( *xSdrObj ); |
| rDffConv.Progress(); |
| return xSdrObj.release(); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpArcObj::XclImpArcObj( const XclImpRoot& rRoot ) : |
| XclImpDrawObjBase( rRoot ), |
| mnQuadrant( EXC_OBJ_ARC_TR ) |
| { |
| SetAreaObj( false ); // arc may be 2-dimensional |
| } |
| |
| void XclImpArcObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| rStrm >> maFillData >> maLineData >> mnQuadrant; |
| rStrm.Ignore( 1 ); |
| ReadMacro3( rStrm, nMacroSize ); |
| } |
| |
| void XclImpArcObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| rStrm >> maFillData >> maLineData >> mnQuadrant; |
| rStrm.Ignore( 1 ); |
| ReadMacro4( rStrm, nMacroSize ); |
| } |
| |
| void XclImpArcObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) |
| { |
| rStrm >> maFillData >> maLineData >> mnQuadrant; |
| rStrm.Ignore( 1 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, nMacroSize ); |
| } |
| |
| SdrObject* XclImpArcObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const |
| { |
| Rectangle aNewRect = rAnchorRect; |
| long nStartAngle = 0; |
| long nEndAngle = 0; |
| switch( mnQuadrant ) |
| { |
| default: |
| case EXC_OBJ_ARC_TR: |
| nStartAngle = 0; |
| nEndAngle = 9000; |
| aNewRect.Left() -= rAnchorRect.GetWidth(); |
| aNewRect.Bottom() += rAnchorRect.GetHeight(); |
| break; |
| case EXC_OBJ_ARC_TL: |
| nStartAngle = 9000; |
| nEndAngle = 18000; |
| aNewRect.Right() += rAnchorRect.GetWidth(); |
| aNewRect.Bottom() += rAnchorRect.GetHeight(); |
| break; |
| case EXC_OBJ_ARC_BL: |
| nStartAngle = 18000; |
| nEndAngle = 27000; |
| aNewRect.Right() += rAnchorRect.GetWidth(); |
| aNewRect.Top() -= rAnchorRect.GetHeight(); |
| break; |
| case EXC_OBJ_ARC_BR: |
| nStartAngle = 27000; |
| nEndAngle = 0; |
| aNewRect.Left() -= rAnchorRect.GetWidth(); |
| aNewRect.Top() -= rAnchorRect.GetHeight(); |
| break; |
| } |
| SdrObjKind eObjKind = maFillData.IsFilled() ? OBJ_SECT : OBJ_CARC; |
| SdrObjectPtr xSdrObj( new SdrCircObj( eObjKind, aNewRect, nStartAngle, nEndAngle ) ); |
| ConvertFillStyle( *xSdrObj, maFillData ); |
| ConvertLineStyle( *xSdrObj, maLineData ); |
| rDffConv.Progress(); |
| return xSdrObj.release(); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpPolygonObj::XclImpPolygonObj( const XclImpRoot& rRoot ) : |
| XclImpRectObj( rRoot ), |
| mnPolyFlags( 0 ), |
| mnPointCount( 0 ) |
| { |
| SetAreaObj( false ); // polygon may be 2-dimensional |
| } |
| |
| void XclImpPolygonObj::ReadCoordList( XclImpStream& rStrm ) |
| { |
| if( (rStrm.GetNextRecId() == EXC_ID_COORDLIST) && rStrm.StartNextRecord() ) |
| { |
| DBG_ASSERT( rStrm.GetRecLeft() / 4 == mnPointCount, "XclImpPolygonObj::ReadCoordList - wrong polygon point count" ); |
| while( rStrm.GetRecLeft() >= 4 ) |
| { |
| sal_uInt16 nX, nY; |
| rStrm >> nX >> nY; |
| maCoords.push_back( Point( nX, nY ) ); |
| } |
| } |
| } |
| |
| void XclImpPolygonObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| ReadFrameData( rStrm ); |
| rStrm >> mnPolyFlags; |
| rStrm.Ignore( 10 ); |
| rStrm >> mnPointCount; |
| rStrm.Ignore( 8 ); |
| ReadMacro4( rStrm, nMacroSize ); |
| ReadCoordList( rStrm ); |
| } |
| |
| void XclImpPolygonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) |
| { |
| ReadFrameData( rStrm ); |
| rStrm >> mnPolyFlags; |
| rStrm.Ignore( 10 ); |
| rStrm >> mnPointCount; |
| rStrm.Ignore( 8 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, nMacroSize ); |
| ReadCoordList( rStrm ); |
| } |
| |
| namespace { |
| |
| ::basegfx::B2DPoint lclGetPolyPoint( const Rectangle& rAnchorRect, const Point& rPoint ) |
| { |
| return ::basegfx::B2DPoint( |
| rAnchorRect.Left() + static_cast< sal_Int32 >( ::std::min< double >( rPoint.X(), 16384.0 ) / 16384.0 * rAnchorRect.GetWidth() + 0.5 ), |
| rAnchorRect.Top() + static_cast< sal_Int32 >( ::std::min< double >( rPoint.Y(), 16384.0 ) / 16384.0 * rAnchorRect.GetHeight() + 0.5 ) ); |
| } |
| |
| } // namespace |
| |
| SdrObject* XclImpPolygonObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const |
| { |
| SdrObjectPtr xSdrObj; |
| if( maCoords.size() >= 2 ) |
| { |
| // create the polygon |
| ::basegfx::B2DPolygon aB2DPolygon; |
| for( PointVector::const_iterator aIt = maCoords.begin(), aEnd = maCoords.end(); aIt != aEnd; ++aIt ) |
| aB2DPolygon.append( lclGetPolyPoint( rAnchorRect, *aIt ) ); |
| // close polygon if specified |
| if( ::get_flag( mnPolyFlags, EXC_OBJ_POLY_CLOSED ) && (maCoords.front() != maCoords.back()) ) |
| aB2DPolygon.append( lclGetPolyPoint( rAnchorRect, maCoords.front() ) ); |
| // create the SdrObject |
| SdrObjKind eObjKind = maFillData.IsFilled() ? OBJ_PATHPOLY : OBJ_PATHPLIN; |
| xSdrObj.reset( new SdrPathObj( eObjKind, ::basegfx::B2DPolyPolygon( aB2DPolygon ) ) ); |
| ConvertRectStyle( *xSdrObj ); |
| } |
| rDffConv.Progress(); |
| return xSdrObj.release(); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| void XclImpObjTextData::ReadByteString( XclImpStream& rStrm ) |
| { |
| mxString.reset(); |
| if( maData.mnTextLen > 0 ) |
| { |
| mxString.reset( new XclImpString( rStrm.ReadRawByteString( maData.mnTextLen ) ) ); |
| // skip padding byte for word boundaries |
| if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 ); |
| } |
| } |
| |
| void XclImpObjTextData::ReadFormats( XclImpStream& rStrm ) |
| { |
| if( mxString.is() ) |
| mxString->ReadObjFormats( rStrm, maData.mnFormatSize ); |
| else |
| rStrm.Ignore( maData.mnFormatSize ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpTextObj::XclImpTextObj( const XclImpRoot& rRoot ) : |
| XclImpRectObj( rRoot ) |
| { |
| } |
| |
| void XclImpTextObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| ReadFrameData( rStrm ); |
| maTextData.maData.ReadObj3( rStrm ); |
| ReadMacro3( rStrm, nMacroSize ); |
| maTextData.ReadByteString( rStrm ); |
| maTextData.ReadFormats( rStrm ); |
| } |
| |
| void XclImpTextObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| ReadFrameData( rStrm ); |
| maTextData.maData.ReadObj3( rStrm ); |
| ReadMacro4( rStrm, nMacroSize ); |
| maTextData.ReadByteString( rStrm ); |
| maTextData.ReadFormats( rStrm ); |
| } |
| |
| void XclImpTextObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) |
| { |
| ReadFrameData( rStrm ); |
| maTextData.maData.ReadObj5( rStrm ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, nMacroSize ); |
| maTextData.ReadByteString( rStrm ); |
| rStrm.Ignore( maTextData.maData.mnLinkSize ); // ignore text link formula |
| maTextData.ReadFormats( rStrm ); |
| } |
| |
| SdrObject* XclImpTextObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const |
| { |
| TSdrObjectPtr< SdrObjCustomShape > xSdrObj( new SdrObjCustomShape ); |
| xSdrObj->NbcSetSnapRect( rAnchorRect ); |
| OUString aRectType = CREATE_OUSTRING( "rectangle" ); |
| xSdrObj->MergeDefaultAttributes( &aRectType ); |
| ConvertRectStyle( *xSdrObj ); |
| sal_Bool bAutoSize = ::get_flag( maTextData.maData.mnFlags, EXC_OBJ_TEXT_AUTOSIZE ); |
| xSdrObj->SetMergedItem( SdrTextAutoGrowWidthItem( bAutoSize ) ); |
| xSdrObj->SetMergedItem( SdrTextAutoGrowHeightItem( bAutoSize ) ); |
| xSdrObj->SetMergedItem( SdrTextWordWrapItem( sal_True ) ); |
| rDffConv.Progress(); |
| return xSdrObj.release(); |
| } |
| |
| void XclImpTextObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const |
| { |
| // set text data |
| if( SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( &rSdrObj ) ) |
| { |
| if( maTextData.mxString.is() ) |
| { |
| if( maTextData.mxString->IsRich() ) |
| { |
| // rich text |
| ::std::auto_ptr< EditTextObject > xEditObj( |
| XclImpStringHelper::CreateTextObject( GetRoot(), *maTextData.mxString ) ); |
| OutlinerParaObject* pOutlineObj = new OutlinerParaObject( *xEditObj ); |
| pOutlineObj->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT ); |
| // text object takes ownership of the outliner object |
| pTextObj->NbcSetOutlinerParaObject( pOutlineObj ); |
| } |
| else |
| { |
| // plain text |
| pTextObj->NbcSetText( maTextData.mxString->GetText() ); |
| } |
| |
| /* #i96858# Do not apply any formatting if there is no text. |
| SdrObjCustomShape::SetVerticalWriting (initiated from |
| SetMergedItem) calls SdrTextObj::ForceOutlinerParaObject which |
| ensures that we can erroneously write a ClientTextbox record |
| (with no content) while exporting to XLS, which can cause a |
| corrupted exported document. */ |
| |
| SvxAdjust eHorAlign = SVX_ADJUST_LEFT; |
| SdrTextVertAdjust eVerAlign = SDRTEXTVERTADJUST_TOP; |
| |
| // orientation (this is only a fake, drawing does not support real text orientation) |
| namespace csst = ::com::sun::star::text; |
| csst::WritingMode eWriteMode = csst::WritingMode_LR_TB; |
| switch( maTextData.maData.mnOrient ) |
| { |
| default: |
| case EXC_OBJ_ORIENT_NONE: |
| { |
| eWriteMode = csst::WritingMode_LR_TB; |
| switch( maTextData.maData.GetHorAlign() ) |
| { |
| case EXC_OBJ_HOR_LEFT: eHorAlign = SVX_ADJUST_LEFT; break; |
| case EXC_OBJ_HOR_CENTER: eHorAlign = SVX_ADJUST_CENTER; break; |
| case EXC_OBJ_HOR_RIGHT: eHorAlign = SVX_ADJUST_RIGHT; break; |
| case EXC_OBJ_HOR_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break; |
| } |
| switch( maTextData.maData.GetVerAlign() ) |
| { |
| case EXC_OBJ_VER_TOP: eVerAlign = SDRTEXTVERTADJUST_TOP; break; |
| case EXC_OBJ_VER_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break; |
| case EXC_OBJ_VER_BOTTOM: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break; |
| case EXC_OBJ_VER_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break; |
| } |
| } |
| break; |
| |
| case EXC_OBJ_ORIENT_90CCW: |
| { |
| if( SdrObjCustomShape* pObjCustomShape = dynamic_cast< SdrObjCustomShape* >( &rSdrObj ) ) |
| { |
| double fAngle = 180.0; |
| com::sun::star::beans::PropertyValue aTextRotateAngle; |
| aTextRotateAngle.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) ); |
| aTextRotateAngle.Value <<= fAngle; |
| SdrCustomShapeGeometryItem aGeometryItem((SdrCustomShapeGeometryItem&)pObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )); |
| aGeometryItem.SetPropertyValue( aTextRotateAngle ); |
| pObjCustomShape->SetMergedItem( aGeometryItem ); |
| } |
| eWriteMode = csst::WritingMode_TB_RL; |
| switch( maTextData.maData.GetHorAlign() ) |
| { |
| case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_TOP; break; |
| case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break; |
| case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break; |
| case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break; |
| } |
| MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); |
| switch( eTextAnchor ) |
| { |
| case mso_anchorTopCentered : |
| case mso_anchorMiddleCentered : |
| case mso_anchorBottomCentered : |
| { |
| eHorAlign = SVX_ADJUST_CENTER; |
| } |
| break; |
| |
| default: |
| { |
| switch( maTextData.maData.GetVerAlign() ) |
| { |
| case EXC_OBJ_VER_TOP: eHorAlign = SVX_ADJUST_RIGHT; break; |
| case EXC_OBJ_VER_CENTER: eHorAlign = SVX_ADJUST_CENTER; break; |
| case EXC_OBJ_VER_BOTTOM: eHorAlign = SVX_ADJUST_LEFT; break; |
| case EXC_OBJ_VER_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break; |
| } |
| } |
| } |
| } |
| break; |
| |
| case EXC_OBJ_ORIENT_STACKED: // PASSTHROUGH INTENDED |
| { |
| // sj: STACKED is not supported, maybe it can be optimized here a bit |
| } |
| case EXC_OBJ_ORIENT_90CW: |
| { |
| eWriteMode = csst::WritingMode_TB_RL; |
| switch( maTextData.maData.GetHorAlign() ) |
| { |
| case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break; |
| case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break; |
| case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_TOP; break; |
| case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break; |
| } |
| MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); |
| switch ( eTextAnchor ) |
| { |
| case mso_anchorTopCentered : |
| case mso_anchorMiddleCentered : |
| case mso_anchorBottomCentered : |
| { |
| eHorAlign = SVX_ADJUST_CENTER; |
| } |
| break; |
| |
| default: |
| { |
| switch( maTextData.maData.GetVerAlign() ) |
| { |
| case EXC_OBJ_VER_TOP: eHorAlign = SVX_ADJUST_LEFT; break; |
| case EXC_OBJ_VER_CENTER: eHorAlign = SVX_ADJUST_CENTER; break; |
| case EXC_OBJ_VER_BOTTOM: eHorAlign = SVX_ADJUST_RIGHT; break; |
| case EXC_OBJ_VER_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break; |
| } |
| } |
| } |
| } |
| break; |
| } |
| rSdrObj.SetMergedItem( SvxAdjustItem( eHorAlign, EE_PARA_JUST ) ); |
| rSdrObj.SetMergedItem( SdrTextVertAdjustItem( eVerAlign ) ); |
| rSdrObj.SetMergedItem( SvxWritingModeItem( eWriteMode, SDRATTR_TEXTDIRECTION ) ); |
| } |
| } |
| // base class processing |
| XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpChartObj::XclImpChartObj( const XclImpRoot& rRoot, bool bOwnTab ) : |
| XclImpRectObj( rRoot ), |
| mbOwnTab( bOwnTab ) |
| { |
| SetSimpleMacro( false ); |
| SetCustomDffObj( true ); |
| } |
| |
| void XclImpChartObj::ReadChartSubStream( XclImpStream& rStrm ) |
| { |
| /* If chart is read from a chartsheet (mbOwnTab == true), the BOF record |
| has already been read. If chart is embedded as object, the next record |
| has to be the BOF record. */ |
| if( mbOwnTab ) |
| { |
| /* #i109800# The input stream may point somewhere inside the chart |
| substream and not exactly to the leading BOF record. To read this |
| record correctly in the following, the stream has to rewind it, so |
| that the next call to StartNextRecord() will find it correctly. */ |
| if( rStrm.GetRecId() != EXC_ID5_BOF ) |
| rStrm.RewindRecord(); |
| } |
| else |
| { |
| if( (rStrm.GetNextRecId() == EXC_ID5_BOF) && rStrm.StartNextRecord() ) |
| { |
| sal_uInt16 nBofType; |
| rStrm.Seek( 2 ); |
| rStrm >> nBofType; |
| DBG_ASSERT( nBofType == EXC_BOF_CHART, "XclImpChartObj::ReadChartSubStream - no chart BOF record" ); |
| } |
| else |
| { |
| DBG_ERRORFILE( "XclImpChartObj::ReadChartSubStream - missing chart substream" ); |
| return; |
| } |
| } |
| |
| // read chart, even if BOF record contains wrong substream identifier |
| mxChart.reset( new XclImpChart( GetRoot(), mbOwnTab ) ); |
| mxChart->ReadChartSubStream( rStrm ); |
| if( mbOwnTab ) |
| FinalizeTabChart(); |
| } |
| |
| void XclImpChartObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| // read OBJ record and the following chart substream |
| ReadFrameData( rStrm ); |
| rStrm.Ignore( 18 ); |
| ReadMacro3( rStrm, nMacroSize ); |
| #if 0 |
| ReadChartSubStream( rStrm ); |
| #endif |
| // set frame format from OBJ record, it is used if chart itself is transparent |
| if( mxChart.is() ) |
| mxChart->UpdateObjFrame( maLineData, maFillData ); |
| } |
| |
| void XclImpChartObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| // read OBJ record and the following chart substream |
| ReadFrameData( rStrm ); |
| rStrm.Ignore( 18 ); |
| ReadMacro4( rStrm, nMacroSize ); |
| #if 0 |
| ReadChartSubStream( rStrm ); |
| #endif |
| // set frame format from OBJ record, it is used if chart itself is transparent |
| if( mxChart.is() ) |
| mxChart->UpdateObjFrame( maLineData, maFillData ); |
| } |
| |
| void XclImpChartObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) |
| { |
| // read OBJ record and the following chart substream |
| ReadFrameData( rStrm ); |
| rStrm.Ignore( 18 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, nMacroSize ); |
| ReadChartSubStream( rStrm ); |
| // set frame format from OBJ record, it is used if chart itself is transparent |
| if( mxChart.is() ) |
| mxChart->UpdateObjFrame( maLineData, maFillData ); |
| } |
| |
| void XclImpChartObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 /*nSubRecSize*/ ) |
| { |
| // read the following chart substream |
| if( nSubRecId == EXC_ID_OBJEND ) |
| { |
| // enable CONTINUE handling for the entire chart substream |
| rStrm.ResetRecord( true ); |
| ReadChartSubStream( rStrm ); |
| /* #90118# disable CONTINUE handling again to be able to read |
| following CONTINUE records as MSODRAWING records. */ |
| rStrm.ResetRecord( false ); |
| } |
| } |
| |
| sal_Size XclImpChartObj::DoGetProgressSize() const |
| { |
| return mxChart.is() ? mxChart->GetProgressSize() : 1; |
| } |
| |
| SdrObject* XclImpChartObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const |
| { |
| SdrObjectPtr xSdrObj; |
| SfxObjectShell* pDocShell = GetDocShell(); |
| if( rDffConv.SupportsOleObjects() && SvtModuleOptions().IsChart() && pDocShell && mxChart.is() && !mxChart->IsPivotChart() ) |
| { |
| // create embedded chart object |
| OUString aEmbObjName; |
| Reference< XEmbeddedObject > xEmbObj = pDocShell->GetEmbeddedObjectContainer(). |
| CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aEmbObjName ); |
| |
| /* Set the size to the embedded object, this prevents that font sizes |
| of text objects are changed in the chart when the object is |
| inserted into the draw page. */ |
| sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT; |
| MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xEmbObj->getMapUnit( nAspect ) ); |
| Size aSize( Window::LogicToLogic( rAnchorRect.GetSize(), MapMode( MAP_100TH_MM ), MapMode( aUnit ) ) ); |
| ::com::sun::star::awt::Size aAwtSize( aSize.Width(), aSize.Height() ); |
| xEmbObj->setVisualAreaSize( nAspect, aAwtSize ); |
| |
| // #121334# This call will change the chart's default background fill from white to transparent. |
| // Add here again if this is wanted (see task description for details) |
| // ChartHelper::AdaptDefaultsForChart( xEmbObj ); |
| |
| // create the container OLE object |
| xSdrObj.reset( new SdrOle2Obj( svt::EmbeddedObjectRef( xEmbObj, nAspect ), aEmbObjName, rAnchorRect ) ); |
| } |
| |
| return xSdrObj.release(); |
| } |
| |
| 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& ) |
| { |
| } |
| } |
| } |
| |
| void XclImpChartObj::FinalizeTabChart() |
| { |
| /* #i44077# Calculate and store DFF anchor for sheet charts. |
| Needed to get used area if this chart is inserted as OLE object. */ |
| DBG_ASSERT( mbOwnTab, "XclImpChartObj::FinalizeTabChart - not allowed for embedded chart objects" ); |
| |
| // set uninitialized page to landscape |
| if( !GetPageSettings().GetPageData().mbValid ) |
| GetPageSettings().SetPaperSize( EXC_PAPERSIZE_DEFAULT, false ); |
| |
| // calculate size of the chart object |
| const XclPageData& rPageData = GetPageSettings().GetPageData(); |
| Size aPaperSize = rPageData.GetScPaperSize(); |
| |
| long nWidth = XclTools::GetHmmFromTwips( aPaperSize.Width() ); |
| long nHeight = XclTools::GetHmmFromTwips( aPaperSize.Height() ); |
| |
| // subtract page margins, give some more extra space |
| nWidth -= (XclTools::GetHmmFromInch( rPageData.mfLeftMargin + rPageData.mfRightMargin ) + 2000); |
| nHeight -= (XclTools::GetHmmFromInch( rPageData.mfTopMargin + rPageData.mfBottomMargin ) + 1000); |
| |
| // print column/row headers? |
| if( rPageData.mbPrintHeadings ) |
| { |
| nWidth -= 2000; |
| nHeight -= 1000; |
| } |
| |
| // create the object anchor |
| XclObjAnchor aAnchor; |
| aAnchor.SetRect( GetRoot(), GetCurrScTab(), Rectangle( 1000, 500, nWidth, nHeight ), MAP_100TH_MM ); |
| SetAnchor( aAnchor ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpNoteObj::XclImpNoteObj( const XclImpRoot& rRoot ) : |
| XclImpTextObj( rRoot ), |
| maScPos( ScAddress::INITIALIZE_INVALID ), |
| mnNoteFlags( 0 ) |
| { |
| SetSimpleMacro( false ); |
| // caption object will be created manually |
| SetInsertSdrObj( false ); |
| } |
| |
| void XclImpNoteObj::SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags ) |
| { |
| maScPos = rScPos; |
| mnNoteFlags = nNoteFlags; |
| } |
| |
| void XclImpNoteObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const |
| { |
| // create formatted text |
| XclImpTextObj::DoPreProcessSdrObj( rDffConv, rSdrObj ); |
| OutlinerParaObject* pOutlinerObj = rSdrObj.GetOutlinerParaObject(); |
| if( maScPos.IsValid() && pOutlinerObj ) |
| { |
| // create cell note with all data from drawing object |
| ScNoteUtil::CreateNoteFromObjectData( |
| GetDoc(), maScPos, |
| rSdrObj.GetMergedItemSet().Clone(), // new object on heap expected |
| new OutlinerParaObject( *pOutlinerObj ), // new object on heap expected |
| rSdrObj.GetLogicRect(), |
| ::get_flag( mnNoteFlags, EXC_NOTE_VISIBLE ), |
| false ); |
| } |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpControlHelper::XclImpControlHelper( const XclImpRoot& rRoot, XclCtrlBindMode eBindMode ) : |
| mrRoot( rRoot ), |
| meBindMode( eBindMode ) |
| { |
| } |
| |
| XclImpControlHelper::~XclImpControlHelper() |
| { |
| } |
| |
| SdrObject* XclImpControlHelper::CreateSdrObjectFromShape( |
| const Reference< XShape >& rxShape, const Rectangle& rAnchorRect ) const |
| { |
| mxShape = rxShape; |
| SdrObjectPtr xSdrObj( SdrObject::getSdrObjectFromXShape( rxShape ) ); |
| if( xSdrObj.is() ) |
| { |
| xSdrObj->NbcSetSnapRect( rAnchorRect ); |
| // #i30543# insert into control layer |
| xSdrObj->NbcSetLayer( SC_LAYER_CONTROLS ); |
| } |
| return xSdrObj.release(); |
| } |
| |
| void XclImpControlHelper::ProcessControl( const XclImpDrawObjBase& rDrawObj ) const |
| { |
| Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( mxShape ); |
| if( !xCtrlModel.is() ) |
| return; |
| |
| ScfPropertySet aPropSet( xCtrlModel ); |
| |
| // #118053# #i51348# set object name at control model |
| aPropSet.SetStringProperty( CREATE_OUSTRING( "Name" ), rDrawObj.GetObjName() ); |
| |
| // control visible and printable? |
| aPropSet.SetBoolProperty( CREATE_OUSTRING( "EnableVisible" ), rDrawObj.IsVisible() ); |
| aPropSet.SetBoolProperty( CREATE_OUSTRING( "Printable" ), rDrawObj.IsPrintable() ); |
| |
| // sheet links |
| if( SfxObjectShell* pDocShell = mrRoot.GetDocShell() ) |
| { |
| Reference< XMultiServiceFactory > xFactory( pDocShell->GetModel(), UNO_QUERY ); |
| if( xFactory.is() ) |
| { |
| // cell link |
| if( mxCellLink.is() ) try |
| { |
| Reference< XBindableValue > xBindable( xCtrlModel, UNO_QUERY_THROW ); |
| |
| // create argument sequence for createInstanceWithArguments() |
| CellAddress aApiAddress; |
| ScUnoConversion::FillApiAddress( aApiAddress, *mxCellLink ); |
| |
| NamedValue aValue; |
| aValue.Name = CREATE_OUSTRING( SC_UNONAME_BOUNDCELL ); |
| aValue.Value <<= aApiAddress; |
| |
| Sequence< Any > aArgs( 1 ); |
| aArgs[ 0 ] <<= aValue; |
| |
| // create the CellValueBinding instance and set at the control model |
| OUString aServiceName; |
| switch( meBindMode ) |
| { |
| case EXC_CTRL_BINDCONTENT: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_VALBIND ); break; |
| case EXC_CTRL_BINDPOSITION: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_LISTCELLBIND ); break; |
| } |
| Reference< XValueBinding > xBinding( |
| xFactory->createInstanceWithArguments( aServiceName, aArgs ), UNO_QUERY_THROW ); |
| xBindable->setValueBinding( xBinding ); |
| } |
| catch( const Exception& ) |
| { |
| } |
| |
| // source range |
| if( mxSrcRange.is() ) try |
| { |
| Reference< XListEntrySink > xEntrySink( xCtrlModel, UNO_QUERY_THROW ); |
| |
| // create argument sequence for createInstanceWithArguments() |
| CellRangeAddress aApiRange; |
| ScUnoConversion::FillApiRange( aApiRange, *mxSrcRange ); |
| |
| NamedValue aValue; |
| aValue.Name = CREATE_OUSTRING( SC_UNONAME_CELLRANGE ); |
| aValue.Value <<= aApiRange; |
| |
| Sequence< Any > aArgs( 1 ); |
| aArgs[ 0 ] <<= aValue; |
| |
| // create the EntrySource instance and set at the control model |
| Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments( |
| CREATE_OUSTRING( SC_SERVICENAME_LISTSOURCE ), aArgs ), UNO_QUERY_THROW ); |
| xEntrySink->setListEntrySource( xEntrySource ); |
| } |
| catch( const Exception& ) |
| { |
| } |
| } |
| } |
| |
| // virtual call for type specific processing |
| DoProcessControl( aPropSet ); |
| } |
| |
| void XclImpControlHelper::ReadCellLinkFormula( XclImpStream& rStrm, bool bWithBoundSize ) |
| { |
| ScRangeList aScRanges; |
| ReadRangeList( aScRanges, rStrm, bWithBoundSize ); |
| // Use first cell of first range |
| if( const ScRange* pScRange = aScRanges.GetObject( 0 ) ) |
| mxCellLink.reset( new ScAddress( pScRange->aStart ) ); |
| } |
| |
| void XclImpControlHelper::ReadSourceRangeFormula( XclImpStream& rStrm, bool bWithBoundSize ) |
| { |
| ScRangeList aScRanges; |
| ReadRangeList( aScRanges, rStrm, bWithBoundSize ); |
| // Use first range |
| if( const ScRange* pScRange = aScRanges.GetObject( 0 ) ) |
| mxSrcRange.reset( new ScRange( *pScRange ) ); |
| } |
| |
| void XclImpControlHelper::DoProcessControl( ScfPropertySet& ) const |
| { |
| } |
| |
| void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm ) |
| { |
| XclTokenArray aXclTokArr; |
| aXclTokArr.ReadSize( rStrm ); |
| rStrm.Ignore( 4 ); |
| aXclTokArr.ReadArray( rStrm ); |
| mrRoot.GetFormulaCompiler().CreateRangeList( rScRanges, EXC_FMLATYPE_CONTROL, aXclTokArr, rStrm ); |
| } |
| |
| void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm, bool bWithBoundSize ) |
| { |
| if( bWithBoundSize ) |
| { |
| sal_uInt16 nSize; |
| rStrm >> nSize; |
| if( nSize > 0 ) |
| { |
| rStrm.PushPosition(); |
| ReadRangeList( rScRanges, rStrm ); |
| rStrm.PopPosition(); |
| rStrm.Ignore( nSize ); |
| } |
| } |
| else |
| { |
| ReadRangeList( rScRanges, rStrm ); |
| } |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpTbxObjBase::XclImpTbxObjBase( const XclImpRoot& rRoot ) : |
| XclImpTextObj( rRoot ), |
| XclImpControlHelper( rRoot, EXC_CTRL_BINDPOSITION ) |
| { |
| SetSimpleMacro( false ); |
| SetCustomDffObj( true ); |
| } |
| |
| namespace { |
| |
| void lclExtractColor( sal_uInt8& rnColorIdx, const DffPropSet& rDffPropSet, sal_uInt32 nPropId ) |
| { |
| if( rDffPropSet.IsProperty( nPropId ) ) |
| { |
| sal_uInt32 nColor = rDffPropSet.GetPropertyValue( nPropId ); |
| if( (nColor & 0xFF000000) == 0x08000000 ) |
| rnColorIdx = ::extract_value< sal_uInt8 >( nColor, 0, 8 ); |
| } |
| } |
| |
| } // namespace |
| |
| void XclImpTbxObjBase::SetDffProperties( const DffPropSet& rDffPropSet ) |
| { |
| maFillData.mnPattern = rDffPropSet.GetPropertyBool( DFF_Prop_fFilled ) ? EXC_PATT_SOLID : EXC_PATT_NONE; |
| lclExtractColor( maFillData.mnBackColorIdx, rDffPropSet, DFF_Prop_fillBackColor ); |
| lclExtractColor( maFillData.mnPattColorIdx, rDffPropSet, DFF_Prop_fillColor ); |
| ::set_flag( maFillData.mnAuto, EXC_OBJ_LINE_AUTO, false ); |
| |
| maLineData.mnStyle = rDffPropSet.GetPropertyBool( DFF_Prop_fLine ) ? EXC_OBJ_LINE_SOLID : EXC_OBJ_LINE_NONE; |
| lclExtractColor( maLineData.mnColorIdx, rDffPropSet, DFF_Prop_lineColor ); |
| ::set_flag( maLineData.mnAuto, EXC_OBJ_FILL_AUTO, false ); |
| } |
| |
| bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor ) const |
| { |
| return XclControlHelper::FillMacroDescriptor( rDescriptor, DoGetEventType(), GetMacroName(), GetDocShell() ); |
| } |
| |
| void XclImpTbxObjBase::ConvertFont( ScfPropertySet& rPropSet ) const |
| { |
| if( maTextData.mxString.is() ) |
| { |
| const XclFormatRunVec& rFormatRuns = maTextData.mxString->GetFormats(); |
| if( rFormatRuns.empty() ) |
| GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet ); |
| else |
| GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, rFormatRuns.front().mnFontIdx ); |
| } |
| } |
| |
| void XclImpTbxObjBase::ConvertLabel( ScfPropertySet& rPropSet ) const |
| { |
| if( maTextData.mxString.is() ) |
| { |
| String aLabel = maTextData.mxString->GetText(); |
| if( maTextData.maData.mnShortcut > 0 ) |
| { |
| xub_StrLen nPos = aLabel.Search( static_cast< sal_Unicode >( maTextData.maData.mnShortcut ) ); |
| if( nPos != STRING_NOTFOUND ) |
| aLabel.Insert( '~', nPos ); |
| } |
| rPropSet.SetStringProperty( CREATE_OUSTRING( "Label" ), aLabel ); |
| |
| //Excel Alt text <==> Aoo description |
| //For TBX control, if user does not operate alt text, alt text will be set label text as default value in Excel. |
| //In this case, DFF_Prop_wzDescription will not be set in excel file. |
| //So In the end of SvxMSDffManager::ImportShape, description will not be set. But actually in excel, |
| //the alt text is the label value. So here set description as label text first which is called before ImportShape. |
| Reference< ::com::sun::star::beans::XPropertySet > xPropset( mxShape, UNO_QUERY ); |
| try{ |
| if(xPropset.is()) |
| xPropset->setPropertyValue( CREATE_OUSTRING( "Description" ), makeAny(::rtl::OUString(aLabel)) ); |
| }catch( ... ) |
| { |
| OSL_TRACE( " Can't set a default text for TBX Control "); |
| } |
| } |
| ConvertFont( rPropSet ); |
| } |
| |
| SdrObject* XclImpTbxObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const |
| { |
| SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) ); |
| rDffConv.Progress(); |
| return xSdrObj.release(); |
| } |
| |
| void XclImpTbxObjBase::DoPreProcessSdrObj( XclImpDffConverter& /*rDffConv*/, SdrObject& /*rSdrObj*/ ) const |
| { |
| // do not call DoPreProcessSdrObj() from base class (to skip text processing) |
| ProcessControl( *this ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpButtonObj::XclImpButtonObj( const XclImpRoot& rRoot ) : |
| XclImpTbxObjBase( rRoot ) |
| { |
| } |
| |
| void XclImpButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const |
| { |
| // label and text formatting |
| ConvertLabel( rPropSet ); |
| |
| /* Horizontal text alignment. For unknown reason, the property type is a |
| simple sal_Int16 and not a com.sun.star.style.HorizontalAlignment. */ |
| sal_Int16 nHorAlign = 1; |
| switch( maTextData.maData.GetHorAlign() ) |
| { |
| case EXC_OBJ_HOR_LEFT: nHorAlign = 0; break; |
| case EXC_OBJ_HOR_CENTER: nHorAlign = 1; break; |
| case EXC_OBJ_HOR_RIGHT: nHorAlign = 2; break; |
| } |
| rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), nHorAlign ); |
| |
| // vertical text alignment |
| namespace csss = ::com::sun::star::style; |
| csss::VerticalAlignment eVerAlign = csss::VerticalAlignment_MIDDLE; |
| switch( maTextData.maData.GetVerAlign() ) |
| { |
| case EXC_OBJ_VER_TOP: eVerAlign = csss::VerticalAlignment_TOP; break; |
| case EXC_OBJ_VER_CENTER: eVerAlign = csss::VerticalAlignment_MIDDLE; break; |
| case EXC_OBJ_VER_BOTTOM: eVerAlign = csss::VerticalAlignment_BOTTOM; break; |
| } |
| rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), eVerAlign ); |
| |
| // always wrap text automatically |
| rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true ); |
| |
| // default button |
| bool bDefButton = ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_DEFAULT ); |
| rPropSet.SetBoolProperty( CREATE_OUSTRING( "DefaultButton" ), bDefButton ); |
| |
| // button type (flags cannot be combined in OOo) |
| namespace cssa = ::com::sun::star::awt; |
| cssa::PushButtonType eButtonType = cssa::PushButtonType_STANDARD; |
| if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CLOSE ) ) |
| eButtonType = cssa::PushButtonType_OK; |
| else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CANCEL ) ) |
| eButtonType = cssa::PushButtonType_CANCEL; |
| else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_HELP ) ) |
| eButtonType = cssa::PushButtonType_HELP; |
| // property type is short, not enum |
| rPropSet.SetProperty( CREATE_OUSTRING( "PushButtonType" ), sal_Int16( eButtonType ) ); |
| } |
| |
| OUString XclImpButtonObj::DoGetServiceName() const |
| { |
| return CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" ); |
| } |
| |
| XclTbxEventType XclImpButtonObj::DoGetEventType() const |
| { |
| return EXC_TBX_EVENT_ACTION; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpCheckBoxObj::XclImpCheckBoxObj( const XclImpRoot& rRoot ) : |
| XclImpTbxObjBase( rRoot ), |
| mnState( EXC_OBJ_CHECKBOX_UNCHECKED ), |
| mnCheckBoxFlags( 0 ) |
| { |
| } |
| |
| void XclImpCheckBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ ) |
| { |
| ReadFrameData( rStrm ); |
| rStrm.Ignore( 10 ); |
| rStrm >> maTextData.maData.mnFlags; |
| rStrm.Ignore( 20 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused |
| ReadCellLinkFormula( rStrm, true ); |
| rStrm >> maTextData.maData.mnTextLen; |
| maTextData.ReadByteString( rStrm ); |
| rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags; |
| } |
| |
| void XclImpCheckBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize ) |
| { |
| switch( nSubRecId ) |
| { |
| case EXC_ID_OBJCBLS: |
| // do not read EXC_ID_OBJCBLSDATA, not written by OOo Excel export |
| rStrm >> mnState; |
| rStrm.Ignore( 4 ); |
| rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags; |
| break; |
| case EXC_ID_OBJCBLSFMLA: |
| ReadCellLinkFormula( rStrm, false ); |
| break; |
| default: |
| XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize ); |
| } |
| } |
| |
| void XclImpCheckBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const |
| { |
| // label and text formatting |
| ConvertLabel( rPropSet ); |
| |
| // state |
| bool bSupportsTristate = GetObjType() == EXC_OBJTYPE_CHECKBOX; |
| sal_Int16 nApiState = 0; |
| switch( mnState ) |
| { |
| case EXC_OBJ_CHECKBOX_UNCHECKED: nApiState = 0; break; |
| case EXC_OBJ_CHECKBOX_CHECKED: nApiState = 1; break; |
| case EXC_OBJ_CHECKBOX_TRISTATE: nApiState = bSupportsTristate ? 2 : 1; break; |
| } |
| if( bSupportsTristate ) |
| rPropSet.SetBoolProperty( CREATE_OUSTRING( "TriState" ), nApiState == 2 ); |
| rPropSet.SetProperty( CREATE_OUSTRING( "DefaultState" ), nApiState ); |
| |
| // box style |
| namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect; |
| sal_Int16 nEffect = ::get_flagvalue( mnCheckBoxFlags, EXC_OBJ_CHECKBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D ); |
| rPropSet.SetProperty( CREATE_OUSTRING( "VisualEffect" ), nEffect ); |
| |
| // do not wrap text automatically |
| rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), false ); |
| |
| // #i40279# always centered vertically |
| namespace csss = ::com::sun::star::style; |
| rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_MIDDLE ); |
| |
| // background color |
| if( maFillData.IsFilled() ) |
| { |
| sal_Int32 nColor = static_cast< sal_Int32 >( GetSolidFillColor( maFillData ).GetColor() ); |
| rPropSet.SetProperty( CREATE_OUSTRING( "BackgroundColor" ), nColor ); |
| } |
| } |
| |
| OUString XclImpCheckBoxObj::DoGetServiceName() const |
| { |
| return CREATE_OUSTRING( "com.sun.star.form.component.CheckBox" ); |
| } |
| |
| XclTbxEventType XclImpCheckBoxObj::DoGetEventType() const |
| { |
| return EXC_TBX_EVENT_ACTION; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpOptionButtonObj::XclImpOptionButtonObj( const XclImpRoot& rRoot ) : |
| XclImpCheckBoxObj( rRoot ), |
| mnNextInGroup( 0 ), |
| mnFirstInGroup( 1 ) |
| { |
| } |
| |
| void XclImpOptionButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ ) |
| { |
| ReadFrameData( rStrm ); |
| rStrm.Ignore( 10 ); |
| rStrm >> maTextData.maData.mnFlags; |
| rStrm.Ignore( 32 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused |
| ReadCellLinkFormula( rStrm, true ); |
| rStrm >> maTextData.maData.mnTextLen; |
| maTextData.ReadByteString( rStrm ); |
| rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA; |
| rStrm >> mnCheckBoxFlags >> mnNextInGroup >> mnFirstInGroup; |
| } |
| |
| void XclImpOptionButtonObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize ) |
| { |
| switch( nSubRecId ) |
| { |
| case EXC_ID_OBJRBODATA: |
| rStrm >> mnNextInGroup >> mnFirstInGroup; |
| break; |
| default: |
| XclImpCheckBoxObj::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize ); |
| } |
| } |
| |
| void XclImpOptionButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const |
| { |
| XclImpCheckBoxObj::DoProcessControl( rPropSet ); |
| // TODO: grouping |
| } |
| |
| OUString XclImpOptionButtonObj::DoGetServiceName() const |
| { |
| return CREATE_OUSTRING( "com.sun.star.form.component.RadioButton" ); |
| } |
| |
| XclTbxEventType XclImpOptionButtonObj::DoGetEventType() const |
| { |
| return EXC_TBX_EVENT_ACTION; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpLabelObj::XclImpLabelObj( const XclImpRoot& rRoot ) : |
| XclImpTbxObjBase( rRoot ) |
| { |
| } |
| |
| void XclImpLabelObj::DoProcessControl( ScfPropertySet& rPropSet ) const |
| { |
| // label and text formatting |
| ConvertLabel( rPropSet ); |
| |
| // text alignment (always top/left aligned) |
| rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), sal_Int16( 0 ) ); |
| namespace csss = ::com::sun::star::style; |
| rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_TOP ); |
| |
| // always wrap text automatically |
| rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true ); |
| } |
| |
| OUString XclImpLabelObj::DoGetServiceName() const |
| { |
| return CREATE_OUSTRING( "com.sun.star.form.component.FixedText" ); |
| } |
| |
| XclTbxEventType XclImpLabelObj::DoGetEventType() const |
| { |
| return EXC_TBX_EVENT_MOUSE; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpGroupBoxObj::XclImpGroupBoxObj( const XclImpRoot& rRoot ) : |
| XclImpTbxObjBase( rRoot ), |
| mnGroupBoxFlags( 0 ) |
| { |
| } |
| |
| void XclImpGroupBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ ) |
| { |
| ReadFrameData( rStrm ); |
| rStrm.Ignore( 10 ); |
| rStrm >> maTextData.maData.mnFlags; |
| rStrm.Ignore( 26 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused |
| rStrm >> maTextData.maData.mnTextLen; |
| maTextData.ReadByteString( rStrm ); |
| rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags; |
| } |
| |
| void XclImpGroupBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize ) |
| { |
| switch( nSubRecId ) |
| { |
| case EXC_ID_OBJGBODATA: |
| rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags; |
| break; |
| default: |
| XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize ); |
| } |
| } |
| |
| void XclImpGroupBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const |
| { |
| // label and text formatting |
| ConvertLabel( rPropSet ); |
| } |
| |
| OUString XclImpGroupBoxObj::DoGetServiceName() const |
| { |
| return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" ); |
| } |
| |
| XclTbxEventType XclImpGroupBoxObj::DoGetEventType() const |
| { |
| return EXC_TBX_EVENT_MOUSE; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpDialogObj::XclImpDialogObj( const XclImpRoot& rRoot ) : |
| XclImpTbxObjBase( rRoot ) |
| { |
| } |
| |
| void XclImpDialogObj::DoProcessControl( ScfPropertySet& rPropSet ) const |
| { |
| // label and text formatting |
| ConvertLabel( rPropSet ); |
| } |
| |
| OUString XclImpDialogObj::DoGetServiceName() const |
| { |
| // dialog frame faked by a groupbox |
| return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" ); |
| } |
| |
| XclTbxEventType XclImpDialogObj::DoGetEventType() const |
| { |
| return EXC_TBX_EVENT_MOUSE; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpEditObj::XclImpEditObj( const XclImpRoot& rRoot ) : |
| XclImpTbxObjBase( rRoot ), |
| mnContentType( EXC_OBJ_EDIT_TEXT ), |
| mnMultiLine( 0 ), |
| mnScrollBar( 0 ), |
| mnListBoxObjId( 0 ) |
| { |
| } |
| |
| bool XclImpEditObj::IsNumeric() const |
| { |
| return (mnContentType == EXC_OBJ_EDIT_INTEGER) || (mnContentType == EXC_OBJ_EDIT_DOUBLE); |
| } |
| |
| void XclImpEditObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ ) |
| { |
| ReadFrameData( rStrm ); |
| rStrm.Ignore( 10 ); |
| rStrm >> maTextData.maData.mnFlags; |
| rStrm.Ignore( 14 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused |
| rStrm >> maTextData.maData.mnTextLen; |
| maTextData.ReadByteString( rStrm ); |
| rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId; |
| } |
| |
| void XclImpEditObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize ) |
| { |
| switch( nSubRecId ) |
| { |
| case EXC_ID_OBJEDODATA: |
| rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId; |
| break; |
| default: |
| XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize ); |
| } |
| } |
| |
| void XclImpEditObj::DoProcessControl( ScfPropertySet& rPropSet ) const |
| { |
| if( maTextData.mxString.is() ) |
| { |
| OUString aText = maTextData.mxString->GetText(); |
| if( IsNumeric() ) |
| { |
| // TODO: OUString::toDouble() does not handle local decimal separator |
| rPropSet.SetProperty( CREATE_OUSTRING( "DefaultValue" ), aText.toDouble() ); |
| rPropSet.SetBoolProperty( CREATE_OUSTRING( "Spin" ), mnScrollBar != 0 ); |
| } |
| else |
| { |
| rPropSet.SetProperty( CREATE_OUSTRING( "DefaultText" ), aText ); |
| rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), mnMultiLine != 0 ); |
| rPropSet.SetBoolProperty( CREATE_OUSTRING( "VScroll" ), mnScrollBar != 0 ); |
| } |
| } |
| ConvertFont( rPropSet ); |
| } |
| |
| OUString XclImpEditObj::DoGetServiceName() const |
| { |
| return IsNumeric() ? |
| CREATE_OUSTRING( "com.sun.star.form.component.NumericField" ) : |
| CREATE_OUSTRING( "com.sun.star.form.component.TextField" ); |
| } |
| |
| XclTbxEventType XclImpEditObj::DoGetEventType() const |
| { |
| return EXC_TBX_EVENT_TEXT; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpTbxObjScrollableBase::XclImpTbxObjScrollableBase( const XclImpRoot& rRoot ) : |
| XclImpTbxObjBase( rRoot ), |
| mnValue( 0 ), |
| mnMin( 0 ), |
| mnMax( 100 ), |
| mnStep( 1 ), |
| mnPageStep( 10 ), |
| mnOrient( 0 ), |
| mnThumbWidth( 1 ), |
| mnScrollFlags( 0 ) |
| { |
| } |
| |
| void XclImpTbxObjScrollableBase::ReadSbs( XclImpStream& rStrm ) |
| { |
| rStrm.Ignore( 4 ); |
| rStrm >> mnValue >> mnMin >> mnMax >> mnStep >> mnPageStep >> mnOrient >> mnThumbWidth >> mnScrollFlags; |
| } |
| |
| void XclImpTbxObjScrollableBase::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize ) |
| { |
| switch( nSubRecId ) |
| { |
| case EXC_ID_OBJSBS: |
| ReadSbs( rStrm ); |
| break; |
| case EXC_ID_OBJSBSFMLA: |
| ReadCellLinkFormula( rStrm, false ); |
| break; |
| default: |
| XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize ); |
| } |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpSpinButtonObj::XclImpSpinButtonObj( const XclImpRoot& rRoot ) : |
| XclImpTbxObjScrollableBase( rRoot ) |
| { |
| } |
| |
| void XclImpSpinButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ ) |
| { |
| ReadFrameData( rStrm ); |
| ReadSbs( rStrm ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused |
| ReadCellLinkFormula( rStrm, true ); |
| } |
| |
| void XclImpSpinButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const |
| { |
| // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#) |
| rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE ); |
| rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultSpinValue" ), mnValue ); |
| rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMin" ), mnMin ); |
| rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMax" ), mnMax ); |
| rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinIncrement" ), mnStep ); |
| |
| // Excel spin buttons always vertical |
| rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), ::com::sun::star::awt::ScrollBarOrientation::VERTICAL ); |
| } |
| |
| OUString XclImpSpinButtonObj::DoGetServiceName() const |
| { |
| return CREATE_OUSTRING( "com.sun.star.form.component.SpinButton" ); |
| } |
| |
| XclTbxEventType XclImpSpinButtonObj::DoGetEventType() const |
| { |
| return EXC_TBX_EVENT_VALUE; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpScrollBarObj::XclImpScrollBarObj( const XclImpRoot& rRoot ) : |
| XclImpTbxObjScrollableBase( rRoot ) |
| { |
| } |
| |
| void XclImpScrollBarObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ ) |
| { |
| ReadFrameData( rStrm ); |
| ReadSbs( rStrm ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused |
| ReadCellLinkFormula( rStrm, true ); |
| } |
| |
| void XclImpScrollBarObj::DoProcessControl( ScfPropertySet& rPropSet ) const |
| { |
| // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#) |
| rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE ); |
| rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultScrollValue" ), mnValue ); |
| rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMin" ), mnMin ); |
| rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMax" ), mnMax ); |
| rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "LineIncrement" ), mnStep ); |
| rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "BlockIncrement" ), mnPageStep ); |
| rPropSet.SetProperty( CREATE_OUSTRING( "VisibleSize" ), ::std::min< sal_Int32 >( mnPageStep, 1 ) ); |
| |
| namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation; |
| sal_Int32 nApiOrient = ::get_flagvalue( mnOrient, EXC_OBJ_SCROLLBAR_HOR, AwtScrollOrient::HORIZONTAL, AwtScrollOrient::VERTICAL ); |
| rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), nApiOrient ); |
| } |
| |
| OUString XclImpScrollBarObj::DoGetServiceName() const |
| { |
| return CREATE_OUSTRING( "com.sun.star.form.component.ScrollBar" ); |
| } |
| |
| XclTbxEventType XclImpScrollBarObj::DoGetEventType() const |
| { |
| return EXC_TBX_EVENT_VALUE; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpTbxObjListBase::XclImpTbxObjListBase( const XclImpRoot& rRoot ) : |
| XclImpTbxObjScrollableBase( rRoot ), |
| mnEntryCount( 0 ), |
| mnSelEntry( 0 ), |
| mnListFlags( 0 ), |
| mnEditObjId( 0 ), |
| mbHasDefFontIdx( false ) |
| { |
| } |
| |
| void XclImpTbxObjListBase::ReadLbsData( XclImpStream& rStrm ) |
| { |
| ReadSourceRangeFormula( rStrm, true ); |
| rStrm >> mnEntryCount >> mnSelEntry >> mnListFlags >> mnEditObjId; |
| } |
| |
| void XclImpTbxObjListBase::SetBoxFormatting( ScfPropertySet& rPropSet ) const |
| { |
| // border style |
| namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect; |
| sal_Int16 nApiBorder = ::get_flagvalue( mnListFlags, EXC_OBJ_LISTBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D ); |
| rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), nApiBorder ); |
| |
| // font formatting |
| if( mbHasDefFontIdx ) |
| GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, maTextData.maData.mnDefFontIdx ); |
| else |
| GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpListBoxObj::XclImpListBoxObj( const XclImpRoot& rRoot ) : |
| XclImpTbxObjListBase( rRoot ) |
| { |
| } |
| |
| void XclImpListBoxObj::ReadFullLbsData( XclImpStream& rStrm, sal_Size nRecLeft ) |
| { |
| sal_Size nRecEnd = rStrm.GetRecPos() + nRecLeft; |
| ReadLbsData( rStrm ); |
| DBG_ASSERT( (rStrm.GetRecPos() == nRecEnd) || (rStrm.GetRecPos() + mnEntryCount == nRecEnd), |
| "XclImpListBoxObj::ReadFullLbsData - invalid size of OBJLBSDATA record" ); |
| while( rStrm.IsValid() && (rStrm.GetRecPos() < nRecEnd) ) |
| maSelection.push_back( rStrm.ReaduInt8() ); |
| } |
| |
| void XclImpListBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ ) |
| { |
| ReadFrameData( rStrm ); |
| ReadSbs( rStrm ); |
| rStrm.Ignore( 18 ); |
| rStrm >> maTextData.maData.mnDefFontIdx; |
| rStrm.Ignore( 4 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused |
| ReadCellLinkFormula( rStrm, true ); |
| ReadFullLbsData( rStrm, rStrm.GetRecLeft() ); |
| mbHasDefFontIdx = true; |
| } |
| |
| void XclImpListBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize ) |
| { |
| switch( nSubRecId ) |
| { |
| case EXC_ID_OBJLBSDATA: |
| ReadFullLbsData( rStrm, nSubRecSize ); |
| break; |
| default: |
| XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize ); |
| } |
| } |
| |
| void XclImpListBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const |
| { |
| // listbox formatting |
| SetBoxFormatting( rPropSet ); |
| |
| // selection type |
| sal_uInt8 nSelType = ::extract_value< sal_uInt8 >( mnListFlags, 4, 2 ); |
| bool bMultiSel = nSelType != EXC_OBJ_LISTBOX_SINGLE; |
| rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiSelection" ), bMultiSel ); |
| |
| // selection (do not set, if listbox is linked to a cell) |
| if( !HasCellLink() ) |
| { |
| ScfInt16Vec aSelVec; |
| |
| // multi selection: API expects sequence of list entry indexes |
| if( bMultiSel ) |
| for( ScfUInt8Vec::const_iterator aBeg = maSelection.begin(), aIt = aBeg, aEnd = maSelection.end(); aIt != aEnd; ++aIt ) |
| if( *aIt != 0 ) |
| aSelVec.push_back( static_cast< sal_Int16 >( aIt - aBeg ) ); |
| // single selection: mnSelEntry is one-based, API expects zero-based |
| else if( mnSelEntry > 0 ) |
| aSelVec.push_back( static_cast< sal_Int16 >( mnSelEntry - 1 ) ); |
| |
| if( !aSelVec.empty() ) |
| { |
| Sequence< sal_Int16 > aSelSeq( &aSelVec.front(), static_cast< sal_Int32 >( aSelVec.size() ) ); |
| rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq ); |
| } |
| } |
| } |
| |
| OUString XclImpListBoxObj::DoGetServiceName() const |
| { |
| return CREATE_OUSTRING( "com.sun.star.form.component.ListBox" ); |
| } |
| |
| XclTbxEventType XclImpListBoxObj::DoGetEventType() const |
| { |
| return EXC_TBX_EVENT_CHANGE; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpDropDownObj::XclImpDropDownObj( const XclImpRoot& rRoot ) : |
| XclImpTbxObjListBase( rRoot ), |
| mnLeft( 0 ), |
| mnTop( 0 ), |
| mnRight( 0 ), |
| mnBottom( 0 ), |
| mnDropDownFlags( 0 ), |
| mnLineCount( 0 ), |
| mnMinWidth( 0 ) |
| { |
| } |
| |
| sal_uInt16 XclImpDropDownObj::GetDropDownType() const |
| { |
| return ::extract_value< sal_uInt8 >( mnDropDownFlags, 0, 2 ); |
| } |
| |
| void XclImpDropDownObj::ReadFullLbsData( XclImpStream& rStrm ) |
| { |
| ReadLbsData( rStrm ); |
| rStrm >> mnDropDownFlags >> mnLineCount >> mnMinWidth >> maTextData.maData.mnTextLen; |
| maTextData.ReadByteString( rStrm ); |
| // dropdowns of auto-filters have 'simple' style, they don't have a text area |
| if( GetDropDownType() == EXC_OBJ_DROPDOWN_SIMPLE ) |
| SetProcessSdrObj( false ); |
| } |
| |
| void XclImpDropDownObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ ) |
| { |
| ReadFrameData( rStrm ); |
| ReadSbs( rStrm ); |
| rStrm.Ignore( 18 ); |
| rStrm >> maTextData.maData.mnDefFontIdx; |
| rStrm.Ignore( 14 ); |
| rStrm >> mnLeft >> mnTop >> mnRight >> mnBottom; |
| rStrm.Ignore( 4 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused |
| ReadCellLinkFormula( rStrm, true ); |
| ReadFullLbsData( rStrm ); |
| mbHasDefFontIdx = true; |
| } |
| |
| void XclImpDropDownObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize ) |
| { |
| switch( nSubRecId ) |
| { |
| case EXC_ID_OBJLBSDATA: |
| ReadFullLbsData( rStrm ); |
| break; |
| default: |
| XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize ); |
| } |
| } |
| |
| void XclImpDropDownObj::DoProcessControl( ScfPropertySet& rPropSet ) const |
| { |
| // dropdown listbox formatting |
| SetBoxFormatting( rPropSet ); |
| // enable dropdown button |
| rPropSet.SetBoolProperty( CREATE_OUSTRING( "Dropdown" ), true ); |
| // dropdown line count |
| rPropSet.SetProperty( CREATE_OUSTRING( "LineCount" ), mnLineCount ); |
| |
| if( GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX ) |
| { |
| // text of editable combobox |
| if( maTextData.mxString.is() ) |
| rPropSet.SetStringProperty( CREATE_OUSTRING( "DefaultText" ), maTextData.mxString->GetText() ); |
| } |
| else |
| { |
| // selection (do not set, if dropdown is linked to a cell) |
| if( !HasCellLink() && (mnSelEntry > 0) ) |
| { |
| Sequence< sal_Int16 > aSelSeq( 1 ); |
| aSelSeq[ 0 ] = mnSelEntry - 1; |
| rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq ); |
| } |
| } |
| } |
| |
| OUString XclImpDropDownObj::DoGetServiceName() const |
| { |
| return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ? |
| CREATE_OUSTRING( "com.sun.star.form.component.ComboBox" ) : |
| CREATE_OUSTRING( "com.sun.star.form.component.ListBox" ); |
| } |
| |
| XclTbxEventType XclImpDropDownObj::DoGetEventType() const |
| { |
| return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ? EXC_TBX_EVENT_TEXT : EXC_TBX_EVENT_CHANGE; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpPictureObj::XclImpPictureObj( const XclImpRoot& rRoot ) : |
| XclImpRectObj( rRoot ), |
| XclImpControlHelper( rRoot, EXC_CTRL_BINDCONTENT ), |
| mnStorageId( 0 ), |
| mnCtlsStrmPos( 0 ), |
| mnCtlsStrmSize( 0 ), |
| mbEmbedded( false ), |
| mbLinked( false ), |
| mbSymbol( false ), |
| mbControl( false ), |
| mbUseCtlsStrm( false ) |
| { |
| SetAreaObj( true ); |
| SetSimpleMacro( true ); |
| SetCustomDffObj( true ); |
| } |
| |
| String XclImpPictureObj::GetOleStorageName() const |
| { |
| String aStrgName; |
| if( (mbEmbedded || mbLinked) && !mbControl && (mnStorageId > 0) ) |
| { |
| aStrgName = mbEmbedded ? EXC_STORAGE_OLE_EMBEDDED : EXC_STORAGE_OLE_LINKED; |
| static const sal_Char spcHexChars[] = "0123456789ABCDEF"; |
| for( sal_uInt8 nIndex = 32; nIndex > 0; nIndex -= 4 ) |
| aStrgName.Append( sal_Unicode( spcHexChars[ ::extract_value< sal_uInt8 >( mnStorageId, nIndex - 4, 4 ) ] ) ); |
| } |
| return aStrgName; |
| } |
| |
| void XclImpPictureObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| sal_uInt16 nLinkSize; |
| ReadFrameData( rStrm ); |
| rStrm.Ignore( 6 ); |
| rStrm >> nLinkSize; |
| rStrm.Ignore( 2 ); |
| ReadFlags3( rStrm ); |
| ReadMacro3( rStrm, nMacroSize ); |
| ReadPictFmla( rStrm, nLinkSize ); |
| |
| if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() ) |
| maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); |
| } |
| |
| void XclImpPictureObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) |
| { |
| sal_uInt16 nLinkSize; |
| ReadFrameData( rStrm ); |
| rStrm.Ignore( 6 ); |
| rStrm >> nLinkSize; |
| rStrm.Ignore( 2 ); |
| ReadFlags3( rStrm ); |
| ReadMacro4( rStrm, nMacroSize ); |
| ReadPictFmla( rStrm, nLinkSize ); |
| |
| if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() ) |
| maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); |
| } |
| |
| void XclImpPictureObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) |
| { |
| sal_uInt16 nLinkSize; |
| ReadFrameData( rStrm ); |
| rStrm.Ignore( 6 ); |
| rStrm >> nLinkSize; |
| rStrm.Ignore( 2 ); |
| ReadFlags3( rStrm ); |
| rStrm.Ignore( 4 ); |
| ReadName5( rStrm, nNameLen ); |
| ReadMacro5( rStrm, nMacroSize ); |
| ReadPictFmla( rStrm, nLinkSize ); |
| |
| if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() ) |
| { |
| // page background is stored as hidden picture with name "__BkgndObj" |
| if( IsHidden() && (GetObjName() == CREATE_STRING( "__BkgndObj" )) ) |
| GetPageSettings().ReadImgData( rStrm ); |
| else |
| maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); |
| } |
| } |
| |
| void XclImpPictureObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize ) |
| { |
| switch( nSubRecId ) |
| { |
| case EXC_ID_OBJFLAGS: |
| ReadFlags8( rStrm ); |
| break; |
| case EXC_ID_OBJPICTFMLA: |
| ReadPictFmla( rStrm, rStrm.ReaduInt16() ); |
| break; |
| default: |
| XclImpDrawObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize ); |
| } |
| } |
| |
| SdrObject* XclImpPictureObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const |
| { |
| // try to create an OLE object or form control |
| SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) ); |
| |
| // no OLE - create a plain picture from IMGDATA record data |
| if( !xSdrObj && (maGraphic.GetType() != GRAPHIC_NONE) ) |
| { |
| xSdrObj.reset( new SdrGrafObj( maGraphic, rAnchorRect ) ); |
| ConvertRectStyle( *xSdrObj ); |
| } |
| |
| rDffConv.Progress(); |
| return xSdrObj.release(); |
| } |
| |
| void XclImpPictureObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const |
| { |
| if( IsOcxControl() ) |
| { |
| // do not call XclImpRectObj::DoPreProcessSdrObj(), it would trace missing "printable" feature |
| ProcessControl( *this ); |
| } |
| else if( mbEmbedded || mbLinked ) |
| { |
| // trace missing "printable" feature |
| XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj ); |
| |
| SfxObjectShell* pDocShell = GetDocShell(); |
| SdrOle2Obj* pOleSdrObj = dynamic_cast< SdrOle2Obj* >( &rSdrObj ); |
| if( pOleSdrObj && pDocShell ) |
| { |
| comphelper::EmbeddedObjectContainer& rEmbObjCont = pDocShell->GetEmbeddedObjectContainer(); |
| Reference< XEmbeddedObject > xEmbObj = pOleSdrObj->GetObjRef(); |
| OUString aOldName( pOleSdrObj->GetPersistName() ); |
| |
| /* The object persistence should be already in the storage, but |
| the object still might not be inserted into the container. */ |
| if( rEmbObjCont.HasEmbeddedObject( aOldName ) ) |
| { |
| if( !rEmbObjCont.HasEmbeddedObject( xEmbObj ) ) |
| // filter code is allowed to call the following method |
| rEmbObjCont.AddEmbeddedObject( xEmbObj, aOldName ); |
| } |
| else |
| { |
| /* If the object is still not in container it must be inserted |
| there, the name must be generated in this case. */ |
| OUString aNewName; |
| rEmbObjCont.InsertEmbeddedObject( xEmbObj, aNewName ); |
| if( aOldName != aNewName ) |
| // #95381# SetPersistName, not SetName |
| pOleSdrObj->SetPersistName( aNewName ); |
| } |
| } |
| } |
| } |
| |
| void XclImpPictureObj::ReadFlags3( XclImpStream& rStrm ) |
| { |
| sal_uInt16 nFlags; |
| rStrm >> nFlags; |
| mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL ); |
| } |
| |
| void XclImpPictureObj::ReadFlags8( XclImpStream& rStrm ) |
| { |
| sal_uInt16 nFlags; |
| rStrm >> nFlags; |
| mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL ); |
| mbControl = ::get_flag( nFlags, EXC_OBJ_PIC_CONTROL ); |
| mbUseCtlsStrm = ::get_flag( nFlags, EXC_OBJ_PIC_CTLSSTREAM ); |
| DBG_ASSERT( mbControl || !mbUseCtlsStrm, "XclImpPictureObj::ReadFlags8 - CTLS stream for controls only" ); |
| SetProcessSdrObj( mbControl || !mbUseCtlsStrm ); |
| } |
| |
| void XclImpPictureObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nLinkSize ) |
| { |
| sal_Size nLinkEnd = rStrm.GetRecPos() + nLinkSize; |
| if( nLinkSize >= 6 ) |
| { |
| sal_uInt16 nFmlaSize; |
| rStrm >> nFmlaSize; |
| DBG_ASSERT( nFmlaSize > 0, "XclImpPictureObj::ReadPictFmla - missing link formula" ); |
| // BIFF3/BIFF4 do not support storages, nothing to do here |
| if( (nFmlaSize > 0) && (GetBiff() >= EXC_BIFF5) ) |
| { |
| rStrm.Ignore( 4 ); |
| sal_uInt8 nToken; |
| rStrm >> nToken; |
| |
| // different processing for linked vs. embedded OLE objects |
| if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) ) |
| { |
| mbLinked = true; |
| switch( GetBiff() ) |
| { |
| case EXC_BIFF5: |
| { |
| sal_Int16 nRefIdx; |
| sal_uInt16 nNameIdx; |
| rStrm >> nRefIdx; |
| rStrm.Ignore( 8 ); |
| rStrm >> nNameIdx; |
| rStrm.Ignore( 12 ); |
| const ExtName* pExtName = GetOldRoot().pExtNameBuff->GetNameByIndex( nRefIdx, nNameIdx ); |
| if( pExtName && pExtName->IsOLE() ) |
| mnStorageId = pExtName->nStorageId; |
| } |
| break; |
| case EXC_BIFF8: |
| { |
| sal_uInt16 nXti, nExtName; |
| rStrm >> nXti >> nExtName; |
| const XclImpExtName* pExtName = GetLinkManager().GetExternName( nXti, nExtName ); |
| if( pExtName && (pExtName->GetType() == xlExtOLE) ) |
| mnStorageId = pExtName->GetStorageId(); |
| } |
| break; |
| default: |
| DBG_ERROR_BIFF(); |
| } |
| } |
| else if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_TBL, EXC_TOKCLASS_NONE ) ) |
| { |
| mbEmbedded = true; |
| DBG_ASSERT( nFmlaSize == 5, "XclImpPictureObj::ReadPictFmla - unexpected formula size" ); |
| rStrm.Ignore( nFmlaSize - 1 ); // token ID already read |
| if( nFmlaSize & 1 ) |
| rStrm.Ignore( 1 ); // padding byte |
| |
| // a class name may follow inside the picture link |
| if( rStrm.GetRecPos() + 2 <= nLinkEnd ) |
| { |
| sal_uInt16 nLen; |
| rStrm >> nLen; |
| if( nLen > 0 ) |
| maClassName = (GetBiff() == EXC_BIFF8) ? rStrm.ReadUniString( nLen ) : rStrm.ReadRawByteString( nLen ); |
| } |
| } |
| // else: ignore other formulas, e.g. pictures linked to cell ranges |
| } |
| } |
| |
| // seek behind picture link data |
| rStrm.Seek( nLinkEnd ); |
| |
| // read additional data for embedded OLE objects following the picture link |
| if( IsOcxControl() ) |
| { |
| // #i26521# form controls to be ignored |
| if( maClassName.EqualsAscii( "Forms.HTML:Hidden.1" ) ) |
| { |
| SetProcessSdrObj( false ); |
| return; |
| } |
| |
| if( rStrm.GetRecLeft() <= 8 ) return; |
| |
| // position and size of control data in 'Ctls' stream |
| mnCtlsStrmPos = static_cast< sal_Size >( rStrm.ReaduInt32() ); |
| mnCtlsStrmSize = static_cast< sal_Size >( rStrm.ReaduInt32() ); |
| |
| if( rStrm.GetRecLeft() <= 8 ) return; |
| |
| // additional string (16-bit characters), e.g. for progress bar control |
| sal_uInt32 nAddStrSize; |
| rStrm >> nAddStrSize; |
| DBG_ASSERT( rStrm.GetRecLeft() >= nAddStrSize + 4, "XclImpPictureObj::ReadPictFmla - missing data" ); |
| if( rStrm.GetRecLeft() >= nAddStrSize + 4 ) |
| { |
| rStrm.Ignore( nAddStrSize ); |
| // cell link and source range |
| ReadCellLinkFormula( rStrm, true ); |
| ReadSourceRangeFormula( rStrm, true ); |
| } |
| } |
| else if( mbEmbedded && (rStrm.GetRecLeft() >= 4) ) |
| { |
| rStrm >> mnStorageId; |
| } |
| } |
| |
| // DFF stream conversion ====================================================== |
| |
| //UNUSED2009-05 void XclImpSolverContainer::ReadSolverContainer( SvStream& rDffStrm ) |
| //UNUSED2009-05 { |
| //UNUSED2009-05 rDffStrm >> *this; |
| //UNUSED2009-05 } |
| |
| void XclImpSolverContainer::InsertSdrObjectInfo( SdrObject& rSdrObj, sal_uInt32 nDffShapeId, sal_uInt32 nDffFlags ) |
| { |
| if( nDffShapeId > 0 ) |
| { |
| maSdrInfoMap[ nDffShapeId ].Set( &rSdrObj, nDffFlags ); |
| maSdrObjMap[ &rSdrObj ] = nDffShapeId; |
| } |
| } |
| |
| void XclImpSolverContainer::RemoveSdrObjectInfo( SdrObject& rSdrObj ) |
| { |
| // remove info of passed object from the maps |
| XclImpSdrObjMap::iterator aIt = maSdrObjMap.find( &rSdrObj ); |
| if( aIt != maSdrObjMap.end() ) |
| { |
| maSdrInfoMap.erase( aIt->second ); |
| maSdrObjMap.erase( aIt ); |
| } |
| |
| // remove info of all child objects of a group object |
| if( SdrObjGroup* pGroupObj = dynamic_cast< SdrObjGroup* >( &rSdrObj ) ) |
| { |
| if( SdrObjList* pSubList = pGroupObj->GetSubList() ) |
| { |
| // iterate flat over the list because this function already works recursively |
| SdrObjListIter aObjIt( *pSubList, IM_FLAT ); |
| for( SdrObject* pChildObj = aObjIt.Next(); pChildObj; pChildObj = aObjIt.Next() ) |
| RemoveSdrObjectInfo( *pChildObj ); |
| } |
| } |
| } |
| |
| void XclImpSolverContainer::UpdateConnectorRules() |
| { |
| for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() ) |
| { |
| UpdateConnection( pRule->nShapeA, pRule->pAObj, &pRule->nSpFlagsA ); |
| UpdateConnection( pRule->nShapeB, pRule->pBObj, &pRule->nSpFlagsB ); |
| UpdateConnection( pRule->nShapeC, pRule->pCObj ); |
| } |
| } |
| |
| void XclImpSolverContainer::RemoveConnectorRules() |
| { |
| // base class from SVX uses plain untyped tools/List |
| for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() ) |
| delete pRule; |
| aCList.Clear(); |
| |
| maSdrInfoMap.clear(); |
| maSdrObjMap.clear(); |
| } |
| |
| SvxMSDffConnectorRule* XclImpSolverContainer::GetFirstRule() |
| { |
| return static_cast< SvxMSDffConnectorRule* >( aCList.First() ); |
| } |
| |
| SvxMSDffConnectorRule* XclImpSolverContainer::GetNextRule() |
| { |
| return static_cast< SvxMSDffConnectorRule* >( aCList.Next() ); |
| } |
| |
| void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId, SdrObject*& rpSdrObj, sal_uInt32* pnDffFlags ) |
| { |
| XclImpSdrInfoMap::const_iterator aIt = maSdrInfoMap.find( nDffShapeId ); |
| if( aIt != maSdrInfoMap.end() ) |
| { |
| rpSdrObj = aIt->second.mpSdrObj; |
| if( pnDffFlags ) |
| *pnDffFlags = aIt->second.mnDffFlags; |
| } |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| 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 ); |
| } |
| |
| XclImpSimpleDffConverter::~XclImpSimpleDffConverter() |
| { |
| } |
| |
| FASTBOOL XclImpSimpleDffConverter::GetColorFromPalette( sal_uInt16 nIndex, Color& rColor ) const |
| { |
| ColorData nColor = GetPalette().GetColorData( static_cast< sal_uInt16 >( nIndex ) ); |
| |
| if( nColor == COL_AUTO ) |
| return sal_False; |
| |
| rColor.SetColor( nColor ); |
| return sal_True; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| XclImpDffConverter::XclImpDffConvData::XclImpDffConvData( |
| XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ) : |
| mrDrawing( rDrawing ), |
| mrSdrModel( rSdrModel ), |
| mrSdrPage( rSdrPage ), |
| mnLastCtrlIndex( -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() ) |
| { |
| if( pFilterOpt->IsMathType2Math() ) |
| mnOleImpFlags |= OLE_MATHTYPE_2_STARMATH; |
| if( pFilterOpt->IsWinWord2Writer() ) |
| mnOleImpFlags |= OLE_WINWORD_2_STARWRITER; |
| if( pFilterOpt->IsPowerPoint2Impress() ) |
| mnOleImpFlags |= OLE_POWERPOINT_2_STARIMPRESS; |
| } |
| |
| // try to open the 'Ctls' storage stream containing OCX control properties |
| mxCtlsStrm = OpenStream( EXC_STREAM_CTLS ); |
| |
| // default text margin (convert EMU to drawing layer units) |
| mnDefTextMargin = EXC_OBJ_TEXT_MARGIN; |
| ScaleEmu( mnDefTextMargin ); |
| } |
| |
| XclImpDffConverter::~XclImpDffConverter() |
| { |
| } |
| |
| void XclImpDffConverter::StartProgressBar( sal_Size nProgressSize ) |
| { |
| mxProgress.reset( new ScfProgressBar( GetDocShell(), STR_PROGRESS_CALCULATING ) ); |
| mxProgress->AddSegment( nProgressSize ); |
| mxProgress->Activate(); |
| } |
| |
| void XclImpDffConverter::Progress( sal_Size nDelta ) |
| { |
| DBG_ASSERT( mxProgress.is(), "XclImpDffConverter::Progress - invalid call, no progress bar" ); |
| mxProgress->Progress( nDelta ); |
| } |
| |
| void XclImpDffConverter::InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ) |
| { |
| 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() ) |
| { |
| 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 XclImpDffConverter::ProcessDrawing( const XclImpDrawObjVector& rDrawObjs ) |
| { |
| 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 ) |
| { |
| 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 ); |
| } |
| } |
| |
| 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( SupportsOleObjects() && (aServiceName.getLength() > 0) ) try |
| { |
| // create the form control from scratch |
| Reference< XFormComponent > xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName ), UNO_QUERY_THROW ); |
| // 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; |
| XclImpDffConvData& rConvData = GetConvData(); |
| if( rConvData.mxCtrlForm.is() && InsertControl( xFormComp, aDummySize, &xShape, sal_True ) ) |
| { |
| xSdrObj.reset( rTbxObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) ); |
| // try to attach a macro to the control |
| ScriptEventDescriptor aDescriptor; |
| if( (rConvData.mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) ) |
| { |
| Reference< XEventAttacherManager > xEventMgr( rConvData.mxCtrlForm, UNO_QUERY_THROW ); |
| xEventMgr->registerScriptEvent( rConvData.mnLastCtrlIndex, aDescriptor ); |
| } |
| } |
| } |
| catch( Exception& ) |
| { |
| } |
| |
| return xSdrObj.release(); |
| } |
| |
| SdrObject* XclImpDffConverter::CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect ) |
| { |
| SdrObjectPtr xSdrObj; |
| |
| if( SupportsOleObjects() ) |
| { |
| if( rPicObj.IsOcxControl() ) |
| { |
| if( mxCtlsStrm.Is() ) try |
| { |
| /* 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, sal_True ) ) |
| xSdrObj.reset( rPicObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) ); |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| 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 ) ); |
| } |
| } |
| } |
| } |
| |
| return xSdrObj.release(); |
| } |
| |
| bool XclImpDffConverter::SupportsOleObjects() const |
| { |
| return GetConvData().mrDrawing.SupportsOleObjects(); |
| } |
| |
| // virtual functions ---------------------------------------------------------- |
| |
| void XclImpDffConverter::ProcessClientAnchor2( SvStream& rDffStrm, |
| DffRecordHeader& rHeader, void* /*pClientData*/, DffObjData& rObjData ) |
| { |
| // find the OBJ record data related to the processed shape |
| XclImpDffConvData& rConvData = GetConvData(); |
| if( XclImpDrawObjBase* pDrawObj = rConvData.mrDrawing.FindDrawObj( rObjData.rSpHd ).get() ) |
| { |
| 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 = rConvData.mrDrawing.CalcAnchorRect( aAnchor, true ); |
| rObjData.bChildAnchor = sal_True; |
| } |
| } |
| |
| 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 = rConvData.mrDrawing.FindDrawObj( rDffObjData.rSpHd ); |
| const Rectangle& rAnchorRect = rDffObjData.aChildAnchor; |
| |
| // #102378# Do not process the global page group shape (flag SP_FPATRIARCH) |
| bool bGlobalPageGroup = ::get_flag< sal_uInt32 >( rDffObjData.nSpFlags, SP_FPATRIARCH ); |
| if( !xDrawObj || !xDrawObj->IsProcessSdrObj() || bGlobalPageGroup ) |
| return 0; // simply return, xSdrObj will be destroyed |
| |
| /* Pass pointer to top-level object back to caller. If the processed |
| object is embedded in a group, the pointer is already set to the |
| top-level parent object. */ |
| XclImpDrawObjBase** ppTopLevelObj = reinterpret_cast< XclImpDrawObjBase** >( pClientData ); |
| bool bIsTopLevel = !ppTopLevelObj || !*ppTopLevelObj; |
| if( ppTopLevelObj && bIsTopLevel ) |
| *ppTopLevelObj = xDrawObj.get(); |
| |
| // #119010# connectors don't have to be area objects |
| if( dynamic_cast< SdrEdgeObj* >( xSdrObj.get() ) ) |
| xDrawObj->SetAreaObj( false ); |
| |
| /* Check for valid size for all objects. Needed to ignore lots of invisible |
| phantom objects from deleted rows or columns (for performance reasons). |
| #i30816# Include objects embedded in groups. |
| #i58780# Ignore group shapes, size is not initialized. */ |
| bool bEmbeddedGroup = !bIsTopLevel && dynamic_cast< SdrObjGroup* >( xSdrObj.get() ); |
| if( !bEmbeddedGroup && !xDrawObj->IsValidSize( rAnchorRect ) ) |
| return 0; // simply return, xSdrObj will be destroyed |
| |
| // set shape information from DFF stream |
| String aObjName = GetPropertyString( DFF_Prop_wzName, rDffStrm ); |
| String aHyperlink = ReadHlinkProperty( rDffStrm ); |
| bool bVisible = !GetPropertyBool( DFF_Prop_fHidden ); |
| bool bAutoMargin = GetPropertyBool( DFF_Prop_AutoTextMargin ); |
| xDrawObj->SetDffData( rDffObjData, aObjName, aHyperlink, bVisible, bAutoMargin ); |
| |
| /* 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 = rConvData.mrDrawing.FindTextData( rDffObjData.rSpHd ) ) |
| pTextObj->SetTextData( *pTextData ); |
| |
| // copy line and fill formatting of TBX form controls from DFF properties |
| if( XclImpTbxObjBase* pTbxObj = dynamic_cast< XclImpTbxObjBase* >( xDrawObj.get() ) ) |
| pTbxObj->SetDffProperties( *this ); |
| |
| // try to create a custom SdrObject that overwrites the passed object |
| SdrObjectPtr xNewSdrObj( xDrawObj->CreateSdrObject( *this, rAnchorRect, true ) ); |
| if( xNewSdrObj.is() ) |
| xSdrObj.reset( xNewSdrObj.release() ); |
| |
| // process the SdrObject |
| if( xSdrObj.is() ) |
| { |
| // filled without color -> set system window color |
| if( GetPropertyBool( DFF_Prop_fFilled ) && !IsProperty( DFF_Prop_fillColor ) ) |
| xSdrObj->SetMergedItem( XFillColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWBACK ) ) ); |
| |
| // additional processing on the SdrObject |
| xDrawObj->PreProcessSdrObject( *this, *xSdrObj ); |
| |
| /* If the SdrObject will not be inserted into the draw page, delete it |
| 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(); |
| } |
| |
| if( xSdrObj.is() ) |
| { |
| /* 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(); |
| } |
| |
| sal_uLong XclImpDffConverter::Calc_nBLIPPos( sal_uLong /*nOrgVal*/, sal_uLong nStreamPos ) const |
| { |
| return nStreamPos + 4; |
| } |
| |
| sal_Bool XclImpDffConverter::InsertControl( const Reference< XFormComponent >& rxFormComp, |
| const ::com::sun::star::awt::Size& /*rSize*/, Reference< XShape >* pxShape, |
| sal_Bool /*bFloatingCtrl*/ ) |
| { |
| if( GetDocShell() ) try |
| { |
| XclImpDffConvData& rConvData = GetConvData(); |
| Reference< XIndexContainer > xFormIC( rConvData.mxCtrlForm, UNO_QUERY_THROW ); |
| Reference< XControlModel > xCtrlModel( rxFormComp, UNO_QUERY_THROW ); |
| |
| // create the control shape |
| Reference< XShape > xShape( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ) ), UNO_QUERY_THROW ); |
| Reference< XControlShape > xCtrlShape( xShape, UNO_QUERY_THROW ); |
| |
| // insert the new control into the form |
| sal_Int32 nNewIndex = xFormIC->getCount(); |
| xFormIC->insertByIndex( nNewIndex, Any( rxFormComp ) ); |
| // on success: store new index of the control for later use (macro events) |
| rConvData.mnLastCtrlIndex = nNewIndex; |
| |
| // set control model at control shape and pass back shape to caller |
| xCtrlShape->setControl( xCtrlModel ); |
| if( pxShape ) *pxShape = xShape; |
| return sal_True; |
| } |
| catch( Exception& ) |
| { |
| DBG_ERRORFILE( "XclImpDffConverter::InsertControl - cannot create form control" ); |
| } |
| |
| return sal_False; |
| } |
| |
| // private -------------------------------------------------------------------- |
| |
| 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 |
| implemented in class XclImpHyperlink. This function has to create an |
| instance of the XclImpStream class to be able to reuse the |
| functionality of XclImpHyperlink. */ |
| String aString; |
| sal_uInt32 nBufferSize = GetPropertyValue( DFF_Prop_pihlShape ); |
| if( (0 < nBufferSize) && (nBufferSize <= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape, rDffStrm ) ) |
| { |
| // create a faked BIFF record that can be read by XclImpStream class |
| SvMemoryStream aMemStream; |
| aMemStream << sal_uInt16( 0 ) << static_cast< sal_uInt16 >( nBufferSize ); |
| |
| // copy from DFF stream to memory stream |
| ::std::vector< sal_uInt8 > aBuffer( nBufferSize ); |
| sal_uInt8* pnData = &aBuffer.front(); |
| if( rDffStrm.Read( pnData, nBufferSize ) == nBufferSize ) |
| { |
| aMemStream.Write( pnData, nBufferSize ); |
| |
| // create BIFF import stream to be able to use XclImpHyperlink class |
| XclImpStream aXclStrm( aMemStream, GetRoot() ); |
| if( aXclStrm.StartNextRecord() ) |
| aString = XclImpHyperlink::ReadEmbeddedData( aXclStrm ); |
| } |
| } |
| return aString; |
| } |
| |
| void XclImpDffConverter::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader ) |
| { |
| sal_Size nEndPos = rDgHeader.GetRecEndFilePos(); |
| while( rDffStrm.Tell() < nEndPos ) |
| { |
| DffRecordHeader aHeader; |
| rDffStrm >> aHeader; |
| switch( aHeader.nRecType ) |
| { |
| case DFF_msofbtSolverContainer: |
| ProcessSolverContainer( rDffStrm, aHeader ); |
| break; |
| case DFF_msofbtSpgrContainer: |
| ProcessShGrContainer( rDffStrm, aHeader ); |
| break; |
| default: |
| aHeader.SeekToEndOfRecord( rDffStrm ); |
| } |
| } |
| // seek to end of drawing page container |
| rDgHeader.SeekToEndOfRecord( rDffStrm ); |
| |
| // #i12638# #i37900# connector rules |
| XclImpSolverContainer& rSolverCont = GetConvData().maSolverCont; |
| rSolverCont.UpdateConnectorRules(); |
| SolveSolver( rSolverCont ); |
| rSolverCont.RemoveConnectorRules(); |
| } |
| |
| void XclImpDffConverter::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader ) |
| { |
| sal_Size nEndPos = rShGrHeader.GetRecEndFilePos(); |
| while( rDffStrm.Tell() < nEndPos ) |
| { |
| DffRecordHeader aHeader; |
| rDffStrm >> aHeader; |
| switch( aHeader.nRecType ) |
| { |
| case DFF_msofbtSpgrContainer: |
| case DFF_msofbtSpContainer: |
| ProcessShContainer( rDffStrm, aHeader ); |
| break; |
| default: |
| aHeader.SeekToEndOfRecord( rDffStrm ); |
| } |
| } |
| // seek to end of shape group container |
| rShGrHeader.SeekToEndOfRecord( rDffStrm ); |
| } |
| |
| 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 >> GetConvData().maSolverCont; |
| // seek to end of solver container |
| rSolverHeader.SeekToEndOfRecord( rDffStrm ); |
| } |
| |
| void XclImpDffConverter::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader ) |
| { |
| rShHeader.SeekToBegOfRecord( rDffStrm ); |
| Rectangle aDummy; |
| const XclImpDrawObjBase* pDrawObj = 0; |
| /* The call to ImportObj() creates and returns a new SdrObject for the |
| processed shape. We take ownership of the returned object here. If the |
| shape is a group object, all embedded objects are created recursively, |
| and the returned group object contains them all. ImportObj() calls the |
| virtual functions ProcessClientAnchor2() and ProcessObj() and writes |
| 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( GetConvData().mrSdrPage, *pDrawObj, xSdrObj.release() ); |
| rShHeader.SeekToEndOfRecord( rDffStrm ); |
| } |
| |
| 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), the object is automatically deleted. */ |
| SdrObjectPtr xSdrObj( pSdrObj ); |
| 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() ) |
| rConvData.maSolverCont.RemoveSdrObjectInfo( *xSdrObj ); |
| } |
| |
| void XclImpDffConverter::InitControlForm() |
| { |
| XclImpDffConvData& rConvData = GetConvData(); |
| if( rConvData.mbHasCtrlForm ) |
| return; |
| |
| 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 ) ) |
| { |
| xFormsNC->getByName( maStdFormName ) >>= rConvData.mxCtrlForm; |
| } |
| 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 ) ); |
| } |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| // Drawing manager ============================================================ |
| |
| XclImpDrawing::XclImpDrawing( const XclImpRoot& rRoot, bool bOleObjects ) : |
| XclImpRoot( rRoot ), |
| mbOleObjs( bOleObjects ) |
| { |
| } |
| |
| XclImpDrawing::~XclImpDrawing() |
| { |
| } |
| |
| /*static*/ Graphic XclImpDrawing::ReadImgData( const XclImpRoot& rRoot, XclImpStream& rStrm ) |
| { |
| Graphic aGraphic; |
| sal_uInt16 nFormat, nEnv; |
| sal_uInt32 nDataSize; |
| rStrm >> nFormat >> nEnv >> nDataSize; |
| if( nDataSize <= rStrm.GetRecLeft() ) |
| { |
| switch( nFormat ) |
| { |
| 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 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, "XclImpDrawing::ReadObj - unexpected DFF stream data, OBJ will be ignored" ); |
| if( maDffStrm.Tell() == 0 ) switch( GetBiff() ) |
| { |
| case EXC_BIFF3: |
| xDrawObj = XclImpDrawObjBase::ReadObj3( GetRoot(), rStrm ); |
| break; |
| case EXC_BIFF4: |
| xDrawObj = XclImpDrawObjBase::ReadObj4( GetRoot(), rStrm ); |
| break; |
| case EXC_BIFF5: |
| case EXC_BIFF8: |
| xDrawObj = XclImpDrawObjBase::ReadObj5( GetRoot(), rStrm ); |
| break; |
| default: |
| DBG_ERROR_BIFF(); |
| } |
| |
| if( xDrawObj.is() ) |
| { |
| // insert into maRawObjs or into the last open group object |
| maRawObjs.InsertGrouped( xDrawObj ); |
| // to be able to find objects by ID |
| maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj; |
| } |
| } |
| |
| void XclImpDrawing::ReadMsoDrawing( XclImpStream& rStrm ) |
| { |
| DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 ); |
| // disable internal CONTINUE handling |
| rStrm.ResetRecord( false ); |
| // read leading MSODRAWING record |
| ReadDffRecord( rStrm ); |
| |
| // read following drawing records, but do not start following unrelated record |
| bool bLoop = true; |
| while( bLoop ) switch( rStrm.GetNextRecId() ) |
| { |
| case EXC_ID_MSODRAWING: |
| case EXC_ID_MSODRAWINGSEL: |
| case EXC_ID_CONT: |
| rStrm.StartNextRecord(); |
| ReadDffRecord( rStrm ); |
| break; |
| case EXC_ID_OBJ: |
| rStrm.StartNextRecord(); |
| ReadObj8( rStrm ); |
| break; |
| case EXC_ID_TXO: |
| rStrm.StartNextRecord(); |
| ReadTxo( rStrm ); |
| break; |
| default: |
| bLoop = false; |
| } |
| |
| // re-enable internal CONTINUE handling |
| rStrm.ResetRecord( true ); |
| } |
| |
| 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 |
| passed header. The function upper_bound() finds the first element in |
| the map whose key is greater than the start position of the header. Its |
| end position is used to test whether the found object is really related |
| to the shape. */ |
| XclImpDrawObjRef xDrawObj; |
| XclImpObjMap::const_iterator aIt = maObjMap.upper_bound( rHeader.GetRecBegFilePos() ); |
| if( (aIt != maObjMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) ) |
| xDrawObj = aIt->second; |
| return xDrawObj; |
| } |
| |
| XclImpDrawObjRef XclImpDrawing::FindDrawObj( sal_uInt16 nObjId ) const |
| { |
| XclImpDrawObjRef xDrawObj; |
| XclImpObjMapById::const_iterator aIt = maObjMapId.find( nObjId ); |
| if( aIt != maObjMapId.end() ) |
| xDrawObj = aIt->second; |
| return xDrawObj; |
| } |
| |
| 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 |
| of the passed header. The function upper_bound() finds the first |
| element in the map whose key is greater than the start position of the |
| header. Its end position is used to test whether the found object is |
| really related to the shape. */ |
| XclImpObjTextMap::const_iterator aIt = maTextMap.upper_bound( rHeader.GetRecBegFilePos() ); |
| if( (aIt != maTextMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) ) |
| return aIt->second.get(); |
| return 0; |
| } |
| |
| void XclImpDrawing::SetSkipObj( sal_uInt16 nObjId ) |
| { |
| maSkipObjs.push_back( nObjId ); |
| } |
| |
| sal_Size XclImpDrawing::GetProgressSize() const |
| { |
| 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 XclImpDrawing::ImplConvertObjects( XclImpDffConverter& rDffConv, SdrModel& rSdrModel, SdrPage& rSdrPage ) |
| { |
| // 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(); |
| } |
| |
| // protected ------------------------------------------------------------------ |
| |
| void XclImpDrawing::AppendRawObject( const XclImpDrawObjRef& rxDrawObj ) |
| { |
| DBG_ASSERT( rxDrawObj.is(), "XclImpDrawing::AppendRawObject - unexpected empty reference" ); |
| maRawObjs.push_back( rxDrawObj ); |
| } |
| |
| // private -------------------------------------------------------------------- |
| |
| void XclImpDrawing::ReadWmf( Graphic& rGraphic, const XclImpRoot&, XclImpStream& rStrm ) // static helper |
| { |
| // extract graphic data from IMGDATA and following CONTINUE records |
| rStrm.Ignore( 8 ); |
| SvMemoryStream aMemStrm; |
| rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() ); |
| aMemStrm.Seek( STREAM_SEEK_TO_BEGIN ); |
| // import the graphic from memory stream |
| GDIMetaFile aGDIMetaFile; |
| if( ::ReadWindowMetafile( aMemStrm, aGDIMetaFile, 0 ) ) |
| rGraphic = aGDIMetaFile; |
| } |
| |
| void XclImpDrawing::ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm ) // static helper |
| { |
| // extract graphic data from IMGDATA and following CONTINUE records |
| SvMemoryStream aMemStrm; |
| |
| /* Excel 3 and 4 seem to write broken BMP data. Usually they write a |
| DIBCOREHEADER (12 bytes) containing width, height, planes = 1, and |
| 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( rRoot.GetBiff() <= EXC_BIFF4 ) |
| { |
| rStrm.PushPosition(); |
| sal_uInt32 nHdrSize; |
| sal_uInt16 nWidth, nHeight, nPlanes, nDepth; |
| rStrm >> nHdrSize >> nWidth >> nHeight >> nPlanes >> nDepth; |
| if( (nHdrSize == 12) && (nPlanes == 1) && (nDepth == 32) ) |
| { |
| rStrm.Ignore( 3 ); |
| aMemStrm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); |
| aMemStrm << nHdrSize << nWidth << nHeight << nPlanes << nDepth; |
| rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() ); |
| } |
| rStrm.PopPosition(); |
| } |
| |
| // no special handling above -> just copy the remaining record data |
| if( aMemStrm.Tell() == 0 ) |
| rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() ); |
| |
| // import the graphic from memory stream |
| aMemStrm.Seek( STREAM_SEEK_TO_BEGIN ); |
| Bitmap aBitmap; |
| if( ReadDIB(aBitmap, aMemStrm, false) ) // read DIB without file header |
| rGraphic = aBitmap; |
| } |
| |
| void XclImpDrawing::ReadDffRecord( XclImpStream& rStrm ) |
| { |
| maDffStrm.Seek( STREAM_SEEK_TO_END ); |
| rStrm.CopyRecordToStream( maDffStrm ); |
| } |
| |
| void XclImpDrawing::ReadObj8( XclImpStream& rStrm ) |
| { |
| XclImpDrawObjRef xDrawObj = XclImpDrawObjBase::ReadObj8( GetRoot(), rStrm ); |
| |
| if(xDrawObj.is()) |
| { |
| // store the new object in the internal containers |
| maObjMap[ maDffStrm.Tell() ] = xDrawObj; |
| maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj; |
| } |
| else |
| { |
| OSL_ENSURE(false, "DrawObj could not be loaded (!)"); |
| } |
| } |
| |
| void XclImpDrawing::ReadTxo( XclImpStream& rStrm ) |
| { |
| XclImpObjTextRef xTextData( new XclImpObjTextData ); |
| maTextMap[ maDffStrm.Tell() ] = xTextData; |
| |
| // 1) read the TXO record |
| xTextData->maData.ReadTxo8( rStrm ); |
| |
| // 2) first CONTINUE with string |
| xTextData->mxString.reset(); |
| bool bValid = true; |
| if( xTextData->maData.mnTextLen > 0 ) |
| { |
| bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord(); |
| DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" ); |
| if( bValid ) |
| xTextData->mxString.reset( new XclImpString( rStrm.ReadUniString( xTextData->maData.mnTextLen ) ) ); |
| } |
| |
| // 3) second CONTINUE with formatting runs |
| if( xTextData->maData.mnFormatSize > 0 ) |
| { |
| bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord(); |
| DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" ); |
| if( bValid ) |
| xTextData->ReadFormats( 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( GetRoot(), 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; |
| |
| ScAddress aScNotePos( ScAddress::UNINITIALIZED ); |
| 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 ); |
| nTotalLen = nTotalLen - nPartLen; |
| while( (nTotalLen > 0) && (rStrm.GetNextRecId() == EXC_ID_NOTE) && rStrm.StartNextRecord() ) |
| { |
| rStrm >> aXclPos >> nPartLen; |
| DBG_ASSERT( aXclPos.mnRow == 0xFFFF, "XclImpObjectManager::ReadNote3 - missing continuation NOTE record" ); |
| if( aXclPos.mnRow == 0xFFFF ) |
| { |
| DBG_ASSERT( nPartLen <= nTotalLen, "XclImpObjectManager::ReadNote3 - string too long" ); |
| aNoteText.Append( rStrm.ReadRawByteString( nPartLen ) ); |
| nTotalLen = nTotalLen - ::std::min( nTotalLen, nPartLen ); |
| } |
| else |
| { |
| // seems to be a new note, record already started -> load the note |
| rStrm.Seek( EXC_REC_SEEK_TO_BEGIN ); |
| ReadNote( rStrm ); |
| nTotalLen = 0; |
| } |
| } |
| ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos, aNoteText, false, false ); |
| } |
| } |
| |
| void XclImpSheetDrawing::ReadNote8( XclImpStream& rStrm ) |
| { |
| XclAddress aXclPos; |
| sal_uInt16 nFlags, nObjId; |
| rStrm >> aXclPos >> nFlags >> nObjId; |
| |
| ScAddress aScNotePos( ScAddress::UNINITIALIZED ); |
| if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) ) |
| if( nObjId != EXC_OBJ_INVALID_ID ) |
| if( XclImpNoteObj* pNoteObj = dynamic_cast< XclImpNoteObj* >( FindDrawObj( nObjId ).get() ) ) |
| pNoteObj->SetNoteData( aScNotePos, nFlags ); |
| } |
| |
| // The object manager ========================================================= |
| |
| XclImpObjectManager::XclImpObjectManager( const XclImpRoot& rRoot ) : |
| XclImpRoot( rRoot ) |
| { |
| 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 ); |
| |
| // #i112436# don't call ScChartListenerCollection::SetDirty here, |
| // instead use InterpretDirtyCells in ScDocument::CalcAfterLoad. |
| } |
| |
| 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 ), |
| maDffConv( rRoot, maDummyStrm ) |
| { |
| } |
| |
| void XclImpDffPropSet::Read( XclImpStream& rStrm ) |
| { |
| sal_uInt32 nPropSetSize; |
| |
| rStrm.PushPosition(); |
| rStrm.Ignore( 4 ); |
| rStrm >> nPropSetSize; |
| rStrm.PopPosition(); |
| |
| mxMemStrm.reset( new SvMemoryStream ); |
| rStrm.CopyToStream( *mxMemStrm, 8 + nPropSetSize ); |
| mxMemStrm->Seek( STREAM_SEEK_TO_BEGIN ); |
| maDffConv.ReadPropSet( *mxMemStrm, 0 ); |
| } |
| |
| sal_uInt32 XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId, sal_uInt32 nDefault ) const |
| { |
| return maDffConv.GetPropertyValue( nPropId, nDefault ); |
| } |
| |
| void XclImpDffPropSet::FillToItemSet( SfxItemSet& rItemSet ) const |
| { |
| if( mxMemStrm.get() ) |
| maDffConv.ApplyAttributes( *mxMemStrm, rItemSet ); |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclImpDffPropSet& rPropSet ) |
| { |
| rPropSet.Read( rStrm ); |
| return rStrm; |
| } |
| |
| // ============================================================================ |
| |