1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <vcl/graph.hxx>
23 #include <filter/msfilter/escherex.hxx>
24 #include "xcl97rec.hxx"
25 #include "xlescher.hxx"
26 #include "xlformula.hxx"
27 #include <svx/sdtaitm.hxx>
28 #include <rtl/ustring.hxx>
29 #include <unotools/tempfile.hxx>
35 namespace com::sun::star::chart
{ class XChartDocument
; }
36 namespace com::sun::star::script
{ struct ScriptEventDescriptor
; }
39 // DFF client anchor ==========================================================
41 /** Base class for DFF client anchor atoms used in spreadsheets. */
42 class XclExpDffAnchorBase
: public EscherExClientAnchor_Base
, protected XclExpRoot
45 /** Constructs a dummy client anchor. */
46 explicit XclExpDffAnchorBase( const XclExpRoot
& rRoot
, sal_uInt16 nFlags
= 0 );
48 /** Sets the flags according to the passed SdrObject. */
49 void SetFlags( const SdrObject
& rSdrObj
);
50 /** Sets the anchor position and flags according to the passed SdrObject. */
51 void SetSdrObject( const SdrObject
& rSdrObj
);
53 /** Writes the DFF client anchor structure with the current anchor position. */
54 void WriteDffData( EscherEx
& rEscherEx
) const;
56 /** Called from SVX DFF converter.
57 @param rRect The object anchor rectangle to be exported (in twips). */
58 virtual void WriteData( EscherEx
& rEscherEx
, const tools::Rectangle
& rRect
) override
;
61 virtual void ImplSetFlags( const SdrObject
& rSdrObj
);
62 virtual void ImplCalcAnchorRect( const tools::Rectangle
& rRect
, MapUnit eMapUnit
);
64 protected: // for access in derived classes
65 XclObjAnchor maAnchor
; /// The client anchor data.
66 sal_uInt16 mnFlags
; /// Flags for DFF stream export.
69 /** Represents the position (anchor) of an object in a Calc sheet. */
70 class XclExpDffSheetAnchor
: public XclExpDffAnchorBase
73 explicit XclExpDffSheetAnchor( const XclExpRoot
& rRoot
);
76 virtual void ImplSetFlags( const SdrObject
& rSdrObj
) override
;
77 virtual void ImplCalcAnchorRect( const tools::Rectangle
& rRect
, MapUnit eMapUnit
) override
;
80 SCTAB mnScTab
; /// Calc sheet index.
83 /** Represents the position (anchor) of a shape in an embedded draw page. */
84 class XclExpDffEmbeddedAnchor
: public XclExpDffAnchorBase
87 explicit XclExpDffEmbeddedAnchor( const XclExpRoot
& rRoot
,
88 const Size
& rPageSize
, sal_Int32 nScaleX
, sal_Int32 nScaleY
);
91 virtual void ImplSetFlags( const SdrObject
& rSdrObj
) override
;
92 virtual void ImplCalcAnchorRect( const tools::Rectangle
& rRect
, MapUnit eMapUnit
) override
;
100 /** Represents the position (anchor) of a note object. */
101 class XclExpDffNoteAnchor
: public XclExpDffAnchorBase
104 explicit XclExpDffNoteAnchor( const XclExpRoot
& rRoot
, const tools::Rectangle
& rRect
);
107 /** Represents the position (anchor) of a cell dropdown object. */
108 class XclExpDffDropDownAnchor
: public XclExpDffAnchorBase
111 explicit XclExpDffDropDownAnchor( const XclExpRoot
& rRoot
, const ScAddress
& rScPos
);
114 // MSODRAWING* records ========================================================
116 /** Base class for records holding DFF stream fragments. */
117 class XclExpMsoDrawingBase
: public XclExpRecord
120 explicit XclExpMsoDrawingBase( XclEscherEx
& rEscherEx
, sal_uInt16 nRecId
);
123 virtual void WriteBody( XclExpStream
& rStrm
) override
;
126 XclEscherEx
& mrEscherEx
; /// Reference to the DFF converter containing the DFF stream.
127 sal_uInt32 mnFragmentKey
; /// The key of the DFF stream fragment to be written by this record.
130 /** The MSODRAWINGGROUP record contains the DGGCONTAINER with global DFF data
131 such as the picture container.
133 class XclExpMsoDrawingGroup
: public XclExpMsoDrawingBase
136 explicit XclExpMsoDrawingGroup( XclEscherEx
& rEscherEx
);
139 /** One or more MSODRAWING records contain the DFF stream data for a drawing
142 class XclExpMsoDrawing
: public XclExpMsoDrawingBase
145 explicit XclExpMsoDrawing( XclEscherEx
& rEscherEx
);
148 /** Provides export of bitmap data to an IMGDATA record. */
149 class XclExpImgData
: public XclExpRecordBase
152 explicit XclExpImgData( Graphic aGraphic
, sal_uInt16 nRecId
);
154 /** Writes the BITMAP record. */
155 virtual void Save( XclExpStream
& rStrm
) override
;
156 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
159 Graphic maGraphic
; /// The VCL graphic.
160 sal_uInt16 mnRecId
; /// Record identifier for the IMGDATA record.
163 /** Helper class for form controls to manage spreadsheet links . */
164 class XclExpControlHelper
: protected XclExpRoot
167 explicit XclExpControlHelper( const XclExpRoot
& rRoot
);
168 virtual ~XclExpControlHelper() override
;
171 /** Tries to get spreadsheet cell link and source range link from the passed shape. */
172 void ConvertSheetLinks(
173 css::uno::Reference
< css::drawing::XShape
> const & xShape
);
175 /** Returns the Excel token array of the cell link, or 0, if no link present. */
176 const XclTokenArray
* GetCellLinkTokArr() const { return mxCellLink
.get(); }
177 /** Returns the Excel token array of the source range, or 0, if no link present. */
178 const XclTokenArray
* GetSourceRangeTokArr() const { return mxSrcRange
.get(); }
179 /** Returns the number of entries in the source range, or 0, if no source set. */
180 sal_uInt16
GetSourceEntryCount() const { return mnEntryCount
; }
182 /** Writes a formula with special style only valid in OBJ records. */
183 static void WriteFormula( XclExpStream
& rStrm
, const XclTokenArray
& rTokArr
);
184 /** Writes a formula subrecord with special style only valid in OBJ records. */
185 static void WriteFormulaSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
, const XclTokenArray
& rTokArr
);
188 XclTokenArrayRef mxCellLink
; /// Formula for linked cell.
189 XclTokenArrayRef mxSrcRange
; /// Formula for source data range.
190 sal_uInt16 mnEntryCount
; /// Number of entries in source range.
192 ScAddress mxCellLinkAddress
;
195 class XclMacroHelper
: public XclExpControlHelper
197 XclTokenArrayRef mxMacroLink
; /// Token array containing a link to an attached macro.
198 OUString maMacroName
;
201 explicit XclMacroHelper( const XclExpRoot
& rRoot
);
202 virtual ~XclMacroHelper() override
;
203 /** Writes an ftMacro subrecord containing a macro link, or nothing, if no macro present. */
204 void WriteMacroSubRec( XclExpStream
& rStrm
);
205 /** Sets the name of a macro for object of passed type
206 @return true = The passed event descriptor was valid, macro name has been found. */
207 bool SetMacroLink( const css::script::ScriptEventDescriptor
& rEvent
, const XclTbxEventType
& nEventType
);
209 /** Sets the name of a macro
210 @return true = The passed macro name has been found. */
211 bool SetMacroLink( const OUString
& rMacro
);
212 const OUString
& GetMacroName() const;
215 class XclExpShapeObj
: public XclObjAny
, public XclMacroHelper
218 explicit XclExpShapeObj( XclExpObjectManager
& rRoot
, css::uno::Reference
< css::drawing::XShape
> const & xShape
, ScDocument
* pDoc
);
219 virtual ~XclExpShapeObj() override
;
221 virtual void WriteSubRecs( XclExpStream
& rStrm
) override
;
224 //delete for exporting OCX
225 //#if EXC_EXP_OCX_CTRL
227 /** Represents an OBJ record for an OCX form control. */
228 class XclExpOcxControlObj
: public XclObj
, public XclExpControlHelper
231 explicit XclExpOcxControlObj(
232 XclExpObjectManager
& rObjMgr
,
233 css::uno::Reference
< css::drawing::XShape
> const & xShape
,
234 const tools::Rectangle
* pChildAnchor
,
236 sal_uInt32 nStrmStart
, sal_uInt32 nStrmSize
);
239 virtual void WriteSubRecs( XclExpStream
& rStrm
) override
;
242 OUString maClassName
; /// Class name of the control.
243 sal_uInt32 mnStrmStart
; /// Start position in 'Ctls' stream.
244 sal_uInt32 mnStrmSize
; /// Size in 'Ctls' stream.
249 /** Represents an OBJ record for a TBX form control. */
250 class XclExpTbxControlObj
: public XclObj
, public XclMacroHelper
253 explicit XclExpTbxControlObj(
254 XclExpObjectManager
& rObjMgr
,
255 css::uno::Reference
< css::drawing::XShape
> const & xShape
,
256 const tools::Rectangle
* pChildAnchor
);
258 /** Sets the name of a macro attached to this control.
259 @return true = The passed event descriptor was valid, macro name has been found. */
260 bool SetMacroLink( const css::script::ScriptEventDescriptor
& rEvent
);
262 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
264 void SaveVml(XclExpXmlStream
& rStrm
);
266 OUString
SaveControlPropertiesXml(XclExpXmlStream
& rStrm
) const;
267 void SaveSheetXml(XclExpXmlStream
& rStrm
, const OUString
& aIdFormControlPr
) const;
269 void setShapeId(sal_Int32 aShapeId
);
272 virtual void WriteSubRecs( XclExpStream
& rStrm
) override
;
274 /** Writes a subrecord containing a cell link, or nothing, if no link present. */
275 void WriteCellLinkSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
);
276 /** Writes the ftSbs sub structure containing scrollbar data. */
277 void WriteSbs( XclExpStream
& rStrm
);
280 const css::uno::Reference
< css::drawing::XShape
> mxShape
;
281 ScfInt16Vec maMultiSel
; /// Indexes of all selected entries in a multi selection.
282 XclTbxEventType meEventType
; /// Type of supported macro event.
283 sal_Int32 mnHeight
; /// Height of the control.
284 sal_uInt16 mnState
; /// Checked/unchecked state.
285 sal_Int16 mnLineCount
; /// Combobox dropdown line count.
286 sal_Int16 mnSelEntry
; /// Selected entry in combobox (1-based).
287 sal_uInt16 mnScrollValue
; /// Scrollbar: Current value.
288 sal_uInt16 mnScrollMin
; /// Scrollbar: Minimum value.
289 sal_uInt16 mnScrollMax
; /// Scrollbar: Maximum value.
290 sal_uInt16 mnScrollStep
; /// Scrollbar: Single step.
291 sal_uInt16 mnScrollPage
; /// Scrollbar: Page step.
292 bool mbFlatButton
; /// False = 3D button style; True = Flat button style.
293 bool mbFlatBorder
; /// False = 3D border style; True = Flat border style.
294 bool mbMultiSel
; /// true = Multi selection in listbox.
295 bool mbScrollHor
; /// Scrollbar: true = horizontal.
301 tools::Rectangle maAreaFrom
;
302 tools::Rectangle maAreaTo
;
303 XclExpObjectManager
& mrRoot
;
310 /** A chart object. This is the drawing object wrapper for the chart data. */
311 class XclExpChartObj
: public XclObj
, protected XclExpRoot
314 explicit XclExpChartObj(
315 XclExpObjectManager
& rObjMgr
,
316 css::uno::Reference
< css::drawing::XShape
> const & xShape
,
317 const tools::Rectangle
* pChildAnchor
,
319 virtual ~XclExpChartObj() override
;
321 /** Writes the OBJ record and the entire chart substream. */
322 virtual void Save( XclExpStream
& rStrm
) override
;
323 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
325 css::uno::Reference
<css::chart::XChartDocument
> GetChartDoc() const;
328 typedef std::shared_ptr
< XclExpChart
> XclExpChartRef
;
329 XclExpChartRef mxChart
; /// The chart itself (BOF/EOF substream data).
330 css::uno::Reference
< css::drawing::XShape
> mxShape
;
334 /** Represents a NOTE record containing the relevant data of a cell note.
336 NOTE records differ significantly in various BIFF versions. This class
337 encapsulates all needed actions for each supported BIFF version.
338 BIFF5/BIFF7: Stores the note text and generates a single or multiple NOTE
340 BIFF8: Creates the Escher object containing the drawing information and the
343 class XclExpNote
: public XclExpRecord
346 /** Constructs a NOTE record from the passed note object and/or the text.
347 @descr The additional text will be separated from the note text with
349 @param rScPos The Calc cell address of the note.
350 @param pScNote The Calc note object. May be 0 to create a note from rAddText only.
351 @param rAddText Additional text appended to the note text. */
353 const XclExpRoot
& rRoot
,
354 const ScAddress
& rScPos
,
355 const ScPostIt
* pScNote
,
356 std::u16string_view rAddText
);
358 /** Writes the NOTE record, if the respective Escher object is present. */
359 virtual void Save( XclExpStream
& rStrm
) override
;
361 void WriteXml( sal_Int32 nAuthorId
, XclExpXmlStream
& rStrm
);
363 const XclExpString
& GetAuthor() const { return maAuthor
; }
365 /** Writes the body of the NOTE record. */
366 virtual void WriteBody( XclExpStream
& rStrm
) override
;
369 const XclExpRoot
& mrRoot
;
370 XclExpString maAuthor
; /// Name of the author.
371 OString maNoteText
; /// Main text of the note (<=BIFF7).
372 XclExpStringRef mpNoteContents
; /// Text and formatting data (OOXML)
373 ScAddress maScPos
; /// Calc cell address of the note.
374 sal_uInt16 mnObjId
; /// Escher object ID (BIFF8).
375 bool mbVisible
; /// true = permanently visible.
376 SdrTextHorzAdjust meTHA
; /// text horizontal adjust
377 SdrTextVertAdjust meTVA
; /// text vertical adjust
378 bool mbAutoScale
; /// Auto scale text
379 bool mbLocked
; /// Position & Size locked
380 bool mbAutoFill
; /// Auto Fill Style
381 bool mbColHidden
; /// Column containing the comment is hidden
382 bool mbRowHidden
; /// Row containing the comment is hidden
383 tools::Rectangle maCommentFrom
; /// From and From Offset
384 tools::Rectangle maCommentTo
; /// To and To Offsets
387 class XclExpComments
: public XclExpRecord
390 XclExpComments( SCTAB nTab
, XclExpRecordList
< XclExpNote
>& rNotes
);
392 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
396 XclExpRecordList
< XclExpNote
>& mrNotes
;
399 // object manager =============================================================
401 class XclExpObjectManager
: public XclExpRoot
404 explicit XclExpObjectManager( const XclExpRoot
& rRoot
);
405 virtual ~XclExpObjectManager() override
;
407 /** Creates a new DFF client anchor object. Caller takes ownership! May be
408 overwritten in derived classes. */
409 virtual XclExpDffAnchorBase
* CreateDffAnchor() const;
411 /** Creates and returns the MSODRAWINGGROUP record containing global DFF
412 data in the DGGCONTAINER. */
413 rtl::Reference
< XclExpRecordBase
> CreateDrawingGroup();
415 /** Initializes the object manager for a new sheet. */
418 /** Processes a drawing page and returns the record block containing all
419 related records (MSODRAWING, OBJ, TXO, charts, etc.). */
420 rtl::Reference
< XclExpRecordBase
> ProcessDrawing( const SdrPage
* pSdrPage
);
421 /** Processes a collection of UNO shapes and returns the record block
422 containing all related records (MSODRAWING, OBJ, TXO, charts, etc.). */
423 rtl::Reference
< XclExpRecordBase
> ProcessDrawing( const css::uno::Reference
< css::drawing::XShapes
>& rxShapes
);
425 /** Finalizes the object manager after conversion of all sheets. */
428 XclEscherEx
& GetEscherEx() { return *mxEscherEx
; }
429 XclExpMsoDrawing
* GetMsodrawingPerSheet();
431 sal_uInt16
AddObj( std::unique_ptr
<XclObj
> pObjRec
);
432 std::unique_ptr
<XclObj
> RemoveLastObj();
435 explicit XclExpObjectManager( const XclExpObjectManager
& rParent
);
438 void InitStream( bool bTempFile
);
441 std::optional
< ::utl::TempFileFast
> moTempFile
;
442 SvStream
* mpDffStrm
= nullptr;
443 std::unique_ptr
<SvMemoryStream
> mpBackupStrm
;
444 std::shared_ptr
< XclEscherEx
> mxEscherEx
;
445 rtl::Reference
< XclExpObjList
> mxObjList
;
448 class XclExpEmbeddedObjectManager
: public XclExpObjectManager
451 explicit XclExpEmbeddedObjectManager(
452 const XclExpObjectManager
& rParent
,
453 const Size
& rPageSize
,
454 sal_Int32 nScaleX
, sal_Int32 nScaleY
);
456 /** Creates a new DFF client anchor object for embedded objects according
457 to the scaling data passed to the constructor. Caller takes ownership! */
458 virtual XclExpDffAnchorBase
* CreateDffAnchor() const override
;
466 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */