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 .
20 #include <sal/config.h>
24 #include <xlescher.hxx>
26 #include <com/sun/star/drawing/XControlShape.hpp>
27 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
28 #include <tools/UnitConversion.hxx>
29 #include <document.hxx>
30 #include <xistream.hxx>
32 #include <xltools.hxx>
34 using ::com::sun::star::uno::Reference
;
35 using ::com::sun::star::uno::UNO_QUERY
;
36 using ::com::sun::star::drawing::XShape
;
37 using ::com::sun::star::drawing::XControlShape
;
38 using ::com::sun::star::awt::XControlModel
;
39 using ::com::sun::star::script::ScriptEventDescriptor
;
43 /** Returns the scaling factor to calculate coordinates from twips. */
44 double lclGetTwipsScale( MapUnit eMapUnit
)
47 if (const auto eTo
= MapToO3tlLength(eMapUnit
); eTo
!= o3tl::Length::invalid
)
48 fScale
= o3tl::convert(1.0, o3tl::Length::twip
, eTo
);
50 OSL_FAIL("lclGetTwipsScale - map unit not implemented");
54 /** Calculates a drawing layer X position (in twips) from an object column position. */
55 tools::Long
lclGetXFromCol( const ScDocument
& rDoc
, SCTAB nScTab
, sal_uInt16 nXclCol
, sal_uInt16 nOffset
, double fScale
)
57 SCCOL nScCol
= static_cast< SCCOL
>( nXclCol
);
58 return static_cast< tools::Long
>( fScale
* (rDoc
.GetColOffset( nScCol
, nScTab
) +
59 ::std::min( nOffset
/ 1024.0, 1.0 ) * rDoc
.GetColWidth( nScCol
, nScTab
)) + 0.5 );
62 /** Calculates a drawing layer Y position (in twips) from an object row position. */
63 tools::Long
lclGetYFromRow( const ScDocument
& rDoc
, SCTAB nScTab
, sal_uInt16 nXclRow
, sal_uInt16 nOffset
, double fScale
)
65 SCROW nScRow
= static_cast< SCROW
>( nXclRow
);
66 return static_cast< tools::Long
>( fScale
* (rDoc
.GetRowOffset( nScRow
, nScTab
) +
67 ::std::min( nOffset
/ 256.0, 1.0 ) * rDoc
.GetRowHeight( nScRow
, nScTab
)) + 0.5 );
70 /** Calculates an object column position from a drawing layer X position (in twips). */
72 const ScDocument
& rDoc
, SCTAB nScTab
, sal_uInt16
& rnXclCol
,
73 sal_uInt16
& rnOffset
, sal_uInt16 nXclStartCol
, sal_uInt16 nXclMaxCol
,
74 tools::Long
& rnStartW
, tools::Long nX
, double fScale
)
76 // rnStartW in conjunction with nXclStartCol is used as buffer for previously calculated width
77 tools::Long nTwipsX
= static_cast< tools::Long
>( nX
/ fScale
+ 0.5 );
78 tools::Long nColW
= 0;
79 for( rnXclCol
= nXclStartCol
; rnXclCol
<= nXclMaxCol
; ++rnXclCol
)
81 nColW
= rDoc
.GetColWidth( static_cast< SCCOL
>( rnXclCol
), nScTab
);
82 if( rnStartW
+ nColW
> nTwipsX
)
86 rnOffset
= nColW
? static_cast< sal_uInt16
>( (nTwipsX
- rnStartW
) * 1024.0 / nColW
+ 0.5 ) : 0;
89 /** Calculates an object row position from a drawing layer Y position (in twips). */
91 const ScDocument
& rDoc
, SCTAB nScTab
, sal_uInt32
& rnXclRow
,
92 sal_uInt32
& rnOffset
, sal_uInt32 nXclStartRow
, sal_uInt32 nXclMaxRow
,
93 tools::Long
& rnStartH
, tools::Long nY
, double fScale
)
95 // rnStartH in conjunction with nXclStartRow is used as buffer for previously calculated height
96 tools::Long nTwipsY
= static_cast< tools::Long
>( nY
/ fScale
+ 0.5 );
97 tools::Long nRowH
= 0;
99 for( sal_uInt32 nRow
= nXclStartRow
; nRow
<= nXclMaxRow
; ++nRow
)
101 nRowH
= rDoc
.GetRowHeight( nRow
, nScTab
);
102 if( rnStartH
+ nRowH
> nTwipsY
)
111 rnXclRow
= nXclMaxRow
;
112 rnOffset
= static_cast< sal_uInt32
>( nRowH
? std::max((nTwipsY
- rnStartH
) * 256.0 / nRowH
+ 0.5, 0.0) : 0 );
115 /** Mirrors a rectangle (from LTR to RTL layout or vice versa). */
116 void lclMirrorRectangle( tools::Rectangle
& rRect
)
118 tools::Long nLeft
= rRect
.Left();
119 rRect
.SetLeft( -rRect
.Right() );
120 rRect
.SetRight( -nLeft
);
123 sal_uInt16
lclGetEmbeddedScale( tools::Long nPageSize
, sal_Int32 nPageScale
, tools::Long nPos
, double fPosScale
)
125 return static_cast< sal_uInt16
>( nPos
* fPosScale
/ nPageSize
* nPageScale
+ 0.5 );
130 XclObjAnchor::XclObjAnchor() :
138 tools::Rectangle
XclObjAnchor::GetRect( const XclRoot
& rRoot
, SCTAB nScTab
, MapUnit eMapUnit
) const
140 ScDocument
& rDoc
= rRoot
.GetDoc();
141 double fScale
= lclGetTwipsScale( eMapUnit
);
142 tools::Rectangle
aRect(
143 lclGetXFromCol(rDoc
, nScTab
, std::min
<SCCOL
>(maFirst
.mnCol
, rDoc
.MaxCol()), mnLX
, fScale
),
144 lclGetYFromRow(rDoc
, nScTab
, std::min
<SCROW
>(maFirst
.mnRow
, rDoc
.MaxRow()), mnTY
, fScale
),
145 lclGetXFromCol(rDoc
, nScTab
, std::min
<SCCOL
>(maLast
.mnCol
, rDoc
.MaxCol()), mnRX
+ 1, fScale
),
146 lclGetYFromRow(rDoc
, nScTab
, std::min
<SCROW
>(maLast
.mnRow
, rDoc
.MaxRow()), mnBY
, fScale
));
148 // adjust coordinates in mirrored sheets
149 if( rDoc
.IsLayoutRTL( nScTab
) )
150 lclMirrorRectangle( aRect
);
154 void XclObjAnchor::SetRect( const XclRoot
& rRoot
, SCTAB nScTab
, const tools::Rectangle
& rRect
, MapUnit eMapUnit
)
156 ScDocument
& rDoc
= rRoot
.GetDoc();
157 sal_uInt16 nXclMaxCol
= rRoot
.GetXclMaxPos().Col();
158 sal_uInt16 nXclMaxRow
= static_cast<sal_uInt16
>( rRoot
.GetXclMaxPos().Row());
160 // adjust coordinates in mirrored sheets
161 tools::Rectangle
aRect( rRect
);
162 if( rDoc
.IsLayoutRTL( nScTab
) )
163 lclMirrorRectangle( aRect
);
165 double fScale
= lclGetTwipsScale( eMapUnit
);
166 tools::Long nDummy
= 0;
167 lclGetColFromX( rDoc
, nScTab
, maFirst
.mnCol
, mnLX
, 0, nXclMaxCol
, nDummy
, aRect
.Left(), fScale
);
168 lclGetColFromX( rDoc
, nScTab
, maLast
.mnCol
, mnRX
, maFirst
.mnCol
, nXclMaxCol
, nDummy
, aRect
.Right(), fScale
);
170 lclGetRowFromY( rDoc
, nScTab
, maFirst
.mnRow
, mnTY
, 0, nXclMaxRow
, nDummy
, aRect
.Top(), fScale
);
171 lclGetRowFromY( rDoc
, nScTab
, maLast
.mnRow
, mnBY
, maFirst
.mnRow
, nXclMaxRow
, nDummy
, aRect
.Bottom(), fScale
);
174 void XclObjAnchor::SetRect( const Size
& rPageSize
, sal_Int32 nScaleX
, sal_Int32 nScaleY
,
175 const tools::Rectangle
& rRect
, MapUnit eMapUnit
)
178 if (const auto eFrom
= MapToO3tlLength(eMapUnit
); eFrom
!= o3tl::Length::invalid
)
179 fScale
= o3tl::convert(1.0, eFrom
, o3tl::Length::mm100
);
181 OSL_FAIL("XclObjAnchor::SetRect - map unit not implemented");
183 /* In objects with DFF client anchor, the position of the shape is stored
184 in the cell address components of the client anchor. In old BIFF3-BIFF5
185 objects, the position is stored in the offset components of the anchor. */
186 maFirst
.mnCol
= lclGetEmbeddedScale( rPageSize
.Width(), nScaleX
, rRect
.Left(), fScale
);
187 maFirst
.mnRow
= lclGetEmbeddedScale( rPageSize
.Height(), nScaleY
, rRect
.Top(), fScale
);
188 maLast
.mnCol
= lclGetEmbeddedScale( rPageSize
.Width(), nScaleX
, rRect
.Right(), fScale
);
189 maLast
.mnRow
= lclGetEmbeddedScale( rPageSize
.Height(), nScaleY
, rRect
.Bottom(), fScale
);
191 // for safety, clear the other members
192 mnLX
= mnTY
= mnRX
= mnBY
= 0;
195 XclObjLineData::XclObjLineData() :
196 mnColorIdx( EXC_OBJ_LINE_AUTOCOLOR
),
197 mnStyle( EXC_OBJ_LINE_SOLID
),
198 mnWidth( EXC_OBJ_LINE_HAIR
),
199 mnAuto( EXC_OBJ_LINE_AUTO
)
203 XclImpStream
& operator>>( XclImpStream
& rStrm
, XclObjLineData
& rLineData
)
205 rLineData
.mnColorIdx
= rStrm
.ReaduInt8();
206 rLineData
.mnStyle
= rStrm
.ReaduInt8();
207 rLineData
.mnWidth
= rStrm
.ReaduInt8();
208 rLineData
.mnAuto
= rStrm
.ReaduInt8();
212 XclObjFillData::XclObjFillData() :
213 mnBackColorIdx( EXC_OBJ_LINE_AUTOCOLOR
),
214 mnPattColorIdx( EXC_OBJ_FILL_AUTOCOLOR
),
215 mnPattern( EXC_PATT_SOLID
),
216 mnAuto( EXC_OBJ_FILL_AUTO
)
220 XclImpStream
& operator>>( XclImpStream
& rStrm
, XclObjFillData
& rFillData
)
222 rFillData
.mnBackColorIdx
= rStrm
.ReaduInt8();
223 rFillData
.mnPattColorIdx
= rStrm
.ReaduInt8();
224 rFillData
.mnPattern
= rStrm
.ReaduInt8();
225 rFillData
.mnAuto
= rStrm
.ReaduInt8();
229 XclObjTextData::XclObjTextData() :
233 mnDefFontIdx( EXC_FONT_APP
),
235 mnOrient( EXC_OBJ_ORIENT_NONE
),
242 void XclObjTextData::ReadObj3( XclImpStream
& rStrm
)
244 mnTextLen
= rStrm
.ReaduInt16();
246 mnFormatSize
= rStrm
.ReaduInt16();
247 mnDefFontIdx
= rStrm
.ReaduInt16();
249 mnFlags
= rStrm
.ReaduInt16();
250 mnOrient
= rStrm
.ReaduInt16();
254 void XclObjTextData::ReadObj5( XclImpStream
& rStrm
)
256 mnTextLen
= rStrm
.ReaduInt16();
258 mnFormatSize
= rStrm
.ReaduInt16();
259 mnDefFontIdx
= rStrm
.ReaduInt16();
261 mnFlags
= rStrm
.ReaduInt16();
262 mnOrient
= rStrm
.ReaduInt16();
264 mnLinkSize
= rStrm
.ReaduInt16();
266 mnButtonFlags
= rStrm
.ReaduInt16();
267 mnShortcut
= rStrm
.ReaduInt16();
268 mnShortcutEA
= rStrm
.ReaduInt16();
271 void XclObjTextData::ReadTxo8( XclImpStream
& rStrm
)
273 mnFlags
= rStrm
.ReaduInt16();
274 mnOrient
= rStrm
.ReaduInt16();
275 mnButtonFlags
= rStrm
.ReaduInt16();
276 mnShortcut
= rStrm
.ReaduInt16();
277 mnShortcutEA
= rStrm
.ReaduInt16();
278 mnTextLen
= rStrm
.ReaduInt16();
279 mnFormatSize
= rStrm
.ReaduInt16();
282 Reference
< XControlModel
> XclControlHelper::GetControlModel( Reference
< XShape
> const & xShape
)
284 Reference
< XControlModel
> xCtrlModel
;
285 Reference
< XControlShape
> xCtrlShape( xShape
, UNO_QUERY
);
286 if( xCtrlShape
.is() )
287 xCtrlModel
= xCtrlShape
->getControl();
295 const char* mpcListenerType
;
296 const char* mpcEventMethod
;
298 spTbxListenerData
[] =
300 // Attention: MUST be in order of the XclTbxEventType enum!
301 /*EXC_TBX_EVENT_ACTION*/ { "XActionListener", "actionPerformed" },
302 /*EXC_TBX_EVENT_MOUSE*/ { "XMouseListener", "mouseReleased" },
303 /*EXC_TBX_EVENT_TEXT*/ { "XTextListener", "textChanged" },
304 /*EXC_TBX_EVENT_VALUE*/ { "XAdjustmentListener", "adjustmentValueChanged" },
305 /*EXC_TBX_EVENT_CHANGE*/ { "XChangeListener", "changed" }
310 bool XclControlHelper::FillMacroDescriptor( ScriptEventDescriptor
& rDescriptor
,
311 XclTbxEventType eEventType
, const OUString
& rXclMacroName
, SfxObjectShell
* pDocShell
)
313 if( !rXclMacroName
.isEmpty() )
315 rDescriptor
.ListenerType
= OUString::createFromAscii( spTbxListenerData
[ eEventType
].mpcListenerType
);
316 rDescriptor
.EventMethod
= OUString::createFromAscii( spTbxListenerData
[ eEventType
].mpcEventMethod
);
317 rDescriptor
.ScriptType
= "Script";
318 rDescriptor
.ScriptCode
= XclTools::GetSbMacroUrl( rXclMacroName
, pDocShell
);
324 OUString
XclControlHelper::ExtractFromMacroDescriptor(
325 const ScriptEventDescriptor
& rDescriptor
, XclTbxEventType eEventType
)
327 if( (!rDescriptor
.ScriptCode
.isEmpty()) &&
328 rDescriptor
.ScriptType
.equalsIgnoreAsciiCase("Script") &&
329 rDescriptor
.ListenerType
.equalsAscii( spTbxListenerData
[ eEventType
].mpcListenerType
) &&
330 rDescriptor
.EventMethod
.equalsAscii( spTbxListenerData
[ eEventType
].mpcEventMethod
) )
331 return XclTools::GetXclMacroName( rDescriptor
.ScriptCode
);
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */