bump product version to 6.4.0.3
[LibreOffice.git] / cui / source / tabpages / swpossizetabpage.cxx
blob46a210559892076ce33de0c636b9b9793de02b84
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/swframeposstrings.hxx>
32 #include <svx/rectenum.hxx>
33 #include <sal/macros.h>
34 #include <com/sun/star/text/HoriOrientation.hpp>
35 #include <com/sun/star/text/VertOrientation.hpp>
36 #include <com/sun/star/text/RelOrientation.hpp>
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(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
515 : SfxTabPage(pPage, pController, "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 m_xWidthMF.reset();
601 m_xHeightMF.reset();
602 m_xHoriByMF.reset();
603 m_xVertByMF.reset();
606 namespace
608 struct FrmMaps
610 FrmMap const *pMap;
611 size_t nCount;
615 void SvxSwPosSizeTabPage::setOptimalFrmWidth()
617 static const FrmMaps aMaps[] = {
618 { aHPageMap, SAL_N_ELEMENTS(aHPageMap) },
619 { aHPageHtmlMap, SAL_N_ELEMENTS(aHPageHtmlMap) },
620 { aVPageMap, SAL_N_ELEMENTS(aVPageMap) },
621 { aVPageHtmlMap, SAL_N_ELEMENTS(aVPageHtmlMap) },
622 { aHFrameMap, SAL_N_ELEMENTS(aHFrameMap) },
623 { aHFlyHtmlMap, SAL_N_ELEMENTS(aHFlyHtmlMap) },
624 { aVFrameMap, SAL_N_ELEMENTS(aVFrameMap) },
625 { aVFlyHtmlMap, SAL_N_ELEMENTS(aVFlyHtmlMap) },
626 { aHParaMap, SAL_N_ELEMENTS(aHParaMap) },
627 { aHParaHtmlMap, SAL_N_ELEMENTS(aHParaHtmlMap) },
628 { aHParaHtmlAbsMap, SAL_N_ELEMENTS(aHParaHtmlAbsMap) },
629 { aVParaMap, SAL_N_ELEMENTS(aVParaMap) },
630 { aVParaHtmlMap, SAL_N_ELEMENTS(aVParaHtmlMap) },
631 { aHCharMap, SAL_N_ELEMENTS(aHCharMap) },
632 { aHCharHtmlMap, SAL_N_ELEMENTS(aHCharHtmlMap) },
633 { aHCharHtmlAbsMap, SAL_N_ELEMENTS(aHCharHtmlAbsMap) },
634 { aVCharMap, SAL_N_ELEMENTS(aVCharMap) },
635 { aVCharHtmlMap, SAL_N_ELEMENTS(aVCharHtmlMap) },
636 { aVCharHtmlAbsMap, SAL_N_ELEMENTS(aVCharHtmlAbsMap) },
637 { aVAsCharMap, SAL_N_ELEMENTS(aVAsCharMap) },
638 { aVAsCharHtmlMap, SAL_N_ELEMENTS(aVAsCharHtmlMap) }
641 std::vector<SvxSwFramePosString::StringId> aFrames;
642 for (const FrmMaps& aMap : aMaps)
644 for (size_t j = 0; j < aMap.nCount; ++j)
646 aFrames.push_back(aMap.pMap[j].eStrId);
647 aFrames.push_back(aMap.pMap[j].eMirrorStrId);
651 std::sort(aFrames.begin(), aFrames.end());
652 aFrames.erase(std::unique(aFrames.begin(), aFrames.end()), aFrames.end());
654 for (auto const& frame : aFrames)
656 m_xHoriLB->append_text(SvxSwFramePosString::GetString(frame));
659 Size aBiggest(m_xHoriLB->get_preferred_size());
660 m_xHoriLB->set_size_request(aBiggest.Width(), -1);
661 m_xVertLB->set_size_request(aBiggest.Width(), -1);
662 m_xHoriLB->clear();
665 namespace
667 struct RelationMaps
669 RelationMap const *pMap;
670 size_t nCount;
674 void SvxSwPosSizeTabPage::setOptimalRelWidth()
676 static const RelationMaps aMaps[] = {
677 { aRelationMap, SAL_N_ELEMENTS(aRelationMap) },
678 { aAsCharRelationMap, SAL_N_ELEMENTS(aAsCharRelationMap) }
681 std::vector<SvxSwFramePosString::StringId> aRels;
682 for (const RelationMaps& aMap : aMaps)
684 for (size_t j = 0; j < aMap.nCount; ++j)
686 aRels.push_back(aMap.pMap[j].eStrId);
687 aRels.push_back(aMap.pMap[j].eMirrorStrId);
691 std::sort(aRels.begin(), aRels.end());
692 aRels.erase(std::unique(aRels.begin(), aRels.end()), aRels.end());
694 for (auto const& elem : aRels)
696 m_xHoriLB->append_text(SvxSwFramePosString::GetString(elem));
699 Size aBiggest(m_xHoriLB->get_preferred_size());
700 m_xHoriLB->set_size_request(aBiggest.Width(), -1);
701 m_xVertLB->set_size_request(aBiggest.Width(), -1);
702 m_xHoriLB->clear();
705 std::unique_ptr<SfxTabPage> SvxSwPosSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
707 return std::make_unique<SvxSwPosSizeTabPage>(pPage, pController, *rSet);
710 const sal_uInt16* SvxSwPosSizeTabPage::GetRanges()
712 static const sal_uInt16 pSwPosRanges[] =
714 SID_ATTR_TRANSFORM_POS_X,
715 SID_ATTR_TRANSFORM_POS_Y,
716 SID_ATTR_TRANSFORM_PROTECT_POS,
717 SID_ATTR_TRANSFORM_PROTECT_POS,
718 SID_ATTR_TRANSFORM_INTERN,
719 SID_ATTR_TRANSFORM_INTERN,
720 SID_ATTR_TRANSFORM_ANCHOR,
721 SID_ATTR_TRANSFORM_VERT_ORIENT,
722 SID_ATTR_TRANSFORM_WIDTH,
723 SID_ATTR_TRANSFORM_SIZE_POINT,
724 SID_ATTR_TRANSFORM_PROTECT_POS,
725 SID_ATTR_TRANSFORM_INTERN,
726 SID_ATTR_TRANSFORM_AUTOWIDTH,
727 SID_ATTR_TRANSFORM_VERT_ORIENT,
728 SID_HTML_MODE,
729 SID_HTML_MODE,
730 SID_SW_FOLLOW_TEXT_FLOW,
731 SID_SW_FOLLOW_TEXT_FLOW,
732 SID_ATTR_TRANSFORM_HORI_POSITION,
733 SID_ATTR_TRANSFORM_VERT_POSITION,
736 return pSwPosRanges;
739 bool SvxSwPosSizeTabPage::FillItemSet( SfxItemSet* rSet)
741 bool bAnchorChanged = false;
742 RndStdIds nAnchor = GetAnchorType(&bAnchorChanged);
743 bool bModified = false;
744 if(bAnchorChanged)
746 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor)));
747 bModified = true;
749 if (m_xPositionCB->get_state_changed_from_saved())
751 if (m_xPositionCB->get_inconsistent())
752 rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
753 else
754 rSet->Put(
755 SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
756 m_xPositionCB->get_state() == TRISTATE_TRUE ) );
757 bModified = true;
760 if (m_xSizeCB->get_state_changed_from_saved())
762 if (m_xSizeCB->get_inconsistent())
763 rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
764 else
765 rSet->Put(
766 SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
767 m_xSizeCB->get_state() == TRISTATE_TRUE ) );
768 bModified = true;
771 const SfxItemSet& rOldSet = GetItemSet();
773 if(!m_bPositioningDisabled)
775 //on multiple selections the positioning is set via SdrView
776 if (m_bIsMultiSelection)
778 if (m_xHoriByMF->get_value_changed_from_saved() || m_xVertByMF->get_value_changed_from_saved())
780 auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
781 auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
783 // old rectangle with CoreUnit
784 m_aRect = m_pSdrView->GetAllMarkedRect();
785 m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
787 nHoriByPos += m_aAnchorPos.X();
788 nVertByPos += m_aAnchorPos.Y();
790 rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_X ), nHoriByPos ) );
791 rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_Y ), nVertByPos ) );
793 bModified = true;
796 else
798 if ( m_pHMap )
800 const SfxInt16Item& rHoriOrient =
801 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_ORIENT));
802 const SfxInt16Item& rHoriRelation =
803 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_RELATION));
804 const SfxInt32Item& rHoriPosition =
805 static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_POSITION)) ;
807 sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
808 short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
809 short nRel = GetRelation(*m_xHoriToLB);
810 const auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
811 if (
812 nAlign != rHoriOrient.GetValue() ||
813 nRel != rHoriRelation.GetValue() ||
814 (m_xHoriByMF->get_sensitive() && nHoriByPos != rHoriPosition.GetValue())
817 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, nAlign));
818 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, nRel));
819 if(m_xHoriByMF->get_sensitive())
820 rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, nHoriByPos));
821 bModified = true;
824 if (m_xHoriMirrorCB->get_sensitive() && m_xHoriMirrorCB->get_state_changed_from_saved())
825 bModified |= nullptr != rSet->Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, m_xHoriMirrorCB->get_active()));
827 if ( m_pVMap )
829 const SfxInt16Item& rVertOrient =
830 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_ORIENT));
831 const SfxInt16Item& rVertRelation =
832 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_RELATION));
833 const SfxInt32Item& rVertPosition =
834 static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_POSITION));
836 sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
837 short nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
838 short nRel = GetRelation(*m_xVertToLB);
839 // #i34055# - convert vertical position for
840 // as-character anchored objects
841 auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
842 if (GetAnchorType() == RndStdIds::FLY_AS_CHAR)
844 nVertByPos *= -1;
846 if ( nAlign != rVertOrient.GetValue() ||
847 nRel != rVertRelation.GetValue() ||
848 ( m_xVertByMF->get_sensitive() &&
849 nVertByPos != rVertPosition.GetValue() ) )
851 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, nAlign));
852 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, nRel));
853 if(m_xVertByMF->get_sensitive())
854 rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, nVertByPos));
855 bModified = true;
859 // #i18732#
860 if (m_xFollowCB->get_state_changed_from_saved())
862 //Writer internal type - based on SfxBoolItem
863 const SfxPoolItem* pItem = GetItem( rOldSet, SID_SW_FOLLOW_TEXT_FLOW);
864 if(pItem)
866 std::unique_ptr<SfxBoolItem> pFollow(static_cast<SfxBoolItem*>(pItem->Clone()));
867 pFollow->SetValue(m_xFollowCB->get_active());
868 bModified |= nullptr != rSet->Put(*pFollow);
873 if (m_xWidthMF->get_value_changed_from_saved() || m_xHeightMF->get_value_changed_from_saved())
875 sal_uInt32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
876 sal_uInt32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
877 rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_WIDTH ), nWidth ) );
878 rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_HEIGHT ), nHeight ) );
879 //this item is required by SdrEditView::SetGeoAttrToMarked()
880 rSet->Put( SfxUInt16Item( GetWhich( SID_ATTR_TRANSFORM_SIZE_POINT ), sal_uInt16(RectPoint::LT) ) );
882 bModified = true;
885 return bModified;
888 void SvxSwPosSizeTabPage::Reset( const SfxItemSet* rSet)
890 const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_ANCHOR );
891 bool bInvalidateAnchor = false;
892 RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA;
893 if(pItem)
895 nAnchorType = static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pItem)->GetValue());
896 switch(nAnchorType)
898 case RndStdIds::FLY_AT_PAGE: m_xToPageRB->set_active(true); break;
899 case RndStdIds::FLY_AT_PARA: m_xToParaRB->set_active(true); break;
900 case RndStdIds::FLY_AT_CHAR: m_xToCharRB->set_active(true); break;
901 case RndStdIds::FLY_AS_CHAR: m_xAsCharRB->set_active(true); break;
902 case RndStdIds::FLY_AT_FLY: m_xToFrameRB->set_active(true); break;
903 default : bInvalidateAnchor = true;
905 m_xToPageRB->save_state();
906 m_xToParaRB->save_state();
907 m_xToCharRB->save_state();
908 m_xAsCharRB->save_state();
909 m_xToFrameRB->save_state();
911 if (bInvalidateAnchor)
913 m_xToPageRB->set_sensitive( false );
914 m_xToParaRB->set_sensitive( false );
915 m_xToCharRB->set_sensitive( false );
916 m_xAsCharRB->set_sensitive( false );
917 m_xToFrameRB->set_sensitive( false );
920 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_POS );
921 if (pItem)
923 bool bProtected = static_cast<const SfxBoolItem*>(pItem)->GetValue();
924 m_xPositionCB->set_active(bProtected);
925 m_xSizeCB->set_sensitive(!bProtected);
927 else
929 m_xPositionCB->set_inconsistent(true);
932 m_xPositionCB->save_state();
934 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_SIZE );
936 if (pItem)
938 m_xSizeCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
940 else
941 m_xSizeCB->set_inconsistent(true);
942 m_xSizeCB->save_state();
944 pItem = GetItem( *rSet, SID_HTML_MODE );
945 if(pItem)
947 m_bHtmlMode =
948 (static_cast<const SfxUInt16Item*>(pItem)->GetValue() & HTMLMODE_ON)
949 != 0;
952 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT );
953 if(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue())
955 OUString sHLabel = m_xHoriFT->get_label();
956 m_xHoriFT->set_label(m_xVertFT->get_label());
957 m_xVertFT->set_label(sHLabel);
958 m_bIsVerticalFrame = true;
960 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_RTL_TEXT);
961 if(pItem)
962 m_bIsInRightToLeft = static_cast<const SfxBoolItem*>(pItem)->GetValue();
964 pItem = GetItem( *rSet, SID_SW_FOLLOW_TEXT_FLOW);
965 if(pItem)
967 const bool bFollowTextFlow =
968 static_cast<const SfxBoolItem*>(pItem)->GetValue();
969 m_xFollowCB->set_active(bFollowTextFlow);
971 m_xFollowCB->save_state();
973 if(m_bHtmlMode)
975 m_xHoriMirrorCB->hide();
976 m_xKeepRatioCB->set_sensitive(false);
977 // #i18732# - hide checkbox in HTML mode
978 m_xFollowCB->hide();
980 else
982 // #i18732# correct enable/disable of check box 'Mirror on..'
983 m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
985 // #i18732# - enable/disable check box 'Follow text flow'.
986 m_xFollowCB->set_sensitive(m_xToParaRB->get_active() ||
987 m_xToCharRB->get_active());
990 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_WIDTH );
991 sal_Int32 nWidth = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
993 m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
994 m_xWidthMF->save_value();
996 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HEIGHT );
997 sal_Int32 nHeight = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
998 m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
999 m_xHeightMF->save_value();
1000 m_fWidthHeightRatio = double(nWidth) / double(nHeight);
1002 if(!m_bPositioningDisabled)
1004 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_ORIENT);
1005 if(pItem)
1007 short nHoriOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1008 m_nOldH = nHoriOrientation;
1010 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_ORIENT);
1011 if(pItem)
1013 short nVertOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1014 m_nOldV = nVertOrientation;
1016 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_RELATION);
1017 if(pItem)
1019 m_nOldHRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1022 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_RELATION);
1023 if(pItem)
1025 m_nOldVRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1027 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_MIRROR);
1028 if(pItem)
1029 m_xHoriMirrorCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
1030 m_xHoriMirrorCB->save_state();
1032 sal_Int32 nHoriPos = 0;
1033 sal_Int32 nVertPos = 0;
1034 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_POSITION);
1035 if(pItem)
1036 nHoriPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
1037 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_POSITION);
1038 if(pItem)
1039 nVertPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
1041 InitPos(nAnchorType, m_nOldH, m_nOldHRel, m_nOldV, m_nOldVRel, nHoriPos, nVertPos);
1043 m_xVertByMF->save_value();
1044 m_xHoriByMF->save_value();
1045 // #i18732#
1046 m_xFollowCB->save_state();
1048 RangeModifyHdl(m_xWidthMF->get_widget()); // initially set maximum values
1052 DeactivateRC SvxSwPosSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
1054 if( _pSet )
1056 _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
1057 m_xPositionCB->get_active()));
1058 _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
1059 m_xSizeCB->get_active()));
1060 FillItemSet( _pSet );
1062 return DeactivateRC::LeavePage;
1065 void SvxSwPosSizeTabPage::EnableAnchorTypes(SvxAnchorIds nAnchorEnable)
1067 if (nAnchorEnable & SvxAnchorIds::Fly)
1068 m_xToFrameRB->show();
1069 if (!(nAnchorEnable & SvxAnchorIds::Page))
1070 m_xToPageRB->set_sensitive(false);
1073 RndStdIds SvxSwPosSizeTabPage::GetAnchorType(bool* pbHasChanged)
1075 RndStdIds nRet = RndStdIds::UNKNOWN;
1076 weld::RadioButton* pCheckedButton = nullptr;
1077 if(m_xToParaRB->get_sensitive())
1079 if(m_xToPageRB->get_active())
1081 nRet = RndStdIds::FLY_AT_PAGE;
1082 pCheckedButton = m_xToPageRB.get();
1084 else if(m_xToParaRB->get_active())
1086 nRet = RndStdIds::FLY_AT_PARA;
1087 pCheckedButton = m_xToParaRB.get();
1089 else if(m_xToCharRB->get_active())
1091 nRet = RndStdIds::FLY_AT_CHAR;
1092 pCheckedButton = m_xToCharRB.get();
1094 else if(m_xAsCharRB->get_active())
1096 nRet = RndStdIds::FLY_AS_CHAR;
1097 pCheckedButton = m_xAsCharRB.get();
1099 else if(m_xToFrameRB->get_active())
1101 nRet = RndStdIds::FLY_AT_FLY;
1102 pCheckedButton = m_xToFrameRB.get();
1105 if(pbHasChanged)
1107 if(pCheckedButton)
1108 *pbHasChanged = pCheckedButton->get_state_changed_from_saved();
1109 else
1110 *pbHasChanged = false;
1112 return nRet;
1115 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyClickHdl, weld::ToggleButton&, void)
1117 RangeModifyHdl(m_xWidthMF->get_widget());
1120 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyHdl, weld::Widget&, void)
1122 if (m_bPositioningDisabled)
1123 return;
1124 SvxSwFrameValidation aVal;
1126 aVal.nAnchorType = GetAnchorType();
1127 aVal.bAutoHeight = false;
1128 aVal.bMirror = m_xHoriMirrorCB->get_active();
1129 // #i18732#
1130 aVal.bFollowTextFlow = m_xFollowCB->get_active();
1132 if ( m_pHMap )
1134 // horizontal alignment
1135 sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriToLB);
1136 sal_uInt16 nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
1137 sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
1139 aVal.nHoriOrient = static_cast<short>(nAlign);
1140 aVal.nHRelOrient = static_cast<short>(nRel);
1142 else
1143 aVal.nHoriOrient = HoriOrientation::NONE;
1145 if ( m_pVMap )
1147 // vertical alignment
1148 sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
1149 sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
1150 sal_uInt16 nRel = GetRelation(*m_xVertToLB);
1152 aVal.nVertOrient = static_cast<short>(nAlign);
1153 aVal.nVRelOrient = static_cast<short>(nRel);
1155 else
1156 aVal.nVertOrient = VertOrientation::NONE;
1158 const auto nAtHorzPosVal = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
1159 const auto nAtVertPosVal = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
1161 aVal.nHPos = nAtHorzPosVal;
1162 aVal.nVPos = nAtVertPosVal;
1164 sal_Int32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
1165 sal_Int32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
1166 aVal.nWidth = nWidth;
1167 aVal.nHeight = nHeight;
1169 m_aValidateLink.Call(aVal);
1171 // minimum width also for style
1172 m_xHeightMF->set_min(m_xHeightMF->normalize(aVal.nMinHeight), FieldUnit::TWIP);
1173 m_xWidthMF->set_min(m_xWidthMF->normalize(aVal.nMinWidth), FieldUnit::TWIP);
1175 sal_Int32 nMaxWidth(aVal.nMaxWidth);
1176 sal_Int32 nMaxHeight(aVal.nMaxHeight);
1178 sal_Int64 nTmp = m_xHeightMF->normalize(nMaxHeight);
1179 m_xHeightMF->set_max(nTmp, FieldUnit::TWIP);
1181 nTmp = m_xWidthMF->normalize(nMaxWidth);
1182 m_xWidthMF->set_max(nTmp, FieldUnit::TWIP);
1184 m_xHoriByMF->set_range(m_xHoriByMF->normalize(aVal.nMinHPos),
1185 m_xHoriByMF->normalize(aVal.nMaxHPos), FieldUnit::TWIP);
1186 if ( aVal.nHPos != nAtHorzPosVal )
1187 m_xHoriByMF->set_value(m_xHoriByMF->normalize(aVal.nHPos), FieldUnit::TWIP);
1189 m_xVertByMF->set_range(m_xVertByMF->normalize(aVal.nMinVPos),
1190 m_xVertByMF->normalize(aVal.nMaxVPos), FieldUnit::TWIP);
1191 if ( aVal.nVPos != nAtVertPosVal )
1192 m_xVertByMF->set_value(m_xVertByMF->normalize(aVal.nVPos), FieldUnit::TWIP);
1195 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, AnchorTypeHdl, weld::ToggleButton&, void)
1197 m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
1199 // #i18732# - enable check box 'Follow text flow' for anchor
1200 // type to-paragraph' and to-character
1201 m_xFollowCB->set_sensitive(m_xToParaRB->get_active() || m_xToCharRB->get_active());
1203 RndStdIds nId = GetAnchorType();
1205 InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
1206 RangeModifyHdl(m_xWidthMF->get_widget());
1208 if(m_bHtmlMode)
1210 PosHdl(*m_xHoriLB);
1211 PosHdl(*m_xVertLB);
1215 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, MirrorHdl, weld::ToggleButton&, void)
1217 RndStdIds nId = GetAnchorType();
1218 InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
1221 IMPL_LINK( SvxSwPosSizeTabPage, RelHdl, weld::ComboBox&, rLB, void )
1223 bool bHori = &rLB == m_xHoriToLB.get();
1225 UpdateExample();
1227 if (m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()) // again special treatment
1229 if(bHori)
1231 sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
1232 if(RelOrientation::PRINT_AREA == nRel && 0 == m_xVertLB->get_active())
1234 m_xVertLB->set_active(1);
1236 else if(RelOrientation::CHAR == nRel && 1 == m_xVertLB->get_active())
1238 m_xVertLB->set_active(0);
1242 RangeModifyHdl(m_xWidthMF->get_widget());
1245 IMPL_LINK(SvxSwPosSizeTabPage, PosHdl, weld::ComboBox&, rLB, void)
1247 bool bHori = &rLB == m_xHoriLB.get();
1248 weld::ComboBox* pRelLB = bHori ? m_xHoriToLB.get() : m_xVertToLB.get();
1249 weld::Label* pRelFT = bHori ? m_xHoriToFT.get() : m_xVertToFT.get();
1250 FrmMap const *pMap = bHori ? m_pHMap : m_pVMap;
1253 sal_uInt16 nMapPos = GetMapPos(pMap, rLB);
1254 sal_uInt16 nAlign = GetAlignment(pMap, nMapPos, *pRelLB);
1256 if (bHori)
1258 bool bEnable = HoriOrientation::NONE == nAlign;
1259 m_xHoriByMF->set_sensitive( bEnable );
1260 m_xHoriByFT->set_sensitive( bEnable );
1262 else
1264 bool bEnable = VertOrientation::NONE == nAlign;
1265 m_xVertByMF->set_sensitive( bEnable );
1266 m_xVertByFT->set_sensitive( bEnable );
1269 RangeModifyHdl(m_xWidthMF->get_widget());
1271 short nRel = 0;
1272 if (rLB.get_active() != -1)
1274 if (pRelLB->get_active() != -1)
1275 nRel = reinterpret_cast<RelationMap*>(pRelLB->get_active_id().toUInt64())->nRelation;
1277 FillRelLB(pMap, nMapPos, nAlign, nRel, *pRelLB, *pRelFT);
1279 else
1280 pRelLB->clear();
1282 UpdateExample();
1284 // special treatment for HTML-Mode with horz-vert-dependencies
1285 if (m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType())
1287 bool bSet = false;
1288 if(bHori)
1290 // on the right only below is allowed - from the left only at the top
1291 // from the left at the character -> below
1292 if((HoriOrientation::LEFT == nAlign || HoriOrientation::RIGHT == nAlign) &&
1293 0 == m_xVertLB->get_active())
1295 if(RelOrientation::FRAME == nRel)
1296 m_xVertLB->set_active(1);
1297 else
1298 m_xVertLB->set_active(0);
1299 bSet = true;
1301 else if(HoriOrientation::LEFT == nAlign && 1 == m_xVertLB->get_active())
1303 m_xVertLB->set_active(0);
1304 bSet = true;
1306 else if(HoriOrientation::NONE == nAlign && 1 == m_xVertLB->get_active())
1308 m_xVertLB->set_active(0);
1309 bSet = true;
1311 if(bSet)
1312 PosHdl(*m_xVertLB);
1314 else
1316 if(VertOrientation::TOP == nAlign)
1318 if(1 == m_xHoriLB->get_active())
1320 m_xHoriLB->set_active(0);
1321 bSet = true;
1323 m_xHoriToLB->set_active(1);
1325 else if(VertOrientation::CHAR_BOTTOM == nAlign)
1327 if(2 == m_xHoriLB->get_active())
1329 m_xHoriLB->set_active(0);
1330 bSet = true;
1332 m_xHoriToLB->set_active(0) ;
1334 if(bSet)
1335 PosHdl(*m_xHoriLB);
1341 IMPL_LINK( SvxSwPosSizeTabPage, ModifyHdl, weld::MetricSpinButton&, rEdit, void )
1343 auto nWidth = m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP));
1344 auto nHeight = m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP));
1345 if (m_xKeepRatioCB->get_active())
1347 if ( &rEdit == m_xWidthMF.get() )
1349 nHeight = int(static_cast<double>(nWidth) / m_fWidthHeightRatio);
1350 m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
1352 else if(&rEdit == m_xHeightMF.get())
1354 nWidth = int(static_cast<double>(nHeight) * m_fWidthHeightRatio);
1355 m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
1358 m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
1359 UpdateExample();
1362 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, ProtectHdl, weld::ToggleButton&, void)
1364 if (m_xSizeCB->get_sensitive())
1366 m_nProtectSizeState = m_xSizeCB->get_state();
1369 m_xSizeCB->set_state(m_xPositionCB->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : m_nProtectSizeState);
1370 m_xSizeCB->set_sensitive(m_xPositionCB->get_sensitive() && !m_xPositionCB->get_active());
1373 short SvxSwPosSizeTabPage::GetRelation(const weld::ComboBox& rRelationLB)
1375 short nRel = 0;
1376 int nPos = rRelationLB.get_active();
1377 if (nPos != -1)
1379 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rRelationLB.get_id(nPos).toUInt64());
1380 nRel = pEntry->nRelation;
1383 return nRel;
1386 short SvxSwPosSizeTabPage::GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox& rRelationLB)
1388 short nAlign = 0;
1390 // #i22341# - special handling also for map <aVCharMap>,
1391 // because it contains ambiguous items for alignment
1392 if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap ||
1393 pMap == aVCharMap )
1395 if (rRelationLB.get_active() != -1)
1397 LB nRel = reinterpret_cast<RelationMap*>(rRelationLB.get_active_id().toUInt64())->nLBRelation;
1398 std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1399 SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
1401 for (std::size_t i = 0; i < nMapCount; i++)
1403 if (pMap[i].eStrId == eStrId)
1405 LB nLBRelations = pMap[i].nLBRelations;
1406 if (nLBRelations & nRel)
1408 nAlign = pMap[i].nAlign;
1409 break;
1415 else if (pMap)
1416 nAlign = pMap[nMapPos].nAlign;
1418 return nAlign;
1421 sal_uInt16 SvxSwPosSizeTabPage::GetMapPos(FrmMap const *pMap, const weld::ComboBox& rAlignLB)
1423 sal_uInt16 nMapPos = 0;
1424 int nLBSelPos = rAlignLB.get_active();
1426 if (nLBSelPos != -1)
1428 if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
1430 std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1431 OUString sSelEntry(rAlignLB.get_active_text());
1433 for (std::size_t i = 0; i < nMapCount; i++)
1435 SvxSwFramePosString::StringId eResId = pMap[i].eStrId;
1437 OUString sEntry = SvxSwFramePosString::GetString(eResId);
1439 if (sEntry == sSelEntry)
1441 nMapPos = sal::static_int_cast< sal_uInt16 >(i);
1442 break;
1446 else
1447 nMapPos = nLBSelPos;
1450 return nMapPos;
1453 void SvxSwPosSizeTabPage::InitPos(RndStdIds nAnchor,
1454 sal_uInt16 nH,
1455 sal_uInt16 nHRel,
1456 sal_uInt16 nV,
1457 sal_uInt16 nVRel,
1458 long nX,
1459 long nY)
1461 int nPos = m_xVertLB->get_active();
1462 if (nPos != -1 && m_pVMap)
1464 m_nOldV = m_pVMap[nPos].nAlign;
1465 nPos = m_xVertToLB->get_active();
1466 if (nPos != -1)
1467 m_nOldVRel = reinterpret_cast<RelationMap*>(m_xVertToLB->get_id(nPos).toUInt64())->nRelation;
1470 nPos = m_xHoriLB->get_active();
1471 if (nPos != -1 && m_pHMap)
1473 m_nOldH = m_pHMap[nPos].nAlign;
1475 nPos = m_xHoriToLB->get_active();
1476 if (nPos != -1)
1477 m_nOldHRel = reinterpret_cast<RelationMap*>(m_xHoriToLB->get_id(nPos).toUInt64())->nRelation;
1480 bool bEnable = true;
1481 if( m_bIsMultiSelection )
1483 m_pVMap = aVMultiSelectionMap;
1484 m_pHMap = aHMultiSelectionMap;
1486 else if (nAnchor == RndStdIds::FLY_AT_PAGE)
1488 m_pVMap = m_bHtmlMode ? aVPageHtmlMap : aVPageMap;
1489 m_pHMap = m_bHtmlMode ? aHPageHtmlMap : aHPageMap;
1491 else if (nAnchor == RndStdIds::FLY_AT_FLY)
1493 // #i18732# - own vertical alignment map for to frame
1494 // anchored objects.
1495 m_pVMap = m_bHtmlMode ? aVFlyHtmlMap : aVFrameMap;
1496 m_pHMap = m_bHtmlMode ? aHFlyHtmlMap : aHFrameMap;
1498 else if (nAnchor == RndStdIds::FLY_AT_PARA)
1500 if(m_bHtmlMode)
1502 m_pVMap = aVParaHtmlMap;
1503 m_pHMap = aHParaHtmlAbsMap;
1505 else
1507 m_pVMap = aVParaMap;
1508 m_pHMap = aHParaMap;
1511 else if (nAnchor == RndStdIds::FLY_AT_CHAR)
1513 if(m_bHtmlMode)
1515 m_pVMap = aVCharHtmlAbsMap;
1516 m_pHMap = aHCharHtmlAbsMap;
1518 else
1520 m_pVMap = aVCharMap;
1521 m_pHMap = aHCharMap;
1524 else if (nAnchor == RndStdIds::FLY_AS_CHAR)
1526 m_pVMap = m_bHtmlMode ? aVAsCharHtmlMap : aVAsCharMap;
1527 m_pHMap = nullptr;
1528 bEnable = false;
1530 m_xHoriLB->set_sensitive(bEnable);
1531 m_xHoriFT->set_sensitive(bEnable);
1533 // select current Pos
1534 // horizontal
1535 if ( nH == USHRT_MAX )
1537 nH = m_nOldH;
1538 nHRel = m_nOldHRel;
1540 // #i22341# - pass <nHRel> as 3rd parameter to method <FillPosLB>
1541 sal_uInt16 nMapPos = FillPosLB(m_pHMap, nH, nHRel, *m_xHoriLB);
1542 FillRelLB(m_pHMap, nMapPos, nH, nHRel, *m_xHoriToLB, *m_xHoriToFT);
1544 // vertical
1545 if ( nV == USHRT_MAX )
1547 nV = m_nOldV;
1548 nVRel = m_nOldVRel;
1550 // #i22341# - pass <nVRel> as 3rd parameter to method <FillPosLB>
1551 nMapPos = FillPosLB(m_pVMap, nV, nVRel, *m_xVertLB);
1552 FillRelLB(m_pVMap, nMapPos, nV, nVRel, *m_xVertToLB, *m_xVertToFT);
1554 // Edits init
1555 bEnable = nH == HoriOrientation::NONE && nAnchor != RndStdIds::FLY_AS_CHAR; //#61359# why not in formats&& !bFormat;
1556 if (!bEnable)
1558 m_xHoriByMF->set_value(0, FieldUnit::TWIP);
1560 else if(m_bIsMultiSelection)
1562 m_xHoriByMF->set_value(m_xHoriByMF->normalize(m_aRect.Left()), FieldUnit::TWIP);
1564 else
1566 if (nX != LONG_MAX)
1567 m_xHoriByMF->set_value(m_xHoriByMF->normalize(nX), FieldUnit::TWIP);
1569 m_xHoriByFT->set_sensitive(bEnable);
1570 m_xHoriByMF->set_sensitive(bEnable);
1572 bEnable = nV == VertOrientation::NONE;
1573 if ( !bEnable )
1575 m_xVertByMF->set_value( 0, FieldUnit::TWIP );
1577 else if(m_bIsMultiSelection)
1579 m_xVertByMF->set_value(m_xVertByMF->normalize(m_aRect.Top()), FieldUnit::TWIP);
1581 else
1583 if (nAnchor == RndStdIds::FLY_AS_CHAR)
1585 if ( nY == LONG_MAX )
1586 nY = 0;
1587 else
1588 nY *= -1;
1590 if ( nY != LONG_MAX )
1591 m_xVertByMF->set_value( m_xVertByMF->normalize(nY), FieldUnit::TWIP );
1593 m_xVertByFT->set_sensitive( bEnable );
1594 m_xVertByMF->set_sensitive( bEnable );
1595 UpdateExample();
1598 void SvxSwPosSizeTabPage::UpdateExample()
1600 int nPos = m_xHoriLB->get_active();
1601 if (m_pHMap && nPos != -1)
1603 sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
1604 short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
1605 short nRel = GetRelation(*m_xHoriToLB);
1607 m_aExampleWN.SetHAlign(nAlign);
1608 m_aExampleWN.SetHoriRel(nRel);
1611 nPos = m_xVertLB->get_active();
1612 if (m_pVMap && nPos != -1)
1614 sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
1615 sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
1616 sal_uInt16 nRel = GetRelation(*m_xVertToLB);
1618 m_aExampleWN.SetVAlign(nAlign);
1619 m_aExampleWN.SetVertRel(nRel);
1622 // Size
1623 auto nXPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
1624 auto nYPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
1625 m_aExampleWN.SetRelPos(Point(nXPos, nYPos));
1627 m_aExampleWN.SetAnchor( GetAnchorType() );
1628 m_aExampleWN.Invalidate();
1631 void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, sal_uInt16 nMapPos, sal_uInt16 nAlign,
1632 sal_uInt16 nRel, weld::ComboBox& rLB, weld::Label& rFT)
1634 OUString sSelEntry;
1635 LB nLBRelations = LB::NONE;
1636 std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1638 rLB.clear();
1640 if (nMapPos < nMapCount)
1642 if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
1644 OUString sOldEntry(rLB.get_active_text());
1645 SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
1647 for (std::size_t _nMapPos = 0; _nMapPos < nMapCount; _nMapPos++)
1649 if (pMap[_nMapPos].eStrId == eStrId)
1651 nLBRelations = pMap[_nMapPos].nLBRelations;
1652 for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aAsCharRelationMap); nRelPos++)
1654 if (nLBRelations & aAsCharRelationMap[nRelPos].nLBRelation)
1656 SvxSwFramePosString::StringId sStrId1 = aAsCharRelationMap[nRelPos].eStrId;
1658 sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
1659 OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
1660 rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aAsCharRelationMap[nRelPos])), sEntry);
1661 if (pMap[_nMapPos].nAlign == nAlign)
1662 sSelEntry = sEntry;
1663 break;
1668 if (!sSelEntry.isEmpty())
1669 rLB.set_active_text(sSelEntry);
1670 else
1672 rLB.set_active_text(sOldEntry);
1673 if (rLB.get_active() == -1)
1675 for (int i = 0; i < rLB.get_count(); i++)
1677 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
1678 if (pEntry->nLBRelation == LB::RelChar) // Default
1680 rLB.set_active(i);
1681 break;
1687 else
1689 // #i22341# - special handling for map <aVCharMap>,
1690 // because its ambiguous in its <eStrId>/<eMirrorStrId>.
1691 if ( pMap == aVCharMap )
1693 nLBRelations = ::lcl_GetLBRelationsForStrID( pMap,
1694 ( m_xHoriMirrorCB->get_active()
1695 ? pMap[nMapPos].eMirrorStrId
1696 : pMap[nMapPos].eStrId ),
1697 m_xHoriMirrorCB->get_active() );
1699 else
1701 nLBRelations = pMap[nMapPos].nLBRelations;
1704 for (sal_uLong nBit = 1; nBit < sal_uLong(LB::LAST); nBit <<= 1)
1706 if (nLBRelations & static_cast<LB>(nBit))
1708 for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aRelationMap); nRelPos++)
1710 if (aRelationMap[nRelPos].nLBRelation == static_cast<LB>(nBit))
1712 SvxSwFramePosString::StringId sStrId1 = m_xHoriMirrorCB->get_active() ? aRelationMap[nRelPos].eMirrorStrId : aRelationMap[nRelPos].eStrId;
1713 sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
1714 OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
1715 rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aRelationMap[nRelPos])), sEntry);
1716 if (sSelEntry.isEmpty() && aRelationMap[nRelPos].nRelation == nRel)
1717 sSelEntry = sEntry;
1722 if (!sSelEntry.isEmpty())
1723 rLB.set_active_text(sSelEntry);
1724 else
1726 // Probably anchor change. So look for a similar relation.
1727 switch (nRel)
1729 case RelOrientation::FRAME: nRel = RelOrientation::PAGE_FRAME; break;
1730 case RelOrientation::PRINT_AREA: nRel = RelOrientation::PAGE_PRINT_AREA; break;
1731 case RelOrientation::PAGE_LEFT: nRel = RelOrientation::FRAME_LEFT; break;
1732 case RelOrientation::PAGE_RIGHT: nRel = RelOrientation::FRAME_RIGHT; break;
1733 case RelOrientation::FRAME_LEFT: nRel = RelOrientation::PAGE_LEFT; break;
1734 case RelOrientation::FRAME_RIGHT: nRel = RelOrientation::PAGE_RIGHT; break;
1735 case RelOrientation::PAGE_FRAME: nRel = RelOrientation::FRAME; break;
1736 case RelOrientation::PAGE_PRINT_AREA: nRel = RelOrientation::PRINT_AREA; break;
1738 default:
1739 if (rLB.get_count())
1741 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(rLB.get_count() - 1).toUInt64());
1742 nRel = pEntry->nRelation;
1744 break;
1747 for (int i = 0; i < rLB.get_count(); ++i)
1749 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
1750 if (pEntry->nRelation == nRel)
1752 rLB.set_active(i);
1753 break;
1757 if (rLB.get_active() == -1)
1758 rLB.set_active(0);
1763 rLB.set_sensitive(rLB.get_count() != 0);
1764 rFT.set_sensitive(rLB.get_count() != 0);
1766 RelHdl(rLB);
1769 sal_uInt16 SvxSwPosSizeTabPage::FillPosLB(FrmMap const *_pMap,
1770 sal_uInt16 _nAlign,
1771 const sal_uInt16 _nRel,
1772 weld::ComboBox& _rLB)
1774 OUString sSelEntry, sOldEntry;
1775 sOldEntry = _rLB.get_active_text();
1777 _rLB.clear();
1779 // #i22341# - determine all possible listbox relations for
1780 // given relation for map <aVCharMap>
1781 const LB nLBRelations = (_pMap != aVCharMap)
1782 ? LB::NONE
1783 : ::lcl_GetLBRelationsForRelations( _nRel );
1785 // fill listbox
1786 std::size_t nCount = ::lcl_GetFrmMapCount(_pMap);
1787 for (std::size_t i = 0; _pMap && i < nCount; ++i)
1789 SvxSwFramePosString::StringId eStrId = m_xHoriMirrorCB->get_active() ? _pMap[i].eMirrorStrId : _pMap[i].eStrId;
1790 eStrId = lcl_ChangeResIdToVerticalOrRTL(eStrId, m_bIsVerticalFrame, m_bIsInRightToLeft);
1791 OUString sEntry(SvxSwFramePosString::GetString(eStrId));
1792 if (_rLB.find_text(sEntry) == -1)
1794 // don't insert duplicate entries at character wrapped borders
1795 _rLB.append_text(sEntry);
1797 // #i22341# - add condition to handle map <aVCharMap>
1798 // that is ambiguous in the alignment.
1799 if ( _pMap[i].nAlign == _nAlign &&
1800 ( _pMap != aVCharMap || _pMap[i].nLBRelations & nLBRelations ) )
1802 sSelEntry = sEntry;
1806 _rLB.set_active_text(sSelEntry);
1807 if (_rLB.get_active() == -1)
1808 _rLB.set_active_text(sOldEntry);
1810 if (_rLB.get_active() == -1)
1811 _rLB.set_active(0);
1813 PosHdl(_rLB);
1815 return GetMapPos(_pMap, _rLB);
1818 void SvxSwPosSizeTabPage::SetView( const SdrView* pSdrView )
1820 m_pSdrView = pSdrView;
1821 if(!m_pSdrView)
1823 OSL_FAIL("No SdrView* set");
1824 return;
1827 // setting of the rectangle and the working area
1828 m_aRect = m_pSdrView->GetAllMarkedRect();
1829 m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
1831 // get WorkArea
1832 m_aWorkArea = m_pSdrView->GetWorkArea();
1834 // consider anchor position (for Writer)
1835 const SdrMarkList& rMarkList = m_pSdrView->GetMarkedObjectList();
1836 if( rMarkList.GetMarkCount() > 0 )
1838 const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
1839 m_aAnchorPos = pObj->GetAnchorPos();
1841 if( m_aAnchorPos != Point(0,0) ) // -> Writer
1843 for( size_t i = 1; i < rMarkList.GetMarkCount(); ++i )
1845 pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
1846 if( m_aAnchorPos != pObj->GetAnchorPos() )
1848 // different anchor positions -> disable positioning
1849 m_xPosFrame->set_sensitive(false);
1850 m_bPositioningDisabled = true;
1851 return;
1855 Point aPt = m_aAnchorPos * -1;
1856 Point aPt2 = aPt;
1858 aPt += m_aWorkArea.TopLeft();
1859 m_aWorkArea.SetPos( aPt );
1861 aPt2 += m_aRect.TopLeft();
1862 m_aRect.SetPos( aPt2 );
1865 // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
1866 if( rMarkList.GetMarkCount() != 1 )
1867 m_bIsMultiSelection = true;
1868 #if OSL_DEBUG_LEVEL > 1
1869 else
1871 const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
1872 SdrObjKind eKind = (SdrObjKind) pObj->GetObjIdentifier();
1873 if( ( pObj->GetObjInventor() == SdrInventor::Default ) &&
1874 ( eKind==OBJ_TEXT || eKind==OBJ_TITLETEXT || eKind==OBJ_OUTLINETEXT) &&
1875 pObj->HasText() )
1877 OSL_FAIL("AutoWidth/AutoHeight should be enabled");
1880 #endif
1883 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */