bump product version to 6.3.0.0.beta1
[LibreOffice.git] / cui / source / tabpages / swpossizetabpage.cxx
blobbedbecfa9fa9ba7166013760bfb265d275362cf7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <memory>
21 #include <cstddef>
22 #include <swpossizetabpage.hxx>
23 #include <svx/dlgutil.hxx>
24 #include <svx/anchorid.hxx>
25 #include <svl/aeitem.hxx>
26 #include <svl/intitem.hxx>
27 #include <svx/swframevalidation.hxx>
28 #include <sfx2/htmlmode.hxx>
29 #include <svx/svdview.hxx>
30 #include <svx/svdpagv.hxx>
31 #include <svx/rectenum.hxx>
32 #include <sal/macros.h>
33 #include <com/sun/star/text/HoriOrientation.hpp>
34 #include <com/sun/star/text/VertOrientation.hpp>
35 #include <com/sun/star/text/RelOrientation.hpp>
36 #include <svx/dialogs.hrc>
37 #include <svx/svxids.hrc>
38 #include <svtools/unitconv.hxx>
40 using namespace ::com::sun::star::text;
42 #define SwFPos SvxSwFramePosString
44 enum class LB;
46 struct FrmMap
48 SvxSwFramePosString::StringId eStrId;
49 SvxSwFramePosString::StringId eMirrorStrId;
50 short nAlign;
51 LB nLBRelations;
54 struct RelationMap
56 SvxSwFramePosString::StringId eStrId;
57 SvxSwFramePosString::StringId eMirrorStrId;
58 LB nLBRelation;
59 short nRelation;
61 struct StringIdPair_Impl
63 SvxSwFramePosString::StringId eHori;
64 SvxSwFramePosString::StringId eVert;
67 enum class LB {
68 NONE = 0x000000,
69 Frame = 0x000001, // paragraph text area
70 PrintArea = 0x000002, // paragraph text area + indents
71 VertFrame = 0x000004, // vertical paragraph text area
72 VertPrintArea = 0x000008, // vertical paragraph text area + indents
73 RelFrameLeft = 0x000010, // left paragraph margin
74 RelFrameRight = 0x000020, // right paragraph margin
76 RelPageLeft = 0x000040, // left page margin
77 RelPageRight = 0x000080, // right page margin
78 RelPageFrame = 0x000100, // complete page
79 RelPagePrintArea = 0x000200, // text area of page
81 FlyRelPageLeft = 0x000400, // left frame margin
82 FlyRelPageRight = 0x000800, // right frame margin
83 FlyRelPageFrame = 0x001000, // complete frame
84 FlyRelPagePrintArea = 0x002000, // frame interior
86 RelBase = 0x004000, // as char, relative to baseline
87 RelChar = 0x008000, // as char, relative to character
88 RelRow = 0x010000, // as char, relative to line
90 // #i22305#
91 FlyVertFrame = 0x020000, // vertical entire frame
92 FlyVertPrintArea = 0x040000, // vertical frame text area
94 // #i22341#
95 VertLine = 0x080000, // vertical text line
97 LAST = VertLine
99 namespace o3tl {
100 template<> struct typed_flags<LB> : is_typed_flags<LB, 0x0fffff> {};
103 static RelationMap const aRelationMap[] =
105 {SwFPos::FRAME, SwFPos::FRAME, LB::Frame, RelOrientation::FRAME},
106 {SwFPos::PRTAREA, SwFPos::PRTAREA, LB::PrintArea, RelOrientation::PRINT_AREA},
107 {SwFPos::REL_PG_LEFT, SwFPos::MIR_REL_PG_LEFT, LB::RelPageLeft, RelOrientation::PAGE_LEFT},
108 {SwFPos::REL_PG_RIGHT, SwFPos::MIR_REL_PG_RIGHT, LB::RelPageRight, RelOrientation::PAGE_RIGHT},
109 {SwFPos::REL_FRM_LEFT, SwFPos::MIR_REL_FRM_LEFT, LB::RelFrameLeft, RelOrientation::FRAME_LEFT},
110 {SwFPos::REL_FRM_RIGHT, SwFPos::MIR_REL_FRM_RIGHT, LB::RelFrameRight, RelOrientation::FRAME_RIGHT},
111 {SwFPos::REL_PG_FRAME, SwFPos::REL_PG_FRAME, LB::RelPageFrame, RelOrientation::PAGE_FRAME},
112 {SwFPos::REL_PG_PRTAREA,SwFPos::REL_PG_PRTAREA, LB::RelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
113 {SwFPos::REL_CHAR, SwFPos::REL_CHAR, LB::RelChar, RelOrientation::CHAR},
115 {SwFPos::FLY_REL_PG_LEFT, SwFPos::FLY_MIR_REL_PG_LEFT, LB::FlyRelPageLeft, RelOrientation::PAGE_LEFT},
116 {SwFPos::FLY_REL_PG_RIGHT, SwFPos::FLY_MIR_REL_PG_RIGHT, LB::FlyRelPageRight, RelOrientation::PAGE_RIGHT},
117 {SwFPos::FLY_REL_PG_FRAME, SwFPos::FLY_REL_PG_FRAME, LB::FlyRelPageFrame, RelOrientation::PAGE_FRAME},
118 {SwFPos::FLY_REL_PG_PRTAREA, SwFPos::FLY_REL_PG_PRTAREA, LB::FlyRelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
120 {SwFPos::REL_BORDER, SwFPos::REL_BORDER, LB::VertFrame, RelOrientation::FRAME},
121 {SwFPos::REL_PRTAREA, SwFPos::REL_PRTAREA, LB::VertPrintArea, RelOrientation::PRINT_AREA},
123 // #i22305#
124 {SwFPos::FLY_REL_PG_FRAME, SwFPos::FLY_REL_PG_FRAME, LB::FlyVertFrame, RelOrientation::FRAME},
125 {SwFPos::FLY_REL_PG_PRTAREA, SwFPos::FLY_REL_PG_PRTAREA, LB::FlyVertPrintArea, RelOrientation::PRINT_AREA},
127 // #i22341#
128 {SwFPos::REL_LINE, SwFPos::REL_LINE, LB::VertLine, RelOrientation::TEXT_LINE}
131 static RelationMap const aAsCharRelationMap[] =
133 {SwFPos::REL_BASE, SwFPos::REL_BASE, LB::RelBase, RelOrientation::FRAME},
134 {SwFPos::REL_CHAR, SwFPos::REL_CHAR, LB::RelChar, RelOrientation::FRAME},
135 {SwFPos::REL_ROW, SwFPos::REL_ROW, LB::RelRow, RelOrientation::FRAME}
138 /*--------------------------------------------------------------------
139 Anchored at page
140 --------------------------------------------------------------------*/
142 static constexpr auto HORI_PAGE_REL = LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPageLeft|
143 LB::RelPageRight;
145 static FrmMap const aHPageMap[] =
147 {SwFPos::LEFT, SwFPos::MIR_LEFT, HoriOrientation::LEFT, HORI_PAGE_REL},
148 {SwFPos::RIGHT, SwFPos::MIR_RIGHT, HoriOrientation::RIGHT, HORI_PAGE_REL},
149 {SwFPos::CENTER_HORI,SwFPos::CENTER_HORI, HoriOrientation::CENTER, HORI_PAGE_REL},
150 {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, HoriOrientation::NONE, HORI_PAGE_REL}
153 static FrmMap const aHPageHtmlMap[] =
155 {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
158 #define VERT_PAGE_REL (LB::RelPageFrame|LB::RelPagePrintArea)
160 static FrmMap const aVPageMap[] =
162 {SwFPos::TOP, SwFPos::TOP, VertOrientation::TOP, VERT_PAGE_REL},
163 {SwFPos::BOTTOM, SwFPos::BOTTOM, VertOrientation::BOTTOM, VERT_PAGE_REL},
164 {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, VertOrientation::CENTER, VERT_PAGE_REL},
165 {SwFPos::FROMTOP, SwFPos::FROMTOP, VertOrientation::NONE, VERT_PAGE_REL}
168 static FrmMap const aVPageHtmlMap[] =
170 {SwFPos::FROMTOP, SwFPos::FROMTOP, VertOrientation::NONE, LB::RelPageFrame}
173 /*--------------------------------------------------------------------
174 Anchored at frame
175 --------------------------------------------------------------------*/
177 static constexpr auto HORI_FRAME_REL = LB::FlyRelPageFrame|LB::FlyRelPagePrintArea|
178 LB::FlyRelPageLeft|LB::FlyRelPageRight;
180 static FrmMap const aHFrameMap[] =
182 {SwFPos::LEFT, SwFPos::MIR_LEFT, HoriOrientation::LEFT, HORI_FRAME_REL},
183 {SwFPos::RIGHT, SwFPos::MIR_RIGHT, HoriOrientation::RIGHT, HORI_FRAME_REL},
184 {SwFPos::CENTER_HORI, SwFPos::CENTER_HORI, HoriOrientation::CENTER, HORI_FRAME_REL},
185 {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, HoriOrientation::NONE, HORI_FRAME_REL}
188 static FrmMap const aHFlyHtmlMap[] =
190 {SwFPos::LEFT, SwFPos::MIR_LEFT, HoriOrientation::LEFT, LB::FlyRelPageFrame},
191 {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, HoriOrientation::NONE, LB::FlyRelPageFrame}
194 // #i18732# - own vertical alignment map for to frame anchored objects
195 // #i22305#
196 #define VERT_FRAME_REL (LB::VertFrame|LB::FlyVertPrintArea)
198 static FrmMap const aVFrameMap[] =
200 {SwFPos::TOP, SwFPos::TOP, VertOrientation::TOP, VERT_FRAME_REL},
201 {SwFPos::BOTTOM, SwFPos::BOTTOM, VertOrientation::BOTTOM, VERT_FRAME_REL},
202 {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, VertOrientation::CENTER, VERT_FRAME_REL},
203 {SwFPos::FROMTOP, SwFPos::FROMTOP, VertOrientation::NONE, VERT_FRAME_REL}
206 static FrmMap const aVFlyHtmlMap[] =
208 {SwFPos::TOP, SwFPos::TOP, VertOrientation::TOP, LB::FlyVertFrame},
209 {SwFPos::FROMTOP, SwFPos::FROMTOP, VertOrientation::NONE, LB::FlyVertFrame}
212 static FrmMap const aVMultiSelectionMap[] =
214 {SwFPos::FROMTOP, SwFPos::FROMTOP, VertOrientation::NONE, LB::NONE}
216 static FrmMap const aHMultiSelectionMap[] =
218 {SwFPos::FROMLEFT, SwFPos::FROMLEFT, HoriOrientation::NONE, LB::NONE}
221 /*--------------------------------------------------------------------
222 Anchored at paragraph
223 --------------------------------------------------------------------*/
225 static constexpr auto HORI_PARA_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
226 LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
227 LB::RelFrameRight;
229 static FrmMap const aHParaMap[] =
231 {SwFPos::LEFT, SwFPos::MIR_LEFT, HoriOrientation::LEFT, HORI_PARA_REL},
232 {SwFPos::RIGHT, SwFPos::MIR_RIGHT, HoriOrientation::RIGHT, HORI_PARA_REL},
233 {SwFPos::CENTER_HORI, SwFPos::CENTER_HORI, HoriOrientation::CENTER, HORI_PARA_REL},
234 {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, HoriOrientation::NONE, HORI_PARA_REL}
237 #define HTML_HORI_PARA_REL (LB::Frame|LB::PrintArea)
239 static FrmMap const aHParaHtmlMap[] =
241 {SwFPos::LEFT, SwFPos::LEFT, HoriOrientation::LEFT, HTML_HORI_PARA_REL},
242 {SwFPos::RIGHT, SwFPos::RIGHT, HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
245 static FrmMap const aHParaHtmlAbsMap[] =
247 {SwFPos::LEFT, SwFPos::MIR_LEFT, HoriOrientation::LEFT, HTML_HORI_PARA_REL},
248 {SwFPos::RIGHT, SwFPos::MIR_RIGHT, HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
252 static constexpr auto VERT_PARA_REL = LB::VertFrame|LB::VertPrintArea|
253 LB::RelPageFrame|LB::RelPagePrintArea;
255 static FrmMap const aVParaMap[] =
257 {SwFPos::TOP, SwFPos::TOP, VertOrientation::TOP, VERT_PARA_REL},
258 {SwFPos::BOTTOM, SwFPos::BOTTOM, VertOrientation::BOTTOM, VERT_PARA_REL},
259 {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, VertOrientation::CENTER, VERT_PARA_REL},
260 {SwFPos::FROMTOP, SwFPos::FROMTOP, VertOrientation::NONE, VERT_PARA_REL}
263 static FrmMap const aVParaHtmlMap[] =
265 {SwFPos::TOP, SwFPos::TOP, VertOrientation::TOP, LB::VertPrintArea}
268 /*--------------------------------------------------------------------
269 Anchored at character
270 --------------------------------------------------------------------*/
272 static constexpr auto HORI_CHAR_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
273 LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
274 LB::RelFrameRight|LB::RelChar;
276 static FrmMap aHCharMap[] =
278 {SwFPos::LEFT, SwFPos::MIR_LEFT, HoriOrientation::LEFT, HORI_CHAR_REL},
279 {SwFPos::RIGHT, SwFPos::MIR_RIGHT, HoriOrientation::RIGHT, HORI_CHAR_REL},
280 {SwFPos::CENTER_HORI, SwFPos::CENTER_HORI, HoriOrientation::CENTER, HORI_CHAR_REL},
281 {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, HoriOrientation::NONE, HORI_CHAR_REL}
284 #define HTML_HORI_CHAR_REL (LB::Frame|LB::PrintArea|LB::RelChar)
286 static FrmMap aHCharHtmlMap[] =
288 {SwFPos::LEFT, SwFPos::LEFT, HoriOrientation::LEFT, HTML_HORI_CHAR_REL},
289 {SwFPos::RIGHT, SwFPos::RIGHT, HoriOrientation::RIGHT, HTML_HORI_CHAR_REL}
292 static FrmMap aHCharHtmlAbsMap[] =
294 {SwFPos::LEFT, SwFPos::MIR_LEFT, HoriOrientation::LEFT, LB::PrintArea|LB::RelChar},
295 {SwFPos::RIGHT, SwFPos::MIR_RIGHT, HoriOrientation::RIGHT, LB::PrintArea},
296 {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
299 // #i18732# - allow vertical alignment at page areas
300 // #i22341# - handle <LB::RelChar> on its own
301 static constexpr auto VERT_CHAR_REL = LB::VertFrame|LB::VertPrintArea|
302 LB::RelPageFrame|LB::RelPagePrintArea;
304 static FrmMap aVCharMap[] =
306 // #i22341#
307 // introduce mappings for new vertical alignment at top of line <LB::VertLine>
308 // and correct mapping for vertical alignment at character for position <FROM_BOTTOM>
309 // Note: because of these adjustments the map becomes ambiguous in its values
310 // <eStrId>/<eMirrorStrId> and <nAlign>. These ambiguities are considered
311 // in the methods <SwFrmPage::FillRelLB(..)>, <SwFrmPage::GetAlignment(..)>
312 // and <SwFrmPage::FillPosLB(..)>
313 {SwFPos::TOP, SwFPos::TOP, VertOrientation::TOP, VERT_CHAR_REL|LB::RelChar},
314 {SwFPos::BOTTOM, SwFPos::BOTTOM, VertOrientation::BOTTOM, VERT_CHAR_REL|LB::RelChar},
315 {SwFPos::BELOW, SwFPos::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar},
316 {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, VertOrientation::CENTER, VERT_CHAR_REL|LB::RelChar},
317 {SwFPos::FROMTOP, SwFPos::FROMTOP, VertOrientation::NONE, VERT_CHAR_REL},
318 {SwFPos::FROMBOTTOM, SwFPos::FROMBOTTOM, VertOrientation::NONE, LB::RelChar|LB::VertLine},
319 {SwFPos::TOP, SwFPos::TOP, VertOrientation::LINE_TOP, LB::VertLine},
320 {SwFPos::BOTTOM, SwFPos::BOTTOM, VertOrientation::LINE_BOTTOM, LB::VertLine},
321 {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, VertOrientation::LINE_CENTER, LB::VertLine}
325 static FrmMap const aVCharHtmlMap[] =
327 {SwFPos::BELOW, SwFPos::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
330 static FrmMap const aVCharHtmlAbsMap[] =
332 {SwFPos::TOP, SwFPos::TOP, VertOrientation::TOP, LB::RelChar},
333 {SwFPos::BELOW, SwFPos::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
335 /*--------------------------------------------------------------------
336 anchored as character
337 --------------------------------------------------------------------*/
339 static FrmMap const aVAsCharMap[] =
341 {SwFPos::TOP, SwFPos::TOP, VertOrientation::TOP, LB::RelBase},
342 {SwFPos::BOTTOM, SwFPos::BOTTOM, VertOrientation::BOTTOM, LB::RelBase},
343 {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
345 {SwFPos::TOP, SwFPos::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
346 {SwFPos::BOTTOM, SwFPos::BOTTOM, VertOrientation::CHAR_BOTTOM, LB::RelChar},
347 {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, VertOrientation::CHAR_CENTER, LB::RelChar},
349 {SwFPos::TOP, SwFPos::TOP, VertOrientation::LINE_TOP, LB::RelRow},
350 {SwFPos::BOTTOM, SwFPos::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
351 {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow},
353 {SwFPos::FROMBOTTOM, SwFPos::FROMBOTTOM, VertOrientation::NONE, LB::RelBase}
356 static FrmMap const aVAsCharHtmlMap[] =
358 {SwFPos::TOP, SwFPos::TOP, VertOrientation::TOP, LB::RelBase},
359 {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
361 {SwFPos::TOP, SwFPos::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
363 {SwFPos::TOP, SwFPos::TOP, VertOrientation::LINE_TOP, LB::RelRow},
364 {SwFPos::BOTTOM, SwFPos::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
365 {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow}
368 static std::size_t lcl_GetFrmMapCount(const FrmMap* pMap)
370 if( pMap )
372 if( pMap == aVParaHtmlMap )
373 return SAL_N_ELEMENTS(aVParaHtmlMap);
374 if( pMap == aVAsCharHtmlMap )
375 return SAL_N_ELEMENTS( aVAsCharHtmlMap );
376 if( pMap == aHParaHtmlMap )
377 return SAL_N_ELEMENTS( aHParaHtmlMap );
378 if( pMap == aHParaHtmlAbsMap )
379 return SAL_N_ELEMENTS( aHParaHtmlAbsMap );
380 if( pMap == aVPageMap )
381 return SAL_N_ELEMENTS( aVPageMap );
382 if( pMap == aVPageHtmlMap )
383 return SAL_N_ELEMENTS( aVPageHtmlMap );
384 if( pMap == aVAsCharMap )
385 return SAL_N_ELEMENTS( aVAsCharMap );
386 if( pMap == aVParaMap )
387 return SAL_N_ELEMENTS( aVParaMap );
388 if( pMap == aHParaMap )
389 return SAL_N_ELEMENTS( aHParaMap );
390 if( pMap == aHFrameMap )
391 return SAL_N_ELEMENTS( aHFrameMap );
392 if( pMap == aVFrameMap )
393 return SAL_N_ELEMENTS( aVFrameMap );
394 if( pMap == aHCharMap )
395 return SAL_N_ELEMENTS( aHCharMap );
396 if( pMap == aHCharHtmlMap )
397 return SAL_N_ELEMENTS( aHCharHtmlMap );
398 if( pMap == aHCharHtmlAbsMap )
399 return SAL_N_ELEMENTS( aHCharHtmlAbsMap );
400 if( pMap == aVCharMap )
401 return SAL_N_ELEMENTS( aVCharMap );
402 if( pMap == aVCharHtmlMap )
403 return SAL_N_ELEMENTS( aVCharHtmlMap );
404 if( pMap == aVCharHtmlAbsMap )
405 return SAL_N_ELEMENTS( aVCharHtmlAbsMap );
406 if( pMap == aHPageHtmlMap )
407 return SAL_N_ELEMENTS( aHPageHtmlMap );
408 if( pMap == aHFlyHtmlMap )
409 return SAL_N_ELEMENTS( aHFlyHtmlMap );
410 if( pMap == aVFlyHtmlMap )
411 return SAL_N_ELEMENTS( aVFlyHtmlMap );
412 if( pMap == aVMultiSelectionMap )
413 return SAL_N_ELEMENTS( aVMultiSelectionMap );
414 if( pMap == aHMultiSelectionMap )
415 return SAL_N_ELEMENTS( aHMultiSelectionMap );
416 return SAL_N_ELEMENTS(aHPageMap);
418 return 0;
421 static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(
422 SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL)
424 //special handling of STR_FROMLEFT
425 if(SwFPos::FROMLEFT == eStringId)
427 eStringId = bVertical ?
428 bRTL ? SwFPos::FROMBOTTOM : SwFPos::FROMTOP :
429 bRTL ? SwFPos::FROMRIGHT : SwFPos::FROMLEFT;
430 return eStringId;
432 if(bVertical)
434 //exchange horizontal strings with vertical strings and vice versa
435 static const StringIdPair_Impl aHoriIds[] =
437 {SwFPos::LEFT, SwFPos::TOP},
438 {SwFPos::RIGHT, SwFPos::BOTTOM},
439 {SwFPos::CENTER_HORI, SwFPos::CENTER_VERT},
440 {SwFPos::FROMTOP, SwFPos::FROMRIGHT},
441 {SwFPos::REL_PG_LEFT, SwFPos::REL_PG_TOP},
442 {SwFPos::REL_PG_RIGHT, SwFPos::REL_PG_BOTTOM} ,
443 {SwFPos::REL_FRM_LEFT, SwFPos::REL_FRM_TOP},
444 {SwFPos::REL_FRM_RIGHT, SwFPos::REL_FRM_BOTTOM}
446 static const StringIdPair_Impl aVertIds[] =
448 {SwFPos::TOP, SwFPos::RIGHT},
449 {SwFPos::BOTTOM, SwFPos::LEFT },
450 {SwFPos::CENTER_VERT, SwFPos::CENTER_HORI},
451 {SwFPos::FROMTOP, SwFPos::FROMRIGHT },
452 {SwFPos::REL_PG_TOP, SwFPos::REL_PG_LEFT },
453 {SwFPos::REL_PG_BOTTOM, SwFPos::REL_PG_RIGHT } ,
454 {SwFPos::REL_FRM_TOP, SwFPos::REL_FRM_LEFT },
455 {SwFPos::REL_FRM_BOTTOM, SwFPos::REL_FRM_RIGHT }
457 for(size_t nIndex = 0; nIndex < SAL_N_ELEMENTS(aHoriIds); ++nIndex)
459 if(aHoriIds[nIndex].eHori == eStringId)
461 eStringId = aHoriIds[nIndex].eVert;
462 return eStringId;
465 for(size_t nIndex = 0; nIndex < SAL_N_ELEMENTS(aVertIds); ++nIndex)
467 if(aVertIds[nIndex].eHori == eStringId)
469 eStringId = aVertIds[nIndex].eVert;
470 break;
474 return eStringId;
476 // #i22341# - helper method in order to determine all possible
477 // listbox relations in a relation map for a given relation
478 static LB lcl_GetLBRelationsForRelations( const sal_uInt16 _nRel )
480 LB nLBRelations = LB::NONE;
482 for (RelationMap const & nRelMapPos : aRelationMap)
484 if ( nRelMapPos.nRelation == _nRel )
486 nLBRelations |= nRelMapPos.nLBRelation;
490 return nLBRelations;
493 // #i22341# - helper method on order to determine all possible
494 // listbox relations in a relation map for a given string ID
495 static LB lcl_GetLBRelationsForStrID(const FrmMap* _pMap,
496 const SvxSwFramePosString::StringId _eStrId,
497 const bool _bUseMirrorStr )
499 LB nLBRelations = LB::NONE;
501 std::size_t nRelMapSize = lcl_GetFrmMapCount( _pMap );
502 for ( std::size_t nRelMapPos = 0; nRelMapPos < nRelMapSize; ++nRelMapPos )
504 if ( ( !_bUseMirrorStr && _pMap[nRelMapPos].eStrId == _eStrId ) ||
505 ( _bUseMirrorStr && _pMap[nRelMapPos].eMirrorStrId == _eStrId ) )
507 nLBRelations |= _pMap[nRelMapPos].nLBRelations;
511 return nLBRelations;
514 SvxSwPosSizeTabPage::SvxSwPosSizeTabPage(TabPageParent pParent, const SfxItemSet& rInAttrs)
515 : SfxTabPage(pParent, "cui/ui/swpossizepage.ui", "SwPosSizePage", &rInAttrs)
516 , m_pVMap(nullptr)
517 , m_pHMap(nullptr)
518 , m_pSdrView(nullptr)
519 , m_nOldH(HoriOrientation::CENTER)
520 , m_nOldHRel(RelOrientation::FRAME)
521 , m_nOldV(VertOrientation::TOP)
522 , m_nOldVRel(RelOrientation::PRINT_AREA)
523 , m_fWidthHeightRatio(1.0)
524 , m_bHtmlMode(false)
525 , m_bIsVerticalFrame(false)
526 , m_bPositioningDisabled(false)
527 , m_bIsMultiSelection(false)
528 , m_bIsInRightToLeft(false)
529 , m_nProtectSizeState(TRISTATE_FALSE)
530 , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
531 , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
532 , m_xKeepRatioCB(m_xBuilder->weld_check_button("ratio"))
533 , m_xToPageRB(m_xBuilder->weld_radio_button("topage"))
534 , m_xToParaRB(m_xBuilder->weld_radio_button("topara"))
535 , m_xToCharRB(m_xBuilder->weld_radio_button("tochar"))
536 , m_xAsCharRB(m_xBuilder->weld_radio_button("aschar"))
537 , m_xToFrameRB(m_xBuilder->weld_radio_button("toframe"))
538 , m_xPositionCB(m_xBuilder->weld_check_button("pos"))
539 , m_xSizeCB(m_xBuilder->weld_check_button("size"))
540 , m_xPosFrame(m_xBuilder->weld_widget("posframe"))
541 , m_xHoriFT(m_xBuilder->weld_label("horiposft"))
542 , m_xHoriLB(m_xBuilder->weld_combo_box("horipos"))
543 , m_xHoriByFT(m_xBuilder->weld_label("horibyft"))
544 , m_xHoriByMF(m_xBuilder->weld_metric_spin_button("byhori", FieldUnit::CM))
545 , m_xHoriToFT(m_xBuilder->weld_label("horitoft"))
546 , m_xHoriToLB(m_xBuilder->weld_combo_box("horianchor"))
547 , m_xHoriMirrorCB(m_xBuilder->weld_check_button("mirror"))
548 , m_xVertFT(m_xBuilder->weld_label("vertposft"))
549 , m_xVertLB(m_xBuilder->weld_combo_box("vertpos"))
550 , m_xVertByFT(m_xBuilder->weld_label("vertbyft"))
551 , m_xVertByMF(m_xBuilder->weld_metric_spin_button("byvert", FieldUnit::CM))
552 , m_xVertToFT(m_xBuilder->weld_label("verttoft"))
553 , m_xVertToLB(m_xBuilder->weld_combo_box("vertanchor"))
554 , m_xFollowCB(m_xBuilder->weld_check_button("followtextflow"))
555 , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
557 setOptimalFrmWidth();
558 setOptimalRelWidth();
560 FieldUnit eDlgUnit = GetModuleFieldUnit( rInAttrs );
561 SetFieldUnit(*m_xHoriByMF, eDlgUnit, true);
562 SetFieldUnit(*m_xVertByMF, eDlgUnit, true);
563 SetFieldUnit(*m_xWidthMF , eDlgUnit, true);
564 SetFieldUnit(*m_xHeightMF, eDlgUnit, true);
566 SetExchangeSupport();
568 Link<weld::Widget&,void> aLk3 = LINK(this, SvxSwPosSizeTabPage, RangeModifyHdl);
569 m_xWidthMF->connect_focus_out(aLk3);
570 m_xHeightMF->connect_focus_out(aLk3);
571 m_xHoriByMF->connect_focus_out(aLk3);
572 m_xVertByMF->connect_focus_out(aLk3);
573 m_xFollowCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, RangeModifyClickHdl));
575 Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxSwPosSizeTabPage, ModifyHdl);
576 m_xWidthMF->connect_value_changed( aLk );
577 m_xHeightMF->connect_value_changed( aLk );
578 m_xHoriByMF->connect_value_changed( aLk );
579 m_xVertByMF->connect_value_changed( aLk );
581 Link<weld::ToggleButton&,void> aLk2 = LINK(this, SvxSwPosSizeTabPage, AnchorTypeHdl);
582 m_xToPageRB->connect_toggled( aLk2 );
583 m_xToParaRB->connect_toggled( aLk2 );
584 m_xToCharRB->connect_toggled( aLk2 );
585 m_xAsCharRB->connect_toggled( aLk2 );
586 m_xToFrameRB->connect_toggled( aLk2 );
588 m_xHoriLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
589 m_xVertLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
591 m_xHoriToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
592 m_xVertToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
594 m_xHoriMirrorCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, MirrorHdl));
595 m_xPositionCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, ProtectHdl));
598 SvxSwPosSizeTabPage::~SvxSwPosSizeTabPage()
600 disposeOnce();
603 void SvxSwPosSizeTabPage::dispose()
605 m_xWidthMF.reset();
606 m_xHeightMF.reset();
607 m_xHoriByMF.reset();
608 m_xVertByMF.reset();
609 SfxTabPage::dispose();
612 namespace
614 struct FrmMaps
616 FrmMap const *pMap;
617 size_t nCount;
621 void SvxSwPosSizeTabPage::setOptimalFrmWidth()
623 static const FrmMaps aMaps[] = {
624 { aHPageMap, SAL_N_ELEMENTS(aHPageMap) },
625 { aHPageHtmlMap, SAL_N_ELEMENTS(aHPageHtmlMap) },
626 { aVPageMap, SAL_N_ELEMENTS(aVPageMap) },
627 { aVPageHtmlMap, SAL_N_ELEMENTS(aVPageHtmlMap) },
628 { aHFrameMap, SAL_N_ELEMENTS(aHFrameMap) },
629 { aHFlyHtmlMap, SAL_N_ELEMENTS(aHFlyHtmlMap) },
630 { aVFrameMap, SAL_N_ELEMENTS(aVFrameMap) },
631 { aVFlyHtmlMap, SAL_N_ELEMENTS(aVFlyHtmlMap) },
632 { aHParaMap, SAL_N_ELEMENTS(aHParaMap) },
633 { aHParaHtmlMap, SAL_N_ELEMENTS(aHParaHtmlMap) },
634 { aHParaHtmlAbsMap, SAL_N_ELEMENTS(aHParaHtmlAbsMap) },
635 { aVParaMap, SAL_N_ELEMENTS(aVParaMap) },
636 { aVParaHtmlMap, SAL_N_ELEMENTS(aVParaHtmlMap) },
637 { aHCharMap, SAL_N_ELEMENTS(aHCharMap) },
638 { aHCharHtmlMap, SAL_N_ELEMENTS(aHCharHtmlMap) },
639 { aHCharHtmlAbsMap, SAL_N_ELEMENTS(aHCharHtmlAbsMap) },
640 { aVCharMap, SAL_N_ELEMENTS(aVCharMap) },
641 { aVCharHtmlMap, SAL_N_ELEMENTS(aVCharHtmlMap) },
642 { aVCharHtmlAbsMap, SAL_N_ELEMENTS(aVCharHtmlAbsMap) },
643 { aVAsCharMap, SAL_N_ELEMENTS(aVAsCharMap) },
644 { aVAsCharHtmlMap, SAL_N_ELEMENTS(aVAsCharHtmlMap) }
647 std::vector<SvxSwFramePosString::StringId> aFrames;
648 for (const FrmMaps& aMap : aMaps)
650 for (size_t j = 0; j < aMap.nCount; ++j)
652 aFrames.push_back(aMap.pMap[j].eStrId);
653 aFrames.push_back(aMap.pMap[j].eMirrorStrId);
657 std::sort(aFrames.begin(), aFrames.end());
658 aFrames.erase(std::unique(aFrames.begin(), aFrames.end()), aFrames.end());
660 for (auto const& frame : aFrames)
662 m_xHoriLB->append_text(SvxSwFramePosString::GetString(frame));
665 Size aBiggest(m_xHoriLB->get_preferred_size());
666 m_xHoriLB->set_size_request(aBiggest.Width(), -1);
667 m_xVertLB->set_size_request(aBiggest.Width(), -1);
668 m_xHoriLB->clear();
671 namespace
673 struct RelationMaps
675 RelationMap const *pMap;
676 size_t nCount;
680 void SvxSwPosSizeTabPage::setOptimalRelWidth()
682 static const RelationMaps aMaps[] = {
683 { aRelationMap, SAL_N_ELEMENTS(aRelationMap) },
684 { aAsCharRelationMap, SAL_N_ELEMENTS(aAsCharRelationMap) }
687 std::vector<SvxSwFramePosString::StringId> aRels;
688 for (const RelationMaps& aMap : aMaps)
690 for (size_t j = 0; j < aMap.nCount; ++j)
692 aRels.push_back(aMap.pMap[j].eStrId);
693 aRels.push_back(aMap.pMap[j].eMirrorStrId);
697 std::sort(aRels.begin(), aRels.end());
698 aRels.erase(std::unique(aRels.begin(), aRels.end()), aRels.end());
700 for (auto const& elem : aRels)
702 m_xHoriLB->append_text(SvxSwFramePosString::GetString(elem));
705 Size aBiggest(m_xHoriLB->get_preferred_size());
706 m_xHoriLB->set_size_request(aBiggest.Width(), -1);
707 m_xVertLB->set_size_request(aBiggest.Width(), -1);
708 m_xHoriLB->clear();
711 VclPtr<SfxTabPage> SvxSwPosSizeTabPage::Create(TabPageParent pParent, const SfxItemSet* rSet)
713 return VclPtr<SvxSwPosSizeTabPage>::Create(pParent, *rSet);
716 const sal_uInt16* SvxSwPosSizeTabPage::GetRanges()
718 static const sal_uInt16 pSwPosRanges[] =
720 SID_ATTR_TRANSFORM_POS_X,
721 SID_ATTR_TRANSFORM_POS_Y,
722 SID_ATTR_TRANSFORM_PROTECT_POS,
723 SID_ATTR_TRANSFORM_PROTECT_POS,
724 SID_ATTR_TRANSFORM_INTERN,
725 SID_ATTR_TRANSFORM_INTERN,
726 SID_ATTR_TRANSFORM_ANCHOR,
727 SID_ATTR_TRANSFORM_VERT_ORIENT,
728 SID_ATTR_TRANSFORM_WIDTH,
729 SID_ATTR_TRANSFORM_SIZE_POINT,
730 SID_ATTR_TRANSFORM_PROTECT_POS,
731 SID_ATTR_TRANSFORM_INTERN,
732 SID_ATTR_TRANSFORM_AUTOWIDTH,
733 SID_ATTR_TRANSFORM_VERT_ORIENT,
734 SID_HTML_MODE,
735 SID_HTML_MODE,
736 SID_SW_FOLLOW_TEXT_FLOW,
737 SID_SW_FOLLOW_TEXT_FLOW,
738 SID_ATTR_TRANSFORM_HORI_POSITION,
739 SID_ATTR_TRANSFORM_VERT_POSITION,
742 return pSwPosRanges;
745 bool SvxSwPosSizeTabPage::FillItemSet( SfxItemSet* rSet)
747 bool bAnchorChanged = false;
748 RndStdIds nAnchor = GetAnchorType(&bAnchorChanged);
749 bool bModified = false;
750 if(bAnchorChanged)
752 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor)));
753 bModified = true;
755 if (m_xPositionCB->get_state_changed_from_saved())
757 if (m_xPositionCB->get_inconsistent())
758 rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
759 else
760 rSet->Put(
761 SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
762 m_xPositionCB->get_state() == TRISTATE_TRUE ) );
763 bModified = true;
766 if (m_xSizeCB->get_state_changed_from_saved())
768 if (m_xSizeCB->get_inconsistent())
769 rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
770 else
771 rSet->Put(
772 SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
773 m_xSizeCB->get_state() == TRISTATE_TRUE ) );
774 bModified = true;
777 const SfxItemSet& rOldSet = GetItemSet();
779 if(!m_bPositioningDisabled)
781 //on multiple selections the positioning is set via SdrView
782 if (m_bIsMultiSelection)
784 if (m_xHoriByMF->get_value_changed_from_saved() || m_xVertByMF->get_value_changed_from_saved())
786 auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
787 auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
789 // old rectangle with CoreUnit
790 m_aRect = m_pSdrView->GetAllMarkedRect();
791 m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
793 nHoriByPos += m_aAnchorPos.X();
794 nVertByPos += m_aAnchorPos.Y();
796 rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_X ), nHoriByPos ) );
797 rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_Y ), nVertByPos ) );
799 bModified = true;
802 else
804 if ( m_pHMap )
806 const SfxInt16Item& rHoriOrient =
807 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_ORIENT));
808 const SfxInt16Item& rHoriRelation =
809 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_RELATION));
810 const SfxInt32Item& rHoriPosition =
811 static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_POSITION)) ;
813 sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
814 short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
815 short nRel = GetRelation(*m_xHoriToLB);
816 const auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
817 if (
818 nAlign != rHoriOrient.GetValue() ||
819 nRel != rHoriRelation.GetValue() ||
820 (m_xHoriByMF->get_sensitive() && nHoriByPos != rHoriPosition.GetValue())
823 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, nAlign));
824 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, nRel));
825 if(m_xHoriByMF->get_sensitive())
826 rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, nHoriByPos));
827 bModified = true;
830 if (m_xHoriMirrorCB->get_sensitive() && m_xHoriMirrorCB->get_state_changed_from_saved())
831 bModified |= nullptr != rSet->Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, m_xHoriMirrorCB->get_active()));
833 if ( m_pVMap )
835 const SfxInt16Item& rVertOrient =
836 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_ORIENT));
837 const SfxInt16Item& rVertRelation =
838 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_RELATION));
839 const SfxInt32Item& rVertPosition =
840 static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_POSITION));
842 sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
843 short nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
844 short nRel = GetRelation(*m_xVertToLB);
845 // #i34055# - convert vertical position for
846 // as-character anchored objects
847 auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
848 if (GetAnchorType() == RndStdIds::FLY_AS_CHAR)
850 nVertByPos *= -1;
852 if ( nAlign != rVertOrient.GetValue() ||
853 nRel != rVertRelation.GetValue() ||
854 ( m_xVertByMF->get_sensitive() &&
855 nVertByPos != rVertPosition.GetValue() ) )
857 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, nAlign));
858 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, nRel));
859 if(m_xVertByMF->get_sensitive())
860 rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, nVertByPos));
861 bModified = true;
865 // #i18732#
866 if (m_xFollowCB->get_state_changed_from_saved())
868 //Writer internal type - based on SfxBoolItem
869 const SfxPoolItem* pItem = GetItem( rOldSet, SID_SW_FOLLOW_TEXT_FLOW);
870 if(pItem)
872 std::unique_ptr<SfxBoolItem> pFollow(static_cast<SfxBoolItem*>(pItem->Clone()));
873 pFollow->SetValue(m_xFollowCB->get_active());
874 bModified |= nullptr != rSet->Put(*pFollow);
879 if (m_xWidthMF->get_value_changed_from_saved() || m_xHeightMF->get_value_changed_from_saved())
881 sal_uInt32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
882 sal_uInt32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
883 rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_WIDTH ), nWidth ) );
884 rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_HEIGHT ), nHeight ) );
885 //this item is required by SdrEditView::SetGeoAttrToMarked()
886 rSet->Put( SfxAllEnumItem( GetWhich( SID_ATTR_TRANSFORM_SIZE_POINT ), sal_uInt16(RectPoint::LT) ) );
888 bModified = true;
891 return bModified;
894 void SvxSwPosSizeTabPage::Reset( const SfxItemSet* rSet)
896 const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_ANCHOR );
897 bool bInvalidateAnchor = false;
898 RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA;
899 if(pItem)
901 nAnchorType = static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pItem)->GetValue());
902 switch(nAnchorType)
904 case RndStdIds::FLY_AT_PAGE: m_xToPageRB->set_active(true); break;
905 case RndStdIds::FLY_AT_PARA: m_xToParaRB->set_active(true); break;
906 case RndStdIds::FLY_AT_CHAR: m_xToCharRB->set_active(true); break;
907 case RndStdIds::FLY_AS_CHAR: m_xAsCharRB->set_active(true); break;
908 case RndStdIds::FLY_AT_FLY: m_xToFrameRB->set_active(true); break;
909 default : bInvalidateAnchor = true;
911 m_xToPageRB->save_state();
912 m_xToParaRB->save_state();
913 m_xToCharRB->save_state();
914 m_xAsCharRB->save_state();
915 m_xToFrameRB->save_state();
917 if (bInvalidateAnchor)
919 m_xToPageRB->set_sensitive( false );
920 m_xToParaRB->set_sensitive( false );
921 m_xToCharRB->set_sensitive( false );
922 m_xAsCharRB->set_sensitive( false );
923 m_xToFrameRB->set_sensitive( false );
926 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_POS );
927 if (pItem)
929 bool bProtected = static_cast<const SfxBoolItem*>(pItem)->GetValue();
930 m_xPositionCB->set_active(bProtected);
931 m_xSizeCB->set_sensitive(!bProtected);
933 else
935 m_xPositionCB->set_inconsistent(true);
938 m_xPositionCB->save_state();
940 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_SIZE );
942 if (pItem)
944 m_xSizeCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
946 else
947 m_xSizeCB->set_inconsistent(true);
948 m_xSizeCB->save_state();
950 pItem = GetItem( *rSet, SID_HTML_MODE );
951 if(pItem)
953 m_bHtmlMode =
954 (static_cast<const SfxUInt16Item*>(pItem)->GetValue() & HTMLMODE_ON)
955 != 0;
958 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT );
959 if(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue())
961 OUString sHLabel = m_xHoriFT->get_label();
962 m_xHoriFT->set_label(m_xVertFT->get_label());
963 m_xVertFT->set_label(sHLabel);
964 m_bIsVerticalFrame = true;
966 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_RTL_TEXT);
967 if(pItem)
968 m_bIsInRightToLeft = static_cast<const SfxBoolItem*>(pItem)->GetValue();
970 pItem = GetItem( *rSet, SID_SW_FOLLOW_TEXT_FLOW);
971 if(pItem)
973 const bool bFollowTextFlow =
974 static_cast<const SfxBoolItem*>(pItem)->GetValue();
975 m_xFollowCB->set_active(bFollowTextFlow);
977 m_xFollowCB->save_state();
979 if(m_bHtmlMode)
981 m_xHoriMirrorCB->hide();
982 m_xKeepRatioCB->set_sensitive(false);
983 // #i18732# - hide checkbox in HTML mode
984 m_xFollowCB->hide();
986 else
988 // #i18732# correct enable/disable of check box 'Mirror on..'
989 m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
991 // #i18732# - enable/disable check box 'Follow text flow'.
992 m_xFollowCB->set_sensitive(m_xToParaRB->get_active() ||
993 m_xToCharRB->get_active());
996 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_WIDTH );
997 sal_Int32 nWidth = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
999 m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
1001 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HEIGHT );
1002 sal_Int32 nHeight = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
1003 m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
1004 m_fWidthHeightRatio = double(nWidth) / double(nHeight);
1006 if(!m_bPositioningDisabled)
1008 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_ORIENT);
1009 if(pItem)
1011 short nHoriOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1012 m_nOldH = nHoriOrientation;
1014 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_ORIENT);
1015 if(pItem)
1017 short nVertOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1018 m_nOldV = nVertOrientation;
1020 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_RELATION);
1021 if(pItem)
1023 m_nOldHRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1026 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_RELATION);
1027 if(pItem)
1029 m_nOldVRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1031 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_MIRROR);
1032 if(pItem)
1033 m_xHoriMirrorCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
1034 m_xHoriMirrorCB->save_state();
1036 sal_Int32 nHoriPos = 0;
1037 sal_Int32 nVertPos = 0;
1038 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_POSITION);
1039 if(pItem)
1040 nHoriPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
1041 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_POSITION);
1042 if(pItem)
1043 nVertPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
1045 InitPos(nAnchorType, m_nOldH, m_nOldHRel, m_nOldV, m_nOldVRel, nHoriPos, nVertPos);
1047 m_xVertByMF->save_value();
1048 m_xHoriByMF->save_value();
1049 // #i18732#
1050 m_xFollowCB->save_state();
1052 RangeModifyHdl(m_xWidthMF->get_widget()); // initially set maximum values
1056 DeactivateRC SvxSwPosSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
1058 if( _pSet )
1060 _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
1061 m_xPositionCB->get_active()));
1062 _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
1063 m_xSizeCB->get_active()));
1064 FillItemSet( _pSet );
1066 return DeactivateRC::LeavePage;
1069 void SvxSwPosSizeTabPage::EnableAnchorTypes(SvxAnchorIds nAnchorEnable)
1071 if (nAnchorEnable & SvxAnchorIds::Fly)
1072 m_xToFrameRB->show();
1073 if (!(nAnchorEnable & SvxAnchorIds::Page))
1074 m_xToPageRB->set_sensitive(false);
1077 RndStdIds SvxSwPosSizeTabPage::GetAnchorType(bool* pbHasChanged)
1079 RndStdIds nRet = RndStdIds::UNKNOWN;
1080 weld::RadioButton* pCheckedButton = nullptr;
1081 if(m_xToParaRB->get_sensitive())
1083 if(m_xToPageRB->get_active())
1085 nRet = RndStdIds::FLY_AT_PAGE;
1086 pCheckedButton = m_xToPageRB.get();
1088 else if(m_xToParaRB->get_active())
1090 nRet = RndStdIds::FLY_AT_PARA;
1091 pCheckedButton = m_xToParaRB.get();
1093 else if(m_xToCharRB->get_active())
1095 nRet = RndStdIds::FLY_AT_CHAR;
1096 pCheckedButton = m_xToCharRB.get();
1098 else if(m_xAsCharRB->get_active())
1100 nRet = RndStdIds::FLY_AS_CHAR;
1101 pCheckedButton = m_xAsCharRB.get();
1103 else if(m_xToFrameRB->get_active())
1105 nRet = RndStdIds::FLY_AT_FLY;
1106 pCheckedButton = m_xToFrameRB.get();
1109 if(pbHasChanged)
1111 if(pCheckedButton)
1112 *pbHasChanged = pCheckedButton->get_state_changed_from_saved();
1113 else
1114 *pbHasChanged = false;
1116 return nRet;
1119 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyClickHdl, weld::ToggleButton&, void)
1121 RangeModifyHdl(m_xWidthMF->get_widget());
1124 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyHdl, weld::Widget&, void)
1126 if (m_bPositioningDisabled)
1127 return;
1128 SvxSwFrameValidation aVal;
1130 aVal.nAnchorType = GetAnchorType();
1131 aVal.bAutoHeight = false;
1132 aVal.bMirror = m_xHoriMirrorCB->get_active();
1133 // #i18732#
1134 aVal.bFollowTextFlow = m_xFollowCB->get_active();
1136 if ( m_pHMap )
1138 // horizontal alignment
1139 sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriToLB);
1140 sal_uInt16 nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
1141 sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
1143 aVal.nHoriOrient = static_cast<short>(nAlign);
1144 aVal.nHRelOrient = static_cast<short>(nRel);
1146 else
1147 aVal.nHoriOrient = HoriOrientation::NONE;
1149 if ( m_pVMap )
1151 // vertical alignment
1152 sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
1153 sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
1154 sal_uInt16 nRel = GetRelation(*m_xVertToLB);
1156 aVal.nVertOrient = static_cast<short>(nAlign);
1157 aVal.nVRelOrient = static_cast<short>(nRel);
1159 else
1160 aVal.nVertOrient = VertOrientation::NONE;
1162 const auto nAtHorzPosVal = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
1163 const auto nAtVertPosVal = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
1165 aVal.nHPos = nAtHorzPosVal;
1166 aVal.nVPos = nAtVertPosVal;
1168 sal_Int32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
1169 sal_Int32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
1170 aVal.nWidth = nWidth;
1171 aVal.nHeight = nHeight;
1173 m_aValidateLink.Call(aVal);
1175 // minimum width also for style
1176 m_xHeightMF->set_min(m_xHeightMF->normalize(aVal.nMinHeight), FieldUnit::TWIP);
1177 m_xWidthMF->set_min(m_xWidthMF->normalize(aVal.nMinWidth), FieldUnit::TWIP);
1179 sal_Int32 nMaxWidth(aVal.nMaxWidth);
1180 sal_Int32 nMaxHeight(aVal.nMaxHeight);
1182 sal_Int64 nTmp = m_xHeightMF->normalize(nMaxHeight);
1183 m_xHeightMF->set_max(nTmp, FieldUnit::TWIP);
1185 nTmp = m_xWidthMF->normalize(nMaxWidth);
1186 m_xWidthMF->set_max(nTmp, FieldUnit::TWIP);
1188 m_xHoriByMF->set_range(m_xHoriByMF->normalize(aVal.nMinHPos),
1189 m_xHoriByMF->normalize(aVal.nMaxHPos), FieldUnit::TWIP);
1190 if ( aVal.nHPos != nAtHorzPosVal )
1191 m_xHoriByMF->set_value(m_xHoriByMF->normalize(aVal.nHPos), FieldUnit::TWIP);
1193 m_xVertByMF->set_range(m_xVertByMF->normalize(aVal.nMinVPos),
1194 m_xVertByMF->normalize(aVal.nMaxVPos), FieldUnit::TWIP);
1195 if ( aVal.nVPos != nAtVertPosVal )
1196 m_xVertByMF->set_value(m_xVertByMF->normalize(aVal.nVPos), FieldUnit::TWIP);
1199 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, AnchorTypeHdl, weld::ToggleButton&, void)
1201 m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
1203 // #i18732# - enable check box 'Follow text flow' for anchor
1204 // type to-paragraph' and to-character
1205 m_xFollowCB->set_sensitive(m_xToParaRB->get_active() || m_xToCharRB->get_active());
1207 RndStdIds nId = GetAnchorType();
1209 InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
1210 RangeModifyHdl(m_xWidthMF->get_widget());
1212 if(m_bHtmlMode)
1214 PosHdl(*m_xHoriLB);
1215 PosHdl(*m_xVertLB);
1219 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, MirrorHdl, weld::ToggleButton&, void)
1221 RndStdIds nId = GetAnchorType();
1222 InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
1225 IMPL_LINK( SvxSwPosSizeTabPage, RelHdl, weld::ComboBox&, rLB, void )
1227 bool bHori = &rLB == m_xHoriToLB.get();
1229 UpdateExample();
1231 if (m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()) // again special treatment
1233 if(bHori)
1235 sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
1236 if(RelOrientation::PRINT_AREA == nRel && 0 == m_xVertLB->get_active())
1238 m_xVertLB->set_active(1);
1240 else if(RelOrientation::CHAR == nRel && 1 == m_xVertLB->get_active())
1242 m_xVertLB->set_active(0);
1246 RangeModifyHdl(m_xWidthMF->get_widget());
1249 IMPL_LINK(SvxSwPosSizeTabPage, PosHdl, weld::ComboBox&, rLB, void)
1251 bool bHori = &rLB == m_xHoriLB.get();
1252 weld::ComboBox* pRelLB = bHori ? m_xHoriToLB.get() : m_xVertToLB.get();
1253 weld::Label* pRelFT = bHori ? m_xHoriToFT.get() : m_xVertToFT.get();
1254 FrmMap const *pMap = bHori ? m_pHMap : m_pVMap;
1257 sal_uInt16 nMapPos = GetMapPos(pMap, rLB);
1258 sal_uInt16 nAlign = GetAlignment(pMap, nMapPos, *pRelLB);
1260 if (bHori)
1262 bool bEnable = HoriOrientation::NONE == nAlign;
1263 m_xHoriByMF->set_sensitive( bEnable );
1264 m_xHoriByFT->set_sensitive( bEnable );
1266 else
1268 bool bEnable = VertOrientation::NONE == nAlign;
1269 m_xVertByMF->set_sensitive( bEnable );
1270 m_xVertByFT->set_sensitive( bEnable );
1273 RangeModifyHdl(m_xWidthMF->get_widget());
1275 short nRel = 0;
1276 if (rLB.get_active() != -1)
1278 if (pRelLB->get_active() != -1)
1279 nRel = reinterpret_cast<RelationMap*>(pRelLB->get_active_id().toUInt64())->nRelation;
1281 FillRelLB(pMap, nMapPos, nAlign, nRel, *pRelLB, *pRelFT);
1283 else
1284 pRelLB->clear();
1286 UpdateExample();
1288 // special treatment for HTML-Mode with horz-vert-dependencies
1289 if (m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType())
1291 bool bSet = false;
1292 if(bHori)
1294 // on the right only below is allowed - from the left only at the top
1295 // from the left at the character -> below
1296 if((HoriOrientation::LEFT == nAlign || HoriOrientation::RIGHT == nAlign) &&
1297 0 == m_xVertLB->get_active())
1299 if(RelOrientation::FRAME == nRel)
1300 m_xVertLB->set_active(1);
1301 else
1302 m_xVertLB->set_active(0);
1303 bSet = true;
1305 else if(HoriOrientation::LEFT == nAlign && 1 == m_xVertLB->get_active())
1307 m_xVertLB->set_active(0);
1308 bSet = true;
1310 else if(HoriOrientation::NONE == nAlign && 1 == m_xVertLB->get_active())
1312 m_xVertLB->set_active(0);
1313 bSet = true;
1315 if(bSet)
1316 PosHdl(*m_xVertLB);
1318 else
1320 if(VertOrientation::TOP == nAlign)
1322 if(1 == m_xHoriLB->get_active())
1324 m_xHoriLB->set_active(0);
1325 bSet = true;
1327 m_xHoriToLB->set_active(1);
1329 else if(VertOrientation::CHAR_BOTTOM == nAlign)
1331 if(2 == m_xHoriLB->get_active())
1333 m_xHoriLB->set_active(0);
1334 bSet = true;
1336 m_xHoriToLB->set_active(0) ;
1338 if(bSet)
1339 PosHdl(*m_xHoriLB);
1345 IMPL_LINK( SvxSwPosSizeTabPage, ModifyHdl, weld::MetricSpinButton&, rEdit, void )
1347 auto nWidth = m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP));
1348 auto nHeight = m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP));
1349 if (m_xKeepRatioCB->get_active())
1351 if ( &rEdit == m_xWidthMF.get() )
1353 nHeight = int(static_cast<double>(nWidth) / m_fWidthHeightRatio);
1354 m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
1356 else if(&rEdit == m_xHeightMF.get())
1358 nWidth = int(static_cast<double>(nHeight) * m_fWidthHeightRatio);
1359 m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
1362 m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
1363 UpdateExample();
1366 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, ProtectHdl, weld::ToggleButton&, void)
1368 if (m_xSizeCB->get_sensitive())
1370 m_nProtectSizeState = m_xSizeCB->get_state();
1373 m_xSizeCB->set_state(m_xPositionCB->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : m_nProtectSizeState);
1374 m_xSizeCB->set_sensitive(m_xPositionCB->get_sensitive() && !m_xPositionCB->get_active());
1377 short SvxSwPosSizeTabPage::GetRelation(const weld::ComboBox& rRelationLB)
1379 short nRel = 0;
1380 int nPos = rRelationLB.get_active();
1381 if (nPos != -1)
1383 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rRelationLB.get_id(nPos).toUInt64());
1384 nRel = pEntry->nRelation;
1387 return nRel;
1390 short SvxSwPosSizeTabPage::GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox& rRelationLB)
1392 short nAlign = 0;
1394 // #i22341# - special handling also for map <aVCharMap>,
1395 // because it contains ambiguous items for alignment
1396 if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap ||
1397 pMap == aVCharMap )
1399 if (rRelationLB.get_active() != -1)
1401 LB nRel = reinterpret_cast<RelationMap*>(rRelationLB.get_active_id().toUInt64())->nLBRelation;
1402 std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1403 SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
1405 for (std::size_t i = 0; i < nMapCount; i++)
1407 if (pMap[i].eStrId == eStrId)
1409 LB nLBRelations = pMap[i].nLBRelations;
1410 if (nLBRelations & nRel)
1412 nAlign = pMap[i].nAlign;
1413 break;
1419 else if (pMap)
1420 nAlign = pMap[nMapPos].nAlign;
1422 return nAlign;
1425 sal_uInt16 SvxSwPosSizeTabPage::GetMapPos(FrmMap const *pMap, const weld::ComboBox& rAlignLB)
1427 sal_uInt16 nMapPos = 0;
1428 int nLBSelPos = rAlignLB.get_active();
1430 if (nLBSelPos != -1)
1432 if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
1434 std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1435 OUString sSelEntry(rAlignLB.get_active_text());
1437 for (std::size_t i = 0; i < nMapCount; i++)
1439 SvxSwFramePosString::StringId eResId = pMap[i].eStrId;
1441 OUString sEntry = SvxSwFramePosString::GetString(eResId);
1443 if (sEntry == sSelEntry)
1445 nMapPos = sal::static_int_cast< sal_uInt16 >(i);
1446 break;
1450 else
1451 nMapPos = nLBSelPos;
1454 return nMapPos;
1457 void SvxSwPosSizeTabPage::InitPos(RndStdIds nAnchor,
1458 sal_uInt16 nH,
1459 sal_uInt16 nHRel,
1460 sal_uInt16 nV,
1461 sal_uInt16 nVRel,
1462 long nX,
1463 long nY)
1465 int nPos = m_xVertLB->get_active();
1466 if (nPos != -1 && m_pVMap)
1468 m_nOldV = m_pVMap[nPos].nAlign;
1469 nPos = m_xVertToLB->get_active();
1470 if (nPos != -1)
1471 m_nOldVRel = reinterpret_cast<RelationMap*>(m_xVertToLB->get_id(nPos).toUInt64())->nRelation;
1474 nPos = m_xHoriLB->get_active();
1475 if (nPos != -1 && m_pHMap)
1477 m_nOldH = m_pHMap[nPos].nAlign;
1479 nPos = m_xHoriToLB->get_active();
1480 if (nPos != -1)
1481 m_nOldHRel = reinterpret_cast<RelationMap*>(m_xHoriToLB->get_id(nPos).toUInt64())->nRelation;
1484 bool bEnable = true;
1485 if( m_bIsMultiSelection )
1487 m_pVMap = aVMultiSelectionMap;
1488 m_pHMap = aHMultiSelectionMap;
1490 else if (nAnchor == RndStdIds::FLY_AT_PAGE)
1492 m_pVMap = m_bHtmlMode ? aVPageHtmlMap : aVPageMap;
1493 m_pHMap = m_bHtmlMode ? aHPageHtmlMap : aHPageMap;
1495 else if (nAnchor == RndStdIds::FLY_AT_FLY)
1497 // #i18732# - own vertical alignment map for to frame
1498 // anchored objects.
1499 m_pVMap = m_bHtmlMode ? aVFlyHtmlMap : aVFrameMap;
1500 m_pHMap = m_bHtmlMode ? aHFlyHtmlMap : aHFrameMap;
1502 else if (nAnchor == RndStdIds::FLY_AT_PARA)
1504 if(m_bHtmlMode)
1506 m_pVMap = aVParaHtmlMap;
1507 m_pHMap = aHParaHtmlAbsMap;
1509 else
1511 m_pVMap = aVParaMap;
1512 m_pHMap = aHParaMap;
1515 else if (nAnchor == RndStdIds::FLY_AT_CHAR)
1517 if(m_bHtmlMode)
1519 m_pVMap = aVCharHtmlAbsMap;
1520 m_pHMap = aHCharHtmlAbsMap;
1522 else
1524 m_pVMap = aVCharMap;
1525 m_pHMap = aHCharMap;
1528 else if (nAnchor == RndStdIds::FLY_AS_CHAR)
1530 m_pVMap = m_bHtmlMode ? aVAsCharHtmlMap : aVAsCharMap;
1531 m_pHMap = nullptr;
1532 bEnable = false;
1534 m_xHoriLB->set_sensitive(bEnable);
1535 m_xHoriFT->set_sensitive(bEnable);
1537 // select current Pos
1538 // horizontal
1539 if ( nH == USHRT_MAX )
1541 nH = m_nOldH;
1542 nHRel = m_nOldHRel;
1544 // #i22341# - pass <nHRel> as 3rd parameter to method <FillPosLB>
1545 sal_uInt16 nMapPos = FillPosLB(m_pHMap, nH, nHRel, *m_xHoriLB);
1546 FillRelLB(m_pHMap, nMapPos, nH, nHRel, *m_xHoriToLB, *m_xHoriToFT);
1548 // vertical
1549 if ( nV == USHRT_MAX )
1551 nV = m_nOldV;
1552 nVRel = m_nOldVRel;
1554 // #i22341# - pass <nVRel> as 3rd parameter to method <FillPosLB>
1555 nMapPos = FillPosLB(m_pVMap, nV, nVRel, *m_xVertLB);
1556 FillRelLB(m_pVMap, nMapPos, nV, nVRel, *m_xVertToLB, *m_xVertToFT);
1558 // Edits init
1559 bEnable = nH == HoriOrientation::NONE && nAnchor != RndStdIds::FLY_AS_CHAR; //#61359# why not in formats&& !bFormat;
1560 if (!bEnable)
1562 m_xHoriByMF->set_value(0, FieldUnit::TWIP);
1564 else if(m_bIsMultiSelection)
1566 m_xHoriByMF->set_value(m_xHoriByMF->normalize(m_aRect.Left()), FieldUnit::TWIP);
1568 else
1570 if (nX != LONG_MAX)
1571 m_xHoriByMF->set_value(m_xHoriByMF->normalize(nX), FieldUnit::TWIP);
1573 m_xHoriByFT->set_sensitive(bEnable);
1574 m_xHoriByMF->set_sensitive(bEnable);
1576 bEnable = nV == VertOrientation::NONE;
1577 if ( !bEnable )
1579 m_xVertByMF->set_value( 0, FieldUnit::TWIP );
1581 else if(m_bIsMultiSelection)
1583 m_xVertByMF->set_value(m_xVertByMF->normalize(m_aRect.Top()), FieldUnit::TWIP);
1585 else
1587 if (nAnchor == RndStdIds::FLY_AS_CHAR)
1589 if ( nY == LONG_MAX )
1590 nY = 0;
1591 else
1592 nY *= -1;
1594 if ( nY != LONG_MAX )
1595 m_xVertByMF->set_value( m_xVertByMF->normalize(nY), FieldUnit::TWIP );
1597 m_xVertByFT->set_sensitive( bEnable );
1598 m_xVertByMF->set_sensitive( bEnable );
1599 UpdateExample();
1602 void SvxSwPosSizeTabPage::UpdateExample()
1604 int nPos = m_xHoriLB->get_active();
1605 if (m_pHMap && nPos != -1)
1607 sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
1608 short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
1609 short nRel = GetRelation(*m_xHoriToLB);
1611 m_aExampleWN.SetHAlign(nAlign);
1612 m_aExampleWN.SetHoriRel(nRel);
1615 nPos = m_xVertLB->get_active();
1616 if (m_pVMap && nPos != -1)
1618 sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
1619 sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
1620 sal_uInt16 nRel = GetRelation(*m_xVertToLB);
1622 m_aExampleWN.SetVAlign(nAlign);
1623 m_aExampleWN.SetVertRel(nRel);
1626 // Size
1627 auto nXPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
1628 auto nYPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
1629 m_aExampleWN.SetRelPos(Point(nXPos, nYPos));
1631 m_aExampleWN.SetAnchor( GetAnchorType() );
1632 m_aExampleWN.Invalidate();
1635 void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, sal_uInt16 nMapPos, sal_uInt16 nAlign,
1636 sal_uInt16 nRel, weld::ComboBox& rLB, weld::Label& rFT)
1638 OUString sSelEntry;
1639 LB nLBRelations = LB::NONE;
1640 std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1642 rLB.clear();
1644 if (nMapPos < nMapCount)
1646 if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
1648 OUString sOldEntry(rLB.get_active_text());
1649 SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
1651 for (std::size_t _nMapPos = 0; _nMapPos < nMapCount; _nMapPos++)
1653 if (pMap[_nMapPos].eStrId == eStrId)
1655 nLBRelations = pMap[_nMapPos].nLBRelations;
1656 for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aAsCharRelationMap); nRelPos++)
1658 if (nLBRelations & aAsCharRelationMap[nRelPos].nLBRelation)
1660 SvxSwFramePosString::StringId sStrId1 = aAsCharRelationMap[nRelPos].eStrId;
1662 sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
1663 OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
1664 rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aAsCharRelationMap[nRelPos])), sEntry);
1665 if (pMap[_nMapPos].nAlign == nAlign)
1666 sSelEntry = sEntry;
1667 break;
1672 if (!sSelEntry.isEmpty())
1673 rLB.set_active_text(sSelEntry);
1674 else
1676 rLB.set_active_text(sOldEntry);
1677 if (rLB.get_active() == -1)
1679 for (int i = 0; i < rLB.get_count(); i++)
1681 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
1682 if (pEntry->nLBRelation == LB::RelChar) // Default
1684 rLB.set_active(i);
1685 break;
1691 else
1693 // #i22341# - special handling for map <aVCharMap>,
1694 // because its ambiguous in its <eStrId>/<eMirrorStrId>.
1695 if ( pMap == aVCharMap )
1697 nLBRelations = ::lcl_GetLBRelationsForStrID( pMap,
1698 ( m_xHoriMirrorCB->get_active()
1699 ? pMap[nMapPos].eMirrorStrId
1700 : pMap[nMapPos].eStrId ),
1701 m_xHoriMirrorCB->get_active() );
1703 else
1705 nLBRelations = pMap[nMapPos].nLBRelations;
1708 for (sal_uLong nBit = 1; nBit < sal_uLong(LB::LAST); nBit <<= 1)
1710 if (nLBRelations & static_cast<LB>(nBit))
1712 for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aRelationMap); nRelPos++)
1714 if (aRelationMap[nRelPos].nLBRelation == static_cast<LB>(nBit))
1716 SvxSwFramePosString::StringId sStrId1 = m_xHoriMirrorCB->get_active() ? aRelationMap[nRelPos].eMirrorStrId : aRelationMap[nRelPos].eStrId;
1717 sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
1718 OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
1719 rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aRelationMap[nRelPos])), sEntry);
1720 if (sSelEntry.isEmpty() && aRelationMap[nRelPos].nRelation == nRel)
1721 sSelEntry = sEntry;
1726 if (!sSelEntry.isEmpty())
1727 rLB.set_active_text(sSelEntry);
1728 else
1730 // Probably anchor change. So look for a similar relation.
1731 switch (nRel)
1733 case RelOrientation::FRAME: nRel = RelOrientation::PAGE_FRAME; break;
1734 case RelOrientation::PRINT_AREA: nRel = RelOrientation::PAGE_PRINT_AREA; break;
1735 case RelOrientation::PAGE_LEFT: nRel = RelOrientation::FRAME_LEFT; break;
1736 case RelOrientation::PAGE_RIGHT: nRel = RelOrientation::FRAME_RIGHT; break;
1737 case RelOrientation::FRAME_LEFT: nRel = RelOrientation::PAGE_LEFT; break;
1738 case RelOrientation::FRAME_RIGHT: nRel = RelOrientation::PAGE_RIGHT; break;
1739 case RelOrientation::PAGE_FRAME: nRel = RelOrientation::FRAME; break;
1740 case RelOrientation::PAGE_PRINT_AREA: nRel = RelOrientation::PRINT_AREA; break;
1742 default:
1743 if (rLB.get_count())
1745 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(rLB.get_count() - 1).toUInt64());
1746 nRel = pEntry->nRelation;
1748 break;
1751 for (int i = 0; i < rLB.get_count(); ++i)
1753 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
1754 if (pEntry->nRelation == nRel)
1756 rLB.set_active(i);
1757 break;
1761 if (rLB.get_active() == -1)
1762 rLB.set_active(0);
1767 rLB.set_sensitive(rLB.get_count() != 0);
1768 rFT.set_sensitive(rLB.get_count() != 0);
1770 RelHdl(rLB);
1773 sal_uInt16 SvxSwPosSizeTabPage::FillPosLB(FrmMap const *_pMap,
1774 sal_uInt16 _nAlign,
1775 const sal_uInt16 _nRel,
1776 weld::ComboBox& _rLB)
1778 OUString sSelEntry, sOldEntry;
1779 sOldEntry = _rLB.get_active_text();
1781 _rLB.clear();
1783 // #i22341# - determine all possible listbox relations for
1784 // given relation for map <aVCharMap>
1785 const LB nLBRelations = (_pMap != aVCharMap)
1786 ? LB::NONE
1787 : ::lcl_GetLBRelationsForRelations( _nRel );
1789 // fill listbox
1790 std::size_t nCount = ::lcl_GetFrmMapCount(_pMap);
1791 for (std::size_t i = 0; _pMap && i < nCount; ++i)
1793 SvxSwFramePosString::StringId eStrId = m_xHoriMirrorCB->get_active() ? _pMap[i].eMirrorStrId : _pMap[i].eStrId;
1794 eStrId = lcl_ChangeResIdToVerticalOrRTL(eStrId, m_bIsVerticalFrame, m_bIsInRightToLeft);
1795 OUString sEntry(SvxSwFramePosString::GetString(eStrId));
1796 if (_rLB.find_text(sEntry) == -1)
1798 // don't insert duplicate entries at character wrapped borders
1799 _rLB.append_text(sEntry);
1801 // #i22341# - add condition to handle map <aVCharMap>
1802 // that is ambiguous in the alignment.
1803 if ( _pMap[i].nAlign == _nAlign &&
1804 ( _pMap != aVCharMap || _pMap[i].nLBRelations & nLBRelations ) )
1806 sSelEntry = sEntry;
1810 _rLB.set_active_text(sSelEntry);
1811 if (_rLB.get_active() == -1)
1812 _rLB.set_active_text(sOldEntry);
1814 if (_rLB.get_active() == -1)
1815 _rLB.set_active(0);
1817 PosHdl(_rLB);
1819 return GetMapPos(_pMap, _rLB);
1822 void SvxSwPosSizeTabPage::SetView( const SdrView* pSdrView )
1824 m_pSdrView = pSdrView;
1825 if(!m_pSdrView)
1827 OSL_FAIL("No SdrView* set");
1828 return;
1831 // setting of the rectangle and the working area
1832 m_aRect = m_pSdrView->GetAllMarkedRect();
1833 m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
1835 // get WorkArea
1836 m_aWorkArea = m_pSdrView->GetWorkArea();
1838 // consider anchor position (for Writer)
1839 const SdrMarkList& rMarkList = m_pSdrView->GetMarkedObjectList();
1840 if( rMarkList.GetMarkCount() > 0 )
1842 const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
1843 m_aAnchorPos = pObj->GetAnchorPos();
1845 if( m_aAnchorPos != Point(0,0) ) // -> Writer
1847 for( size_t i = 1; i < rMarkList.GetMarkCount(); ++i )
1849 pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
1850 if( m_aAnchorPos != pObj->GetAnchorPos() )
1852 // different anchor positions -> disable positioning
1853 m_xPosFrame->set_sensitive(false);
1854 m_bPositioningDisabled = true;
1855 return;
1859 Point aPt = m_aAnchorPos * -1;
1860 Point aPt2 = aPt;
1862 aPt += m_aWorkArea.TopLeft();
1863 m_aWorkArea.SetPos( aPt );
1865 aPt2 += m_aRect.TopLeft();
1866 m_aRect.SetPos( aPt2 );
1869 // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
1870 if( rMarkList.GetMarkCount() != 1 )
1871 m_bIsMultiSelection = true;
1872 #if OSL_DEBUG_LEVEL > 1
1873 else
1875 const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
1876 SdrObjKind eKind = (SdrObjKind) pObj->GetObjIdentifier();
1877 if( ( pObj->GetObjInventor() == SdrInventor::Default ) &&
1878 ( eKind==OBJ_TEXT || eKind==OBJ_TITLETEXT || eKind==OBJ_OUTLINETEXT) &&
1879 pObj->HasText() )
1881 OSL_FAIL("AutoWidth/AutoHeight should be enabled");
1884 #endif
1887 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */