/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#pragma once
#include <vcl/graph.hxx>
#include <filter/msfilter/escherex.hxx>
#include "xcl97rec.hxx"
#include "xlescher.hxx"
#include "xlformula.hxx"
#include <svx/sdtaitm.hxx>
#include <rtl/ustring.hxx>
#include <unotools/securityoptions.hxx>
#include <unotools/tempfile.hxx>
#include <memory>
#include <optional>
class ScPostIt;
namespace com::sun::star::chart { class XChartDocument; }
namespace com::sun::star::script { struct ScriptEventDescriptor; }
// DFF client anchor ==========================================================
/** Base class for DFF client anchor atoms used in spreadsheets. */
class XclExpDffAnchorBase : public EscherExClientAnchor_Base, protected XclExpRoot
{
public:
/** Constructs a dummy client anchor. */
explicit XclExpDffAnchorBase( const XclExpRoot& rRoot, sal_uInt16 nFlags = 0 );
/** Sets the flags according to the passed SdrObject. */
void SetFlags( const SdrObject& rSdrObj );
/** Sets the anchor position and flags according to the passed SdrObject. */
void SetSdrObject( const SdrObject& rSdrObj );
/** Writes the DFF client anchor structure with the current anchor position. */
void WriteDffData( EscherEx& rEscherEx ) const;
/** Called from SVX DFF converter.
@param rRect The object anchor rectangle to be exported (in twips). */
virtual void WriteData( EscherEx& rEscherEx, const tools::Rectangle& rRect ) override;
private:
virtual void ImplSetFlags( const SdrObject& rSdrObj );
virtual void ImplCalcAnchorRect( const tools::Rectangle& rRect, MapUnit eMapUnit );
protected: // for access in derived classes
XclObjAnchor maAnchor; /// The client anchor data.
sal_uInt16 mnFlags; /// Flags for DFF stream export.
};
/** Represents the position (anchor) of an object in a Calc sheet. */
class XclExpDffSheetAnchor : public XclExpDffAnchorBase
{
public:
explicit XclExpDffSheetAnchor( const XclExpRoot& rRoot );
private:
virtual void ImplSetFlags( const SdrObject& rSdrObj ) override;
virtual void ImplCalcAnchorRect( const tools::Rectangle& rRect, MapUnit eMapUnit ) override;
private:
SCTAB mnScTab; /// Calc sheet index.
};
/** Represents the position (anchor) of a shape in an embedded draw page. */
class XclExpDffEmbeddedAnchor : public XclExpDffAnchorBase
{
public:
explicit XclExpDffEmbeddedAnchor( const XclExpRoot& rRoot,
const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY );
private:
virtual void ImplSetFlags( const SdrObject& rSdrObj ) override;
virtual void ImplCalcAnchorRect( const tools::Rectangle& rRect, MapUnit eMapUnit ) override;
private:
Size maPageSize;
sal_Int32 mnScaleX;
sal_Int32 mnScaleY;
};
/** Represents the position (anchor) of a note object. */
class XclExpDffNoteAnchor : public XclExpDffAnchorBase
{
public:
explicit XclExpDffNoteAnchor( const XclExpRoot& rRoot, const tools::Rectangle& rRect );
};
/** Represents the position (anchor) of a cell dropdown object. */
class XclExpDffDropDownAnchor : public XclExpDffAnchorBase
{
public:
explicit XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos );
};
// MSODRAWING* records ========================================================
/** Base class for records holding DFF stream fragments. */
class XclExpMsoDrawingBase : public XclExpRecord
{
public:
explicit XclExpMsoDrawingBase( XclEscherEx& rEscherEx, sal_uInt16 nRecId );
private:
virtual void WriteBody( XclExpStream& rStrm ) override;
protected:
XclEscherEx& mrEscherEx; /// Reference to the DFF converter containing the DFF stream.
sal_uInt32 mnFragmentKey; /// The key of the DFF stream fragment to be written by this record.
};
/** The MSODRAWINGGROUP record contains the DGGCONTAINER with global DFF data
such as the picture container.
*/
class XclExpMsoDrawingGroup : public XclExpMsoDrawingBase
{
public:
explicit XclExpMsoDrawingGroup( XclEscherEx& rEscherEx );
};
/** One or more MSODRAWING records contain the DFF stream data for a drawing
shape.
*/
class XclExpMsoDrawing : public XclExpMsoDrawingBase
{
public:
explicit XclExpMsoDrawing( XclEscherEx& rEscherEx );
};
/** Provides export of bitmap data to an IMGDATA record. */
class XclExpImgData : public XclExpRecordBase
{
public:
explicit XclExpImgData( Graphic aGraphic, sal_uInt16 nRecId );
/** Writes the BITMAP record. */
virtual void Save( XclExpStream& rStrm ) override;
virtual void SaveXml( XclExpXmlStream& rStrm ) override;
private:
Graphic maGraphic; /// The VCL graphic.
sal_uInt16 mnRecId; /// Record identifier for the IMGDATA record.
};
/** Helper class for form controls to manage spreadsheet links . */
class XclExpControlHelper : protected XclExpRoot
{
public:
explicit XclExpControlHelper( const XclExpRoot& rRoot );
virtual ~XclExpControlHelper() override;
protected:
/** Tries to get spreadsheet cell link and source range link from the passed shape. */
void ConvertSheetLinks(
css::uno::Reference< css::drawing::XShape > const & xShape );
/** Returns the Excel token array of the cell link, or 0, if no link present. */
const XclTokenArray* GetCellLinkTokArr() const { return mxCellLink.get(); }
/** Returns the Excel token array of the source range, or 0, if no link present. */
const XclTokenArray* GetSourceRangeTokArr() const { return mxSrcRange.get(); }
/** Returns the number of entries in the source range, or 0, if no source set. */
sal_uInt16 GetSourceEntryCount() const { return mnEntryCount; }
/** Writes a formula with special style only valid in OBJ records. */
static void WriteFormula( XclExpStream& rStrm, const XclTokenArray& rTokArr );
/** Writes a formula subrecord with special style only valid in OBJ records. */
static void WriteFormulaSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId, const XclTokenArray& rTokArr );
private:
XclTokenArrayRef mxCellLink; /// Formula for linked cell.
XclTokenArrayRef mxSrcRange; /// Formula for source data range.
sal_uInt16 mnEntryCount; /// Number of entries in source range.
protected:
ScAddress mxCellLinkAddress;
};
class XclMacroHelper : public XclExpControlHelper
{
XclTokenArrayRef mxMacroLink; /// Token array containing a link to an attached macro.
OUString maMacroName;
public:
explicit XclMacroHelper( const XclExpRoot& rRoot );
virtual ~XclMacroHelper() override;
/** Writes an ftMacro subrecord containing a macro link, or nothing, if no macro present. */
void WriteMacroSubRec( XclExpStream& rStrm );
/** Sets the name of a macro for object of passed type
@return true = The passed event descriptor was valid, macro name has been found. */
bool SetMacroLink( const css::script::ScriptEventDescriptor& rEvent, const XclTbxEventType& nEventType );
/** Sets the name of a macro
@return true = The passed macro name has been found. */
bool SetMacroLink( const OUString& rMacro );
const OUString& GetMacroName() const;
};
class XclExpShapeObj : public XclObjAny, public XclMacroHelper
{
public:
explicit XclExpShapeObj( XclExpObjectManager& rRoot, css::uno::Reference< css::drawing::XShape > const & xShape, ScDocument* pDoc );
virtual ~XclExpShapeObj() override;
private:
virtual void WriteSubRecs( XclExpStream& rStrm ) override;
};
//delete for exporting OCX
//#if EXC_EXP_OCX_CTRL
/** Represents an OBJ record for an OCX form control. */
class XclExpOcxControlObj : public XclObj, public XclExpControlHelper
{
public:
explicit XclExpOcxControlObj(
XclExpObjectManager& rObjMgr,
css::uno::Reference< css::drawing::XShape > const & xShape,
const tools::Rectangle* pChildAnchor,
OUString aClassName,
sal_uInt32 nStrmStart, sal_uInt32 nStrmSize );
private:
virtual void WriteSubRecs( XclExpStream& rStrm ) override;
private:
OUString maClassName; /// Class name of the control.
sal_uInt32 mnStrmStart; /// Start position in 'Ctls' stream.
sal_uInt32 mnStrmSize; /// Size in 'Ctls' stream.
};
//#else
/** Represents an OBJ record for a TBX form control. */
class XclExpTbxControlObj : public XclObj, public XclMacroHelper
{
public:
explicit XclExpTbxControlObj(
XclExpObjectManager& rObjMgr,
css::uno::Reference< css::drawing::XShape > const & xShape,
const tools::Rectangle* pChildAnchor );
/** Sets the name of a macro attached to this control.
@return true = The passed event descriptor was valid, macro name has been found. */
bool SetMacroLink( const css::script::ScriptEventDescriptor& rEvent );
virtual void SaveXml( XclExpXmlStream& rStrm ) override;
void SaveVml(XclExpXmlStream& rStrm);
OUString SaveControlPropertiesXml(XclExpXmlStream& rStrm) const;
void SaveSheetXml(XclExpXmlStream& rStrm, const OUString& aIdFormControlPr) const;
void setShapeId(sal_Int32 aShapeId);
private:
virtual void WriteSubRecs( XclExpStream& rStrm ) override;
/** Writes a subrecord containing a cell link, or nothing, if no link present. */
void WriteCellLinkSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId );
/** Writes the ftSbs sub structure containing scrollbar data. */
void WriteSbs( XclExpStream& rStrm );
private:
const css::uno::Reference< css::drawing::XShape > mxShape;
ScfInt16Vec maMultiSel; /// Indexes of all selected entries in a multi selection.
XclTbxEventType meEventType; /// Type of supported macro event.
sal_Int32 mnHeight; /// Height of the control.
sal_uInt16 mnState; /// Checked/unchecked state.
sal_Int16 mnLineCount; /// Combobox dropdown line count.
sal_Int16 mnSelEntry; /// Selected entry in combobox (1-based).
sal_uInt16 mnScrollValue; /// Scrollbar: Current value.
sal_uInt16 mnScrollMin; /// Scrollbar: Minimum value.
sal_uInt16 mnScrollMax; /// Scrollbar: Maximum value.
sal_uInt16 mnScrollStep; /// Scrollbar: Single step.
sal_uInt16 mnScrollPage; /// Scrollbar: Page step.
bool mbFlatButton; /// False = 3D button style; True = Flat button style.
bool mbFlatBorder; /// False = 3D border style; True = Flat border style.
bool mbMultiSel; /// true = Multi selection in listbox.
bool mbScrollHor; /// Scrollbar: true = horizontal.
bool mbPrint;
bool mbVisible;
OUString msCtrlName;
OUString msLabel;
sal_Int32 mnShapeId;
tools::Rectangle maAreaFrom;
tools::Rectangle maAreaTo;
XclExpObjectManager& mrRoot;
};
//#endif
class XclExpChart;
/** A chart object. This is the drawing object wrapper for the chart data. */
class XclExpChartObj : public XclObj, protected XclExpRoot
{
public:
explicit XclExpChartObj(
XclExpObjectManager& rObjMgr,
css::uno::Reference< css::drawing::XShape > const & xShape,
const tools::Rectangle* pChildAnchor,
ScDocument* pDoc );
virtual ~XclExpChartObj() override;
/** Writes the OBJ record and the entire chart substream. */
virtual void Save( XclExpStream& rStrm ) override;
virtual void SaveXml( XclExpXmlStream& rStrm ) override;
css::uno::Reference<css::chart::XChartDocument> GetChartDoc() const;
private:
typedef std::shared_ptr< XclExpChart > XclExpChartRef;
XclExpChartRef mxChart; /// The chart itself (BOF/EOF substream data).
css::uno::Reference< css::drawing::XShape > mxShape;
ScDocument* mpDoc;
};
/** Represents a NOTE record containing the relevant data of a cell note.
NOTE records differ significantly in various BIFF versions. This class
encapsulates all needed actions for each supported BIFF version.
BIFF5/BIFF7: Stores the note text and generates a single or multiple NOTE
records on saving.
BIFF8: Creates the Escher object containing the drawing information and the
note text.
*/
class XclExpNote : public XclExpRecord
{
public:
/** Constructs a NOTE record from the passed note object and/or the text.
@descr The additional text will be separated from the note text with
an empty line.
@param rScPos The Calc cell address of the note.
@param pScNote The Calc note object. May be 0 to create a note from rAddText only.
@param rAddText Additional text appended to the note text. */
explicit XclExpNote(
const XclExpRoot& rRoot,
const ScAddress& rScPos,
const ScPostIt* pScNote,
std::u16string_view rAddText );
/** Writes the NOTE record, if the respective Escher object is present. */
virtual void Save( XclExpStream& rStrm ) override;
void WriteXml( sal_Int32 nAuthorId, XclExpXmlStream& rStrm );
const XclExpString& GetAuthor() const { return maAuthor; }
private:
/** Writes the body of the NOTE record. */
virtual void WriteBody( XclExpStream& rStrm ) override;
private:
const XclExpRoot& mrRoot;
XclExpString maAuthor; /// Name of the author.
OString maNoteText; /// Main text of the note (<=BIFF7).
XclExpStringRef mpNoteContents; /// Text and formatting data (OOXML)
ScAddress maScPos; /// Calc cell address of the note.
sal_uInt16 mnObjId; /// Escher object ID (BIFF8).
bool mbVisible; /// true = permanently visible.
SdrTextHorzAdjust meTHA; /// text horizontal adjust
SdrTextVertAdjust meTVA; /// text vertical adjust
bool mbAutoScale; /// Auto scale text
bool mbLocked; /// Position & Size locked
bool mbAutoFill; /// Auto Fill Style
bool mbColHidden; /// Column containing the comment is hidden
bool mbRowHidden; /// Row containing the comment is hidden
tools::Rectangle maCommentFrom; /// From and From Offset
tools::Rectangle maCommentTo; /// To and To Offsets
/// map authors to remove personal info
std::unique_ptr<SvtSecurityMapPersonalInfo> mpAuthorIDs;
};
class XclExpComments : public XclExpRecord
{
public:
XclExpComments( SCTAB nTab, XclExpRecordList< XclExpNote >& rNotes );
virtual void SaveXml( XclExpXmlStream& rStrm ) override;
private:
SCTAB mnTab;
XclExpRecordList< XclExpNote >& mrNotes;
};
// object manager =============================================================
class XclExpObjectManager : public XclExpRoot
{
public:
explicit XclExpObjectManager( const XclExpRoot& rRoot );
virtual ~XclExpObjectManager() override;
/** Creates a new DFF client anchor object. Caller takes ownership! May be
overwritten in derived classes. */
virtual XclExpDffAnchorBase* CreateDffAnchor() const;
/** Creates and returns the MSODRAWINGGROUP record containing global DFF
data in the DGGCONTAINER. */
rtl::Reference< XclExpRecordBase > CreateDrawingGroup();
/** Initializes the object manager for a new sheet. */
void StartSheet();
/** Processes a drawing page and returns the record block containing all
related records (MSODRAWING, OBJ, TXO, charts, etc.). */
rtl::Reference< XclExpRecordBase > ProcessDrawing( const SdrPage* pSdrPage );
/** Processes a collection of UNO shapes and returns the record block
containing all related records (MSODRAWING, OBJ, TXO, charts, etc.). */
rtl::Reference< XclExpRecordBase > ProcessDrawing( const css::uno::Reference< css::drawing::XShapes >& rxShapes );
/** Finalizes the object manager after conversion of all sheets. */
void EndDocument();
XclEscherEx& GetEscherEx() { return *mxEscherEx; }
XclExpMsoDrawing* GetMsodrawingPerSheet();
bool HasObj() const;
sal_uInt16 AddObj( std::unique_ptr<XclObj> pObjRec );
std::unique_ptr<XclObj> RemoveLastObj();
protected:
explicit XclExpObjectManager( const XclExpObjectManager& rParent );
private:
void InitStream( bool bTempFile );
private:
std::optional< ::utl::TempFileFast > moTempFile;
SvStream* mpDffStrm = nullptr;
std::unique_ptr<SvMemoryStream> mpBackupStrm;
std::shared_ptr< XclEscherEx > mxEscherEx;
rtl::Reference< XclExpObjList > mxObjList;
};
class XclExpEmbeddedObjectManager : public XclExpObjectManager
{
public:
explicit XclExpEmbeddedObjectManager(
const XclExpObjectManager& rParent,
const Size& rPageSize,
sal_Int32 nScaleX, sal_Int32 nScaleY );
/** Creates a new DFF client anchor object for embedded objects according
to the scaling data passed to the constructor. Caller takes ownership! */
virtual XclExpDffAnchorBase* CreateDffAnchor() const override;
private:
Size maPageSize;
sal_Int32 mnScaleX;
sal_Int32 mnScaleY;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V690 The 'XclExpObjectManager' class implements a copy constructor, but lacks the copy assignment operator. It is dangerous to use such a class.